diff --git a/assets/entities/Game_End_Trigger.symtres b/assets/entities/Game_End_Trigger.symtres new file mode 100644 index 0000000..4fb576b --- /dev/null +++ b/assets/entities/Game_End_Trigger.symtres @@ -0,0 +1,14 @@ +Entity +{ + type : 9 + scale : 8.000 6.000 7.000 + rotation : 0.000 0.000 0.000 1.000 + trigger_mask : 1 + position : -20.000 4.000 -6.000 + flags : 1 + trigger_type : 0 + name : Game_End_Trigger + bounding_box_min : -0.500 -0.500 -0.500 + bounding_box_max : 0.500 0.500 0.500 +} + diff --git a/assets/entities/sponza.symtres b/assets/entities/sponza.symtres new file mode 100644 index 0000000..bd19dcc --- /dev/null +++ b/assets/entities/sponza.symtres @@ -0,0 +1,14 @@ +Entity +{ + type : 6 + material : 0 + diffuse_color : 1.000 1.000 1.000 1.000 + geometry : sponza.symbres + specular : 1.0000 + active : true + diffuse_texture : default.tga + diffuse : 1.0000 + specular_strength : 1.0000 + name : Sponza +} + diff --git a/assets/models/sponza.symbres b/assets/models/sponza.symbres new file mode 100644 index 0000000..fb681e1 Binary files /dev/null and b/assets/models/sponza.symbres differ diff --git a/src/common/memory_utils.c b/src/common/memory_utils.c index b754ce5..8621319 100644 --- a/src/common/memory_utils.c +++ b/src/common/memory_utils.c @@ -41,9 +41,9 @@ void* memory_reallocate_(void** ptr, size_t size) } else { - current_allocation = reallocated_memory; memory.allocated += (size - current_allocation->size); current_allocation->size = size; + current_allocation = reallocated_memory; } return current_allocation->allocation; @@ -72,6 +72,7 @@ void memory_free(void* ptr) struct Memory_Allocation* allocation = memory_get_allocation_ptr(ptr); //memory->allocated -= allocation->size; memory.allocated -= allocation->size + sizeof(*allocation); + memory.freed += allocation->size + sizeof(*allocation); free(allocation); } diff --git a/src/common/version.h b/src/common/version.h index 0daa88e..b0b49a7 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 2 -#define SYMMETRY_VERSION_REVISION 365 +#define SYMMETRY_VERSION_REVISION 366 #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 c9b8167..415b198 100755 --- a/src/game/editor.c +++ b/src/game/editor.c @@ -2761,7 +2761,7 @@ void editor_window_settings_scene(struct nk_context* context, struct Editor* edi } else { - editor->window_settings_renderer = 0; + editor->window_settings_scene = 0; } nk_end(context); } diff --git a/src/game/game.c b/src/game/game.c index 45fbfa1..3a582df 100755 --- a/src/game/game.c +++ b/src/game/game.c @@ -105,6 +105,8 @@ bool game_init(struct Window* window, struct Hashmap* cvars) hashmap_ptr_set(game_state->scene_func_table, "scene_func_stub", &scene_func_stub); hashmap_ptr_set(game_state->scene_func_table, "scene_1_init", &scene_1_init); hashmap_ptr_set(game_state->scene_func_table, "scene_1_cleanup", &scene_1_cleanup); + hashmap_ptr_set(game_state->scene_func_table, "scene_game_end_init", &scene_game_end_init); + hashmap_ptr_set(game_state->scene_func_table, "scene_game_end_cleanup", &scene_game_end_cleanup); srand(time(NULL)); diff --git a/src/game/gui_game.c b/src/game/gui_game.c index a2a268b..2049ffd 100644 --- a/src/game/gui_game.c +++ b/src/game/gui_game.c @@ -18,6 +18,7 @@ static void gui_game_next_level_dialog(struct nk_context* context); static void gui_game_restart_level_dialog(struct nk_context* context); static void gui_game_on_player_death(struct Event* event); static void gui_game_on_scene_cleared(struct Event* event); +static void gui_game_end_dialog(struct nk_context* context); void gui_game_init(struct Game_Gui* game_gui) { @@ -120,6 +121,9 @@ void gui_game_update(struct Game_Gui* game_gui, float dt) if(game_gui->show_restart_level_dialog) gui_game_restart_level_dialog(context); + + if(game_gui->show_game_end_dialog) + gui_game_end_dialog(context); } else if(game_state->game_mode == GAME_MODE_PAUSE) { @@ -313,7 +317,7 @@ static void gui_game_next_level_dialog(struct nk_context* context) } } -static void gui_game_restart_level_dialog(struct nk_context* context) +void gui_game_restart_level_dialog(struct nk_context* context) { struct Game_State* game_state = game_state_get(); struct Game_Gui* game_gui = game_state->gui_game; @@ -366,6 +370,66 @@ void gui_game_on_player_death(struct Event* event) void gui_game_on_scene_cleared(struct Event* event) { - game_state_get()->gui_game->show_next_level_dialog = true; + struct Game_State* game_state = game_state_get(); + if(!game_state->gui_game->show_game_end_dialog) game_state->gui_game->show_next_level_dialog = true; input_mouse_mode_set(MM_NORMAL); } + +void gui_game_show_game_end_dialog(struct Game_Gui* game_gui) +{ + game_gui->show_game_end_dialog = true; + game_gui->show_next_level_dialog = false; +} + +void gui_game_end_dialog(struct nk_context* context) +{ + struct Game_State* game_state = game_state_get(); + struct Game_Gui* game_gui = game_state->gui_game; + int row_height = 30; + int popup_x = 0; + int popup_y = 0; + int popup_width = 300; + int popup_height = 200; + int display_width = 0; + int display_height = 0; + int popup_flags = NK_WINDOW_TITLE | NK_WINDOW_BORDER; + window_get_drawable_size(game_state_get()->window, &display_width, &display_height); + popup_x = (display_width / 2) - (popup_width / 2); + popup_y = (display_height / 2) - (popup_height / 2); + + int background_window_flags = NK_WINDOW_BACKGROUND; + if(nk_begin(context, "Game End Dialog", nk_rect(0, 0, display_width, display_height), background_window_flags)) + { + context->style.window.fixed_background = game_gui->skin.menu_background; + nk_window_set_focus(context, "Game End Dialog"); + if(nk_popup_begin(context, NK_POPUP_DYNAMIC, "Congratulations!", popup_flags, nk_recti(popup_x, popup_y, popup_width, popup_height))) + { + nk_layout_row_dynamic(context, row_height, 1); + nk_label(context, "YOU BEAT THE GAME!", NK_TEXT_ALIGN_CENTERED | NK_TEXT_ALIGN_MIDDLE); + if(nk_button_label(context, "Restart Level")) + { + char filename[MAX_FILENAME_LEN]; + strncpy(filename, game_state->scene->filename, MAX_FILENAME_LEN); + if(!scene_load(game_state->scene, filename, DIRT_INSTALL)) + log_error("gui_game:end_dialog", "Failed to reload Level"); + else + game_gui->show_game_end_dialog = false; + } + + if(nk_button_label(context, "Restart from first Level")) + { + if(scene_load(game_state->scene, "scene_1", DIRT_INSTALL)) + game_gui->show_game_end_dialog = false; + else + log_error("gui_game:end_dialog", "Failed to load first level"); + } + + if(nk_button_label(context, "Quit")) + game_state->quit = true; + + nk_popup_end(context); + } + + nk_end(context); + } +} diff --git a/src/game/gui_game.h b/src/game/gui_game.h index c3a222a..0f2c794 100644 --- a/src/game/gui_game.h +++ b/src/game/gui_game.h @@ -8,6 +8,7 @@ struct Game_Gui struct Gui* gui; bool show_next_level_dialog; bool show_restart_level_dialog; + bool show_game_end_dialog; struct { @@ -31,5 +32,6 @@ void gui_game_init(struct Game_Gui* game_gui); void gui_game_cleanup(struct Game_Gui* game_gui); void gui_game_update(struct Game_Gui* gui_game, float dt); void gui_game_show_door_locked_dialog(struct Game_Gui* game_gui, struct Door* door); +void gui_game_show_game_end_dialog(struct Game_Gui* game_gui); #endif \ No newline at end of file diff --git a/src/game/scene.c b/src/game/scene.c index c24b677..7894b7e 100755 --- a/src/game/scene.c +++ b/src/game/scene.c @@ -496,7 +496,7 @@ void scene_write_entity_entry(struct Scene* scene, struct Entity* entity, struct // For entities with archetypes, we only write the name of the archetype to load // them from and their transformation info struct Parser_Object* object = parser_object_new(parser, PO_SCENE_ENTITY_ENTRY); - ////hashmap_str_set(object->data, "filename", &scene->entity_archetypes[entity->archetype_index][0]); + hashmap_str_set(object->data, "filename", &scene->entity_archetypes[entity->archetype_index][0]); hashmap_str_set(object->data, "name", entity->name); hashmap_vec3_set(object->data, "position", &entity->transform.position); hashmap_vec3_set(object->data, "scale", &entity->transform.scale); diff --git a/src/game/scene_funcs.c b/src/game/scene_funcs.c index 387a5e7..4507ab3 100644 --- a/src/game/scene_funcs.c +++ b/src/game/scene_funcs.c @@ -1,10 +1,12 @@ #include "scene_funcs.h" #include "event.h" #include "game.h" +#include "gui_game.h" #include "../common/log.h" static void scene_on_end_trigger(const struct Event* event, void* sender); +static void scene_on_game_end_trigger(const struct Event* event, void* sender); void scene_func_stub(struct Scene* scene) { @@ -45,3 +47,37 @@ void scene_on_end_trigger(const struct Event* event, void* sender) scene_cleared_event->scene_cleared.scene = game_state_get()->scene; event_manager_send_event(event_manager, scene_cleared_event); } + +void scene_game_end_init(struct Scene* scene) +{ + struct Trigger* game_end_trigger = scene_trigger_find(scene, "Game_End_Trigger"); + if(game_end_trigger) + { + struct Event_Manager* event_manager = game_state_get()->event_manager; + event_manager_subscribe_with_sender(event_manager, EVT_TRIGGER, &scene_on_game_end_trigger, game_end_trigger); + } + else + { + log_message("Trigger not found"); + } +} + +void scene_game_end_cleanup(struct Scene* scene) +{ + struct Trigger* game_end_trigger = scene_trigger_find(scene, "Game_End_Trigger"); + if(game_end_trigger) + { + struct Event_Manager* event_manager = game_state_get()->event_manager; + event_manager_unsubscribe_sender(event_manager, EVT_TRIGGER, &scene_on_game_end_trigger, game_end_trigger); + } +} + +void scene_on_game_end_trigger(const struct Event* event, void* sender) +{ + struct Event_Manager* event_manager = game_state_get()->event_manager; + struct Event* scene_cleared_event = event_manager_create_new_event(event_manager); + scene_cleared_event->type = EVT_SCENE_CLEARED; + scene_cleared_event->scene_cleared.scene = game_state_get()->scene; + event_manager_send_event(event_manager, scene_cleared_event); + gui_game_show_game_end_dialog(game_state_get()->gui_game); +} diff --git a/src/game/scene_funcs.h b/src/game/scene_funcs.h index 56e0f58..e297d8a 100644 --- a/src/game/scene_funcs.h +++ b/src/game/scene_funcs.h @@ -6,6 +6,8 @@ void scene_func_stub(struct Scene* scene); void scene_1_init(struct Scene* scene); void scene_1_cleanup(struct Scene* scene); +void scene_game_end_cleanup(struct Scene* scene); +void scene_game_end_init(struct Scene* scene); #endif \ No newline at end of file diff --git a/todo.txt b/todo.txt index 8e0c6ba..c9da550 100644 --- a/todo.txt +++ b/todo.txt @@ -1,6 +1,6 @@ Todo: - Game End - - Add functionality to editor that enables adding a default empty entity without having to load it from file + - Save NONE when next_scene is not set and the scene is being saved - Don't save parent entity's transform when saving entity archetype. Only save the transformation values for children - Save case sensitive file names when scene entity entries - Disbale all player actions when scene cleared dialog or scene restart dialog are active