#include #include #include // memcpy #include "tile.h" #include "wall.h" #include "common.h" #include "npc.h" #include "message.h" #include "player.h" /**** allocateTile Allocated the memory for a new Tile to the passed Tile pointer and sets the tid and id to the new Tile struct. Arguments: struct Tile** tile, unsigned int tid, short id Returns: ERROR if malloc fails SUCCESS if malloc is ok ****/ int allocateTile(struct Tile** tile, unsigned int tid, short id) { *tile = (struct Tile *) malloc(sizeof(struct Tile)); if (tile == NULL) { printf("ERROR: could not malloc Tile"); return ERROR; } (*tile)->tid = tid; (*tile)->id = id; return SUCCESS; } /**** freeTile Frees the given tile's memory Arguments: struct Tile* tile Returns: void ****/ void freeTile(struct Tile* tile) { // @@ FIXME //free(tile->data); free(tile); } /**** newTile Defacto function for creating a new Tile. Handles populating the default Tile->data struct. Arguments: unsignted int type_id, short id, short x, short y Returns: struct Tile* ****/ struct Tile *newTile(unsigned int type_id, short id, short x, short y) { struct Tile *new_tile; new_tile = malloc(sizeof(struct Tile)); if (new_tile == NULL) { printf("ERROR: could not malloc Tile"); return NULL; } new_tile->tid = type_id; new_tile->id = id; new_tile->x = x; new_tile->y = y; new_tile->next = NULL; new_tile->prev = NULL; switch(type_id) { case WALL: new_tile->data = (WallTile *) malloc(sizeof(WallTile)); memcpy(new_tile->data, &walls[id], sizeof(WallTile)); break; case FLOOR: new_tile->data = (FloorTile *) malloc(sizeof(FloorTile)); memcpy(new_tile->data, &floors[id], sizeof(FloorTile)); break; case DOOR: new_tile->data = (struct DoorTile *) malloc(sizeof(struct DoorTile)); memcpy(new_tile->data, &doors[id], sizeof(struct DoorTile)); break; case PLAYER: new_tile->data = (struct PlayerTile *) malloc(sizeof(struct PlayerTile)); memcpy(new_tile->data, &players[id], sizeof(struct PlayerTile)); break; case NPC: new_tile->data = (struct NpcTile *) malloc(sizeof(struct NpcTile)); memcpy(new_tile->data, &npcs[id], sizeof(struct NpcTile)); break; case ITEM: new_tile->data = (struct ItemTile *) malloc(sizeof(struct ItemTile)); memcpy(new_tile->data, &items[id], sizeof(struct ItemTile)); break; case EQUIP: new_tile->data = (struct EquipTile *) malloc(sizeof(struct EquipTile)); memcpy(new_tile->data, &equips[id], sizeof(struct EquipTile)); break; default: new_tile->data = (struct BasicTile *) malloc(sizeof(struct BasicTile)); memcpy(new_tile->data, &walls[id], sizeof(struct BasicTile)); break; } return (new_tile); } /**** activateTile This function attempts to activate the target_tile through the activator_tile. The common usage scenario would be a PlayerTile activating a DoorTile to open/close it. Depending on if the activation succeeds or not, messageTile is called from the target_tile to the activator_tile to notify the activator that a change has occurred. Arguments: struct Tile *target_tile, struct Tile *activator_tile Returns: 0 on anything TODO: probably make it return void or return the new state of the target_tile ****/ int activateTile(struct Tile *target_tile, struct Tile *activator_tile) { char string[64]; if (target_tile) { switch (target_tile->tid) { case DOOR: switch (((struct DoorTile*)target_tile->data)->state) { case STATE_OPEN: ((struct DoorTile*)target_tile->data)->state = STATE_CLOSED; sprintf(string, MESSAGE_CLOSE, ((struct BasicTile*)target_tile->data)->name); break; case STATE_CLOSED: ((struct DoorTile*)target_tile->data)->state = STATE_OPEN; sprintf(string, MESSAGE_OPEN, ((struct BasicTile*)target_tile->data)->name); break; } messageTile(target_tile, activator_tile, string); return ((struct DoorTile*)target_tile->data)->state; break; case NPC: sprintf(string, MESSAGE_ACTIVATE_NAUGHTY, ((struct BasicTile*)target_tile->data)->name); break; default: sprintf(string, MESSAGE_ACTIVATE_FAIL); break; } } else { sprintf(string, MESSAGE_ACTIVATE_NULL); } messageTile(target_tile, activator_tile, string); return 0; } /**** removeFromChain Cleanly removes the passed Tile from its position in the Tile Chain. Connects its neighbors if either exist. Arguments: struct Tile *tile Returns: void ****/ void removeFromChain(struct Tile* tile) { if (tile->prev) { if (tile->next) { tile->prev->next = tile->next; } else { tile->prev->next = NULL; } } if (tile->next) { if (tile->prev) { tile->next->prev = tile->prev; } else { tile->next->prev= NULL; } } tile->prev = NULL; // we exist in limbo tile->next = NULL; } /**** Iterates from given Tile's position until the last Tile in the Chain is reached, then returns a pointer to the last Tile. Arguments: struct Tile *starting_tile Returns: struct Tile* ****/ struct Tile *getLastTile(struct Tile* tile) { if (!tile->next) { return tile; // passed tile IS end of chain } else { struct Tile *target = tile->next; while (target) { if (!target->next) return target; // found it target = target->next; } } return NULL; } /* current tile entries. TODO: parse tiles from some sort of data file (future modding!) */ struct DoorTile doors[] = { { "wooden door", STATE_CLOSED } // 0 }; struct PlayerTile players[] = { { "selfie", 16, "S8D8C8I8W8C8", "H1F1N2S2A2a2h2D8w2T1W1L2l2f2" } //{ 10, 10, 8, 6, 6, 6 }, { 1, 1, 1, 2, 2, 2, 2, 10, 1, 1, 2, 2, 2 } } }; //{ collision, name, target tile, behavior, basevision} struct NpcTile npcs[] = { { "nupi", 4, BEHAVE_WANDER, "S6D6C8I4W4C4" } }; struct ItemTile items[] = { { "small key" }, }; struct EquipTile equips[] = { { "small macana", 1, "w1", "P1d4", "P1", "", "" }, { "large macana", 1, "w2", "P1d8", "P2", "", "" } };