#include "Map.h" #include "LiveMap.h" #include "report.h" #include "Animation.h" #include "fifo.h" #include "string.h" #include "game_globals.h" #include "Vector.h" #include "Phys.h" #include "EntityData.h" #include // Loading ================================ /*int loadLiveMap(struct LiveMap *map, const char *file) { if (map == NULL) { report(ERROR, "loadLiveMap", "passed map is NULL"); return 1; } if (file == NULL) { report(ERROR, "loadLiveMap", "passed file name isNULL"); return 2; } // open file FILE *input = fopen(file, "rb"); if (input == NULL) { report(ERROR, "loadLiveMap", "cannot open map file \"%s\" for reading", file); return 3; } // alright, start loading in map data! uint32_t val; readData(input, T_MAGIC, &val); // check magick if (((char *)val)[0] != 'N' || ((char *)val)[1] != 'b' || ((char *)val)[2] != 'M' || ((char *)val)[3] != 1) { report(ERROR, "loadLiveMap", "Magic number mismatch, expected %d, got %d\n", 1, ((char *)val)[3]); fclose(input); return 4; } // read in name map->name = readData(input, T_STRING, map->name); map->session = readData(input, T_STRING, map->session); // read in width & height readData(input, T_INT, &map->location); readData(input, T_INT, &map->width); readData(input, T_INT, &map->height); // create and load in cells map->cells = malloc(map->width * sizeof(struct Cell)); if (map->cells == NULL) { report(ERROR, "loadLiveMap", "could not malloc cells"); fclose(input); return 5; } // allocate memory for cells int x, y; for (x = 0; x < map->width; x++) { map->cells[x] = malloc(sizeof *map->cells[x] * map->height); if (map->cells[x] == NULL) { report(ERROR, "loadLiveMap", "could not alloc memory for cells[%d]", x); // this is not actually y, I'm just (ab)using it. for (y = 0; y < x; y++) { free(map->cells[y]); } map->width = 0; map->height = 0; free(map->cells); map->cells = NULL; fclose(input); return 6; } for (y = 0; y < map->height; y++) { // load in cell flags readData(input, T_INT, &map->cells[x][y].flags); // load in decor count readData(input, T_INT, &map->cells[x][y].decor_count); // load in decors! struct Cell *cell = &map->cells[x][y]; if (cell->decor_count > 0) { if ((cell->decor = malloc(sizeof(struct Decor)*cell->decor_count)) == NULL) { report(ERROR, "loadLiveMap", "could not malloc for %d decors in %dx%d", cell->decor_count, x, y); // TODO: something cell->decor_count = 0; } else { // read 'em in int d; for (d = 0; d < cell->decor_count; d++) { // read in x readData(input, T_INT, &cell->decor[d].x); // read in y readData(input, T_INT, &cell->decor[d].y); // read in animation boolean readData(input, T_INT, &cell->decor[d].animation.anim_bool); // read in animation frame index readData(input, T_INT, &cell->decor[d].animation.f); // read in animation animation name readData(input, T_INT, &cell->decor[d].animation.); } } } // fclose(input); return 0; }*/ // LiveMap ================================ struct LiveMap *newLiveMap() { struct LiveMap *map = malloc(sizeof(struct LiveMap)); if (map == NULL) { report(ERROR, "newLiveMap", "could not malloc LiveMap"); return NULL; } map->name = NULL; map->session = NULL; map->location = 0; map->width = 0; map->height = 0; map->cells = NULL; map->player.x = 0; map->player.y = 0; map->entities = NULL; map->triggers = NULL; map->active_triggers = NULL; map->events = NULL; cleanAnim(&map->player.animation); return map; } int freeLiveMap(struct LiveMap *map) { if (map == NULL) return 1; if (map->name != NULL) free(map->name); if (map->session != NULL) free(map->session); if (map->cells != NULL) { freeCells(map->cells, map->width, map->height); int x; for (x = 0; x < map->width; x++) { free(map->cells[x]); } free(map->cells); map->cells = NULL; } if (map->entities) { struct Entity *entity; while((entity = iterObject(map->entities)) != NULL) { freeEntity(entity); } freeVoidMan(map->entities); } if (map->triggers) { struct Trigger *trigger; while((trigger = iterObject(map->triggers)) != NULL) { freeTrigger(trigger); } freeVoidMan(map->triggers); } if (map->active_triggers) { struct Trigger *trigger; while((trigger = iterObject(map->active_triggers)) != NULL) { freeTrigger(trigger); } freeVoidMan(map->active_triggers); } if (map->events) { struct Event *event; while((event = iterObject(map->events)) != NULL) { freeEvent(event); } freeVoidMan(map->events); } free(map); return 0; } int freeCells(struct Cell **cells, int width, int height) { int x, y; for (x = 0; x < width; x++) { for (y = 0; y < height; y++) { freeCell(&cells[x][y]); } } return 0; } // THIS SEEMS STUPID, but whatevs~ struct LiveMap *initLiveMap(struct MapData *map) { if (map == NULL) return NULL; struct LiveMap *live = newLiveMap(); live->location = map->location; live->session = copyString(live->session, map->session); live->name = copyString(live->name, map->name); live->width = map->width; live->height = map->height; // allocate memory for cells live->cells = malloc(live->width * sizeof(struct Cell)); if (live->cells == NULL) { report(ERROR, "initLiveMap", "could not malloc cells"); freeLiveMap(live); return NULL; } int x, y; for (x = 0; x < live->width; x++) { live->cells[x] = malloc(sizeof *live->cells[x] * live->height); if (live->cells[x] == NULL) { report(ERROR, "initLiveMap", "could not alloc memory for cells[%d]", x); // this is not actually y, I'm just (ab)using it. for (y = 0; y < x; y++) { free(live->cells[y]); } live->width = 0; live->height = 0; free(live->cells); live->cells = NULL; freeLiveMap(live); return NULL; } for (y = 0; y < live->height; y++) { live->cells[x][y].flags = map->cells[x][y].flags; live->cells[x][y].decor_count = map->cells[x][y].decor_count; // load 'er up struct Cell *cell = &live->cells[x][y]; if (cell->decor_count > 0) { if ((cell->decor = malloc(sizeof(struct Decor)*cell->decor_count)) == NULL) { report(ERROR, "loadLiveMap", "could not malloc for %d decors in %dx%d", cell->decor_count, x, y); // TODO: something with freeing cell->decor_count = 0; } else { int d; for (d = 0; d < cell->decor_count; d++) { cell->decor[d].x = map->cells[x][y].decor[d]->x; cell->decor[d].y = map->cells[x][y].decor[d]->y; cleanAnim(&cell->decor[d].animation); // get full animation path name, as live_animations expects it cell->decor[d].animation.anim = getResource(live_animations, map->cells[x][y].decor[d]->anim); if (cell->decor[d].animation.anim == NULL) { printf("getting anim %s was null\n", map->cells[x][y].decor[d]->anim); } cell->decor[d].animation.anim_bool = map->cells[x][y].decor[d]->animated; setAnimSet(&cell->decor[d].animation, map->cells[x][y].decor[d]->set); setAnimFace(&cell->decor[d].animation, map->cells[x][y].decor[d]->face); setAnimFrame(&cell->decor[d].animation, map->cells[x][y].decor[d]->frame); } } } } } // done with cells, finally live->player.x = map->player_data.x; live->player.y = map->player_data.y; live->player.animation.anim = getResource(live_animations, map->player_data.anim); setAnimSet(&live->player.animation, map->player_data.set); setAnimFace(&live->player.animation, map->player_data.face); setAnimFrame(&live->player.animation, map->player_data.frame); cleanPhys(&live->player.phys); cleanPhys(&live->player.l_phys); live->player.phys.position.x = map->player_data.x; live->player.phys.position.y = map->player_data.y; // gather entities live->entities = newVoidMan(8); struct EntityMapData *entity_map_data; while((entity_map_data = iterObject(map->entities)) != NULL) { struct Entity *entity = newEntity(); entity->phys.position.x = entity_map_data->x; entity->phys.position.y = entity_map_data->y; struct EntityData *entity_data = getResource(live_entities, entity_map_data->name); if (entity_data == NULL) { report(ERROR, "initLiveMap", "could not get EntityData for %s", entity_map_data->name); freeEntity(entity); continue; } entity->name = copyString(entity->name, entity_data->name); // load entity animation if ((entity->animation.anim = getResource(live_animations, entity_data->anim)) == NULL) { report(ERROR, "initLiveMap", "could not get Animation %s for %s", entity_data->anim, entity->name); freeEntity(entity); continue; } setAnimSet(&entity->animation, entity_map_data->set); setAnimFace(&entity->animation, entity_map_data->face); setAnimFrame(&entity->animation, entity_map_data->frame); if (entity->animation.sheet != NULL) { if (entity->animation.sheet->surfaces[0] != NULL) { entity->height = (entity->animation.sheet->surfaces[0]->h/2)-(entity->animation.sheet->surfaces[0]->h/4); } } // load up logic entity->logic = entity_data->behave; entity->type = entity_data->type; // physics entity->phys.radius = entity_data->radius; entity->phys.mass = entity_data->mass; entity->speed = entity_data->speed; entity->turn_rate = entity_data->turn; // hp and sight entity->max_hp = entity_data->hp; entity->hp = entity_data->hp; entity->sight = entity_data->sight; // attack-related entity->range = entity_data->range; entity->attack = entity_data->attack; entity->damage = entity_data->damage; entity->spawn_data = getResource(live_entities, entity_data->spawn); // despawn time if projectile type entity->time = entity_data->time; addObject(live->entities, entity); } // gather events, populate events, creating an array of strings to correlate name->index live->events = newVoidMan(8); char **event_names = malloc(sizeof(char*)*map->event_count); struct EventMapData *event_data; while((event_data = iterObject(map->events)) != NULL) { struct Event *event = newEvent(); event->box.x = event_data->x; event->box.y = event_data->y; event->box.w = event_data->w; event->box.h = event_data->h; printf("set to: %dx%dby%dx%d\n", event->box.x, event->box.y, event->box.w, event->box.h); event->type = event_data->type; event->param_count = event_data->param_count; event->params = malloc(event->param_count * sizeof(void*)); event->param_type = malloc(event->param_count * sizeof(int)); int i; for(i = 0; i < event->param_count; i++) { event->param_type[i] = event_data->param_type[i]; switch(event_data->param_type[i]) { case T_CHAR: event->params[i] = malloc(sizeof(char)); *(char*)event->params[i] = *(char*)event_data->params[i]; break; case T_INT: event->params[i] = malloc(sizeof(int)); *(int*)event->params[i] = *(int*)event_data->params[i]; break; case T_FLOAT: event->params[i] = malloc(sizeof(float)); *(float*)event->params[i] = *(float*)event_data->params[i]; break; case T_STRING: {} int size = strlen((char*)event_data->params[i])+1; event->params[i] = malloc(size); memcpy(event->params[i], event_data->params[i], size); break; } } int id = addObject(live->events, event); int size = strlen(event_data->name)+1; event_names[id] = malloc(size); memcpy(event_names[id], event_data->name, size); } // in trigger, strcmp trigger's event name to earlier array of strings, setting the target event to the returned index if it exists. live->triggers = newVoidMan(8); live->active_triggers = newVoidMan(8); struct TriggerMapData *trigger_data; while((trigger_data = iterObject(map->triggers)) != NULL) { struct Trigger *trigger = newTrigger(); trigger->box.x = trigger_data->x; trigger->box.y = trigger_data->y; trigger->box.w = trigger_data->w; trigger->box.h = trigger_data->h; trigger->type = trigger_data->type; trigger->behavior = trigger_data->behavior; trigger->activator = trigger_data->activator; trigger->time = trigger_data->time; trigger->iter = trigger_data->iter; trigger->event_count = trigger_data->event_count; trigger->events = malloc(sizeof(int)*trigger->event_count); int i; for (i = 0; i < trigger_data->event_count; i++) { trigger->events[i] = -1; int j; for (j = 0; j < map->event_count; j++) { if (strcmp(trigger_data->events[i], event_names[j]) == 0) { trigger->events[i] = j; break; } } } addObject(live->triggers, trigger); } // free list of event names int i; for (i = 0; i < map->event_count; i++) { free(event_names[i]); } free(event_names); return live; } // Event ================================ struct Event *newEvent() { struct Event *event = malloc(sizeof(struct Event)); event->type = 0; event->param_count = 0; event->param_type = NULL; event->params = NULL; return event; } int freeEvent(struct Event *event) { int i; for (i = 0; i < event->param_count; i++) { free(event->params[i]); } if (event->params != NULL) free(event->params); if (event->param_type != NULL) free(event->param_type); //free(event); // voidman frees return 0; } // Trigger ================================ struct Trigger *newTrigger() { struct Trigger *trigger = malloc(sizeof(struct Trigger)); trigger->type = 0; trigger->iter = 0; trigger->activator = 0; trigger->behavior = 0; trigger->time = 0; trigger->elapsed = 0; trigger->runs = 0; trigger->event_runs = 0; trigger->events = NULL; return trigger; } int freeTrigger(struct Trigger *trigger) { if (trigger == NULL) return 1; if (trigger->events != NULL) free(trigger->events); //free(trigger); // voidman frees return 0; } // Cell ================================ struct Cell *newCell(int flags, int decor_count) { struct Cell *cell = malloc(sizeof(struct Cell)); cell->flags = flags; cell->decor_count = decor_count; cell->decor = malloc(sizeof(struct Decor)*decor_count); int i; for (i = 0; i < cell->decor_count; i++) { cell->decor[i].x = 0; cell->decor[i].y = 0; cleanAnim(&cell->decor[i].animation); } return cell; } int freeCell(struct Cell *cell) { if (cell == NULL) return 1; if (cell->decor == NULL) return 2; if (cell->decor_count > 0) { free(cell->decor); } return 0; } int delDecor(struct Cell *cell, int pos) { if (cell == NULL) return 1; if (pos < 0 || pos >= cell->decor_count) return 2; struct Decor *temp = malloc((cell->decor_count-1)*sizeof(struct Decor)); memmove(temp, cell->decor, (pos+1)*sizeof(struct Decor)); memmove(temp+pos, cell->decor+(pos+1), (cell->decor_count-pos)*sizeof(struct Decor)); /*if (pos != 0) { memcpy(temp, cell->decor, (pos-1)*sizeof(struct Decor)); } if (pos != cell->decor_count-1) { memcpy(temp+pos, cell->decor+pos+1, (cell->decor_count - pos -1)*sizeof(struct Decor)); }*/ free(cell->decor); cell->decor = temp; printf("deleting pos %d\n", pos); cell->decor_count--; printf("new decor_count is %d\n", cell->decor_count); if (cell->decor_count <= 0) { free(cell->decor); cell->decor = NULL; } return 0; } int collideCell(struct Cell *cell, struct Phys *phys) { if (cell->flags & CELL_BLOCKS_ENTITY) { return 1; } return 0; }