kettek2/wiki/games/newsboy/Newsboy_0x00/engine/EntityManager.c

185 lines
4.7 KiB
C

#include <stdlib.h>
#include "EntityManager.h"
#include "report.h"
int initEntityManager(struct EntityManager *manager){
if (manager == NULL) {
return 1;
}
manager->sprites = NULL;
manager->animations = NULL;
manager->entities = NULL;
manager->live_entities = NULL;
manager->live_count = 0;
initIndex(&manager->index, 0);
return 0;
}
int setEntityAnimation(struct EntityManager *manager, int entity_id, char *name) {
if (manager == NULL) {
return 1;
}
if (entity_id < 0) {
return 2;
}
if (entity_id > manager->live_count) {
return 3;
}
if (name == NULL) {
return 4;
}
struct Entity *entity = getEntity(manager, entity_id);
if (entity == NULL) {
return 5;
}
int anim_id = getResourceId(manager->animations, name);
if (anim_id < 0) {
return 6;
}
entity->anim.anim_id = anim_id;
return 0;
}
int setEntitySet(struct EntityManager *manager, int entity_id, char *name) {
if (manager == NULL) {
return 1;
}
if (entity_id < 0) {
return 2;
}
if (entity_id > manager->live_count) {
return 3;
}
if (name == NULL) {
return 4;
}
struct Entity *entity = getEntity(manager, entity_id);
if (entity == NULL) {
return 5;
}
struct Resources *anim_data = getResourceById(manager->animations, entity->anim.anim_id);
if (anim_data == NULL) {
return 6;
}
int set_id = getResourceId(anim_data, name);
if (set_id < 0) {
return 7;
}
entity->anim.set_id = set_id;
return 0;
}
int setEntityFace(struct EntityManager *manager, int entity_id, char *name) {
if (manager == NULL) {
return 1;
}
if (entity_id < 0) {
return 2;
}
if (entity_id > manager->live_count) {
return 3;
}
if (name == NULL) {
return 4;
}
struct Entity *entity = getEntity(manager, entity_id);
if (entity == NULL) {
return 5;
}
struct Resources *anim_data = getResourceById(manager->animations, entity->anim.anim_id);
if (anim_data == NULL) {
return 6;
}
struct Resources *set_data = getResourceById(anim_data, entity->anim.set_id);
if (set_data == NULL) {
return 6;
}
int face_id = getResourceId(set_data, name);
//printf("set to %d!!!!", face_id);
entity->anim.face_id = face_id;
return 0;
}
int growEntityManager(struct EntityManager *manager, int amount) {
if (manager == NULL) {
report(WARNING, "growEntityManager", "passed manager is NULL");
return 1;
}
if (amount <= 0) {
report(WARNING, "growEntityManager", "grow amount %d is invalid", amount);
return 2;
}
int start = manager->index.size;
if (growIndex(&manager->index, amount) != 0) {
report(ERROR, "growEntityManager", "could not grow Index by %d", amount);
return 3;
}
if ((manager->live_entities = realloc(manager->live_entities, manager->index.size+amount*sizeof(struct Entity*))) == NULL) {
report(ERROR, "growEntityManager", "could not resize live_entities by %d", amount);
return 4;
}
int i = start;
while (i < manager->index.size) {
manager->live_entities[i] = NULL;
i++;
}
return 0;
}
int addEntity(struct EntityManager *manager, struct Entity *entity) {
if (manager == NULL) {
report(ERROR, "addEntity", "passed EntityManager is NULL");
return -1;
}
if (entity == NULL) {
report(ERROR, "addEntity", "passed Entity is NULL");
return -2;
}
int id;
if ((id = acquireIndex(&manager->index)) < 0) {
growEntityManager(manager, 8); // grow by 8, I guess. more efficient than 1 in terms of realloc
if ((id = acquireIndex(&manager->index)) < 0) {
report(ERROR, "addEntity", "could not acquireIndex after growEntityManager, bailing");
return -3;
}
}
manager->live_entities[id] = entity;
addIndex(&manager->index, id);
manager->live_count++;
return id;
}
int remEntity(struct EntityManager *manager, int id) {
if (manager == NULL) {
report(ERROR, "remEntity", "passed manager is NULL");
return 1;
}
if (id < 0 || id > manager->live_count) {
report(WARNING, "remEntity", "passed id is out of bounds");
return 2;
}
if (remIndex(&manager->index, id) != 0) {
report(WARNING, "remEntity", "%d could not be removed from Index", id);
return 3;
}
manager->live_entities[id] = NULL; // since remEntity is self-managed, we don't free.
manager->live_count--;
return 0;
}
struct Entity *getEntity(struct EntityManager *manager, int entity_id) {
if (manager == NULL ) {
report(ERROR, "getEntity", "passed manager is NULL");
return NULL;
}
if (entity_id < 0) {
report(ERROR, "getEntity", "entity_id %d out of range", entity_id);
return NULL;
}
if (entity_id > manager->index.size) {
report(ERROR, "getEntity", "entity_id %d is beyond %d", entity_id, manager->index.size);
return NULL;
}
return manager->live_entities[entity_id];
}