#include "entity.h" #include "game.h" const EntityEntry entityEntries[ENTITY_COUNT] = { }; Entity createEntity(EntityId id, Vector3 position) { Entity entity; entity.id = id; entity.state = ENTITY_DEFAULT_STATE; entity.data = NULL; // Bounding boxes. switch (id) { case OLD_MINT: case STICKY_NICKEL: entity.box = entityBoxFromScale(1.0, 32.0, 32.0); break; case TREE: entity.box = entityBoxFromScale(TREE_SCALE, 113.0, 250.0); break; case BUSH: entity.box = entityBoxFromScale(BUSH_SCALE, 87.0, 62.0); break; case FLOWER: entity.box = entityBoxFromScale(FLOWER_SCALE, 32.0, 54.0); break; case POND: entity.box = (BoundingBox){ .min = (Vector3){-POND_SIZE, -POND_HEIGHT, -POND_SIZE}, .max = (Vector3){POND_SIZE, POND_HEIGHT, POND_SIZE} }; break; case UTILITY_POLE: entity.box = (BoundingBox){ .min = (Vector3){-UTILITY_POLE_RADIUS, -UTILITY_POLE_HEIGHT, -UTILITY_POLE_RADIUS}, .max = (Vector3){UTILITY_POLE_RADIUS, UTILITY_POLE_HEIGHT, UTILITY_POLE_RADIUS}, }; break; case SAMANTHA: entity.box = (BoundingBox){ .min = (Vector3){-SAMANTHA_WIDTH, -SAMANTHA_HEIGHT, -SAMANTHA_THICKNESS}, .max = (Vector3){SAMANTHA_WIDTH, SAMANTHA_HEIGHT, SAMANTHA_THICKNESS} }; break; case SAMANTHAS_SPOT: entity.box = (BoundingBox){ .min = (Vector3){-SAMANTHAS_SPOT_SIZE, -SAMANTHAS_SPOT_HEIGHT, -SAMANTHAS_SPOT_SIZE}, .max = (Vector3){SAMANTHAS_SPOT_SIZE, SAMANTHAS_SPOT_HEIGHT, SAMANTHAS_SPOT_SIZE}, }; break; case TRASHCAN: entity.box = entityBoxFromScale(TRASHCAN_SCALE, TRASHCAN_WIDTH, TRASHCAN_HEIGHT); break; case TRASH: entity.box = entityBoxFromScale(TRASH_SCALE, 202.0, 122.0); break; case MEDICAL_TRASH: entity.box = entityBoxFromScale(MEDICAL_TRASH_SCALE, 200.0, 132.0); break; // TODO: do the thing case JOHN: case RON: // John and Ron ARE NOT the same person. entity.box = (BoundingBox){ .min = (Vector3){-SHOPKEEPER_WIDTH, -SHOPKEEPER_HEIGHT, -SHOPKEEPER_THICKNESS}, .max = (Vector3){SHOPKEEPER_WIDTH, SHOPKEEPER_HEIGHT, SHOPKEEPER_THICKNESS} }; break; default: break; } entity.position = Vector3Zero(); setEntityPosition(&entity, position); return entity; } void updateEntity(Entity* entity, Game* game) { //DrawBoundingBox(entity->box, RED); switch (entity->id) { case OLD_MINT: DrawBillboard(game->player.camera, game->assets.textures[MINT_TEXTURE], entity->position, 1.0, WHITE); break; case STICKY_NICKEL: DrawBillboard(game->player.camera, game->assets.textures[NICKEL_TEXTURE], entity->position, 1.0, WHITE); break; case TREE: DrawBillboard(game->player.camera, game->assets.textures[TREE_TEXTURE], entity->position, TREE_SCALE, WHITE); break; case BUSH: DrawBillboard(game->player.camera, game->assets.textures[BUSH_TEXTURE], entity->position, BUSH_SCALE, WHITE); break; case FLOWER: DrawBillboard(game->player.camera, game->assets.textures[FLOWER_TEXTURE], entity->position, FLOWER_SCALE, WHITE); break; case POND: DrawPlane( Vector3Add(entity->position, (Vector3){0.0, POND_HEIGHT, 0.0}), (Vector2){POND_SIZE * 2.5, POND_SIZE * 2.5}, BLUE); break; case SAMANTHA: //updateSamantha(entity, game); break; case SAMANTHAS_SPOT: DrawModel(game->world.samanthasSpotFloor, Vector3Add(entity->position, (Vector3){0.0, -SAMANTHAS_SPOT_HEIGHT + 0.01, 0.0}), 1.0, WHITE); break; case TRASHCAN: //updateTrashcan(entity, game); break; case TRASH: DrawBillboard(game->player.camera, game->assets.textures[TRASH_TEXTURE], entity->position, TRASH_SCALE, WHITE); break; case MEDICAL_TRASH: DrawBillboard(game->player.camera, game->assets.textures[MEDICAL_TRASH_TEXTURE], entity->position, MEDICAL_TRASH_SCALE, WHITE); break; case JOHN: DrawModel(game->assets.models[JOHN_MODEL], entity->position, 1.0, WHITE); break; case RON: DrawModel(game->assets.models[RON_MODEL], entity->position, 1.0, WHITE); break; default: break; } } void setEntityPosition(Entity* entity, Vector3 position) { Vector3 movedBy = Vector3Subtract(position, entity->position); entity->position = position; entity->box.min = Vector3Add(entity->box.min, movedBy); entity->box.max = Vector3Add(entity->box.max, movedBy); } void placeEntityOnGround(Entity* entity, const World* world) { Vector3 position = entity->position; position.y = getWorldHeightAtLocation( world, entity->position.x, entity->position.z); position.y += (entity->box.max.y - entity->box.min.y) / 2.0; setEntityPosition(entity, position); } bool entityCanBeSelected(EntityId id) { switch (id) { case SAMANTHAS_SPOT: return false; default: return true; } } InteractionCommand interactWithOldMint(Entity* entity, Game* game, Selection selection) { if (selection == SELECTION_INTERACT) { // Run display message code. return INTERACTION_TALK; } else { return INTERACTION_END; } } InteractionCommand interactWithEntity(Entity* entity, Game* game, Selection selection) { switch (entity->id) { case OLD_MINT: // For testing. return interactWithOldMint(entity, game, selection); default: break; } return INTERACTION_END; } BoundingBox entityBoxFromScale(float scale, float width, float height) { Vector2 size = (Vector2){width / height * scale, scale}; size = Vector2Scale(size, 0.5); return (BoundingBox){ .min = (Vector3){-size.x, -size.y, -size.x}, .max = (Vector3){size.x, size.y, size.x} }; }