diff --git a/assets/entities/cube.symtres b/assets/entities/cube.symtres index 45cdd0a..1a894e5 100644 --- a/assets/entities/cube.symtres +++ b/assets/entities/cube.symtres @@ -1,14 +1,18 @@ - Entity { type : 6 + scale : 135.000 1.000 135.000 material : 0 + rotation : 0.000 0.000 0.000 1.000 diffuse_color : 1.000 1.000 1.000 1.000 geometry : cube.symbres specular : 1.0000 active : true diffuse_texture : default.tga diffuse : 1.0000 + position : -17.000 0.000 -20.000 specular_strength : 1.0000 - name : Cube -} \ No newline at end of file + name : Ground + uv_scale : 7.700 8.900 +} + diff --git a/assets/entities/cube_uv.symtres b/assets/entities/cube_uv.symtres index f7b5653..f80eaeb 100755 --- a/assets/entities/cube_uv.symtres +++ b/assets/entities/cube_uv.symtres @@ -1,7 +1,7 @@ Entity { type : 6 - scale : 68.000 3.000 1.000 + scale : 135.000 5.000 1.000 material : 0 rotation : 0.000 0.000 0.000 1.000 diffuse_color : 1.000 1.000 1.000 1.000 @@ -10,9 +10,9 @@ Entity active : true diffuse_texture : default.tga diffuse : 1.0000 - position : -17.000 4.000 -87.000 + position : -17.000 3.000 -87.000 specular_strength : 1.0000 name : Cube - uv_scale : 15.000 1.000 + uv_scale : 5.000 63.500 } diff --git a/assets/entities/turret.symtres b/assets/entities/turret.symtres index bd73074..bd07cae 100644 --- a/assets/entities/turret.symtres +++ b/assets/entities/turret.symtres @@ -5,7 +5,7 @@ Entity pulsate_height : 1.5000 vision_range : 15.0000 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 alert_cooldown : 1.0000 color_alert : 1.000 1.000 0.000 1.000 diff --git a/assets/models/cube.symbres b/assets/models/cube.symbres index 7306f16..b556980 100755 Binary files a/assets/models/cube.symbres and b/assets/models/cube.symbres differ diff --git a/assets/scenes/scene_1.symtres b/assets/scenes/scene_1.symtres index 6533864..12d4fca 100755 --- a/assets/scenes/scene_1.symtres +++ b/assets/scenes/scene_1.symtres @@ -10,17 +10,15 @@ Scene_Config debug_draw_enabled : false debug_draw_mode : 0 ambient_light : 0.100 0.100 0.100 - init_func : scene_1 - cleanup_func : scene_1 } Player { type : 2 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 - position : -30.395 2.857 -17.708 + position : -56.360 2.292 -37.583 bouding_box_min : -1.500 -1.500 -1.000 name : Player bouding_box_max : 1.500 1.500 1.000 @@ -47,7 +45,7 @@ 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 position : -17.000 0.000 -20.000 filename : cube @@ -56,72 +54,54 @@ 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 - position : -17.000 4.000 -87.000 + position : -17.000 3.000 47.000 filename : cube_uv name : Cube } Scene_Entity_Entry { - scale : 68.000 3.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 + scale : 135.000 5.000 1.000 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 name : Cube } 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 - position : -84.000 4.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 + position : -84.000 3.000 -20.000 filename : cube_uv name : Cube } 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 - position : -17.000 4.000 -87.000 + position : -60.000 3.000 2.000 filename : cube_uv name : Cube } 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 - position : -17.000 4.000 -87.000 + position : 15.000 3.000 -30.000 filename : cube_uv name : Cube } 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 - position : 15.000 4.000 -30.000 + position : -17.000 3.000 -87.000 filename : cube_uv name : Cube } @@ -138,7 +118,7 @@ Scene_Entity_Entry Scene_Entity_Entry { 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 filename : turret name : Turret @@ -156,7 +136,7 @@ Scene_Entity_Entry Scene_Entity_Entry { 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 filename : turret name : Turret @@ -171,3 +151,12 @@ Scene_Entity_Entry 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 +} + diff --git a/src/common/limits.h b/src/common/limits.h index 36aaa22..efd34b9 100644 --- a/src/common/limits.h +++ b/src/common/limits.h @@ -15,6 +15,7 @@ #define MAX_SCENE_SOUND_SOURCES 128 #define MAX_SCENE_ENTITY_ARCHETYPES 32 #define MAX_SCENE_ENEMIES 64 +#define MAX_SCENE_TRIGGERS 256 #define MAX_UNIFORM_NAME_LEN 64 diff --git a/src/common/version.h b/src/common/version.h index e610257..5e43eb3 100755 --- a/src/common/version.h +++ b/src/common/version.h @@ -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 327 +#define SYMMETRY_VERSION_REVISION 328 #define SYMMETRY_VERSION_BRANCH "dev" #endif \ No newline at end of file diff --git a/src/game/editor.c b/src/game/editor.c index e95eaf0..770ee18 100755 --- a/src/game/editor.c +++ b/src/game/editor.c @@ -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); } 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 */ @@ -1732,6 +1740,13 @@ void editor_window_scene_hierarchy(struct nk_context* context, struct Editor* ed 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)) { for(int i = 0; i < MAX_SCENE_ENTITIES; i++) @@ -2260,7 +2275,6 @@ void editor_window_property_inspector(struct nk_context* context, struct Editor* nk_tree_pop(context); } } - /* Enemy */ if(entity->type == ET_ENEMY) @@ -2294,13 +2308,39 @@ void editor_window_property_inspector(struct nk_context* context, struct Editor* nk_label(context, "Scan", LABEL_FLAGS_ALIGN_LEFT); nk_labelf(context, LABEL_FLAGS_ALIGN_LEFT, "%s", enemy->Turret.scan ? "True" : "False"); nk_label(context, "Default Color", LABEL_FLAGS_ALIGN_LEFT); editor_widget_color_combov4(context, &enemy->Turret.color_default, 50, row_height * 2); nk_label(context, "Alert Color", LABEL_FLAGS_ALIGN_LEFT); editor_widget_color_combov4(context, &enemy->Turret.color_alert, 50, row_height * 2); - nk_label(context, "Attack Color", LABEL_FLAGS_ALIGN_LEFT); editor_widget_color_combov4(context, &enemy->Turret.color_attack, 50, row_height * 2); + nk_label(context, "Attack Color", LABEL_FLAGS_ALIGN_LEFT); editor_widget_color_combov4(context, &enemy->Turret.color_attack, 50, row_height * 2); } break; } 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 { diff --git a/src/game/entity.c b/src/game/entity.c index 09e1a86..3404267 100755 --- a/src/game/entity.c +++ b/src/game/entity.c @@ -271,6 +271,14 @@ bool entity_write(struct Entity* entity, struct Parser_Object* object, bool writ enemy_write(enemy, entity_data); } 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; @@ -512,6 +520,18 @@ struct Entity* entity_read(struct Parser_Object* object, struct Entity* parent_e return new_entity; } 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: log_warning("Unhandled Entity type '%d' detected", type); break; @@ -628,6 +648,8 @@ const char* entity_type_name_get(struct Entity* entity) case ET_ROOT: typename = "Root"; break; case ET_SOUND_SOURCE: typename = "Sound Source"; 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; }; return typename; diff --git a/src/game/entity.h b/src/game/entity.h index 6cf8633..2a16e48 100755 --- a/src/game/entity.h +++ b/src/game/entity.h @@ -15,6 +15,7 @@ struct Material_Param; struct Parser_Object; typedef void (*Collision_CB)(struct Entity* this_entity, struct Entity* other_entity, Rigidbody, Rigidbody); +typedef void (*Trigger_Func)(struct Trigger* trigger); enum Entity_Type { @@ -27,6 +28,7 @@ enum Entity_Type ET_STATIC_MESH, ET_SOUND_SOURCE, ET_ENEMY, + ET_TRIGGER, ET_MAX }; @@ -74,7 +76,23 @@ enum Entity_Ray_Mask ERM_STATIC_MESH = 1 << 4, ERM_SOUND_SOURCE = 1 << 5, 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 @@ -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_reset(struct Entity* entity, int id); bool entity_save(struct Entity* entity, const char* filename, int directory_type); diff --git a/src/game/scene.c b/src/game/scene.c index 179dbb4..c1b22e6 100755 --- a/src/game/scene.c +++ b/src/game/scene.c @@ -21,6 +21,7 @@ #include "enemy.h" #include "event.h" #include "scene_funcs.h" +#include "trigger.h" #include #include @@ -82,6 +83,12 @@ void scene_init(struct Scene* scene) 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); editor_camera_init(game_state->editor, game_state->cvars); 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_SOUND_SOURCE, 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)) 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; stride = sizeof(struct Enemy); break; + case ET_TRIGGER: + max_length = MAX_SCENE_TRIGGERS; + entity = &scene->triggers[0].base; + stride = sizeof(struct Trigger); + break; default: return; } @@ -393,6 +406,12 @@ void scene_update_physics(struct Scene* scene, float fixed_dt) if(scene->enemies[i].base.flags & EF_ACTIVE) 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) { 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; } +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) { 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); } +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) { assert(scene && camera); @@ -867,6 +931,23 @@ struct Enemy* scene_enemy_find(struct Scene* scene, const char* name) 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) { 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_SOUND_SOURCE: entity = &scene->sound_sources[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_ROOT: entity = &scene->root_entity; break; } diff --git a/src/game/scene.h b/src/game/scene.h index 0d94f4d..62b970b 100755 --- a/src/game/scene.h +++ b/src/game/scene.h @@ -22,6 +22,7 @@ struct Scene struct Light lights[MAX_SCENE_LIGHTS]; struct Sound_Source sound_sources[MAX_SCENE_SOUND_SOURCES]; struct Enemy enemies[MAX_SCENE_ENEMIES]; + struct Trigger triggers[MAX_SCENE_TRIGGERS]; char entity_archetypes[MAX_SCENE_ENTITY_ARCHETYPES][MAX_FILENAME_LEN]; int active_camera_index; 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 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 trigger_event, int mask); void scene_entity_base_remove(struct Scene* scene, struct Entity* entity); 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_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_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); @@ -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 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); 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 diff --git a/src/game/trigger.c b/src/game/trigger.c new file mode 100644 index 0000000..0d75664 --- /dev/null +++ b/src/game/trigger.c @@ -0,0 +1,102 @@ +#include "trigger.h" +#include "entity.h" +#include "game.h" +#include "event.h" +#include "bounding_volumes.h" +#include "scene.h" + +#include + +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; + } +} diff --git a/src/game/trigger.h b/src/game/trigger.h new file mode 100644 index 0000000..79f2ff4 --- /dev/null +++ b/src/game/trigger.h @@ -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 \ No newline at end of file diff --git a/todo.txt b/todo.txt index 76e135e..21e6b95 100644 --- a/todo.txt +++ b/todo.txt @@ -1,10 +1,10 @@ Todo: - - Figure out how to write Scene/Level specific logic, save/load it and be able to differenciate it according to specific scene - - How to specify and track level objectives and track them - - 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 Triggers + - 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 + - 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 - Player shooting - Player jump cooldown, don't allow jump until a certian time interval has passed, even if we're grounded