First implementation for doors

dev
Shariq Shah 6 years ago
parent 1aa4d1149d
commit 64dcb37310
  1. 1
      src/common/limits.h
  2. 2
      src/common/version.h
  3. 106
      src/game/door.c
  4. 24
      src/game/door.h
  5. 15
      src/game/entity.c
  6. 21
      src/game/entity.h
  7. 79
      src/game/scene.c
  8. 4
      src/game/scene.h
  9. 6
      todo.txt

@ -16,6 +16,7 @@
#define MAX_SCENE_ENTITY_ARCHETYPES 32
#define MAX_SCENE_ENEMIES 64
#define MAX_SCENE_TRIGGERS 256
#define MAX_SCENE_DOORS 256
#define MAX_UNIFORM_NAME_LEN 64

@ -4,7 +4,7 @@
/* Auto generated version file. DO NOT MODIFY */
#define SYMMETRY_VERSION_MAJOR 0
#define SYMMETRY_VERSION_MINOR 1
#define SYMMETRY_VERSION_REVISION 337
#define SYMMETRY_VERSION_REVISION 338
#define SYMMETRY_VERSION_BRANCH "dev"
#endif

@ -0,0 +1,106 @@
#include "door.h"
#include "entity.h"
#include "scene.h"
#include "game.h"
#include "transform.h"
#include "trigger.h"
#include "event.h"
#include "../common/log.h"
#include "../common/parser.h"
#include "../common/hashmap.h"
static void door_on_scene_loaded(struct Event* event, void* door_ptr);
static void door_on_trigger(struct Event* event, void* trigger_ptr);
void door_init(struct Door* door, int mask)
{
struct Game_State* game_state = game_state_get();
struct Event_Manager* event_manager = game_state->event_manager;
door->base.type = ET_DOOR;
door->mask = mask;
door->speed = 20.f;
door->state = DOOR_CLOSED;
event_manager_subscribe_with_object(event_manager, EVT_SCENE_LOADED, &door_on_scene_loaded, (void*)door);
}
void door_reset(struct Door* door)
{
door->state = -1;
door->speed = 0.f;
struct Event_Manager* event_manager = game_state_get()->event_manager;
event_manager_unsubscribe_with_object(event_manager, EVT_TRIGGER, &door_on_trigger, (void*)door);
event_manager_unsubscribe_with_object(event_manager, EVT_SCENE_LOADED, &door_on_scene_loaded, (void*)door);
}
struct Door* door_read(struct Parser_Object* object, const char* name, struct Entity* parent_entity)
{
struct Door* new_door = NULL;
struct Scene* scene = game_state_get()->scene;
new_door = scene_door_create(scene, name, parent_entity, DOOR_KEY_NONE);
if(hashmap_value_exists(object->data, "door_speed")) new_door->speed = hashmap_float_get(object->data, "door_speed");
if(hashmap_value_exists(object->data, "door_state")) new_door->state = hashmap_int_get(object->data, "door_state");
if(hashmap_value_exists(object->data, "door_mask")) new_door->mask = hashmap_int_get(object->data, "door_mask");
return new_door;
}
void door_write(struct Door* door, struct Hashmap* entity_data)
{
hashmap_int_set(entity_data, "door_state", door->state);
hashmap_int_set(entity_data, "door_mask", door->mask);
hashmap_float_set(entity_data, "door_speed", door->speed);
}
void door_update(struct Door* door, struct Scene* scene, float dt)
{
switch(door->state)
{
case DOOR_CLOSED:
case DOOR_OPEN:
break;
case DOOR_OPENING:
break;
case DOOR_CLOSING:
break;
}
}
void door_on_scene_loaded(struct Event* event, void* door_ptr)
{
struct Door* door = (struct Door*)door_ptr;
struct Entity* door_mesh[1] = { NULL };
struct Entity* door_sound[1] = { NULL };
struct Entity* door_trigger[1] = { NULL };
if(entity_get_num_children_of_type(door, ET_STATIC_MESH, &door_mesh, 1) == 1)
door->mesh = door_mesh[0];
else
log_error("door:on_scene_load", "Could not find mesh entity for door %s", door->base.name);
if(entity_get_num_children_of_type(door, ET_SOUND_SOURCE, &door_sound, 1) == 1)
door->sound = door_sound[0];
else
log_error("door:on_scene_load", "Could not find sound entity for door %s", door->base.name);
if(entity_get_num_children_of_type(door, ET_TRIGGER, &door_trigger, 1) == 1)
{
door->trigger = door_trigger[0];
struct Event_Manager* event_manager = game_state_get()->event_manager;
event_manager_subscribe_with_object(event_manager, EVT_TRIGGER, &door_on_trigger, (void*)door);
}
else
{
log_error("door:on_scene_load", "Could not find trigger entity for door %s", door->base.name);
}
}
void door_on_trigger(struct Event* event, void* trigger_ptr)
{
}

@ -0,0 +1,24 @@
#ifndef DOOR_H
#define DOOR_H
struct Door;
struct Static_Mesh;
struct Sound_Source;
struct Parser_Object;
struct Entity;
enum Door_State
{
DOOR_CLOSED = 0,
DOOR_OPEN,
DOOR_CLOSING,
DOOR_OPENING
};
void door_init(struct Door* door, int mask);
void door_reset(struct Door* door);
void door_update(struct Door* door, struct Scene* scene, float dt);
struct Door* door_read(struct Parser_Object* object, const char* name, struct Entity* parent_entity);
void door_write(struct Door* door, struct Hashmap* entity_data);
#endif

@ -20,6 +20,7 @@
#include "enemy.h"
#include "event.h"
#include "sound_source.h"
#include "door.h"
#include <stdlib.h>
#include <string.h>
@ -216,6 +217,12 @@ bool entity_write(struct Entity* entity, struct Parser_Object* object, bool writ
enemy_write(enemy, entity_data);
}
break;
case ET_DOOR:
{
struct Door* door = (struct Door*)entity;
door_write(door, entity_data);
}
break;
case ET_TRIGGER:
{
struct Trigger* trigger = (struct Trigger*)entity;
@ -477,6 +484,13 @@ struct Entity* entity_read(struct Parser_Object* object, struct Entity* parent_e
new_entity = &trigger->base;
}
break;
case ET_DOOR:
{
new_entity = &door_read(object, name, parent_entity)->base;
if(!new_entity)
return new_entity;
}
break;
default:
log_warning("Unhandled Entity type '%d' detected", type);
break;
@ -595,6 +609,7 @@ const char* entity_type_name_get(struct Entity* entity)
case ET_STATIC_MESH: typename = "Static Mesh"; break;
case ET_ENEMY: typename = "Enemy"; break;
case ET_TRIGGER: typename = "Trigger"; break;
case ET_DOOR: typename = "Door"; break;
default: typename = "Unknown"; break;
};
return typename;

@ -27,6 +27,7 @@ enum Entity_Type
ET_SOUND_SOURCE,
ET_ENEMY,
ET_TRIGGER,
ET_DOOR,
ET_MAX
};
@ -85,6 +86,15 @@ enum Trigger_Mask
TRIGM_ALL = TRIGM_PLAYER | TRIGM_ENEMY
};
enum Door_Mask
{
DOOR_KEY_NONE = 0,
DOOR_KEY_RED = 1 << 0,
DOOR_KEY_GREEN = 1 << 1,
DOOR_KEY_BLUE = 1 << 2,
DOOR_KEY_ALL = DOOR_KEY_RED | DOOR_KEY_GREEN | DOOR_KEY_BLUE
};
enum Trigger_Type
{
TRIG_TOGGLE = 0, // Toggled on once and fires event then wont fire event until it is deactivated and activated again
@ -243,6 +253,17 @@ struct Trigger
int trigger_mask;
};
struct Door
{
struct Entity base;
int mask;
int state;
float speed;
struct Static_Mesh* mesh;
struct Sound_Source* sound;
struct Trigger* trigger;
};
void entity_init(struct Entity* entity, const char* name, struct Entity* parent);
void entity_reset(struct Entity* entity, int id);
bool entity_save(struct Entity* entity, const char* filename, int directory_type);

@ -21,6 +21,7 @@
#include "event.h"
#include "scene_funcs.h"
#include "trigger.h"
#include "door.h"
#include <assert.h>
#include <string.h>
@ -277,6 +278,7 @@ bool scene_save(struct Scene* scene, const char* filename, int directory_type)
scene_write_entity_list(scene, ET_SOUND_SOURCE, parser);
scene_write_entity_list(scene, ET_ENEMY, parser);
scene_write_entity_list(scene, ET_TRIGGER, parser);
scene_write_entity_list(scene, ET_DOOR, parser);
if(parser_write_objects(parser, scene_file, prefixed_filename))
log_message("Scene saved to %s", prefixed_filename);
@ -329,6 +331,11 @@ void scene_write_entity_list(struct Scene* scene, int entity_type, struct Parser
entity = &scene->triggers[0].base;
stride = sizeof(struct Trigger);
break;
case ET_DOOR:
max_length = MAX_SCENE_DOORS;
entity = &scene->doors[0].base;
stride = sizeof(struct Door);
break;
default: return;
}
@ -378,6 +385,8 @@ void scene_destroy(struct Scene* scene)
for(int i = 0; i < MAX_SCENE_STATIC_MESHES; i++) scene_static_mesh_remove(scene, &scene->static_meshes[i]);
for(int i = 0; i < MAX_SCENE_SOUND_SOURCES; i++) scene_sound_source_remove(scene, &scene->sound_sources[i]);
for(int i = 0; i < MAX_SCENE_ENEMIES; i++) scene_enemy_remove(scene, &scene->enemies[i]);
for(int i = 0; i < MAX_SCENE_TRIGGERS; i++) scene_trigger_remove(scene, &scene->triggers[i]);
for(int i = 0; i < MAX_SCENE_DOORS; i++) scene_door_remove(scene, &scene->doors[i]);
for(int i = 0; i < MAX_SCENE_ENTITY_ARCHETYPES; i++) memset(&scene->entity_archetypes[i][0], '\0', MAX_FILENAME_LEN);
player_destroy(&scene->player);
entity_reset(&scene->root_entity, 0);
@ -393,6 +402,12 @@ void scene_update(struct Scene* scene, float dt)
if(scene->enemies[i].base.flags & EF_ACTIVE)
enemy_update(&scene->enemies[i], scene, dt);
}
for(int i = 0; i < MAX_SCENE_DOORS; i++)
{
if(scene->doors[i].base.flags & EF_ACTIVE)
door_update(&scene->doors[i], scene, dt);
}
}
}
@ -521,6 +536,18 @@ void scene_post_update(struct Scene* scene)
}
}
for(int i = 0; i < MAX_SCENE_DOORS; i++)
{
struct Door* door = &scene->doors[i];
if(!(door->base.flags & EF_ACTIVE)) continue;
if(door->base.flags & EF_MARKED_FOR_DELETION)
{
scene_door_remove(scene, door);
continue;
}
}
if(scene->player.base.transform.is_modified)
{
scene->player.base.transform.is_modified = false;
@ -731,6 +758,33 @@ struct Enemy* scene_enemy_create(struct Scene* scene, const char* name, struct E
return new_enemy;
}
struct Door* scene_door_create(struct Scene* scene, const char* name, struct Entity* parent, int mask)
{
assert(scene);
struct Door* new_door = NULL;
for(int i = 0; i < MAX_SCENE_DOORS; i++)
{
struct Door* door = &scene->doors[i];
if(!(door->base.flags & EF_ACTIVE))
{
new_door = door;
break;
}
}
if(new_door)
{
entity_init(&new_door->base, name, parent ? parent : &scene->root_entity);
door_init(new_door, mask);
}
else
{
log_error("scene:door_create", "Max door limit reached!");
}
return new_door;
}
struct Trigger* scene_trigger_create(struct Scene* scene, const char* name, struct Entity* parent, int type, int mask)
{
assert(scene);
@ -757,6 +811,7 @@ struct Trigger* scene_trigger_create(struct Scene* scene, const char* name, stru
return new_trigger;
}
void scene_entity_base_remove(struct Scene* scene, struct Entity* entity)
{
assert(scene && entity && entity->id >= 0);
@ -782,6 +837,13 @@ void scene_enemy_remove(struct Scene* scene, struct Enemy* enemy)
scene_entity_base_remove(scene, enemy);
}
void scene_door_remove(struct Scene* scene, struct Door* door)
{
assert(scene && door);
door_reset(door);
scene_entity_base_remove(scene, door);
}
void scene_trigger_remove(struct Scene* scene, struct Trigger* trigger)
{
assert(scene && trigger);
@ -915,6 +977,23 @@ struct Enemy* scene_enemy_find(struct Scene* scene, const char* name)
return enemy;
}
struct Door* scene_door_find(struct Scene* scene, const char* name)
{
assert(scene && name);
struct Door* door = NULL;
for(int i = 0; i < MAX_SCENE_DOORS; i++)
{
if(strncmp(name, scene->doors[i].base.name, MAX_ENTITY_NAME_LEN) == 0)
{
door = &scene->doors[i];
break;
}
}
return door;
}
struct Trigger* scene_trigger_find(struct Scene* scene, const char* name)
{
assert(scene && name);

@ -23,6 +23,7 @@ struct Scene
struct Sound_Source sound_sources[MAX_SCENE_SOUND_SOURCES];
struct Enemy enemies[MAX_SCENE_ENEMIES];
struct Trigger triggers[MAX_SCENE_TRIGGERS];
struct Door doors[MAX_SCENE_DOORS];
char entity_archetypes[MAX_SCENE_ENTITY_ARCHETYPES][MAX_FILENAME_LEN];
int active_camera_index;
Scene_Init_Func init;
@ -45,6 +46,7 @@ struct Static_Mesh* scene_static_mesh_create(struct Scene* scene, const char* n
struct Sound_Source* scene_sound_source_create(struct Scene* scene, const char* name, struct Entity* parent, const char* filename, int type, bool loop, bool play);
struct Enemy* scene_enemy_create(struct Scene* scene, const char* name, struct Entity* parent, int type);
struct Trigger* scene_trigger_create(struct Scene* scene, const char* name, struct Entity* parent, int type, int mask);
struct Door* scene_door_create(struct Scene* scene, const char* name, struct Entity* parent, int mask);
void scene_entity_base_remove(struct Scene* scene, struct Entity* entity);
void scene_light_remove(struct Scene* scene, struct Light* light);
@ -53,6 +55,7 @@ void scene_static_mesh_remove(struct Scene* scene, struct Static_Mesh* mesh);
void scene_sound_source_remove(struct Scene* scene, struct Sound_Source* source);
void scene_enemy_remove(struct Scene* scene, struct Enemy* enemy);
void scene_trigger_remove(struct Scene* scene, struct Trigger* trigger);
void scene_door_remove(struct Scene* scene, struct Door* door);
void* scene_find(struct Scene* scene, const char* name); // Looks in all entity type arrays and returns the first one found. Result should be cast back to expected type
struct Entity* scene_entity_find(struct Scene* scene, const char* name);
@ -63,6 +66,7 @@ struct Sound_Source* scene_sound_source_find(struct Scene* scene, const char* na
struct Entity* scene_base_entity_get(struct Scene* scene, int id, int type);
struct Enemy* scene_enemy_find(struct Scene* scene, const char* name);
struct Trigger* scene_trigger_find(struct Scene* scene, const char* name);
struct Door* scene_door_find(struct Scene* scene, const char* name);
void scene_entity_parent_set(struct Scene* scene, struct Entity* entity, struct Entity* parent);
void scene_entity_parent_reset(struct Scene* scene, struct Entity* entity); // Sets root entity as parent

@ -1,4 +1,10 @@
Todo:
- Composite door entity made up of static mesh, sound entity and trigger. Door might require 0-3 keys in order to be opened.
- Doors that open using the red/green/blue keys only as a way of progressing the level or cordoing off certain sections
- RGB keys to progress to next level
- Player/enemies getting hit by bullets
- Win/fail States
- Remove excessive repitition in scene related code that handles multiple entity types
- Allow switching to editor mode when game is in pause mode
- Implement flag for ignoring collisions with certain entities
- Implement separate property window for player related variables that can be shown in the editor similar to renderer settings etc

Loading…
Cancel
Save