Started implementing trigger entity type

dev
Shariq Shah 6 years ago
parent e62bf12bc5
commit ac16c151a3
  1. 8
      assets/entities/cube.symtres
  2. 6
      assets/entities/cube_uv.symtres
  3. 2
      assets/entities/turret.symtres
  4. BIN
      assets/models/cube.symbres
  5. 63
      assets/scenes/scene_1.symtres
  6. 1
      src/common/limits.h
  7. 2
      src/common/version.h
  8. 42
      src/game/editor.c
  9. 22
      src/game/entity.c
  10. 30
      src/game/entity.h
  11. 82
      src/game/scene.c
  12. 4
      src/game/scene.h
  13. 102
      src/game/trigger.c
  14. 10
      src/game/trigger.h
  15. 10
      todo.txt

@ -1,14 +1,18 @@
Entity Entity
{ {
type : 6 type : 6
scale : 135.000 1.000 135.000
material : 0 material : 0
rotation : 0.000 0.000 0.000 1.000
diffuse_color : 1.000 1.000 1.000 1.000 diffuse_color : 1.000 1.000 1.000 1.000
geometry : cube.symbres geometry : cube.symbres
specular : 1.0000 specular : 1.0000
active : true active : true
diffuse_texture : default.tga diffuse_texture : default.tga
diffuse : 1.0000 diffuse : 1.0000
position : -17.000 0.000 -20.000
specular_strength : 1.0000 specular_strength : 1.0000
name : Cube name : Ground
uv_scale : 7.700 8.900
} }

@ -1,7 +1,7 @@
Entity Entity
{ {
type : 6 type : 6
scale : 68.000 3.000 1.000 scale : 135.000 5.000 1.000
material : 0 material : 0
rotation : 0.000 0.000 0.000 1.000 rotation : 0.000 0.000 0.000 1.000
diffuse_color : 1.000 1.000 1.000 1.000 diffuse_color : 1.000 1.000 1.000 1.000
@ -10,9 +10,9 @@ Entity
active : true active : true
diffuse_texture : default.tga diffuse_texture : default.tga
diffuse : 1.0000 diffuse : 1.0000
position : -17.000 4.000 -87.000 position : -17.000 3.000 -87.000
specular_strength : 1.0000 specular_strength : 1.0000
name : Cube name : Cube
uv_scale : 15.000 1.000 uv_scale : 5.000 63.500
} }

@ -5,7 +5,7 @@ Entity
pulsate_height : 1.5000 pulsate_height : 1.5000
vision_range : 15.0000 vision_range : 15.0000
pulsate_speed_scale : 0.1000 pulsate_speed_scale : 0.1000
rotation : 0.000 0.001 0.000 1.001 rotation : 0.000 0.000 0.000 1.000
health : 116 health : 116
alert_cooldown : 1.0000 alert_cooldown : 1.0000
color_alert : 1.000 1.000 0.000 1.000 color_alert : 1.000 1.000 0.000 1.000

Binary file not shown.

@ -10,17 +10,15 @@ Scene_Config
debug_draw_enabled : false debug_draw_enabled : false
debug_draw_mode : 0 debug_draw_mode : 0
ambient_light : 0.100 0.100 0.100 ambient_light : 0.100 0.100 0.100
init_func : scene_1
cleanup_func : scene_1
} }
Player Player
{ {
type : 2 type : 2
scale : 1.000 1.000 1.000 scale : 1.000 1.000 1.000
rotation : 0.000 0.971 0.000 -0.249 rotation : 0.000 -0.892 0.000 0.452
active : true active : true
position : -30.395 2.857 -17.708 position : -56.360 2.292 -37.583
bouding_box_min : -1.500 -1.500 -1.000 bouding_box_min : -1.500 -1.500 -1.000
name : Player name : Player
bouding_box_max : 1.500 1.500 1.000 bouding_box_max : 1.500 1.500 1.000
@ -47,7 +45,7 @@ Scene_Entity_Entry
Scene_Entity_Entry Scene_Entity_Entry
{ {
scale : 68.000 1.000 68.000 scale : 135.000 1.000 135.000
rotation : 0.000 0.000 0.000 1.000 rotation : 0.000 0.000 0.000 1.000
position : -17.000 0.000 -20.000 position : -17.000 0.000 -20.000
filename : cube filename : cube
@ -56,72 +54,54 @@ Scene_Entity_Entry
Scene_Entity_Entry Scene_Entity_Entry
{ {
scale : 68.000 3.000 1.000 scale : 135.000 6.000 1.000
rotation : 0.000 0.000 0.000 1.000 rotation : 0.000 0.000 0.000 1.000
position : -17.000 4.000 -87.000 position : -17.000 3.000 47.000
filename : cube_uv filename : cube_uv
name : Cube name : Cube
} }
Scene_Entity_Entry Scene_Entity_Entry
{ {
scale : 68.000 3.000 1.000 scale : 135.000 5.000 1.000
rotation : 0.000 0.000 0.000 1.000
position : -17.000 4.000 47.000
filename : cube_uv
name : Cube
}
Scene_Entity_Entry
{
scale : 68.000 3.000 1.000
rotation : 0.000 0.707 0.000 0.707 rotation : 0.000 0.707 0.000 0.707
position : 50.000 4.000 -20.000 position : 50.000 3.000 -20.000
filename : cube_uv filename : cube_uv
name : Cube name : Cube
} }
Scene_Entity_Entry Scene_Entity_Entry
{ {
scale : 68.000 3.000 1.000 scale : 135.000 5.000 1.000
rotation : 0.000 -0.707 0.000 0.707 rotation : 0.000 -0.707 0.000 0.707
position : -84.000 4.000 -20.000 position : -84.000 3.000 -20.000
filename : cube_uv
name : Cube
}
Scene_Entity_Entry
{
scale : 18.900 3.000 1.000
rotation : 0.000 0.000 0.000 1.000
position : -64.000 4.000 2.000
filename : cube_uv filename : cube_uv
name : Cube name : Cube
} }
Scene_Entity_Entry Scene_Entity_Entry
{ {
scale : 68.000 3.000 1.000 scale : 49.800 5.000 1.000
rotation : 0.000 0.000 0.000 1.000 rotation : 0.000 0.000 0.000 1.000
position : -17.000 4.000 -87.000 position : -60.000 3.000 2.000
filename : cube_uv filename : cube_uv
name : Cube name : Cube
} }
Scene_Entity_Entry Scene_Entity_Entry
{ {
scale : 68.000 3.000 1.000 scale : 65.000 5.000 1.000
rotation : 0.000 0.000 0.000 1.000 rotation : 0.000 0.000 0.000 1.000
position : -17.000 4.000 -87.000 position : 15.000 3.000 -30.000
filename : cube_uv filename : cube_uv
name : Cube name : Cube
} }
Scene_Entity_Entry Scene_Entity_Entry
{ {
scale : 35.500 3.000 1.000 scale : 135.000 5.000 1.000
rotation : 0.000 0.000 0.000 1.000 rotation : 0.000 0.000 0.000 1.000
position : 15.000 4.000 -30.000 position : -17.000 3.000 -87.000
filename : cube_uv filename : cube_uv
name : Cube name : Cube
} }
@ -138,7 +118,7 @@ Scene_Entity_Entry
Scene_Entity_Entry Scene_Entity_Entry
{ {
scale : 1.000 1.000 1.000 scale : 1.000 1.000 1.000
rotation : 0.000 -0.348 0.000 0.938 rotation : 0.000 0.001 0.000 1.000
position : -13.000 3.000 4.000 position : -13.000 3.000 4.000
filename : turret filename : turret
name : Turret name : Turret
@ -156,7 +136,7 @@ Scene_Entity_Entry
Scene_Entity_Entry Scene_Entity_Entry
{ {
scale : 1.000 1.000 1.000 scale : 1.000 1.000 1.000
rotation : 0.000 -0.288 0.000 0.958 rotation : 0.000 -0.001 0.000 1.000
position : -7.000 3.000 2.000 position : -7.000 3.000 2.000
filename : turret filename : turret
name : Turret name : Turret
@ -171,3 +151,12 @@ Scene_Entity_Entry
name : Turret name : Turret
} }
Scene_Entity_Entry
{
scale : 1.000 1.000 1.000
rotation : 0.000 0.000 0.000 1.000
position : -25.000 2.000 -18.000
filename : Trigger
name : Trigger
}

@ -15,6 +15,7 @@
#define MAX_SCENE_SOUND_SOURCES 128 #define MAX_SCENE_SOUND_SOURCES 128
#define MAX_SCENE_ENTITY_ARCHETYPES 32 #define MAX_SCENE_ENTITY_ARCHETYPES 32
#define MAX_SCENE_ENEMIES 64 #define MAX_SCENE_ENEMIES 64
#define MAX_SCENE_TRIGGERS 256
#define MAX_UNIFORM_NAME_LEN 64 #define MAX_UNIFORM_NAME_LEN 64

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

@ -253,6 +253,14 @@ void editor_render(struct Editor* editor, struct Camera * active_camera)
im_circle(sound_source->max_distance, 32, false, abs_pos, rot, editor->selected_entity_color, 5); im_circle(sound_source->max_distance, 32, false, abs_pos, rot, editor->selected_entity_color, 5);
} }
break; break;
case ET_TRIGGER:
{
struct Trigger* trigger = (struct Trigger*)editor->selected_entity;
vec3 extents = { 0.f };
vec3_sub(&extents, &trigger->base.derived_bounding_box.max, &trigger->base.derived_bounding_box.min);
im_box(extents.x, extents.y, extents.z, abs_pos, abs_rot, (vec4) { 1.f, 0.f, 0.f, 0.5f }, GDM_TRIANGLES, 5);
}
break;
} }
/* Draw bounding box for selected entity */ /* Draw bounding box for selected entity */
@ -1732,6 +1740,13 @@ void editor_window_scene_hierarchy(struct nk_context* context, struct Editor* ed
nk_tree_pop(context); nk_tree_pop(context);
} }
if(nk_tree_push(context, NK_TREE_TAB, "Triggers", NK_MAXIMIZED))
{
for(int i = 0; i < MAX_SCENE_TRIGGERS; i++)
editor_show_entity_in_list(editor, context, scene, &scene->triggers[i]);
nk_tree_pop(context);
}
if(nk_tree_push(context, NK_TREE_TAB, "Entities", NK_MAXIMIZED)) if(nk_tree_push(context, NK_TREE_TAB, "Entities", NK_MAXIMIZED))
{ {
for(int i = 0; i < MAX_SCENE_ENTITIES; i++) for(int i = 0; i < MAX_SCENE_ENTITIES; i++)
@ -2261,7 +2276,6 @@ void editor_window_property_inspector(struct nk_context* context, struct Editor*
} }
} }
/* Enemy */ /* Enemy */
if(entity->type == ET_ENEMY) if(entity->type == ET_ENEMY)
{ {
@ -2301,6 +2315,32 @@ void editor_window_property_inspector(struct nk_context* context, struct Editor*
nk_tree_pop(context); nk_tree_pop(context);
} }
} }
/* Trigger */
if(entity->type == ET_TRIGGER)
{
struct Trigger* trigger = (struct Trigger*)entity;
if(nk_tree_push(context, NK_TREE_TAB, "Trigger", NK_MAXIMIZED))
{
nk_layout_row_dynamic(context, row_height, 2);
float combo_width = nk_widget_width(context), combo_height = row_height * TRIG_MAX;
nk_label(context, "Type", LABEL_FLAGS_ALIGN_LEFT);
int trigger_type = nk_combo_string(context, "Toggle\0Continuous\0One Shot", trigger->type, TRIG_MAX, row_height, nk_vec2(combo_width, combo_height));
trigger->type = trigger_type;
nk_label(context, "Triggered", LABEL_FLAGS_ALIGN_LEFT);
nk_label(context, trigger->triggered ? "True" : "False", LABEL_FLAGS_ALIGN_LEFT);
nk_label(context, "Trigger Count", LABEL_FLAGS_ALIGN_LEFT);
nk_labelf(context, LABEL_FLAGS_ALIGN_LEFT, "%d", trigger->count);
nk_label(context, "Mask", LABEL_FLAGS_ALIGN_LEFT);
nk_labelf(context, LABEL_FLAGS_ALIGN_LEFT, "%d", trigger->trigger_mask);
nk_tree_pop(context);
}
}
} }
else else
{ {

@ -271,6 +271,14 @@ bool entity_write(struct Entity* entity, struct Parser_Object* object, bool writ
enemy_write(enemy, entity_data); enemy_write(enemy, entity_data);
} }
break; break;
case ET_TRIGGER:
{
struct Trigger* trigger = (struct Trigger*)entity;
hashmap_int_set(entity_data, "trigger_type", trigger->type);
hashmap_int_set(entity_data, "trigger_mask", trigger->trigger_mask);
hashmap_int_set(entity_data, "trigger_event", trigger->trigger_event);
}
break;
}; };
return true; return true;
@ -512,6 +520,18 @@ struct Entity* entity_read(struct Parser_Object* object, struct Entity* parent_e
return new_entity; return new_entity;
} }
break; break;
case ET_TRIGGER:
{
int type = hashmap_value_exists(object->data, "trigger_type") ? hashmap_int_get(object->data, "trigger_type") : TRIG_TOGGLE;
int mask = hashmap_value_exists(object->data, "trigger_mask") ? hashmap_int_get(object->data, "trigger_mask") : TRIGM_ALL;
int trigger_event = hashmap_value_exists(object->data, "trigger_event") ? hashmap_int_get(object->data, "trigger_event") : -1;
struct Trigger* trigger = scene_trigger_create(scene, name, parent_entity, type, trigger_event, mask);
if(!trigger)
return new_entity;
else
new_entity = &trigger->base;
}
break;
default: default:
log_warning("Unhandled Entity type '%d' detected", type); log_warning("Unhandled Entity type '%d' detected", type);
break; break;
@ -628,6 +648,8 @@ const char* entity_type_name_get(struct Entity* entity)
case ET_ROOT: typename = "Root"; break; case ET_ROOT: typename = "Root"; break;
case ET_SOUND_SOURCE: typename = "Sound Source"; break; case ET_SOUND_SOURCE: typename = "Sound Source"; break;
case ET_STATIC_MESH: typename = "Static Mesh"; break; case ET_STATIC_MESH: typename = "Static Mesh"; break;
case ET_ENEMY: typename = "Enemy"; break;
case ET_TRIGGER: typename = "Trigger"; break;
default: typename = "Unknown"; break; default: typename = "Unknown"; break;
}; };
return typename; return typename;

@ -15,6 +15,7 @@ struct Material_Param;
struct Parser_Object; struct Parser_Object;
typedef void (*Collision_CB)(struct Entity* this_entity, struct Entity* other_entity, Rigidbody, Rigidbody); typedef void (*Collision_CB)(struct Entity* this_entity, struct Entity* other_entity, Rigidbody, Rigidbody);
typedef void (*Trigger_Func)(struct Trigger* trigger);
enum Entity_Type enum Entity_Type
{ {
@ -27,6 +28,7 @@ enum Entity_Type
ET_STATIC_MESH, ET_STATIC_MESH,
ET_SOUND_SOURCE, ET_SOUND_SOURCE,
ET_ENEMY, ET_ENEMY,
ET_TRIGGER,
ET_MAX ET_MAX
}; };
@ -74,7 +76,23 @@ enum Entity_Ray_Mask
ERM_STATIC_MESH = 1 << 4, ERM_STATIC_MESH = 1 << 4,
ERM_SOUND_SOURCE = 1 << 5, ERM_SOUND_SOURCE = 1 << 5,
ERM_ENEMY = 1 << 6, ERM_ENEMY = 1 << 6,
ERM_ALL = ERM_DEFAULT | ERM_PLAYER | ERM_CAMERA | ERM_LIGHT | ERM_STATIC_MESH | ERM_SOUND_SOURCE | ERM_ENEMY ERM_TRIGGER = 1 << 7,
ERM_ALL = ERM_DEFAULT | ERM_PLAYER | ERM_CAMERA | ERM_LIGHT | ERM_STATIC_MESH | ERM_SOUND_SOURCE | ERM_ENEMY | ERM_TRIGGER
};
enum Trigger_Mask
{
TRIGM_PLAYER = 0,
TRIGM_ENEMY = 1 << 0,
TRIGM_ALL = TRIGM_PLAYER | TRIGM_ENEMY
};
enum Trigger_Type
{
TRIG_TOGGLE = 0, // Toggled on once and fires event then wont fire event until it is deactivated and activated again
TRIG_CONTINUOUS, // Continuously fire events while the trigger is active
TRIG_ONE_SHOT, // Fire event once when triggerd and then get deleted
TRIG_MAX
}; };
struct Transform struct Transform
@ -226,6 +244,16 @@ struct Enemy
}; };
}; };
struct Trigger
{
struct Entity base;
bool triggered;
int type;
int count;
int trigger_mask;
int trigger_event; // Event to fire when triggered
};
void entity_init(struct Entity* entity, const char* name, struct Entity* parent); void entity_init(struct Entity* entity, const char* name, struct Entity* parent);
void entity_reset(struct Entity* entity, int id); void entity_reset(struct Entity* entity, int id);
bool entity_save(struct Entity* entity, const char* filename, int directory_type); bool entity_save(struct Entity* entity, const char* filename, int directory_type);

@ -21,6 +21,7 @@
#include "enemy.h" #include "enemy.h"
#include "event.h" #include "event.h"
#include "scene_funcs.h" #include "scene_funcs.h"
#include "trigger.h"
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
@ -82,6 +83,12 @@ void scene_init(struct Scene* scene)
scene->enemies->base.type = ET_ENEMY; scene->enemies->base.type = ET_ENEMY;
} }
for(int i = 0; i < MAX_SCENE_TRIGGERS; i++)
{
entity_reset(&scene->triggers[i], i);
scene->triggers->base.type = ET_TRIGGER;
}
player_init(&scene->player, scene); player_init(&scene->player, scene);
editor_camera_init(game_state->editor, game_state->cvars); editor_camera_init(game_state->editor, game_state->cvars);
editor_init_entities(game_state->editor); editor_init_entities(game_state->editor);
@ -269,6 +276,7 @@ bool scene_save(struct Scene* scene, const char* filename, int directory_type)
scene_write_entity_list(scene, ET_CAMERA, parser); scene_write_entity_list(scene, ET_CAMERA, parser);
scene_write_entity_list(scene, ET_SOUND_SOURCE, parser); scene_write_entity_list(scene, ET_SOUND_SOURCE, parser);
scene_write_entity_list(scene, ET_ENEMY, parser); scene_write_entity_list(scene, ET_ENEMY, parser);
scene_write_entity_list(scene, ET_TRIGGER, parser);
if(parser_write_objects(parser, scene_file, prefixed_filename)) if(parser_write_objects(parser, scene_file, prefixed_filename))
log_message("Scene saved to %s", prefixed_filename); log_message("Scene saved to %s", prefixed_filename);
@ -316,6 +324,11 @@ void scene_write_entity_list(struct Scene* scene, int entity_type, struct Parser
entity = &scene->enemies[0].base; entity = &scene->enemies[0].base;
stride = sizeof(struct Enemy); stride = sizeof(struct Enemy);
break; break;
case ET_TRIGGER:
max_length = MAX_SCENE_TRIGGERS;
entity = &scene->triggers[0].base;
stride = sizeof(struct Trigger);
break;
default: return; default: return;
} }
@ -393,6 +406,12 @@ void scene_update_physics(struct Scene* scene, float fixed_dt)
if(scene->enemies[i].base.flags & EF_ACTIVE) if(scene->enemies[i].base.flags & EF_ACTIVE)
enemy_update_physics(&scene->enemies[i], scene, fixed_dt); enemy_update_physics(&scene->enemies[i], scene, fixed_dt);
} }
for(int i = 0; i < MAX_SCENE_TRIGGERS; i++)
{
if(scene->triggers[i].base.flags & EF_ACTIVE)
trigger_update_physics(&scene->triggers[i], scene, fixed_dt);
}
} }
} }
@ -505,6 +524,18 @@ void scene_post_update(struct Scene* scene)
} }
for(int i = 0; i < MAX_SCENE_TRIGGERS; i++)
{
struct Trigger* trigger = &scene->triggers[i];
if(!(trigger->base.flags & EF_ACTIVE)) continue;
if(trigger->base.flags & EF_MARKED_FOR_DELETION)
{
scene_trigger_remove(scene, trigger);
continue;
}
}
if(scene->player.base.transform.is_modified) if(scene->player.base.transform.is_modified)
{ {
scene->player.base.transform.is_modified = false; scene->player.base.transform.is_modified = false;
@ -712,6 +743,32 @@ struct Enemy* scene_enemy_create(struct Scene* scene, const char* name, struct E
return new_enemy; return new_enemy;
} }
struct Trigger* scene_trigger_create(struct Scene* scene, const char* name, struct Entity* parent, int type, int trigger_event, int mask)
{
assert(scene);
struct Trigger* new_trigger = NULL;
for(int i = 0; i < MAX_SCENE_TRIGGERS; i++)
{
struct Trigger* trigger = &scene->triggers[i];
if(!(trigger->base.flags & EF_ACTIVE))
{
new_trigger = trigger;
break;
}
}
if(new_trigger)
{
entity_init(&new_trigger->base, name, parent ? parent : &scene->root_entity);
trigger_init(new_trigger, type, trigger_event, mask);
}
else
{
log_error("scene:trigger_create", "Max trigger limit reached!");
}
return new_trigger;
}
void scene_entity_base_remove(struct Scene* scene, struct Entity* entity) void scene_entity_base_remove(struct Scene* scene, struct Entity* entity)
{ {
assert(scene && entity && entity->id >= 0); assert(scene && entity && entity->id >= 0);
@ -737,6 +794,13 @@ void scene_enemy_remove(struct Scene* scene, struct Enemy* enemy)
scene_entity_base_remove(scene, enemy); scene_entity_base_remove(scene, enemy);
} }
void scene_trigger_remove(struct Scene* scene, struct Trigger* trigger)
{
assert(scene && trigger);
trigger_reset(trigger);
scene_entity_base_remove(scene, &trigger->base);
}
void scene_camera_remove(struct Scene* scene, struct Camera* camera) void scene_camera_remove(struct Scene* scene, struct Camera* camera)
{ {
assert(scene && camera); assert(scene && camera);
@ -867,6 +931,23 @@ struct Enemy* scene_enemy_find(struct Scene* scene, const char* name)
return enemy; return enemy;
} }
struct Trigger* scene_trigger_find(struct Scene* scene, const char* name)
{
assert(scene && name);
struct Trigger* trigger = NULL;
for(int i = 0; i < MAX_SCENE_TRIGGERS; i++)
{
if(strncmp(name, scene->triggers[i].base.name, MAX_ENTITY_NAME_LEN) == 0)
{
trigger = &scene->triggers[i];
break;
}
}
return trigger;
}
struct Entity* scene_base_entity_get(struct Scene* scene, int id, int type) struct Entity* scene_base_entity_get(struct Scene* scene, int id, int type)
{ {
assert(scene && id != -1 && type < ET_MAX); assert(scene && id != -1 && type < ET_MAX);
@ -881,6 +962,7 @@ struct Entity* scene_base_entity_get(struct Scene* scene, int id, int type)
case ET_STATIC_MESH: entity = &scene->static_meshes[id]; break; case ET_STATIC_MESH: entity = &scene->static_meshes[id]; break;
case ET_SOUND_SOURCE: entity = &scene->sound_sources[id]; break; case ET_SOUND_SOURCE: entity = &scene->sound_sources[id]; break;
case ET_ENEMY: entity = &scene->enemies[id]; break; case ET_ENEMY: entity = &scene->enemies[id]; break;
case ET_TRIGGER: entity = &scene->triggers[id]; break;
case ET_PLAYER: entity = &scene->player; break; case ET_PLAYER: entity = &scene->player; break;
case ET_ROOT: entity = &scene->root_entity; break; case ET_ROOT: entity = &scene->root_entity; break;
} }

@ -22,6 +22,7 @@ struct Scene
struct Light lights[MAX_SCENE_LIGHTS]; struct Light lights[MAX_SCENE_LIGHTS];
struct Sound_Source sound_sources[MAX_SCENE_SOUND_SOURCES]; struct Sound_Source sound_sources[MAX_SCENE_SOUND_SOURCES];
struct Enemy enemies[MAX_SCENE_ENEMIES]; struct Enemy enemies[MAX_SCENE_ENEMIES];
struct Trigger triggers[MAX_SCENE_TRIGGERS];
char entity_archetypes[MAX_SCENE_ENTITY_ARCHETYPES][MAX_FILENAME_LEN]; char entity_archetypes[MAX_SCENE_ENTITY_ARCHETYPES][MAX_FILENAME_LEN];
int active_camera_index; int active_camera_index;
Scene_Init_Func init; Scene_Init_Func init;
@ -43,6 +44,7 @@ struct Camera* scene_camera_create(struct Scene* scene, const char* name,
struct Static_Mesh* scene_static_mesh_create(struct Scene* scene, const char* name, struct Entity* parent, const char* geometry_name, int material_type); struct Static_Mesh* scene_static_mesh_create(struct Scene* scene, const char* name, struct Entity* parent, const char* geometry_name, int material_type);
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 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 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 trigger_event, int mask);
void scene_entity_base_remove(struct Scene* scene, struct Entity* entity); void scene_entity_base_remove(struct Scene* scene, struct Entity* entity);
void scene_light_remove(struct Scene* scene, struct Light* light); void scene_light_remove(struct Scene* scene, struct Light* light);
@ -50,6 +52,7 @@ void scene_camera_remove(struct Scene* scene, struct Camera* camera);
void scene_static_mesh_remove(struct Scene* scene, struct Static_Mesh* mesh); 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_sound_source_remove(struct Scene* scene, struct Sound_Source* source);
void scene_enemy_remove(struct Scene* scene, struct Enemy* enemy); void scene_enemy_remove(struct Scene* scene, struct Enemy* enemy);
void scene_trigger_remove(struct Scene* scene, struct Trigger* trigger);
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 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); struct Entity* scene_entity_find(struct Scene* scene, const char* name);
@ -59,6 +62,7 @@ struct Static_Mesh* scene_static_mesh_find(struct Scene* scene, const char* nam
struct Sound_Source* scene_sound_source_find(struct Scene* scene, const char* name); struct Sound_Source* scene_sound_source_find(struct Scene* scene, const char* name);
struct Entity* scene_base_entity_get(struct Scene* scene, int id, int type); 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 Enemy* scene_enemy_find(struct Scene* scene, const char* name);
struct Trigger* scene_trigger_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_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 void scene_entity_parent_reset(struct Scene* scene, struct Entity* entity); // Sets root entity as parent

@ -0,0 +1,102 @@
#include "trigger.h"
#include "entity.h"
#include "game.h"
#include "event.h"
#include "bounding_volumes.h"
#include "scene.h"
#include <assert.h>
void trigger_init(struct Trigger* trigger, int type, int trigger_event, int trigger_mask)
{
assert(type < TRIG_MAX);
trigger->base.type = ET_TRIGGER;
trigger->count = 0;
trigger->triggered = false;
trigger->type = type;
trigger->trigger_event = trigger_event;
trigger->trigger_mask = trigger_mask;
}
void trigger_reset(struct Trigger* trigger)
{
}
void trigger_update_physics(struct Trigger* trigger, struct Scene* scene, float fixed_dt)
{
// Check if we're triggered and fire the associated event
bool intersecting = false;
if(trigger->trigger_mask & TRIGM_PLAYER)
{
int intersection = bv_intersect_bounding_boxes(&trigger->base.derived_bounding_box, &scene->player.base.derived_bounding_box);
if(intersection == IT_INSIDE || intersection == IT_INTERSECT)
{
intersecting = true;
}
}
if(trigger->trigger_mask & TRIGM_ENEMY)
{
for(int i = 0; i < MAX_SCENE_ENEMIES; i++)
{
struct Enemy* enemy = &scene->enemies[i];
if(!(enemy->base.flags & EF_ACTIVE))
continue;
int intersection = bv_intersect_bounding_boxes(&trigger->base.derived_bounding_box, &enemy->mesh->base.derived_bounding_box);
if(intersection == IT_INTERSECT || intersection == IT_INSIDE)
{
intersecting = true;
}
}
}
if(intersecting)
{
bool fire_event = false;
switch(trigger->type)
{
case TRIG_ONE_SHOT:
{
fire_event = true;
trigger->triggered = true;
scene_trigger_remove(scene, trigger);
}
break;
case TRIG_TOGGLE:
{
// if trigger is already triggered last frame and is also intersecting this frame, then
// it means event has already been fired and we cannot fire an event until it is empty
if(trigger->triggered)
{
fire_event = false;
}
else
{
trigger->triggered = true;
fire_event = true;
}
}
break;
case TRIG_CONTINUOUS:
{
trigger->triggered = true;
fire_event = true;
}
}
if(fire_event && trigger->trigger_event != -1)
{
struct Event_Manager* event_manager = game_state_get()->event_manager;
struct Event* trigger_event = event_manager_create_new_event(event_manager);
trigger_event->type = trigger->trigger_event;
event_manager_send_event(event_manager, trigger_event);
}
}
else
{
trigger->triggered = false;
}
}

@ -0,0 +1,10 @@
#ifndef TRIGGER_H
#define TRIGGER_H
struct Trigger;
void trigger_init(struct Trigger* trigger, int type, int trigger_event, int trigger_mask);
void trigger_reset(struct Trigger* trigger);
void trigger_update_physics(struct Trigger* trigger, struct Scene* scene, float fixed_dt);
#endif

@ -1,10 +1,10 @@
Todo: Todo:
- Figure out how to write Scene/Level specific logic, save/load it and be able to differenciate it according to specific scene - Implement Triggers
- How to specify and track level objectives and track them - Implement flag for ignoring collisions with certain entities
- How to move from one scene to another
- Level-wide events and responses
- Main menu as a level or just have a pause menu where game's options etc can be changed?
- Implement separate property window for player related variables that can be shown in the editor similar to renderer settings etc - Implement separate property window for player related variables that can be shown in the editor similar to renderer settings etc
- Implement game gui either with a separate nuklear context or as part of existing context
- Property inspector in editor should only show/apply local transformation values and world transformation values should be shown as non-editabale values
- Add "Select Parent" button to property inspector
- Fix rotate gizmo's origin not being set to the selected entity - Fix rotate gizmo's origin not being set to the selected entity
- Player shooting - Player shooting
- Player jump cooldown, don't allow jump until a certian time interval has passed, even if we're grounded - Player jump cooldown, don't allow jump until a certian time interval has passed, even if we're grounded

Loading…
Cancel
Save