Dynamically Adding Entities to a geWorld
Posted: Sat Oct 20, 2007 7:41 pm
The following code allows to add an entity to a geWorld at runtime. The entity can be of any class that is available in the editor
(as all entity class definitions are stored in the bsp file even if there is actually no entity of a specific type). All you have to pass to
the function is the current world, the name of the entity class, a name for the entity to identify it and the user data for that entity.
On success the function returns a pointer to the created geEntity, otherwise it returns a NULL pointer.
in Genesis.h add
in World.c add
(as all entity class definitions are stored in the bsp file even if there is actually no entity of a specific type). All you have to pass to
the function is the current world, the name of the entity class, a name for the entity to identify it and the user data for that entity.
On success the function returns a pointer to the created geEntity, otherwise it returns a NULL pointer.

in Genesis.h add
Code: Select all
GENESISAPI geEntity* geWorld_AddEntity(
geWorld *World,
const char *ClassName,
const char *EntityName,
void *UserData)
Code: Select all
//========================================================================================
// geWorld_AddEntity
//========================================================================================
GENESISAPI geEntity* geWorld_AddEntity(
geWorld *World,
const char *ClassName,
const char *EntityName,
void *UserData)
{
geWorld_EntClassSet *WSets;
int32 i;
geEntity *Entity;
geEntity_Class *Class;
assert(World);
// No classname, just return
if(!ClassName || !EntityName ||!UserData)
{
return NULL;
}
WSets = World->EntClassSets;
Entity = geEntity_Create();
if(!Entity)
{
return NULL;
}
// Add it to the main set
if(!geEntity_EntitySetAddEntity(WSets[0].Set, Entity))
{
geEntity_Destroy(Entity);
return NULL;
}
// create Epair for name (every entity needs one - should be unique but we don't check for it here)
{
geEntity_Epair *EntityNameEpair = geEntity_EpairCreate();
EntityNameEpair->Key = geRam_Allocate(strlen("%Name%")+1);
strcpy(EntityNameEpair->Key, "%Name%");
EntityNameEpair->Value = geRam_Allocate(strlen(EntityName)+1);
strcpy(EntityNameEpair->Value, EntityName);
geEntity_AddEpair(Entity, EntityNameEpair);
}
// remember type class
Class = geEntity_EntitySetFindClassByName(WSets[0].Set, ClassName);
if(!Class)
{
geEntity_Destroy(Entity);
return NULL;
}
Entity->Class = Class;
// allocate space for user data
Entity->UserData = GE_RAM_ALLOCATE_ARRAY(char, Entity->Class->FieldSize);
if(!Entity->UserData)
{
geEntity_Destroy(Entity);
return NULL;
}
memcpy(Entity->UserData, UserData, Entity->Class->FieldSize);
// check all fields and look if there are any strings in this entity class
// if so, add a new Epair, copy the string to the Epair->Value and
// set the char pointer in the UserData to point to Epair->Value
{
geEntity_Field *Field;
char *UData = Entity->UserData;
for(Field=Class->Fields; Field; Field=Field->Next)
{
if(Field->TypeClass->Type == TYPE_STRING)
{
if(*(char**)(UData + Field->Offset) != NULL)
{
geEntity_Epair *Epair = geEntity_EpairCreate();
// get fieldname
Epair->Key = geRam_Allocate(strlen(Field->Name)+1);
strcpy(Epair->Key, Field->Name);
// copy string
Epair->Value = geRam_Allocate(strlen(*(char**)(UData + Field->Offset))+1);
strcpy(Epair->Value, *(char**)(UData + Field->Offset));
*(char**)(UData + Field->Offset) = Epair->Value;
// add epair to entity
geEntity_AddEpair(Entity, Epair);
}
}
}
}
// insert entity in class list
for(i=1; i<World->NumEntClassSets; i++)
{
assert(WSets[i].Set);
if(!stricmp(WSets[i].ClassName, ClassName))
{
geEntity_EntitySetAddEntity(WSets[i].Set, Entity);
return Entity;
}
}
if(i >= MAX_WORLD_ENT_CLASS_SETS)
{
geEntity_Destroy(Entity);
return NULL; // oh well...
}
// Create a new entity set
WSets[i].Set = geEntity_EntitySetCreate();
// Insert the entity into a new class set
WSets[i].ClassName = Entity->Class->Name;
geEntity_EntitySetAddEntity(WSets[i].Set, Entity);
World->NumEntClassSets++;
return Entity;
}