197 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			C
		
	
	
			
		
		
	
	
			197 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			C
		
	
	
| #include <stdlib.h>
 | |
| #include <stdio.h>
 | |
| #include <string.h> // 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;
 | |
|     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;
 | |
| }
 | |
| 
 | |
| struct DoorTile doors[] = {
 | |
| 	{ NO_PASS, "wooden door", STATE_CLOSED } // 0
 | |
| };
 | |
| 
 | |
| struct PlayerTile players[] = {
 | |
|   { NO_PASS, "selfie", 16, "S8D8C8I8W8C8", "H1F1N2S2A2a2h2D2T1W1L2l2f2" }
 | |
|   //{ 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[] = {
 | |
|   { NO_PASS, "nupi", 4, BEHAVE_WANDER, "S6D6C8I4W4C4" }
 | |
| };
 | |
| 
 | |
| struct ItemTile items[] = {
 | |
|   { 0, "small macana", 1, "P1d4", "H1", "", "" },
 | |
|   //{ 0, "small macana", 1, "P1d4", { 6, 4 }, { 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0 } },
 | |
|   //{ 0, "large macana", 1, "P1d8", { 10, 6 } }
 | |
|   { 0, "large macana", 1, "P1d8", "H2", "", "" }
 | |
| };
 |