From 62273786e624f4c74ecc8e2f3df793c753b8d8a1 Mon Sep 17 00:00:00 2001 From: "C. J. Howard" Date: Sun, 20 Jun 2021 00:28:55 +0800 Subject: [PATCH] Revise game states --- CMakeLists.txt | 1 + src/application.cpp | 59 ++- src/application.hpp | 28 +- src/debug/console-commands.cpp | 7 +- src/debug/console-commands.hpp | 9 +- src/game/bootloader.cpp | 76 ++-- src/game/{game-context.hpp => context.hpp} | 13 +- src/game/states/loading.cpp | 268 ++++++++++++ .../states/{loading-state.cpp => loading.hpp} | 33 +- .../{map-state.cpp => nuptial-flight.cpp} | 51 ++- .../{game-states.hpp => nuptial-flight.hpp} | 39 +- src/game/states/play-state.cpp | 401 ------------------ src/game/states/play.cpp | 100 +++++ .../{language-select-state.cpp => play.hpp} | 25 +- .../states/{splash-state.cpp => splash.cpp} | 56 ++- src/game/states/splash.hpp | 39 ++ .../states/{pause-state.cpp => states.hpp} | 19 +- src/game/states/title-state.cpp | 55 --- 18 files changed, 654 insertions(+), 625 deletions(-) rename src/game/{game-context.hpp => context.hpp} (96%) create mode 100644 src/game/states/loading.cpp rename src/game/states/{loading-state.cpp => loading.hpp} (58%) rename src/game/states/{map-state.cpp => nuptial-flight.cpp} (53%) rename src/game/states/{game-states.hpp => nuptial-flight.hpp} (54%) delete mode 100644 src/game/states/play-state.cpp create mode 100644 src/game/states/play.cpp rename src/game/states/{language-select-state.cpp => play.hpp} (68%) rename src/game/states/{splash-state.cpp => splash.cpp} (74%) create mode 100644 src/game/states/splash.hpp rename src/game/states/{pause-state.cpp => states.hpp} (75%) delete mode 100644 src/game/states/title-state.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index d4aa351..af368e1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,6 @@ cmake_minimum_required(VERSION 3.7) + option(VERSION_STRING "Project version string" "0.0.0") project(antkeeper VERSION ${VERSION_STRING} LANGUAGES CXX) diff --git a/src/application.cpp b/src/application.cpp index edfec4f..21f7c16 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -39,7 +39,8 @@ application::application(): closed(false), exit_status(EXIT_SUCCESS), - state({nullptr, nullptr}), + current_state{std::string(), nullptr, nullptr}, + queued_state{std::string(), nullptr, nullptr}, update_callback(nullptr), render_callback(nullptr), fullscreen(true), @@ -277,27 +278,69 @@ int application::execute(bootloader_type bootloader) } // Exit current state - change_state({nullptr, nullptr}); + change_state({std::string(), nullptr, nullptr}); return exit_status; } -void application::change_state(const state_type& next_state) +void application::change_state(const application::state& next_state) { // Exit current state - if (state[1]) + if (current_state.exit) { - state[1](); + logger->push_task("Exiting application state \"" + current_state.name + "\""); + + try + { + current_state.exit(); + } + catch (...) + { + logger->pop_task(EXIT_FAILURE); + throw; + } + logger->pop_task(EXIT_SUCCESS); } + current_state = next_state; + // Enter next state - state = next_state; - if (state[0]) + if (current_state.enter) { - state[0](); + logger->push_task("Entering application state \"" + current_state.name + "\""); + + try + { + current_state.enter(); + } + catch (...) + { + logger->pop_task(EXIT_FAILURE); + throw; + } + logger->pop_task(EXIT_SUCCESS); + } + + // Enter queued state (if any) + if (queued_state.enter != nullptr || queued_state.exit != nullptr) + { + // Make a copy of the queued state + application::state queued_state_copy = queued_state; + + // Clear the queued state + queued_state = {std::string(), nullptr, nullptr}; + + // Enter the queued state + change_state(queued_state_copy); } } +void application::queue_state(const application::state& next_state) +{ + queued_state = next_state; + logger->log("Queued application state \"" + queued_state.name + "\""); +} + std::shared_ptr application::capture_frame() const { int w = viewport_dimensions[0]; diff --git a/src/application.hpp b/src/application.hpp index 8c0b934..43ca4d2 100644 --- a/src/application.hpp +++ b/src/application.hpp @@ -49,7 +49,19 @@ namespace debug class application { public: - typedef std::array, 2> state_type; + /// Application state type. + struct state + { + /// Name of the state. + std::string name; + + /// State enter function. + std::function enter; + + /// State exit function. + std::function exit; + }; + typedef std::function bootloader_type; typedef std::function update_callback_type; typedef std::function render_callback_type; @@ -83,9 +95,16 @@ public: /** * Changes the applications state, resulting in the execution of the current state's exit function (if any), followed by the new state's enter function (if any). * - * @param state A pair of enter and exit functions, respectively, which define the state. + * @param next_state Next application state. + */ + void change_state(const application::state& next_state); + + /** + * Queues the next applications state. This may be called from within a state's enter function. + * + * @param next_state Next application state. */ - void change_state(const state_type& state); + void queue_state(const application::state& next_state); /** * Captures a screenshot of the most recently rendered frame. @@ -206,7 +225,8 @@ private: bool closed; int exit_status; - state_type state; + application::state current_state; + application::state queued_state; update_callback_type update_callback; render_callback_type render_callback; bool fullscreen; diff --git a/src/debug/console-commands.cpp b/src/debug/console-commands.cpp index 79b9f43..857adef 100644 --- a/src/debug/console-commands.cpp +++ b/src/debug/console-commands.cpp @@ -20,7 +20,6 @@ #include "console-commands.hpp" #include "application.hpp" #include "animation/timeline.hpp" -#include "game/game-context.hpp" #include "debug/cli.hpp" namespace debug { @@ -31,19 +30,19 @@ std::string echo(std::string text) return text; } -std::string exit(game_context* ctx) +std::string exit(game::context* ctx) { ctx->app->close(EXIT_SUCCESS); return std::string(); } -std::string scrot(game_context* ctx) +std::string scrot(game::context* ctx) { //ctx->app->take_screenshot(); return std::string("screenshot saved"); } -std::string cue(game_context* ctx, float t, std::string command) +std::string cue(game::context* ctx, float t, std::string command) { ::timeline* timeline = ctx->timeline; debug::cli* cli = ctx->cli; diff --git a/src/debug/console-commands.hpp b/src/debug/console-commands.hpp index 17bbaa5..39cc28e 100644 --- a/src/debug/console-commands.hpp +++ b/src/debug/console-commands.hpp @@ -20,10 +20,9 @@ #ifndef ANTKEEPER_DEBUG_CONSOLE_COMMANDS_HPP #define ANTKEEPER_DEBUG_CONSOLE_COMMANDS_HPP +#include "game/context.hpp" #include -struct game_context; - namespace debug { /// Console commands @@ -31,11 +30,11 @@ namespace cc { std::string echo(std::string text); -std::string exit(game_context* ctx); +std::string exit(game::context* ctx); -std::string scrot(game_context* ctx); +std::string scrot(game::context* ctx); -std::string cue(game_context* ctx, float t, std::string command); +std::string cue(game::context* ctx, float t, std::string command); } // namespace cc } // namespace debug diff --git a/src/game/bootloader.cpp b/src/game/bootloader.cpp index 323513d..8228541 100644 --- a/src/game/bootloader.cpp +++ b/src/game/bootloader.cpp @@ -26,7 +26,7 @@ #include "debug/cli.hpp" #include "debug/console-commands.hpp" #include "debug/logger.hpp" -#include "game/game-context.hpp" +#include "game/context.hpp" #include "gl/framebuffer.hpp" #include "gl/pixel-format.hpp" #include "gl/pixel-type.hpp" @@ -54,7 +54,7 @@ #include "resources/resource-manager.hpp" #include "resources/resource-manager.hpp" #include "scene/scene.hpp" -#include "game/states/game-states.hpp" +#include "game/states/loading.hpp" #include "entity/systems/behavior.hpp" #include "entity/systems/camera.hpp" #include "entity/systems/collision.hpp" @@ -102,19 +102,19 @@ static constexpr double seconds_per_day = 24.0 * 60.0 * 60.0; -static void parse_options(game_context* ctx, int argc, char** argv); -static void setup_resources(game_context* ctx); -static void load_config(game_context* ctx); -static void load_strings(game_context* ctx); -static void setup_window(game_context* ctx); -static void setup_rendering(game_context* ctx); -static void setup_scenes(game_context* ctx); -static void setup_animation(game_context* ctx); -static void setup_entities(game_context* ctx); -static void setup_systems(game_context* ctx); -static void setup_controls(game_context* ctx); -static void setup_cli(game_context* ctx); -static void setup_callbacks(game_context* ctx); +static void parse_options(game::context* ctx, int argc, char** argv); +static void setup_resources(game::context* ctx); +static void load_config(game::context* ctx); +static void load_strings(game::context* ctx); +static void setup_window(game::context* ctx); +static void setup_rendering(game::context* ctx); +static void setup_scenes(game::context* ctx); +static void setup_animation(game::context* ctx); +static void setup_entities(game::context* ctx); +static void setup_systems(game::context* ctx); +static void setup_controls(game::context* ctx); +static void setup_cli(game::context* ctx); +static void setup_callbacks(game::context* ctx); int bootloader(application* app, int argc, char** argv) { @@ -124,7 +124,7 @@ int bootloader(application* app, int argc, char** argv) logger->push_task("Running application bootloader"); // Allocate game context - game_context* ctx = new game_context(); + game::context* ctx = new game::context(); ctx->app = app; ctx->logger = logger; @@ -154,16 +154,19 @@ int bootloader(application* app, int argc, char** argv) logger->pop_task(EXIT_SUCCESS); - // Change state - if (ctx->option_quick_start.has_value()) - app->change_state({std::bind(play_state_enter, ctx), std::bind(play_state_exit, ctx)}); - else - app->change_state({std::bind(splash_state_enter, ctx), std::bind(splash_state_exit, ctx)}); + // Setup initial application state + application::state initial_state; + initial_state.name = "loading"; + initial_state.enter = std::bind(game::state::loading::enter, ctx); + initial_state.exit = std::bind(game::state::loading::exit, ctx); + + // Enter initial application state + app->change_state(initial_state); return EXIT_SUCCESS; } -void parse_options(game_context* ctx, int argc, char** argv) +void parse_options(game::context* ctx, int argc, char** argv) { debug::logger* logger = ctx->logger; logger->push_task("Parsing command line options"); @@ -229,7 +232,7 @@ void parse_options(game_context* ctx, int argc, char** argv) logger->pop_task(EXIT_SUCCESS); } -void setup_resources(game_context* ctx) +void setup_resources(game::context* ctx) { debug::logger* logger = ctx->logger; @@ -352,7 +355,7 @@ void setup_resources(game_context* ctx) ctx->resource_manager->include("/"); } -void load_config(game_context* ctx) +void load_config(game::context* ctx) { debug::logger* logger = ctx->logger; logger->push_task("Loading config"); @@ -368,7 +371,7 @@ void load_config(game_context* ctx) logger->pop_task(EXIT_SUCCESS); } -void load_strings(game_context* ctx) +void load_strings(game::context* ctx) { debug::logger* logger = ctx->logger; logger->push_task("Loading strings"); @@ -392,7 +395,7 @@ void load_strings(game_context* ctx) logger->pop_task(EXIT_SUCCESS); } -void setup_window(game_context* ctx) +void setup_window(game::context* ctx) { debug::logger* logger = ctx->logger; logger->push_task("Setting up window"); @@ -439,7 +442,7 @@ void setup_window(game_context* ctx) logger->pop_task(EXIT_SUCCESS); } -void setup_rendering(game_context* ctx) +void setup_rendering(game::context* ctx) { debug::logger* logger = ctx->logger; logger->push_task("Setting up rendering"); @@ -505,7 +508,7 @@ void setup_rendering(game_context* ctx) ctx->overworld_clear_pass->set_clear_depth(0.0f); ctx->overworld_sky_pass = new sky_pass(ctx->rasterizer, ctx->framebuffer_hdr, ctx->resource_manager); ctx->app->get_event_dispatcher()->subscribe(ctx->overworld_sky_pass); - ctx->overworld_sky_pass->set_enabled(false); + ctx->overworld_sky_pass->set_enabled(true); ctx->overworld_material_pass = new material_pass(ctx->rasterizer, ctx->framebuffer_hdr, ctx->resource_manager); ctx->overworld_material_pass->set_fallback_material(ctx->fallback_material); ctx->overworld_material_pass->shadow_map_pass = ctx->overworld_shadow_map_pass; @@ -601,7 +604,7 @@ void setup_rendering(game_context* ctx) logger->pop_task(EXIT_SUCCESS); } -void setup_scenes(game_context* ctx) +void setup_scenes(game::context* ctx) { debug::logger* logger = ctx->logger; logger->push_task("Setting up scenes"); @@ -720,7 +723,7 @@ void setup_scenes(game_context* ctx) logger->pop_task(EXIT_SUCCESS); } -void setup_animation(game_context* ctx) +void setup_animation(game::context* ctx) { // Setup timeline system ctx->timeline = new timeline(); @@ -736,6 +739,8 @@ void setup_animation(game_context* ctx) // Create fade transition ctx->fade_transition = new screen_transition(); ctx->fade_transition->get_material()->set_shader_program(ctx->resource_manager->load("fade-transition.glsl")); + ctx->fade_transition_color = ctx->fade_transition->get_material()->add_property("color"); + ctx->fade_transition_color->set_value({0, 0, 0}); ctx->ui_scene->add_object(ctx->fade_transition->get_billboard()); ctx->animator->add_animation(ctx->fade_transition->get_animation()); @@ -767,7 +772,7 @@ void setup_animation(game_context* ctx) ctx->ui_material_pass->set_time_tween(ctx->time_tween); } -void setup_entities(game_context* ctx) +void setup_entities(game::context* ctx) { // Create entity registry ctx->entity_registry = new entt::registry(); @@ -783,7 +788,7 @@ void setup_entities(game_context* ctx) ctx->focal_point_entity = ctx->entity_registry->create(); } -void setup_systems(game_context* ctx) +void setup_systems(game::context* ctx) { event_dispatcher* event_dispatcher = ctx->app->get_event_dispatcher(); @@ -878,6 +883,7 @@ void setup_systems(game_context* ctx) // Setup astronomy system ctx->astronomy_system = new entity::system::astronomy(*ctx->entity_registry); + ctx->astronomy_system->set_sky_pass(ctx->overworld_sky_pass); // Setup proteome system ctx->proteome_system = new entity::system::proteome(*ctx->entity_registry); @@ -923,7 +929,7 @@ void setup_systems(game_context* ctx) event_dispatcher->subscribe(ctx->ui_system); } -void setup_controls(game_context* ctx) +void setup_controls(game::context* ctx) { event_dispatcher* event_dispatcher = ctx->app->get_event_dispatcher(); @@ -1227,7 +1233,7 @@ void setup_controls(game_context* ctx) } -void setup_cli(game_context* ctx) +void setup_cli(game::context* ctx) { ctx->cli = new debug::cli(); ctx->cli->register_command("echo", debug::cc::echo); @@ -1239,7 +1245,7 @@ void setup_cli(game_context* ctx) //logger->log(cli.interpret(cmd)); } -void setup_callbacks(game_context* ctx) +void setup_callbacks(game::context* ctx) { // Set update callback ctx->app->set_update_callback diff --git a/src/game/game-context.hpp b/src/game/context.hpp similarity index 96% rename from src/game/game-context.hpp rename to src/game/context.hpp index df64b71..d492ad8 100644 --- a/src/game/game-context.hpp +++ b/src/game/context.hpp @@ -41,6 +41,7 @@ #include #include #include +#include // Forward declarations class animator; @@ -103,10 +104,10 @@ namespace entity } } -/** - * - */ -struct game_context +namespace game { + +/// Structure containing the state of a game. +struct context { application* app; debug::logger* logger; @@ -205,6 +206,7 @@ struct game_context animation* radial_transition_in; animation* radial_transition_out; screen_transition* fade_transition; + material_property* fade_transition_color; screen_transition* radial_transition_inner; screen_transition* radial_transition_outer; animation* equip_tool_animation; @@ -257,6 +259,7 @@ struct game_context entity::system::astronomy* astronomy_system; entity::system::orbit* orbit_system; entity::system::proteome* proteome_system; + std::unordered_map named_entities; // Game biome* biome; @@ -268,4 +271,6 @@ struct game_context pheromone_matrix* pheromones; }; +} // namespace game + #endif // ANTKEEPER_GAME_CONTEXT_HPP diff --git a/src/game/states/loading.cpp b/src/game/states/loading.cpp new file mode 100644 index 0000000..29cc9c0 --- /dev/null +++ b/src/game/states/loading.cpp @@ -0,0 +1,268 @@ +/* + * Copyright (C) 2021 Christopher J. Howard + * + * This file is part of Antkeeper source code. + * + * Antkeeper source code is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Antkeeper source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Antkeeper source code. If not, see . + */ + +#include "game/states/loading.hpp" +#include "game/states/play.hpp" +#include "game/states/splash.hpp" +#include "entity/components/celestial-body.hpp" +#include "entity/components/orbit.hpp" +#include "entity/components/blackbody.hpp" +#include "entity/components/terrain.hpp" +#include "entity/components/atmosphere.hpp" +#include "entity/components/transform.hpp" +#include "entity/systems/astronomy.hpp" +#include "entity/systems/orbit.hpp" +#include "scene/directional-light.hpp" +#include "scene/ambient-light.hpp" +#include "resources/resource-manager.hpp" +#include "application.hpp" +#include "renderer/passes/shadow-map-pass.hpp" + +namespace game { +namespace state { +namespace loading { + +/// Creates the universe and solar system. +static void cosmogenesis(game::context* ctx); + +/// Creates a sun. +static void heliogenesis(game::context* ctx); + +/// Creates a planet. +static void planetogenesis(game::context* ctx); + +/// Creates a moon. +static void selenogenesis(game::context* ctx); + +void enter(game::context* ctx) +{ + // Create universe + ctx->logger->push_task("Creating the universe"); + try + { + cosmogenesis(ctx); + } + catch (...) + { + ctx->logger->pop_task(EXIT_FAILURE); + throw; + } + ctx->logger->pop_task(EXIT_SUCCESS); + + // Determine next game state + application::state next_state; + if (ctx->option_quick_start.has_value()) + { + next_state.name = "play"; + next_state.enter = std::bind(game::state::play::enter, ctx); + next_state.exit = std::bind(game::state::play::exit, ctx); + } + else + { + next_state.name = "splash"; + next_state.enter = std::bind(game::state::splash::enter, ctx); + next_state.exit = std::bind(game::state::splash::exit, ctx); + } + + // Queue next game state + ctx->app->queue_state(next_state); +} + +void exit(game::context* ctx) +{} + +void cosmogenesis(game::context* ctx) +{ + // Init time + const double time = 0.0; + ctx->astronomy_system->set_universal_time(time); + ctx->orbit_system->set_universal_time(time); + + // Create sun + ctx->logger->push_task("Creating the sun"); + try + { + heliogenesis(ctx); + } + catch (...) + { + ctx->logger->pop_task(EXIT_FAILURE); + throw; + } + ctx->logger->pop_task(EXIT_SUCCESS); + + // Create planet + ctx->logger->push_task("Creating the planet"); + try + { + planetogenesis(ctx); + } + catch (...) + { + ctx->logger->pop_task(EXIT_FAILURE); + throw; + } + ctx->logger->pop_task(EXIT_SUCCESS); + + // Create moon + ctx->logger->push_task("Creating the moon"); + try + { + selenogenesis(ctx); + } + catch (...) + { + ctx->logger->pop_task(EXIT_FAILURE); + throw; + } + ctx->logger->pop_task(EXIT_SUCCESS); +} + +void heliogenesis(game::context* ctx) +{ + // Create solar entity + auto sun_eid = ctx->entity_registry->create(); + + // Name solar entity + ctx->named_entities["sun"] = sun_eid; + + // Assign solar celestial body component + entity::component::celestial_body body; + body.radius = 6.957e+8; + body.axial_tilt = math::radians(0.0); + body.axial_rotation = math::radians(0.0); + body.angular_frequency = math::radians(0.0); + ctx->entity_registry->assign(sun_eid, body); + + // Assign solar orbit component + entity::component::orbit orbit; + orbit.elements.a = 0.0; + orbit.elements.e = 0.0; + orbit.elements.i = math::radians(0.0); + orbit.elements.raan = math::radians(0.0); + orbit.elements.w = math::radians(0.0); + orbit.elements.ta = math::radians(0.0); + ctx->entity_registry->assign(sun_eid, orbit); + + // Assign solar blackbody component + entity::component::blackbody blackbody; + blackbody.temperature = 5778.0; + ctx->entity_registry->assign(sun_eid, blackbody); + + // Assign solar transform component + entity::component::transform transform; + transform.local = math::identity_transform; + transform.warp = true; + ctx->entity_registry->assign(sun_eid, transform); + + // Create direct sun light scene object + scene::directional_light* sun_direct = new scene::directional_light(); + + // Create ambient sun light scene object + scene::ambient_light* sun_ambient = new scene::ambient_light(); + sun_ambient->set_color({1, 1, 1}); + sun_ambient->set_intensity(0.0f); + sun_ambient->update_tweens(); + + // Add sun light scene objects to overworld scene + ctx->overworld_scene->add_object(sun_direct); + ctx->overworld_scene->add_object(sun_ambient); + + // Pass direct sun light scene object to shadow map pass and astronomy system + ctx->overworld_shadow_map_pass->set_light(sun_direct); + ctx->astronomy_system->set_sun_light(sun_direct); +} + +void planetogenesis(game::context* ctx) +{ + // Create planetary entity + auto planet_eid = ctx->entity_registry->create(); + + // Name planetary entity + ctx->named_entities["planet"] = planet_eid; + + // Assign planetary celestial body component + entity::component::celestial_body body; + body.radius = 6.3781e6; + body.axial_tilt = math::radians(23.4393); + body.axial_rotation = math::radians(280.46061837504); + body.angular_frequency = math::radians(360.9856122880876128); + ctx->entity_registry->assign(planet_eid, body); + + // Assign planetary orbit component + entity::component::orbit orbit; + orbit.elements.a = 1.496e+11; + orbit.elements.e = 0.01671123; + orbit.elements.i = math::radians(-0.00001531); + orbit.elements.raan = math::radians(0.0); + const double longitude_periapsis = math::radians(102.93768193); + orbit.elements.w = longitude_periapsis - orbit.elements.raan; + orbit.elements.ta = math::radians(100.46457166) - longitude_periapsis; + ctx->entity_registry->assign(planet_eid, orbit); + + // Assign planetary terrain component + entity::component::terrain terrain; + terrain.elevation = [](double, double) -> double + { + //return math::random(0.0, 1.0); + return 0.0; + }; + terrain.max_lod = 18; + terrain.patch_material = ctx->resource_manager->load("desert-terrain.mtl"); + ctx->entity_registry->assign(planet_eid, terrain); + + // Assign planetary atmosphere component + entity::component::atmosphere atmosphere; + atmosphere.exosphere_altitude = 65e3; + atmosphere.index_of_refraction = 1.000293; + atmosphere.rayleigh_density = 2.545e25; + atmosphere.rayleigh_scale_height = 8000.0; + atmosphere.mie_density = 14.8875; + atmosphere.mie_scale_height = 1200.0; + atmosphere.mie_anisotropy = 0.8; + ctx->entity_registry->assign(planet_eid, atmosphere); + + // Assign planetary transform component + entity::component::transform transform; + transform.local = math::identity_transform; + transform.warp = true; + ctx->entity_registry->assign(planet_eid, transform); + + // Pass planet to astronomy system as reference body + ctx->astronomy_system->set_reference_body(planet_eid); + + // Load sky model + ctx->overworld_sky_pass->set_sky_model(ctx->resource_manager->load("sky-dome.mdl")); +} + +void selenogenesis(game::context* ctx) +{ + // Create lunar entity + auto moon_eid = ctx->entity_registry->create(); + + // Name lunar entity + ctx->named_entities["moon"] = moon_eid; + + // Pass moon model to sky pass + ctx->overworld_sky_pass->set_moon_model(ctx->resource_manager->load("moon.mdl")); +} + +} // namespace loading +} // namespace state +} // namespace game diff --git a/src/game/states/loading-state.cpp b/src/game/states/loading.hpp similarity index 58% rename from src/game/states/loading-state.cpp rename to src/game/states/loading.hpp index c26aff1..92ddbd5 100644 --- a/src/game/states/loading-state.cpp +++ b/src/game/states/loading.hpp @@ -17,26 +17,23 @@ * along with Antkeeper source code. If not, see . */ -#include "game/states/game-states.hpp" -#include "game/game-context.hpp" -#include "debug/logger.hpp" -#include "application.hpp" +#ifndef ANTKEEPER_GAME_STATE_LOADING_HPP +#define ANTKEEPER_GAME_STATE_LOADING_HPP -void loading_state_enter(game_context* ctx) -{ - debug::logger* logger = ctx->logger; - logger->push_task("Entering loading state"); +#include "game/context.hpp" - logger->pop_task(EXIT_SUCCESS); - - ctx->app->change_state({std::bind(title_state_enter, ctx), std::bind(title_state_exit, ctx)}); -} +namespace game { +namespace state { -void loading_state_exit(game_context* ctx) -{ - debug::logger* logger = ctx->logger; - logger->push_task("Exiting loading state"); +/// Loading game state functions. +namespace loading { - logger->pop_task(EXIT_SUCCESS); -} +void enter(game::context* ctx); +void exit(game::context* ctx); +} // namespace loading + +} // namespace state +} // namespace game + +#endif // ANTKEEPER_GAME_STATE_LOADING_HPP diff --git a/src/game/states/map-state.cpp b/src/game/states/nuptial-flight.cpp similarity index 53% rename from src/game/states/map-state.cpp rename to src/game/states/nuptial-flight.cpp index b0b2727..13c68da 100644 --- a/src/game/states/map-state.cpp +++ b/src/game/states/nuptial-flight.cpp @@ -17,38 +17,37 @@ * along with Antkeeper source code. If not, see . */ -#include "animation/ease.hpp" +#include "game/states/nuptial-flight.hpp" +#include "entity/systems/astronomy.hpp" +#include "entity/systems/orbit.hpp" +#include "renderer/material-property.hpp" #include "animation/screen-transition.hpp" -#include "animation/timeline.hpp" -#include "application.hpp" -#include "debug/logger.hpp" -#include "game/game-context.hpp" -#include "input/listener.hpp" -#include "event/input-events.hpp" -#include "gl/rasterizer.hpp" -#include "game/states/game-states.hpp" -#include "renderer/passes/sky-pass.hpp" -#include "scene/billboard.hpp" -#include +#include "animation/ease.hpp" +#include "resources/config-file.hpp" -void map_state_enter(game_context* ctx) +namespace game { +namespace state { +namespace nuptial_flight { + +void enter(game::context* ctx) { - debug::logger* logger = ctx->logger; - logger->push_task("Entering map state"); - - // Disable sky pass - ctx->overworld_sky_pass->set_enabled(false); + // Pause motion of celestial objects + ctx->astronomy_system->set_time_scale(0.0); + ctx->orbit_system->set_time_scale(0.0); - // Start fade in + // Start fade in from white + ctx->fade_transition_color->set_value({1, 1, 1}); ctx->fade_transition->transition(1.0f, true, ease::in_quad); - - logger->pop_task(EXIT_SUCCESS); } -void map_state_exit(game_context* ctx) +void exit(game::context* ctx) { - debug::logger* logger = ctx->logger; - logger->push_task("Exiting map state"); - - logger->pop_task(EXIT_SUCCESS); + // Resume motion of celestial objects + const double time_scale = ctx->config->get("time_scale"); + ctx->astronomy_system->set_time_scale(time_scale); + ctx->orbit_system->set_time_scale(time_scale); } + +} // namespace nuptial_flight +} // namespace state +} // namespace game diff --git a/src/game/states/game-states.hpp b/src/game/states/nuptial-flight.hpp similarity index 54% rename from src/game/states/game-states.hpp rename to src/game/states/nuptial-flight.hpp index d7d4530..a03660b 100644 --- a/src/game/states/game-states.hpp +++ b/src/game/states/nuptial-flight.hpp @@ -17,22 +17,23 @@ * along with Antkeeper source code. If not, see . */ -#ifndef ANTKEEPER_GAME_STATES_HPP -#define ANTKEEPER_GAME_STATES_HPP - -struct game_context; - -void loading_state_enter(game_context* ctx); -void loading_state_exit(game_context* ctx); -void language_select_state_enter(game_context* ctx); -void language_select_state_exit(game_context* ctx); -void splash_state_enter(game_context* ctx); -void splash_state_exit(game_context* ctx); -void title_state_enter(game_context* ctx); -void title_state_exit(game_context* ctx); -void play_state_enter(game_context* ctx); -void play_state_exit(game_context* ctx); -void pause_state_enter(game_context* ctx); -void pause_state_exit(game_context* ctx); - -#endif // ANTKEEPER_GAME_STATES_HPP +#ifndef ANTKEEPER_GAME_STATE_NUPTIAL_FLIGHT_HPP +#define ANTKEEPER_GAME_STATE_NUPTIAL_FLIGHT_HPP + +#include "game/context.hpp" + +namespace game { +namespace state { + +/// Nuptial flight game state functions. +namespace nuptial_flight { + +void enter(game::context* ctx); +void exit(game::context* ctx); + +} // namespace nuptial_flight + +} // namespace state +} // namespace game + +#endif // ANTKEEPER_GAME_STATE_NUPTIAL_FLIGHT_HPP diff --git a/src/game/states/play-state.cpp b/src/game/states/play-state.cpp deleted file mode 100644 index 714b28d..0000000 --- a/src/game/states/play-state.cpp +++ /dev/null @@ -1,401 +0,0 @@ -/* - * Copyright (C) 2021 Christopher J. Howard - * - * This file is part of Antkeeper source code. - * - * Antkeeper source code is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Antkeeper source code is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Antkeeper source code. If not, see . - */ - -#include "animation/ease.hpp" -#include "animation/screen-transition.hpp" -#include "configuration.hpp" -#include "debug/logger.hpp" -#include "entity/archetype.hpp" -#include "entity/components/cavity.hpp" -#include "entity/components/copy-transform.hpp" -#include "entity/components/copy-translation.hpp" -#include "entity/components/model.hpp" -#include "entity/components/genome.hpp" -#include "entity/components/snap.hpp" -#include "entity/components/terrain.hpp" -#include "entity/components/tool.hpp" -#include "entity/components/transform.hpp" -#include "entity/components/camera-follow.hpp" -#include "entity/components/orbit.hpp" -#include "entity/components/blackbody.hpp" -#include "entity/components/celestial-body.hpp" -#include "entity/components/atmosphere.hpp" -#include "entity/components/light.hpp" -#include "entity/components/observer.hpp" -#include "entity/commands.hpp" -#include "game/game-context.hpp" -#include "game/states/game-states.hpp" -#include "math/math.hpp" -#include "nest.hpp" -#include "renderer/material.hpp" -#include "gl/texture-2d.hpp" -#include "gl/texture-filter.hpp" -#include "gl/texture-wrapping.hpp" -#include "renderer/model.hpp" -#include "renderer/passes/sky-pass.hpp" -#include "renderer/passes/shadow-map-pass.hpp" -#include "resources/resource-manager.hpp" -#include "scene/model-instance.hpp" -#include "scene/collection.hpp" -#include "scene/camera.hpp" -#include "scene/ambient-light.hpp" -#include "scene/directional-light.hpp" -#include "entity/systems/control.hpp" -#include "entity/systems/camera.hpp" -#include "entity/systems/render.hpp" -#include "entity/systems/tool.hpp" -#include "entity/systems/orbit.hpp" -#include "entity/systems/astronomy.hpp" -#include "game/biome.hpp" -#include "utility/fundamental-types.hpp" -#include "utility/bit-math.hpp" -#include "genetics/genetics.hpp" -#include "math/random.hpp" -#include -#include -#include - -void play_state_enter(game_context* ctx) -{ - debug::logger* logger = ctx->logger; - logger->push_task("Entering play state"); - - resource_manager* resource_manager = ctx->resource_manager; - entt::registry& entity_registry = *ctx->entity_registry; - - // Load biome - if (ctx->option_biome.has_value()) - { - ctx->biome = resource_manager->load(ctx->option_biome.value() + ".bio"); - } - else - { - ctx->biome = resource_manager->load("forest.bio"); - } - - // Apply biome parameters to scene - sky_pass* sky_pass = ctx->overworld_sky_pass; - sky_pass->set_enabled(true); - sky_pass->set_sky_model(ctx->resource_manager->load("sky-dome.mdl")); - sky_pass->set_moon_model(ctx->resource_manager->load("moon.mdl")); - - // Create sun - auto sun_entity = entity_registry.create(); - { - entity::component::celestial_body body; - body.radius = 6.957e+8; - body.axial_tilt = math::radians(0.0); - body.axial_rotation = math::radians(0.0); - body.angular_frequency = math::radians(0.0); - - entity::component::orbit orbit; - orbit.elements.a = 0.0; - orbit.elements.e = 0.0; - orbit.elements.i = math::radians(0.0); - orbit.elements.raan = math::radians(0.0); - orbit.elements.w = math::radians(0.0); - orbit.elements.ta = math::radians(0.0); - - entity::component::blackbody blackbody; - blackbody.temperature = 5778.0; - - entity::component::transform transform; - transform.local = math::identity_transform; - transform.warp = true; - - entity_registry.assign(sun_entity, body); - entity_registry.assign(sun_entity, orbit); - entity_registry.assign(sun_entity, blackbody); - entity_registry.assign(sun_entity, transform); - } - - // Create Earth - auto earth_entity = entity_registry.create(); - { - entity::component::celestial_body body; - body.radius = 6.3781e6; - body.axial_tilt = math::radians(23.4393); - body.axial_rotation = math::radians(280.46061837504); - body.angular_frequency = math::radians(360.9856122880876128); - - entity::component::orbit orbit; - orbit.elements.a = 1.496e+11; - orbit.elements.e = 0.01671123; - orbit.elements.i = math::radians(-0.00001531); - orbit.elements.raan = math::radians(0.0); - const double longitude_periapsis = math::radians(102.93768193); - orbit.elements.w = longitude_periapsis - orbit.elements.raan; - orbit.elements.ta = math::radians(100.46457166) - longitude_periapsis; - - entity::component::terrain terrain; - terrain.elevation = [](double, double) -> double - { - //return math::random(0.0, 1.0); - return 0.0; - }; - terrain.max_lod = 18; - terrain.patch_material = resource_manager->load("desert-terrain.mtl"); - - entity::component::atmosphere atmosphere; - atmosphere.exosphere_altitude = 65e3; - atmosphere.index_of_refraction = 1.000293; - atmosphere.rayleigh_density = 2.545e25; - atmosphere.rayleigh_scale_height = 8000.0; - atmosphere.mie_density = 14.8875; - atmosphere.mie_scale_height = 1200.0; - atmosphere.mie_anisotropy = 0.8; - - entity::component::transform transform; - transform.local = math::identity_transform; - transform.warp = true; - - entity_registry.assign(earth_entity, body); - entity_registry.assign(earth_entity, orbit); - entity_registry.assign(earth_entity, atmosphere); - entity_registry.assign(earth_entity, terrain); - entity_registry.assign(earth_entity, transform); - } - - // Create observer - auto observer_eid = entity_registry.create(); - { - entity::component::observer observer; - observer.reference_body_eid = earth_entity; - observer.elevation = 0.0; - observer.latitude = 0.0; - observer.longitude = 0.0; - observer.camera = ctx->overworld_camera; - - entity_registry.assign(observer_eid, observer); - } - - scene::ambient_light* ambient = new scene::ambient_light(); - ambient->set_color({1, 1, 1}); - ambient->set_intensity(0.0f); - ambient->update_tweens(); - ctx->overworld_scene->add_object(ambient); - - scene::directional_light* sun = new scene::directional_light(); - //sun->set_intensity(1000.0f); - //sun->set_light_texture(resource_manager->load("forest-gobo.tex")); - //sun->set_light_texture_scale({2000, 2000}); - //sun->set_light_texture_opacity(0.925f); - //sun->look_at({2, 1, 0}, {0, 0, 0}, {0, 0, 1}); - //sun->update_tweens(); - ctx->overworld_scene->add_object(sun); - ctx->overworld_shadow_map_pass->set_light(sun); - - // Set universal time - const double universal_time = 0.0; - ctx->astronomy_system->set_universal_time(universal_time); - ctx->orbit_system->set_universal_time(universal_time); - - // Set astronomy system observation parameters - ctx->astronomy_system->set_reference_body(earth_entity); - ctx->astronomy_system->set_observer_location(double3{0.0, math::radians(0.0f), math::radians(0.0f)}); - ctx->astronomy_system->set_sun_light(sun); - ctx->astronomy_system->set_sky_pass(ctx->overworld_sky_pass); - - // Load entity archetypes - entity::archetype* ant_hill_archetype = resource_manager->load("ant-hill.ent"); - entity::archetype* nest_archetype = resource_manager->load("harvester-nest.ent"); - entity::archetype* redwood_archetype = resource_manager->load("redwood.ent"); - entity::archetype* forceps_archetype = resource_manager->load("forceps.ent"); - entity::archetype* lens_archetype = resource_manager->load("lens.ent"); - entity::archetype* brush_archetype = resource_manager->load("brush.ent"); - entity::archetype* marker_archetype = resource_manager->load("marker.ent"); - entity::archetype* container_archetype = resource_manager->load("container.ent"); - entity::archetype* twig_archetype = resource_manager->load("twig.ent"); - entity::archetype* larva_archetype = resource_manager->load("ant-larva.ent"); - entity::archetype* flashlight_archetype = resource_manager->load("flashlight.ent"); - entity::archetype* flashlight_light_cone_archetype = resource_manager->load("flashlight-light-cone.ent"); - entity::archetype* lens_light_cone_archetype = resource_manager->load("lens-light-cone.ent"); - entity::archetype* cube_archetype = resource_manager->load("unit-cube.ent"); - entity::archetype* color_checker_archetype = resource_manager->load("color-checker.ent"); - - // Create tools - /* - forceps_archetype->assign(entity_registry, ctx->forceps_entity); - lens_archetype->assign(entity_registry, ctx->lens_entity); - brush_archetype->assign(entity_registry, ctx->brush_entity); - marker_archetype->assign(entity_registry, ctx->marker_entity); - container_archetype->assign(entity_registry, ctx->container_entity); - twig_archetype->assign(entity_registry, ctx->twig_entity); - */ - - // Create flashlight and light cone, set light cone parent to flashlight, and move both to underworld scene - /* - flashlight_archetype->assign(entity_registry, ctx->flashlight_entity); - auto flashlight_light_cone = flashlight_light_cone_archetype->create(entity_registry); - entity::command::parent(entity_registry, flashlight_light_cone, ctx->flashlight_entity); - entity::command::assign_render_layers(entity_registry, ctx->flashlight_entity, 2); - entity::command::assign_render_layers(entity_registry, flashlight_light_cone, 2); - */ - - // Make lens tool's model instance unculled, so its shadow is always visible. - //scene::model_instance* lens_model_instance = ctx->render_system->get_model_instance(ctx->lens_entity); - //if (lens_model_instance) - //{ - //lens_model_instance->set_culling_mask(&ctx->no_cull); - //} - - // Create lens light cone and set its parent to lens - //auto lens_light_cone = lens_light_cone_archetype->create(entity_registry); - //entity::command::bind_transform(entity_registry, lens_light_cone, ctx->lens_entity); - //entity::command::parent(entity_registry, lens_light_cone, ctx->lens_entity); - - // Hide inactive tools - /* - entity::command::assign_render_layers(entity_registry, ctx->forceps_entity, 0); - entity::command::assign_render_layers(entity_registry, ctx->brush_entity, 0); - entity::command::assign_render_layers(entity_registry, ctx->lens_entity, 0); - entity::command::assign_render_layers(entity_registry, ctx->marker_entity, 0); - entity::command::assign_render_layers(entity_registry, ctx->container_entity, 0); - entity::command::assign_render_layers(entity_registry, ctx->twig_entity, 0); - */ - - // Activate brush tool - //ctx->tool_system->set_active_tool(ctx->brush_entity); - - // Create ant-hill - //auto ant_hill_entity = ant_hill_archetype->create(entity_registry); - //entity::command::place(entity_registry, ant_hill_entity, earth_entity, 0.0, 0.0, 0.0); - - // Create color checker - /* - auto color_checker = color_checker_archetype->create(entity_registry); - entity::command::place(entity_registry, color_checker, {-10, -10}); - auto& cc_transform = entity_registry.get(color_checker); - cc_transform.local.scale *= 10.0f; - cc_transform.local.rotation = math::angle_axis(math::radians(-90.0f), {1, 0, 0}); - */ - - // Setup camera focal point - entity::component::transform focal_point_transform; - focal_point_transform.local = math::identity_transform; - //focal_point_transform.local.translation = {0, 6.3781e6, 0}; - focal_point_transform.warp = true; - entity::component::camera_follow focal_point_follow; - entity::component::snap focal_point_snap; - focal_point_snap.ray = {float3{0, 10000, 0}, float3{0, -1, 0}}; - focal_point_snap.warp = false; - focal_point_snap.relative = true; - focal_point_snap.autoremove = false; - entity_registry.assign_or_replace(ctx->focal_point_entity, focal_point_transform); - entity_registry.assign_or_replace(ctx->focal_point_entity, focal_point_follow); - //entity_registry.assign_or_replace(ctx->focal_point_entity, focal_point_snap); - - // Setup camera - ctx->overworld_camera->look_at({0, 0, 1}, {0, 0, 0}, {0, 1, 0}); - ctx->overworld_camera->set_exposure(-14.5f); - ctx->camera_system->set_camera(ctx->overworld_camera); - - ctx->overworld_scene->update_tweens(); - - // Allocate a nest - nest* nest = new ::nest(); - - // Setup initial nest parameters - float tunnel_radius = 1.15f; - nest->set_tunnel_radius(tunnel_radius); - nest::shaft* central_shaft = nest->get_central_shaft(); - central_shaft->chirality = 1.0f; - central_shaft->rotation = math::radians(0.0f); - central_shaft->depth = {0.0f, 200.0f}; - central_shaft->radius = {15.0f, 15.0f}; - central_shaft->pitch = {40.0f, 40.0f}; - central_shaft->translation = {{{0.0f, 0.0f}, {0.0f, 0.0f}}}; - central_shaft->current_depth = 0.0f; - for (std::size_t i = 0; i < 4; ++i) - { - nest::chamber chamber; - chamber.shaft = central_shaft; - chamber.depth = (i + 1) * 50.0f; - chamber.rotation = math::radians(0.0f); - chamber.inner_radius = 4.0f; - chamber.outer_radius = 10.0f; - central_shaft->chambers.push_back(chamber); - } - - // Dig nest shafts - float shift = 0.1f; - for (int i = 0; i < 800; ++i) - { - entity::component::cavity cavity; - cavity.position = nest->extend_shaft(*nest->get_central_shaft()); - cavity.position += float3{math::random(-shift, shift), math::random(-shift, shift), math::random(-shift, shift)}; - cavity.radius = tunnel_radius * math::random(1.0f, 1.1f); - - entity_registry.assign(entity_registry.create(), cavity); - } - - // Dig nest chambers - /* - for (int i = 0; i < central_shaft->chambers.size(); ++i) - { - for (int j = 0; j < 150; ++j) - { - entity::component::cavity cavity; - cavity.position = nest->expand_chamber(central_shaft->chambers[i]); - cavity.position += float3{math::random(-shift, shift), math::random(-shift, shift), math::random(-shift, shift)}; - cavity.radius = tunnel_radius * math::random(1.0f, 1.1f); - - entity_registry.assign(entity_registry.create(), cavity); - } - } - */ - - // Place larva in chamber - { - auto larva_eid = larva_archetype->create(entity_registry); - entity::command::assign_render_layers(entity_registry, larva_eid, 1); - entity::command::warp_to(entity_registry, larva_eid, {50, 0.1935f, 0}); - //auto& transform = entity_registry.get(larva_entity); - //transform.transform = math::identity_transform; - //transform.transform.translation = nest->get_shaft_position(*central_shaft, central_shaft->depth[1]); - //transform.transform.translation.y -= 1.0f; - - // Construct larva genome - entity::component::genome genome; - genome.ploidy = 2; - const std::string antp = "ATGACCATGAGCACCAACAACTGCGAAAGCATGACCAGCTATTTTACCAACAGCTATATGGGCGCGGATATGCATCATGGCCATTATCCGGGCAACGGCGTGACCGATCTGGATGCGCAGCAGATGCATCATTATAGCCAGAACGCGAACCATCAGGGCAACATGCCGTATCCGCGCTTTCCGCCGTATGATCGCATGCCGTATTATAACGGCCAGGGCATGGATCAGCAGCAGCAGCATCAGGTGTATAGCCGCCCGGATAGCCCGAGCAGCCAGGTGGGCGGCGTGATGCCGCAGGCGCAGACCAACGGCCAGCTGGGCGTGCCGCAGCAGCAGCAGCAGCAGCAGCAGCAGCCGAGCCAGAACCAGCAGCAGCAGCAGGCGCAGCAGGCGCCGCAGCAGCTGCAGCAGCAGCTGCCGCAGGTGACCCAGCAGGTGACCCATCCGCAGCAGCAGCAGCAGCAGCCGGTGGTGTATGCGAGCTGCAAACTGCAGGCGGCGGTGGGCGGCCTGGGCATGGTGCCGGAAGGCGGCAGCCCGCCGCTGGTGGATCAGATGAGCGGCCATCATATGAACGCGCAGATGACCCTGCCGCATCATATGGGCCATCCGCAGGCGCAGGTGCATCAGAACCATCATAACATGGGCATGTATCAGCAGCAGAGCGGCGTGCCGCCGGTGGGCGCGCCGCCGCAGGGCATGATGCATCAGGGCCAGGGCCCGCCGCAGATGCATCAGGGCCATCCGGGCCAGCATACCCCGCCGAGCCAGAACCCGAACAGCCAGAGCAGCGGCATGCCGAGCCCGCTGTATCCGTGGATGCGCAGCCAGTTTGAACGCAAACGCGGCCGCCAGACCTATACCCGCTATCAGACCCTGGAACTGGAAAAAGAATTTCATTTTAACCGCTATCTGACCCGCCGCCGCCGCATTGAAATTGCGCATGCGCTGTGCCTGACCGAACGCCAGATTAAAATTTGGTTTCAGAACCGCCGCATGAAATGGAAAAAAGAAAACAAAACCAAAGGCGAACCGGGCAGCGGCGGCGAAGGCGATGAAATTACCCCGCCGAACAGCCCGCAGTAG"; - genome.chromosomes.push_back(antp); - entity_registry.assign(larva_eid, genome); - } - - entity::system::control* control_system = ctx->control_system; - control_system->update(0.0, 0.0); - control_system->set_nest(nest); - - // Start fade in - ctx->fade_transition->transition(1.0f, true, ease::in_quad); - - logger->pop_task(EXIT_SUCCESS); - - std::string biome_name = (*ctx->strings)[ctx->biome->name]; - logger->log("Entered biome \"" + biome_name + "\""); -} - -void play_state_exit(game_context* ctx) -{ - debug::logger* logger = ctx->logger; - logger->push_task("Exiting play state"); - - logger->pop_task(EXIT_SUCCESS); -} diff --git a/src/game/states/play.cpp b/src/game/states/play.cpp new file mode 100644 index 0000000..e1bce7b --- /dev/null +++ b/src/game/states/play.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2021 Christopher J. Howard + * + * This file is part of Antkeeper source code. + * + * Antkeeper source code is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Antkeeper source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Antkeeper source code. If not, see . + */ + +#include "game/states/play.hpp" +#include "entity/archetype.hpp" +#include "entity/commands.hpp" +#include "entity/components/observer.hpp" +#include "entity/components/camera-follow.hpp" +#include "entity/components/transform.hpp" +#include "entity/systems/astronomy.hpp" +#include "entity/systems/control.hpp" +#include "entity/systems/camera.hpp" +#include "animation/screen-transition.hpp" +#include "animation/ease.hpp" +#include "resources/resource-manager.hpp" + +namespace game { +namespace state { +namespace play { + +void enter(game::context* ctx) +{ + // Find planet EID by name + entity::id planet_eid = entt::null; + if (auto it = ctx->named_entities.find("planet"); it != ctx->named_entities.end()) + { + planet_eid = it->second; + } + + // Create observer + auto observer_eid = ctx->entity_registry->create(); + { + entity::component::observer observer; + observer.reference_body_eid = planet_eid; + observer.elevation = 0.0; + observer.latitude = 0.0; + observer.longitude = 0.0; + observer.camera = ctx->overworld_camera; + ctx->entity_registry->assign(observer_eid, observer); + + // Set reference location of astronomy system + ctx->astronomy_system->set_reference_body(planet_eid); + ctx->astronomy_system->set_observer_location(double3{0.0, math::radians(0.0), math::radians(0.0)}); + } + + // Create camera focal point + { + entity::component::transform focal_point_transform; + focal_point_transform.local = math::identity_transform; + focal_point_transform.warp = true; + ctx->entity_registry->assign_or_replace(ctx->focal_point_entity, focal_point_transform); + + entity::component::camera_follow focal_point_follow; + ctx->entity_registry->assign_or_replace(ctx->focal_point_entity, focal_point_follow); + } + + // Setup camera + ctx->overworld_camera->look_at({0, 0, 1}, {0, 0, 0}, {0, 1, 0}); + ctx->overworld_camera->set_exposure(-14.5f); + ctx->camera_system->set_camera(ctx->overworld_camera); + + entity::system::control* control_system = ctx->control_system; + control_system->update(0.0, 0.0); + control_system->set_nest(nullptr); + + // Create larva + { + entity::archetype* larva_archetype = ctx->resource_manager->load("ant-larva.ent"); + auto larva_eid = larva_archetype->create(*ctx->entity_registry); + entity::command::warp_to(*ctx->entity_registry, larva_eid, {50, 0.1935f, 0}); + } + + ctx->overworld_scene->update_tweens(); + + // Start fade in + ctx->fade_transition->transition(1.0f, true, ease::in_quad); +} + +void exit(game::context* ctx) +{} + +} // namespace play +} // namespace state +} // namespace game diff --git a/src/game/states/language-select-state.cpp b/src/game/states/play.hpp similarity index 68% rename from src/game/states/language-select-state.cpp rename to src/game/states/play.hpp index 1205e4f..0ab8ac2 100644 --- a/src/game/states/language-select-state.cpp +++ b/src/game/states/play.hpp @@ -17,14 +17,23 @@ * along with Antkeeper source code. If not, see . */ -#include "game/states/game-states.hpp" -#include "game/game-context.hpp" +#ifndef ANTKEEPER_GAME_STATE_PLAY_HPP +#define ANTKEEPER_GAME_STATE_PLAY_HPP -void language_select_state_enter(game_context* ctx) -{ -} +#include "game/context.hpp" -void language_select_state_exit(game_context* ctx) -{ -} +namespace game { +namespace state { +/// Play game state functions. +namespace play { + +void enter(game::context* ctx); +void exit(game::context* ctx); + +} // namespace play + +} // namespace state +} // namespace game + +#endif // ANTKEEPER_GAME_STATE_PLAY_HPP diff --git a/src/game/states/splash-state.cpp b/src/game/states/splash.cpp similarity index 74% rename from src/game/states/splash-state.cpp rename to src/game/states/splash.cpp index f82e1e4..48907a6 100644 --- a/src/game/states/splash-state.cpp +++ b/src/game/states/splash.cpp @@ -17,31 +17,19 @@ * along with Antkeeper source code. If not, see . */ -#include "animation/ease.hpp" +#include "game/states/splash.hpp" +#include "game/states/play.hpp" #include "animation/screen-transition.hpp" +#include "animation/ease.hpp" #include "animation/timeline.hpp" #include "application.hpp" -#include "debug/logger.hpp" -#include "game/game-context.hpp" -#include "input/listener.hpp" -#include "event/input-events.hpp" -#include "gl/rasterizer.hpp" -#include "game/states/game-states.hpp" -#include "renderer/passes/sky-pass.hpp" -#include "scene/billboard.hpp" -#include "scene/collection.hpp" -#include -void splash_state_enter(game_context* ctx) +namespace game { +namespace state { +namespace splash { + +void enter(game::context* ctx) { - debug::logger* logger = ctx->logger; - logger->push_task("Entering splash state"); - - //ctx->app->set_window_opacity(0.5f); - - // Disable sky pass - ctx->overworld_sky_pass->set_enabled(false); - // Add splash billboard to UI scene ctx->ui_scene->add_object(ctx->splash_billboard); @@ -62,7 +50,12 @@ void splash_state_enter(game_context* ctx) // Create change state function auto change_state = [ctx]() { - ctx->app->change_state({std::bind(play_state_enter, ctx), std::bind(play_state_exit, ctx)}); + application::state next_state; + next_state.name = "play"; + next_state.enter = std::bind(game::state::play::enter, ctx); + next_state.exit = std::bind(game::state::play::exit, ctx); + + ctx->app->change_state(next_state); }; // Schedule fade out and change state events @@ -88,26 +81,29 @@ void splash_state_enter(game_context* ctx) ctx->rasterizer->set_clear_color(0.0f, 0.0f, 0.0f, 1.0f); ctx->rasterizer->clear_framebuffer(true, false, false); ctx->app->swap_buffers(); - ctx->app->change_state({std::bind(play_state_enter, ctx), std::bind(play_state_exit, ctx)}); + + application::state next_state; + next_state.name = "play"; + next_state.enter = std::bind(game::state::play::enter, ctx); + next_state.exit = std::bind(game::state::play::exit, ctx); + + ctx->app->change_state(next_state); } } ); ctx->input_listener->set_enabled(true); - - logger->pop_task(EXIT_SUCCESS); } -void splash_state_exit(game_context* ctx) +void exit(game::context* ctx) { - debug::logger* logger = ctx->logger; - logger->push_task("Exiting splash state"); - // Disable splash skipper ctx->input_listener->set_enabled(false); ctx->input_listener->set_callback(nullptr); // Remove splash billboard from UI scene ctx->ui_scene->remove_object(ctx->splash_billboard); - - logger->pop_task(EXIT_SUCCESS); } + +} // namespace splash +} // namespace state +} // namespace game diff --git a/src/game/states/splash.hpp b/src/game/states/splash.hpp new file mode 100644 index 0000000..bfb8999 --- /dev/null +++ b/src/game/states/splash.hpp @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2021 Christopher J. Howard + * + * This file is part of Antkeeper source code. + * + * Antkeeper source code is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Antkeeper source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Antkeeper source code. If not, see . + */ + +#ifndef ANTKEEPER_GAME_STATE_SPLASH_HPP +#define ANTKEEPER_GAME_STATE_SPLASH_HPP + +#include "game/context.hpp" + +namespace game { +namespace state { + +/// Splash screen game state functions. +namespace splash { + +void enter(game::context* ctx); +void exit(game::context* ctx); + +} // namespace splash + +} // namespace state +} // namespace game + +#endif // ANTKEEPER_GAME_STATE_SPLASH_HPP diff --git a/src/game/states/pause-state.cpp b/src/game/states/states.hpp similarity index 75% rename from src/game/states/pause-state.cpp rename to src/game/states/states.hpp index 0e134fa..cdbd1ce 100644 --- a/src/game/states/pause-state.cpp +++ b/src/game/states/states.hpp @@ -17,14 +17,17 @@ * along with Antkeeper source code. If not, see . */ -#include "game/states/game-states.hpp" -#include "game/game-context.hpp" +#ifndef ANTKEEPER_GAME_STATES_HPP +#define ANTKEEPER_GAME_STATES_HPP -void pause_state_enter(game_context* ctx) -{ -} +namespace game { -void pause_state_exit(game_context* ctx) -{ -} +/// Game state functions. +namespace state {} +} // namespace game + +#include "game/states/loading.hpp" +#include "game/states/splash.hpp" + +#endif // ANTKEEPER_GAME_STATES_HPP diff --git a/src/game/states/title-state.cpp b/src/game/states/title-state.cpp deleted file mode 100644 index 7561df7..0000000 --- a/src/game/states/title-state.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2021 Christopher J. Howard - * - * This file is part of Antkeeper source code. - * - * Antkeeper source code is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Antkeeper source code is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Antkeeper source code. If not, see . - */ - -#include "game/states/game-states.hpp" -#include "game/game-context.hpp" -#include "debug/logger.hpp" -#include "animation/timeline.hpp" - -void title_state_enter(game_context* ctx) -{ - debug::logger* logger = ctx->logger; - logger->push_task("Entering title state"); - - // Get timeline - timeline* timeline = ctx->timeline; - - // Create title sequence - float t = timeline->get_position(); - timeline::sequence title_sequence = - { - {t + 0.0f, [logger](){ logger->log("cue sound fade-in\n"); }}, - {t + 3.0f, [logger](){ logger->log("cue scene fade-in from black\n"); }}, - {t + 8.0f, [logger](){ logger->log("cue title fade-in\n"); }}, - {t + 10.0f, [logger](){ logger->log("cue menu fade-in\n"); }} - }; - - // Add title sequence to timeline - timeline->add_sequence(title_sequence); - - logger->pop_task(EXIT_SUCCESS); -} - -void title_state_exit(game_context* ctx) -{ - debug::logger* logger = ctx->logger; - logger->push_task("Exiting title state"); - - logger->pop_task(EXIT_SUCCESS); -}