Structures. And make the entity property of the structure. But there are many ways to handle them. This is the architecture that I use for handling a "complex" data structure (keep in mind some data-types and functions are fictional, you'll have to make these yourself):

Code:
//complex structure
typedef struct {
  
  BOOL alive; //indicates if the NPC is alive
  BOOL freeze; //indicates if the NPC is frozen
  
  ENTITY* appearance; //the model for the NPC
  unsigned short npc_type; //what kind of NPC
  unsigned int anim_state; //animation state

  VECTOR* pos;     //current position (passed on to ENTITY*
  VECTOR* target;  //target to move to

  DIALOGUES*  dialoges; //NPC's dialogues
  LINKEDLIST* questlist; //NPC's questlist
  
} NPC;



//npc function (called by create_npc)
void handle_npc(NPC* npc) {
  while(npc->alive == true) {
    //do everything here
    wait(1);
  }

  //npc is dead, apparantly... remove the object!
  remove_npc(npc);
}



//creator function (called by game-logic)
NPC* create_npc(STRING* npc_model, VECTOR* start_pos) {

  //allocate memory for a new NPC!
  NPC* npc = (NPC*)malloc(sizeof(NPC));

  npc->alive = true;
  npc->freeze = false;
  
  npc->appearance = ent_create(npc_model, start_pos, NULL);
  npc->npc_type = NPC_VILLAGER; //regular villager
  npc->anim_state = 0; //start at idle animation

  npc->pos = pos;
  npc->target = NULLVECTOR;

  npc->dialogues = get_dialogues(DIALOGUE_VILLAGER); //get dialogue of the villager
  npc->questlist = create_linkedlist();

    //give the NPC two quests at creation
    add_linkedlist_item( npc->questlist, "quest_1"); //add new item to the linkedlist
    add_linkedlist_item( npc->questlist, "quest_2"); //add new item to the linkedlist

    handle_npc(npc); //start it's main function

    return(npc); //return pointer to the calling function for possible further process
}



//removing function (called by handle_npc())
void remove_npc(NPC* npc) {
  //remove all the stored objects that are only stored as pointer first before removing the npc itself.
  //else we'd lose spaces of memory because we throw away the only pointer available to the object.
  ptr_remove( npc->appearance );
  ptr_remove( npc->pos );
  ptr_remove( npc->target );
 
  //ptr_remove can't throw away our own created structures, we need to call their remove functions to prevent memory gaps.
  //just like we do with this npc remove function.
  //note that we don't use remove_dialogues( npc->dialogues ); because more NPC's make use of the same dialogue. This data array is shared.
  remove_linkedlist( npc->questlist ); //this function will then throw away all the objects stored in the linked list (the two quests we assigned earlier).

  //at last, we can remove the npc object safely
  ptr_remove(npc);
}


And this is, then, the code collection of one object in your game. I put each and every object in a separate file to keep things clear.

simply call create_npc("npc1.mdl", NULLVECTOR); and tatam! You'll get a self-functional NPC.
Of course, my code wont work unless you also create all the other missing structures and functions, but it's just an example.


Last edited by Joozey; 11/30/08 23:50.

Click and join the 3dgs irc community!
Room: #3dgs