diff --git a/CMakeLists.txt b/CMakeLists.txt index c2fc691..912a62c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,6 @@ cmake_minimum_required(VERSION 3.25) + option(APPLICATION_NAME "Application name" "Antkeeper") option(APPLICATION_VERSION "Application version string" "0.0.0") option(APPLICATION_AUTHOR "Application author" "C. J. Howard") diff --git a/src/engine/i18n/string-map.cpp b/src/engine/i18n/string-map.cpp index 998900b..5b8612d 100644 --- a/src/engine/i18n/string-map.cpp +++ b/src/engine/i18n/string-map.cpp @@ -39,17 +39,17 @@ void serializer::serialize(const i18n::string_map& map, serial { // Write number of entries std::uint32_t size = static_cast(map.size()); - ctx.write32(reinterpret_cast(&size), 1); + ctx.write32(reinterpret_cast(&size), 1); // Write entries for (const auto& [key, value]: map) { // Write key - ctx.write32(reinterpret_cast(&key), 1); + ctx.write32(reinterpret_cast(&key), 1); // Write string length std::uint32_t length = static_cast(value.length()); - ctx.write32(reinterpret_cast(&length), 1); + ctx.write32(reinterpret_cast(&length), 1); // Write string ctx.write8(reinterpret_cast(value.data()), length); @@ -71,18 +71,18 @@ void deserializer::deserialize(i18n::string_map& map, deserial // Read number of entries std::uint32_t size = 0; - ctx.read32(reinterpret_cast(&size), 1); + ctx.read32(reinterpret_cast(&size), 1); // Read entries for (std::uint32_t i = 0; i < size; ++i) { // Read key hash::fnv1a32_t key; - ctx.read32(reinterpret_cast(&key), 1); + ctx.read32(reinterpret_cast(&key), 1); // Read string length std::uint32_t length = 0; - ctx.read32(reinterpret_cast(&length), 1); + ctx.read32(reinterpret_cast(&length), 1); // Insert empty string into map auto [iterator, inserted] = map.emplace diff --git a/src/game/ant/ant-caste.hpp b/src/game/ant/ant-caste-type.hpp similarity index 80% rename from src/game/ant/ant-caste.hpp rename to src/game/ant/ant-caste-type.hpp index d424a0e..533e5da 100644 --- a/src/game/ant/ant-caste.hpp +++ b/src/game/ant/ant-caste-type.hpp @@ -17,8 +17,8 @@ * along with Antkeeper source code. If not, see . */ -#ifndef ANTKEEPER_GAME_ANT_CASTE_HPP -#define ANTKEEPER_GAME_ANT_CASTE_HPP +#ifndef ANTKEEPER_GAME_ANT_CASTE_TYPE_HPP +#define ANTKEEPER_GAME_ANT_CASTE_TYPE_HPP #include @@ -27,19 +27,19 @@ * * @see https://www.antwiki.org/wiki/Caste_Terminology */ -enum class ant_caste: std::uint8_t +enum class ant_caste_type: std::uint8_t { /// Queen caste. - queen, + queen = 0b0001, /// Worker caste. - worker, + worker = 0b0010, /// Soldier caste. - soldier, + soldier = 0b0100, /// Male caste. - male + male = 0b1000 }; -#endif // ANTKEEPER_GAME_ANT_CASTE_HPP +#endif // ANTKEEPER_GAME_ANT_CASTE_TYPE_HPP diff --git a/src/game/ant/ant-cladogenesis.hpp b/src/game/ant/ant-cladogenesis.hpp index b374ae3..b3b9cd1 100644 --- a/src/game/ant/ant-cladogenesis.hpp +++ b/src/game/ant/ant-cladogenesis.hpp @@ -33,6 +33,6 @@ * * @return New genome. */ -std::unique_ptr ant_cladogenesis(const ant_gene_pool& pool, std::random_device& rng); +[[nodiscard]] std::unique_ptr ant_cladogenesis(const ant_gene_pool& pool, std::random_device& rng); #endif // ANTKEEPER_GAME_ANT_CLADOGENESIS_HPP diff --git a/src/game/ant/ant-morphogenesis.cpp b/src/game/ant/ant-morphogenesis.cpp index 7d5096a..a3fb41c 100644 --- a/src/game/ant/ant-morphogenesis.cpp +++ b/src/game/ant/ant-morphogenesis.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include static void reskin_vertices @@ -79,13 +80,13 @@ std::unique_ptr ant_morphogenesis(const ant_phenome& phenome) std::shared_ptr exoskeleton_material = build_exoskeleton_material(*phenome.pigmentation, *phenome.sculpturing); // Determine presence of optional parts - bool eyes_present = phenome.eyes->present; - bool lateral_ocelli_present = phenome.ocelli->lateral_ocelli_present; - bool median_ocellus_present = phenome.ocelli->median_ocellus_present; - bool petiole_present = phenome.waist->petiole_present; - bool postpetiole_present = phenome.waist->postpetiole_present; - bool sting_present = phenome.sting->present; - bool wings_present = phenome.wings->present; + const bool eyes_present = phenome.eyes->present; + const bool lateral_ocelli_present = phenome.ocelli->lateral_ocelli_present; + const bool median_ocellus_present = phenome.ocelli->median_ocellus_present; + const bool petiole_present = phenome.waist->petiole_present; + const bool postpetiole_present = phenome.waist->postpetiole_present; + const bool sting_present = phenome.sting->present; + const bool wings_present = phenome.wings->present; // Get body part models const render::model* antennae_model = phenome.antennae->model.get(); @@ -102,6 +103,56 @@ std::unique_ptr ant_morphogenesis(const ant_phenome& phenome) const render::model* sting_model = phenome.sting->model.get(); const render::model* waist_model = phenome.waist->model.get(); + // Check for presence of required part models + if (!antennae_model) + { + throw std::runtime_error("Ant phenome missing antennae model"); + } + if (eyes_present && !eyes_model) + { + throw std::runtime_error("Ant phenome missing eyes model"); + } + if (wings_present && !forewings_model) + { + throw std::runtime_error("Ant phenome missing forewings model"); + } + if (!gaster_model) + { + throw std::runtime_error("Ant phenome missing gaster model"); + } + if (wings_present && !hindwings_model) + { + throw std::runtime_error("Ant phenome missing hindwings model"); + } + if (lateral_ocelli_present && !lateral_ocelli_model) + { + throw std::runtime_error("Ant phenome missing lateral ocelli model"); + } + if (!legs_model) + { + throw std::runtime_error("Ant phenome missing legs model"); + } + if (!mandibles_model) + { + throw std::runtime_error("Ant phenome missing mandibles model"); + } + if (median_ocellus_present && !median_ocellus_model) + { + throw std::runtime_error("Ant phenome missing median ocellus model"); + } + if (!mesosoma_model) + { + throw std::runtime_error("Ant phenome missing mesosoma model"); + } + if (sting_present && !sting_model) + { + throw std::runtime_error("Ant phenome missing sting model"); + } + if (!waist_model) + { + throw std::runtime_error("Ant phenome missing waist model"); + } + // Get body part vertex buffers const gl::vertex_buffer* antennae_vbo = antennae_model->get_vertex_buffer().get(); const gl::vertex_buffer* eyes_vbo = (eyes_present) ? eyes_model->get_vertex_buffer().get() : nullptr; @@ -109,10 +160,10 @@ std::unique_ptr ant_morphogenesis(const ant_phenome& phenome) const gl::vertex_buffer* gaster_vbo = gaster_model->get_vertex_buffer().get(); const gl::vertex_buffer* head_vbo = head_model->get_vertex_buffer().get(); const gl::vertex_buffer* hindwings_vbo = (wings_present) ? hindwings_model->get_vertex_buffer().get() : nullptr; - const gl::vertex_buffer* lateral_ocelli_vbo = (lateral_ocelli_model) ? lateral_ocelli_model->get_vertex_buffer().get() : nullptr; + const gl::vertex_buffer* lateral_ocelli_vbo = (lateral_ocelli_present) ? lateral_ocelli_model->get_vertex_buffer().get() : nullptr; const gl::vertex_buffer* legs_vbo = legs_model->get_vertex_buffer().get(); const gl::vertex_buffer* mandibles_vbo = mandibles_model->get_vertex_buffer().get(); - const gl::vertex_buffer* median_ocellus_vbo = (median_ocellus_model) ? median_ocellus_model->get_vertex_buffer().get() : nullptr; + const gl::vertex_buffer* median_ocellus_vbo = (median_ocellus_present) ? median_ocellus_model->get_vertex_buffer().get() : nullptr; const gl::vertex_buffer* mesosoma_vbo = mesosoma_model->get_vertex_buffer().get(); const gl::vertex_buffer* sting_vbo = (sting_present) ? sting_model->get_vertex_buffer().get() : nullptr; const gl::vertex_buffer* waist_vbo = waist_model->get_vertex_buffer().get(); @@ -135,22 +186,34 @@ std::unique_ptr ant_morphogenesis(const ant_phenome& phenome) vertex_buffer_size += gaster_vbo->size(); std::size_t sting_vbo_offset = vertex_buffer_size; if (sting_present) + { vertex_buffer_size += sting_vbo->size(); + } std::size_t eyes_vbo_offset = vertex_buffer_size; if (eyes_present) + { vertex_buffer_size += eyes_vbo->size(); + } std::size_t lateral_ocelli_vbo_offset = vertex_buffer_size; if (lateral_ocelli_present) + { vertex_buffer_size += lateral_ocelli_vbo->size(); + } std::size_t median_ocellus_vbo_offset = vertex_buffer_size; if (median_ocellus_present) + { vertex_buffer_size += median_ocellus_vbo->size(); + } std::size_t forewings_vbo_offset = vertex_buffer_size; if (wings_present) + { vertex_buffer_size += forewings_vbo->size(); + } std::size_t hindwings_vbo_offset = vertex_buffer_size; if (wings_present) + { vertex_buffer_size += hindwings_vbo->size(); + } // Allocate combined vertex buffer data std::vector vertex_buffer_data(vertex_buffer_size); @@ -681,29 +744,45 @@ std::unique_ptr ant_morphogenesis(const ant_phenome& phenome) reskin_vertices(vertex_buffer_data.data() + antennae_vbo_offset, antennae_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_antennomere1_r_indices, antennomere1_r_bone_index, antenna_r_to_body); // Reskin antennomere2+ bones - const std::vector antennomere_bone_names = - { - "antennomere2", - "antennomere3", - "antennomere4", - "antennomere5", - "antennomere6", - "antennomere7", - "antennomere8", - "antennomere9", - "antennomere10", - "antennomere11", - "antennomere12", - "antennomere13" + const std::vector antennomere_l_bone_keys = + { + "antennomere2_l", + "antennomere3_l", + "antennomere4_l", + "antennomere5_l", + "antennomere6_l", + "antennomere7_l", + "antennomere8_l", + "antennomere9_l", + "antennomere10_l", + "antennomere11_l", + "antennomere12_l", + "antennomere13_l" }; + const std::vector antennomere_r_bone_keys = + { + "antennomere2_r", + "antennomere3_r", + "antennomere4_r", + "antennomere5_r", + "antennomere6_r", + "antennomere7_r", + "antennomere8_r", + "antennomere9_r", + "antennomere10_r", + "antennomere11_r", + "antennomere12_r", + "antennomere13_r" + }; + std::unordered_set old_antennomere_l_indices; - for (const auto& bone_name: antennomere_bone_names) - if (auto it = antennae_skeleton.bone_map.find(bone_name + "_l"); it != antennae_skeleton.bone_map.end()) + for (const auto& bone_key: antennomere_l_bone_keys) + if (auto it = antennae_skeleton.bone_map.find(bone_key); it != antennae_skeleton.bone_map.end()) old_antennomere_l_indices.emplace(it->second); reskin_vertices(vertex_buffer_data.data() + antennae_vbo_offset, antennae_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_antennomere_l_indices, antennomere2_l_bone_index, antenna_l_to_body); std::unordered_set old_antennomere_r_indices; - for (const auto& bone_name: antennomere_bone_names) - if (auto it = antennae_skeleton.bone_map.find(bone_name + "_r"); it != antennae_skeleton.bone_map.end()) + for (const auto& bone_key: antennomere_r_bone_keys) + if (auto it = antennae_skeleton.bone_map.find(bone_key); it != antennae_skeleton.bone_map.end()) old_antennomere_r_indices.emplace(it->second); reskin_vertices(vertex_buffer_data.data() + antennae_vbo_offset, antennae_index_count, *position_attribute, *normal_attribute, *tangent_attribute, *bone_index_attribute, old_antennomere_r_indices, antennomere2_r_bone_index, antenna_r_to_body); diff --git a/src/game/ant/ant-morphogenesis.hpp b/src/game/ant/ant-morphogenesis.hpp index f7bc92b..9be523c 100644 --- a/src/game/ant/ant-morphogenesis.hpp +++ b/src/game/ant/ant-morphogenesis.hpp @@ -31,6 +31,6 @@ * * @return 3D model of the given phenome. */ -std::unique_ptr ant_morphogenesis(const ant_phenome& phenome); +[[nodiscard]] std::unique_ptr ant_morphogenesis(const ant_phenome& phenome); #endif // ANTKEEPER_GAME_ANT_MORPHOGENESIS_HPP diff --git a/src/game/ant/ant-phenome.cpp b/src/game/ant/ant-phenome.cpp index a4979e7..3655ff9 100644 --- a/src/game/ant/ant-phenome.cpp +++ b/src/game/ant/ant-phenome.cpp @@ -19,65 +19,72 @@ #include "game/ant/ant-phenome.hpp" -ant_phenome::ant_phenome(const ant_genome& genome, ant_caste caste) +ant_phenome::ant_phenome(const ant_genome& genome, ant_caste_type caste) { if (genome.antennae) - if (auto it = genome.antennae->phenes.find(caste); it != genome.antennae->phenes.end()) - antennae = &it->second; + if (auto i = genome.antennae->phene_map.find(caste); i != genome.antennae->phene_map.end()) + antennae = i->second; if (genome.body_size) - if (auto it = genome.body_size->phenes.find(caste); it != genome.body_size->phenes.end()) - body_size = &it->second; + if (auto i = genome.body_size->phene_map.find(caste); i != genome.body_size->phene_map.end()) + body_size = i->second; if (genome.cocoon) - cocoon = &genome.cocoon->phene; + if (auto i = genome.cocoon->phene_map.find(caste); i != genome.cocoon->phene_map.end()) + cocoon = i->second; if (genome.diet) - diet = &genome.diet->phene; + if (auto i = genome.diet->phene_map.find(caste); i != genome.diet->phene_map.end()) + diet = i->second; if (genome.egg) - egg = &genome.egg->phene; + if (auto i = genome.egg->phene_map.find(caste); i != genome.egg->phene_map.end()) + egg = i->second; if (genome.eyes) - if (auto it = genome.eyes->phenes.find(caste); it != genome.eyes->phenes.end()) - eyes = &it->second; + if (auto i = genome.eyes->phene_map.find(caste); i != genome.eyes->phene_map.end()) + eyes = i->second; if (genome.foraging_time) - foraging_time = &genome.foraging_time->phene; + if (auto i = genome.foraging_time->phene_map.find(caste); i != genome.foraging_time->phene_map.end()) + foraging_time = i->second; if (genome.founding_mode) - founding_mode = &genome.founding_mode->phene; + if (auto i = genome.founding_mode->phene_map.find(caste); i != genome.founding_mode->phene_map.end()) + founding_mode = i->second; if (genome.gaster) - if (auto it = genome.gaster->phenes.find(caste); it != genome.gaster->phenes.end()) - gaster = &it->second; + if (auto i = genome.gaster->phene_map.find(caste); i != genome.gaster->phene_map.end()) + gaster = i->second; if (genome.head) - if (auto it = genome.head->phenes.find(caste); it != genome.head->phenes.end()) - head = &it->second; + if (auto i = genome.head->phene_map.find(caste); i != genome.head->phene_map.end()) + head = i->second; if (genome.larva) - larva = &genome.larva->phene; + if (auto i = genome.larva->phene_map.find(caste); i != genome.larva->phene_map.end()) + larva = i->second; if (genome.legs) - if (auto it = genome.legs->phenes.find(caste); it != genome.legs->phenes.end()) - legs = &it->second; + if (auto i = genome.legs->phene_map.find(caste); i != genome.legs->phene_map.end()) + legs = i->second; if (genome.mandibles) - if (auto it = genome.mandibles->phenes.find(caste); it != genome.mandibles->phenes.end()) - mandibles = &it->second; + if (auto i = genome.mandibles->phene_map.find(caste); i != genome.mandibles->phene_map.end()) + mandibles = i->second; if (genome.mesosoma) - if (auto it = genome.mesosoma->phenes.find(caste); it != genome.mesosoma->phenes.end()) - mesosoma = &it->second; + if (auto i = genome.mesosoma->phene_map.find(caste); i != genome.mesosoma->phene_map.end()) + mesosoma = i->second; if (genome.nest_site) - nest_site = &genome.nest_site->phene; + if (auto i = genome.nest_site->phene_map.find(caste); i != genome.nest_site->phene_map.end()) + nest_site = i->second; if (genome.ocelli) - if (auto it = genome.ocelli->phenes.find(caste); it != genome.ocelli->phenes.end()) - ocelli = &it->second; + if (auto i = genome.ocelli->phene_map.find(caste); i != genome.ocelli->phene_map.end()) + ocelli = i->second; if (genome.pigmentation) - if (auto it = genome.pigmentation->phenes.find(caste); it != genome.pigmentation->phenes.end()) - pigmentation = &it->second; + if (auto i = genome.pigmentation->phene_map.find(caste); i != genome.pigmentation->phene_map.end()) + pigmentation = i->second; if (genome.pilosity) - if (auto it = genome.pilosity->phenes.find(caste); it != genome.pilosity->phenes.end()) - pilosity = &it->second; + if (auto i = genome.pilosity->phene_map.find(caste); i != genome.pilosity->phene_map.end()) + pilosity = i->second; if (genome.sculpturing) - if (auto it = genome.sculpturing->phenes.find(caste); it != genome.sculpturing->phenes.end()) - sculpturing = &it->second; + if (auto i = genome.sculpturing->phene_map.find(caste); i != genome.sculpturing->phene_map.end()) + sculpturing = i->second; if (genome.sting) - if (auto it = genome.sting->phenes.find(caste); it != genome.sting->phenes.end()) - sting = &it->second; + if (auto i = genome.sting->phene_map.find(caste); i != genome.sting->phene_map.end()) + sting = i->second; if (genome.waist) - if (auto it = genome.waist->phenes.find(caste); it != genome.waist->phenes.end()) - waist = &it->second; + if (auto i = genome.waist->phene_map.find(caste); i != genome.waist->phene_map.end()) + waist = i->second; if (genome.wings) - if (auto it = genome.wings->phenes.find(caste); it != genome.wings->phenes.end()) - wings = &it->second; + if (auto i = genome.wings->phene_map.find(caste); i != genome.wings->phene_map.end()) + wings = i->second; } diff --git a/src/game/ant/ant-phenome.hpp b/src/game/ant/ant-phenome.hpp index 6254ef3..6e186af 100644 --- a/src/game/ant/ant-phenome.hpp +++ b/src/game/ant/ant-phenome.hpp @@ -43,7 +43,7 @@ #include "game/ant/genes/ant-waist-gene.hpp" #include "game/ant/genes/ant-wings-gene.hpp" #include "game/ant/ant-genome.hpp" -#include "game/ant/ant-caste.hpp" +#include "game/ant/ant-caste-type.hpp" /** * Complete set of ant phenes. @@ -56,7 +56,7 @@ struct ant_phenome * @param genome Ant genome. * @param caste Ant caste. */ - ant_phenome(const ant_genome& genome, ant_caste caste); + ant_phenome(const ant_genome& genome, ant_caste_type caste); /// Constructs an empty ant phenome. ant_phenome() = default; diff --git a/src/game/ant/ant-species.hpp b/src/game/ant/ant-species.hpp index a21fd40..efe58a0 100644 --- a/src/game/ant/ant-species.hpp +++ b/src/game/ant/ant-species.hpp @@ -20,7 +20,7 @@ #ifndef ANTKEEPER_GAME_ANT_SPECIES_HPP #define ANTKEEPER_GAME_ANT_SPECIES_HPP -#include "game/ant/ant-caste.hpp" +#include "game/ant/ant-caste-type.hpp" #include "game/ant/ant-phenome.hpp" #include #include @@ -29,7 +29,7 @@ struct ant_species { /// Caste-specific phenomes - std::unordered_map phenomes; + std::unordered_map phenomes; /// Caste-specific models std::unordered_map> models; diff --git a/src/game/ant/ant-subcaste.hpp b/src/game/ant/ant-subcaste.hpp index f87eb6e..e8a5b60 100644 --- a/src/game/ant/ant-subcaste.hpp +++ b/src/game/ant/ant-subcaste.hpp @@ -28,7 +28,7 @@ enum class ant_subcaste: std::uint8_t { /// Worker from the queen's first batch of eggs, smaller than normal workers. - nanitic, + nanitic = 1, /// Small worker or soldier. minor, diff --git a/src/game/ant/ant-swarm.cpp b/src/game/ant/ant-swarm.cpp index 60b66eb..219658a 100644 --- a/src/game/ant/ant-swarm.cpp +++ b/src/game/ant/ant-swarm.cpp @@ -114,11 +114,11 @@ entity::id create_ant_swarm(::game& ctx) // Init queen caste component ant_caste_component queen_caste; - queen_caste.type = ant_caste::queen; + queen_caste.caste_type = ant_caste_type::queen; // Init male caste component ant_caste_component male_caste; - male_caste.type = ant_caste::male; + male_caste.caste_type = ant_caste_type::male; // Construct and seed random number generator std::random_device seed; diff --git a/src/game/ant/genes/ant-antennae-gene.cpp b/src/game/ant/genes/ant-antennae-gene.cpp index 30e9d17..a5a3266 100644 --- a/src/game/ant/genes/ant-antennae-gene.cpp +++ b/src/game/ant/genes/ant-antennae-gene.cpp @@ -17,49 +17,35 @@ * along with Antkeeper source code. If not, see . */ +#include "game/ant/genes/ant-antennae-gene.hpp" #include "game/ant/genes/ant-gene-loader.hpp" #include #include -#include "game/ant/genes/ant-antennae-gene.hpp" #include -#include -#include -static void deserialize_ant_antennae_phene(ant_antennae_phene& phene, const json& phene_element, resource_manager& resource_manager) +namespace { + +void load_ant_antennae_phene(ant_antennae_phene& phene, ::resource_manager& resource_manager, deserialize_context& ctx) { - phene.model = nullptr; - phene.total_antennomere_count = 0; - phene.club_antennomere_count = 0; - - // Load antennae model - if (auto element = phene_element.find("model"); element != phene_element.end()) - phene.model = resource_manager.load(element->get()); + ctx.read8(reinterpret_cast(&phene.total_antennomere_count), 1); + ctx.read8(reinterpret_cast(&phene.club_antennomere_count), 1); - // Parse total antennomere count - if (auto element = phene_element.find("total_antennomere_count"); element != phene_element.end()) - phene.total_antennomere_count = element->get(); + std::uint8_t model_filename_length{0}; + ctx.read8(reinterpret_cast(&model_filename_length), 1); + std::string model_filename(model_filename_length, '\0'); + ctx.read8(reinterpret_cast(model_filename.data()), model_filename_length); - // Parse club antennomere count - if (auto element = phene_element.find("club_antennomere_count"); element != phene_element.end()) - phene.club_antennomere_count = element->get(); + phene.model = resource_manager.load(model_filename); } +} // namespace + template <> std::unique_ptr resource_loader::load(::resource_manager& resource_manager, deserialize_context& ctx) { - // Load JSON data - auto json_data = resource_loader::load(resource_manager, ctx); - - // Validate gene file - auto antennae_element = json_data->find("antennae"); - if (antennae_element == json_data->end()) - throw std::runtime_error("Invalid antennae gene."); - - // Allocate gene - std::unique_ptr antennae = std::make_unique(); + std::unique_ptr gene = std::make_unique(); - // Deserialize gene - deserialize_ant_gene(*antennae, &deserialize_ant_antennae_phene, *antennae_element, resource_manager); + load_ant_gene(*gene, resource_manager, ctx, &load_ant_antennae_phene); - return antennae; + return gene; } diff --git a/src/game/ant/genes/ant-antennae-gene.hpp b/src/game/ant/genes/ant-antennae-gene.hpp index 1d90c3d..fc8267f 100644 --- a/src/game/ant/genes/ant-antennae-gene.hpp +++ b/src/game/ant/genes/ant-antennae-gene.hpp @@ -20,7 +20,7 @@ #ifndef ANTKEEPER_GAME_ANT_ANTENNAE_GENE_HPP #define ANTKEEPER_GAME_ANT_ANTENNAE_GENE_HPP -#include "game/ant/genes/polyphenic-ant-gene.hpp" +#include "game/ant/genes/ant-gene.hpp" #include #include #include @@ -33,17 +33,23 @@ */ struct ant_antennae_phene { - /// 3D model of the antennae. - std::shared_ptr model; - /// Total number of antennal segments per antenna. - std::uint8_t total_antennomere_count; + std::uint8_t total_antennomere_count{0}; /// Number of antennal segments that constitute a club. - std::uint8_t club_antennomere_count; + std::uint8_t club_antennomere_count{0}; + + /// 3D model of the antennae. + std::shared_ptr model; }; /// Ant antennae gene. -using ant_antennae_gene = polyphenic_ant_gene; +using ant_antennae_gene = ant_gene; + +template <> +inline constexpr ant_gene_type ant_antennae_gene::type() const noexcept +{ + return ant_gene_type::antennae; +} #endif // ANTKEEPER_GAME_ANT_ANTENNAE_GENE_HPP diff --git a/src/game/ant/genes/ant-body-size-gene.cpp b/src/game/ant/genes/ant-body-size-gene.cpp index 8c85541..693dc5d 100644 --- a/src/game/ant/genes/ant-body-size-gene.cpp +++ b/src/game/ant/genes/ant-body-size-gene.cpp @@ -17,48 +17,28 @@ * along with Antkeeper source code. If not, see . */ +#include "game/ant/genes/ant-body-size-gene.hpp" #include "game/ant/genes/ant-gene-loader.hpp" #include #include -#include -#include "game/ant/genes/ant-body-size-gene.hpp" -#include -static void deserialize_ant_body_size_phene(ant_body_size_phene& phene, const json& phene_element, resource_manager& resource_manager) +namespace { + +void load_ant_body_size_phene(ant_body_size_phene& phene, ::resource_manager& resource_manager, deserialize_context& ctx) { - phene.min_mesosoma_length = 1.0f; - phene.max_mesosoma_length = 1.0f; - phene.mean_mesosoma_length = 1.0f; - - // Parse min mesosoma length - if (auto element = phene_element.find("min_mesosoma_length"); element != phene_element.end()) - phene.min_mesosoma_length = element->get(); - - // Parse max mesosoma length - if (auto element = phene_element.find("max_mesosoma_length"); element != phene_element.end()) - phene.max_mesosoma_length = element->get(); - - // Parse mean mesosoma length - if (auto element = phene_element.find("mean_mesosoma_length"); element != phene_element.end()) - phene.mean_mesosoma_length = element->get(); + ctx.read32(reinterpret_cast(&phene.min_mesosoma_length), 1); + ctx.read32(reinterpret_cast(&phene.max_mesosoma_length), 1); + ctx.read32(reinterpret_cast(&phene.mean_mesosoma_length), 1); } +} // namespace + template <> std::unique_ptr resource_loader::load(::resource_manager& resource_manager, deserialize_context& ctx) { - // Load JSON data - auto json_data = resource_loader::load(resource_manager, ctx); - - // Validate gene file - auto body_size_element = json_data->find("body_size"); - if (body_size_element == json_data->end()) - throw std::runtime_error("Invalid body_size gene."); - - // Allocate gene - std::unique_ptr body_size = std::make_unique(); + std::unique_ptr gene = std::make_unique(); - // Deserialize gene - deserialize_ant_gene(*body_size, &deserialize_ant_body_size_phene, *body_size_element, resource_manager); + load_ant_gene(*gene, resource_manager, ctx, &load_ant_body_size_phene); - return body_size; + return gene; } diff --git a/src/game/ant/genes/ant-body-size-gene.hpp b/src/game/ant/genes/ant-body-size-gene.hpp index ba1f0a8..c8c875f 100644 --- a/src/game/ant/genes/ant-body-size-gene.hpp +++ b/src/game/ant/genes/ant-body-size-gene.hpp @@ -20,7 +20,7 @@ #ifndef ANTKEEPER_GAME_ANT_BODY_SIZE_GENE_HPP #define ANTKEEPER_GAME_ANT_BODY_SIZE_GENE_HPP -#include "game/ant/genes/polyphenic-ant-gene.hpp" +#include "game/ant/genes/ant-gene.hpp" /** * Ant body size phene. @@ -30,16 +30,22 @@ struct ant_body_size_phene { /// Minimum mesosoma length (Weber's length), in centimeters. - float min_mesosoma_length; + float min_mesosoma_length{0.0f}; /// Maximum mesosoma length (Weber's length), in centimeters. - float max_mesosoma_length; + float max_mesosoma_length{0.0f}; /// Mean mesosoma length (Weber's length), in centimeters. - float mean_mesosoma_length; + float mean_mesosoma_length{0.0f}; }; /// Ant body size gene. -using ant_body_size_gene = polyphenic_ant_gene; +using ant_body_size_gene = ant_gene; + +template <> +inline constexpr ant_gene_type ant_body_size_gene::type() const noexcept +{ + return ant_gene_type::body_size; +} #endif // ANTKEEPER_GAME_ANT_BODY_SIZE_GENE_HPP diff --git a/src/game/ant/genes/ant-cocoon-gene.cpp b/src/game/ant/genes/ant-cocoon-gene.cpp index 78c1bde..1e50bcd 100644 --- a/src/game/ant/genes/ant-cocoon-gene.cpp +++ b/src/game/ant/genes/ant-cocoon-gene.cpp @@ -17,47 +17,39 @@ * along with Antkeeper source code. If not, see . */ +#include "game/ant/genes/ant-cocoon-gene.hpp" #include "game/ant/genes/ant-gene-loader.hpp" #include #include -#include -#include "game/ant/genes/ant-cocoon-gene.hpp" #include -#include -static void deserialize_ant_cocoon_phene(ant_cocoon_phene& phene, const json& phene_element, resource_manager& resource_manager) +namespace { + +void load_ant_cocoon_phene(ant_cocoon_phene& phene, ::resource_manager& resource_manager, deserialize_context& ctx) { - phene.present = false; - phene.model = nullptr; + std::uint8_t present{0}; + ctx.read8(reinterpret_cast(&present), 1); + phene.present = static_cast(present); - // Parse cocoon present - if (auto element = phene_element.find("present"); element != phene_element.end()) - phene.present = element->get(); + std::uint8_t model_filename_length{0}; + ctx.read8(reinterpret_cast(&model_filename_length), 1); + std::string model_filename(model_filename_length, '\0'); + ctx.read8(reinterpret_cast(model_filename.data()), model_filename_length); - // Load cocoon model if (phene.present) { - if (auto element = phene_element.find("model"); element != phene_element.end()) - phene.model = resource_manager.load(element->get()); + phene.model = resource_manager.load(model_filename); } } +} // namespace + template <> std::unique_ptr resource_loader::load(::resource_manager& resource_manager, deserialize_context& ctx) { - // Load JSON data - auto json_data = resource_loader::load(resource_manager, ctx); - - // Validate gene file - auto cocoon_element = json_data->find("cocoon"); - if (cocoon_element == json_data->end()) - throw std::runtime_error("Invalid cocoon gene."); - - // Allocate gene - std::unique_ptr cocoon = std::make_unique(); + std::unique_ptr gene = std::make_unique(); - // Deserialize gene - deserialize_ant_gene(*cocoon, &deserialize_ant_cocoon_phene, *cocoon_element, resource_manager); + load_ant_gene(*gene, resource_manager, ctx, &load_ant_cocoon_phene); - return cocoon; + return gene; } diff --git a/src/game/ant/genes/ant-cocoon-gene.hpp b/src/game/ant/genes/ant-cocoon-gene.hpp index 1acbcd4..2836aff 100644 --- a/src/game/ant/genes/ant-cocoon-gene.hpp +++ b/src/game/ant/genes/ant-cocoon-gene.hpp @@ -20,7 +20,7 @@ #ifndef ANTKEEPER_GAME_ANT_COCOON_GENE_HPP #define ANTKEEPER_GAME_ANT_COCOON_GENE_HPP -#include "game/ant/genes/monophenic-ant-gene.hpp" +#include "game/ant/genes/ant-gene.hpp" #include #include @@ -29,14 +29,20 @@ */ struct ant_cocoon_phene { + /// Indicates whether a cocoon is formed by the larvae or not. + bool present{false}; + /// 3D model of the cocoon, if present. std::shared_ptr model; - - /// Indicates whether a cocoon is formed by the larvae or not. - bool present; }; /// Ant cocoon gene. -using ant_cocoon_gene = monophenic_ant_gene; +using ant_cocoon_gene = ant_gene; + +template <> +inline constexpr ant_gene_type ant_cocoon_gene::type() const noexcept +{ + return ant_gene_type::cocoon; +} #endif // ANTKEEPER_GAME_ANT_COCOON_GENE_HPP diff --git a/src/game/ant/genes/ant-diet-gene.cpp b/src/game/ant/genes/ant-diet-gene.cpp index 52951c8..68e12d1 100644 --- a/src/game/ant/genes/ant-diet-gene.cpp +++ b/src/game/ant/genes/ant-diet-gene.cpp @@ -17,34 +17,26 @@ * along with Antkeeper source code. If not, see . */ +#include "game/ant/genes/ant-diet-gene.hpp" #include "game/ant/genes/ant-gene-loader.hpp" #include #include -#include -#include "game/ant/genes/ant-diet-gene.hpp" -#include -static void deserialize_ant_diet_phene(ant_diet_phene& phene, const json& phene_element, resource_manager& resource_manager) +namespace { + +void load_ant_diet_phene(ant_diet_phene& phene, ::resource_manager& resource_manager, deserialize_context& ctx) { - + } +} // namespace + template <> std::unique_ptr resource_loader::load(::resource_manager& resource_manager, deserialize_context& ctx) { - // Load JSON data - auto json_data = resource_loader::load(resource_manager, ctx); - - // Validate gene file - auto diet_element = json_data->find("diet"); - if (diet_element == json_data->end()) - throw std::runtime_error("Invalid diet gene."); - - // Allocate gene - std::unique_ptr diet = std::make_unique(); + std::unique_ptr gene = std::make_unique(); - // Deserialize gene - deserialize_ant_gene(*diet, &deserialize_ant_diet_phene, *diet_element, resource_manager); + load_ant_gene(*gene, resource_manager, ctx, &load_ant_diet_phene); - return diet; + return gene; } diff --git a/src/game/ant/genes/ant-diet-gene.hpp b/src/game/ant/genes/ant-diet-gene.hpp index 72af8e0..1581036 100644 --- a/src/game/ant/genes/ant-diet-gene.hpp +++ b/src/game/ant/genes/ant-diet-gene.hpp @@ -20,7 +20,7 @@ #ifndef ANTKEEPER_GAME_ANT_DIET_GENE_HPP #define ANTKEEPER_GAME_ANT_DIET_GENE_HPP -#include "game/ant/genes/monophenic-ant-gene.hpp" +#include "game/ant/genes/ant-gene.hpp" /** * Ant diet phene. @@ -28,25 +28,31 @@ struct ant_diet_phene { /// Preference for eating seeds. - float seeds; + float seeds{0.0f}; /// Preference for eating ant brood. - float ant_brood; + float ant_brood{0.0f}; /// Preference for eating arthropod eggs. - float arthropod_eggs; + float arthropod_eggs{0.0f}; /// Preference for eating nectar. - float nectar; + float nectar{0.0f}; /// Preference for eating fungi. - float fungi; + float fungi{0.0f}; /// Preference for eating carrion. - float carrion; + float carrion{0.0f}; }; /// Ant diet gene. -using ant_diet_gene = monophenic_ant_gene; +using ant_diet_gene = ant_gene; + +template <> +inline constexpr ant_gene_type ant_diet_gene::type() const noexcept +{ + return ant_gene_type::diet; +} #endif // ANTKEEPER_GAME_ANT_DIET_GENE_HPP diff --git a/src/game/ant/genes/ant-egg-gene.cpp b/src/game/ant/genes/ant-egg-gene.cpp index 55cd5a1..e7867dd 100644 --- a/src/game/ant/genes/ant-egg-gene.cpp +++ b/src/game/ant/genes/ant-egg-gene.cpp @@ -17,39 +17,32 @@ * along with Antkeeper source code. If not, see . */ +#include "game/ant/genes/ant-egg-gene.hpp" #include "game/ant/genes/ant-gene-loader.hpp" #include #include -#include -#include "game/ant/genes/ant-egg-gene.hpp" #include -#include -static void deserialize_ant_egg_phene(ant_egg_phene& phene, const json& phene_element, resource_manager& resource_manager) +namespace { + +void load_ant_egg_phene(ant_egg_phene& phene, ::resource_manager& resource_manager, deserialize_context& ctx) { - phene.model = nullptr; + std::uint8_t model_filename_length{0}; + ctx.read8(reinterpret_cast(&model_filename_length), 1); + std::string model_filename(model_filename_length, '\0'); + ctx.read8(reinterpret_cast(model_filename.data()), model_filename_length); - // Load egg model - if (auto element = phene_element.find("model"); element != phene_element.end()) - phene.model = resource_manager.load(element->get()); + phene.model = resource_manager.load(model_filename); } +} // namespace + template <> std::unique_ptr resource_loader::load(::resource_manager& resource_manager, deserialize_context& ctx) { - // Load JSON data - auto json_data = resource_loader::load(resource_manager, ctx); - - // Validate gene file - auto egg_element = json_data->find("egg"); - if (egg_element == json_data->end()) - throw std::runtime_error("Invalid egg gene."); - - // Allocate gene - std::unique_ptr egg = std::make_unique(); + std::unique_ptr gene = std::make_unique(); - // Deserialize gene - deserialize_ant_gene(*egg, &deserialize_ant_egg_phene, *egg_element, resource_manager); + load_ant_gene(*gene, resource_manager, ctx, &load_ant_egg_phene); - return egg; + return gene; } diff --git a/src/game/ant/genes/ant-egg-gene.hpp b/src/game/ant/genes/ant-egg-gene.hpp index 756563d..7b15759 100644 --- a/src/game/ant/genes/ant-egg-gene.hpp +++ b/src/game/ant/genes/ant-egg-gene.hpp @@ -20,7 +20,7 @@ #ifndef ANTKEEPER_GAME_ANT_EGG_GENE_HPP #define ANTKEEPER_GAME_ANT_EGG_GENE_HPP -#include "game/ant/genes/monophenic-ant-gene.hpp" +#include "game/ant/genes/ant-gene.hpp" #include #include @@ -34,6 +34,12 @@ struct ant_egg_phene }; /// Ant egg gene. -using ant_egg_gene = monophenic_ant_gene; +using ant_egg_gene = ant_gene; + +template <> +inline constexpr ant_gene_type ant_egg_gene::type() const noexcept +{ + return ant_gene_type::egg; +} #endif // ANTKEEPER_GAME_ANT_EGG_GENE_HPP diff --git a/src/game/ant/genes/ant-eyes-gene.cpp b/src/game/ant/genes/ant-eyes-gene.cpp index a699b13..f9f456c 100644 --- a/src/game/ant/genes/ant-eyes-gene.cpp +++ b/src/game/ant/genes/ant-eyes-gene.cpp @@ -17,67 +17,44 @@ * along with Antkeeper source code. If not, see . */ +#include "game/ant/genes/ant-eyes-gene.hpp" #include "game/ant/genes/ant-gene-loader.hpp" #include #include -#include -#include "game/ant/genes/ant-eyes-gene.hpp" #include -#include -static void deserialize_ant_eyes_phene(ant_eyes_phene& phene, const json& phene_element, resource_manager& resource_manager) +namespace { + +void load_ant_eyes_phene(ant_eyes_phene& phene, ::resource_manager& resource_manager, deserialize_context& ctx) { - phene.present = false; - phene.model = nullptr; - phene.length = 0.0f; - phene.width = 0.0f; - phene.height = 0.0f; - phene.ommatidia_count = 0; + std::uint8_t present{0}; + ctx.read8(reinterpret_cast(&present), 1); + phene.present = static_cast(present); + + ctx.read32(reinterpret_cast(&phene.ommatidia_count), 1); + ctx.read32(reinterpret_cast(&phene.length), 1); + ctx.read32(reinterpret_cast(&phene.width), 1); + ctx.read32(reinterpret_cast(&phene.height), 1); - // Parse present - if (auto element = phene_element.find("present"); element != phene_element.end()) - phene.present = element->get(); + std::uint8_t model_filename_length{0}; + ctx.read8(reinterpret_cast(&model_filename_length), 1); + std::string model_filename(model_filename_length, '\0'); + ctx.read8(reinterpret_cast(model_filename.data()), model_filename_length); if (phene.present) { - // Load eyes model - if (auto element = phene_element.find("model"); element != phene_element.end()) - phene.model = resource_manager.load(element->get()); - - // Parse length - if (auto element = phene_element.find("length"); element != phene_element.end()) - phene.length = element->get(); - - // Parse width - if (auto element = phene_element.find("width"); element != phene_element.end()) - phene.width = element->get(); - - // Parse height - if (auto element = phene_element.find("height"); element != phene_element.end()) - phene.height = element->get(); - - // Parse ommatidia count - if (auto element = phene_element.find("ommatidia_count"); element != phene_element.end()) - phene.ommatidia_count = element->get(); + phene.model = resource_manager.load(model_filename); } } +} // namespace + template <> std::unique_ptr resource_loader::load(::resource_manager& resource_manager, deserialize_context& ctx) { - // Load JSON data - auto json_data = resource_loader::load(resource_manager, ctx); - - // Validate gene file - auto eyes_element = json_data->find("eyes"); - if (eyes_element == json_data->end()) - throw std::runtime_error("Invalid eyes gene."); - - // Allocate gene - std::unique_ptr eyes = std::make_unique(); + std::unique_ptr gene = std::make_unique(); - // Deserialize gene - deserialize_ant_gene(*eyes, &deserialize_ant_eyes_phene, *eyes_element, resource_manager); + load_ant_gene(*gene, resource_manager, ctx, &load_ant_eyes_phene); - return eyes; + return gene; } diff --git a/src/game/ant/genes/ant-eyes-gene.hpp b/src/game/ant/genes/ant-eyes-gene.hpp index 07f56a1..57048eb 100644 --- a/src/game/ant/genes/ant-eyes-gene.hpp +++ b/src/game/ant/genes/ant-eyes-gene.hpp @@ -20,7 +20,7 @@ #ifndef ANTKEEPER_GAME_ANT_EYES_GENE_HPP #define ANTKEEPER_GAME_ANT_EYES_GENE_HPP -#include "game/ant/genes/polyphenic-ant-gene.hpp" +#include "game/ant/genes/ant-gene.hpp" #include #include #include @@ -32,26 +32,32 @@ */ struct ant_eyes_phene { - /// 3D model of the eyes, if present. - std::shared_ptr model; - /// Indicates whether eyes are present. - bool present; + bool present{false}; + + /// Number of ommatidia. + std::uint32_t ommatidia_count{0}; /// Eye length, in mesosomal lengths. - float length; + float length{0.0f}; /// Eye width, in mesosomal lengths. - float width; + float width{0.0f}; /// Eye height, in mesosomal lengths. - float height; + float height{0.0f}; - /// Number of ommatidia. - std::uint32_t ommatidia_count; + /// 3D model of the eyes, if present. + std::shared_ptr model; }; /// Ant eyes gene. -using ant_eyes_gene = polyphenic_ant_gene; +using ant_eyes_gene = ant_gene; + +template <> +inline constexpr ant_gene_type ant_eyes_gene::type() const noexcept +{ + return ant_gene_type::eyes; +} #endif // ANTKEEPER_GAME_ANT_EYES_GENE_HPP diff --git a/src/game/ant/genes/ant-foraging-time-gene.cpp b/src/game/ant/genes/ant-foraging-time-gene.cpp index a2cb353..66ff8d8 100644 --- a/src/game/ant/genes/ant-foraging-time-gene.cpp +++ b/src/game/ant/genes/ant-foraging-time-gene.cpp @@ -17,45 +17,27 @@ * along with Antkeeper source code. If not, see . */ +#include "game/ant/genes/ant-foraging-time-gene.hpp" #include "game/ant/genes/ant-gene-loader.hpp" #include #include -#include -#include "game/ant/genes/ant-foraging-time-gene.hpp" -#include -#include -#include -static void deserialize_ant_foraging_time_phene(ant_foraging_time_phene& phene, const json& phene_element, resource_manager& resource_manager) +namespace { + +void load_ant_foraging_time_phene(ant_foraging_time_phene& phene, ::resource_manager& resource_manager, deserialize_context& ctx) { - phene.min_solar_altitude = -math::half_pi; - phene.max_solar_altitude = math::half_pi; - - // Parse min solar altitude - if (auto element = phene_element.find("min_solar_altitude"); element != phene_element.end()) - phene.min_solar_altitude = math::radians(element->get()); - - // Parse max solar altitude - if (auto element = phene_element.find("max_solar_altitude"); element != phene_element.end()) - phene.max_solar_altitude = math::radians(element->get()); + ctx.read32(reinterpret_cast(&phene.min_solar_altitude), 1); + ctx.read32(reinterpret_cast(&phene.max_solar_altitude), 1); } +} // namespace + template <> std::unique_ptr resource_loader::load(::resource_manager& resource_manager, deserialize_context& ctx) { - // Load JSON data - auto json_data = resource_loader::load(resource_manager, ctx); - - // Validate gene file - auto foraging_time_element = json_data->find("foraging_time"); - if (foraging_time_element == json_data->end()) - throw std::runtime_error("Invalid foraging_time gene."); - - // Allocate gene - std::unique_ptr foraging_time = std::make_unique(); + std::unique_ptr gene = std::make_unique(); - // Deserialize gene - deserialize_ant_gene(*foraging_time, &deserialize_ant_foraging_time_phene, *foraging_time_element, resource_manager); + load_ant_gene(*gene, resource_manager, ctx, &load_ant_foraging_time_phene); - return foraging_time; + return gene; } diff --git a/src/game/ant/genes/ant-foraging-time-gene.hpp b/src/game/ant/genes/ant-foraging-time-gene.hpp index 07c0f5e..8dbdf52 100644 --- a/src/game/ant/genes/ant-foraging-time-gene.hpp +++ b/src/game/ant/genes/ant-foraging-time-gene.hpp @@ -20,21 +20,27 @@ #ifndef ANTKEEPER_GAME_ANT_FORAGING_TIME_GENE_HPP #define ANTKEEPER_GAME_ANT_FORAGING_TIME_GENE_HPP -#include "game/ant/genes/monophenic-ant-gene.hpp" +#include "game/ant/genes/ant-gene.hpp" /** * Ant foraging time phene. */ struct ant_foraging_time_phene { - /// Minimum solar altitude at which foraging occurs. - float min_solar_altitude; + /// Minimum solar altitude, in radians, at which foraging occurs. + float min_solar_altitude{0.0f}; - /// Maximum solar alttiude at which foraging occurs. - float max_solar_altitude; + /// Maximum solar alttiude, in radians, at which foraging occurs. + float max_solar_altitude{0.0f}; }; /// Ant foraging time gene. -using ant_foraging_time_gene = monophenic_ant_gene; +using ant_foraging_time_gene = ant_gene; + +template <> +inline constexpr ant_gene_type ant_foraging_time_gene::type() const noexcept +{ + return ant_gene_type::foraging_time; +} #endif // ANTKEEPER_GAME_ANT_FORAGING_TIME_GENE_HPP diff --git a/src/game/ant/genes/ant-founding-mode-gene.cpp b/src/game/ant/genes/ant-founding-mode-gene.cpp index c0df65e..015e053 100644 --- a/src/game/ant/genes/ant-founding-mode-gene.cpp +++ b/src/game/ant/genes/ant-founding-mode-gene.cpp @@ -17,34 +17,26 @@ * along with Antkeeper source code. If not, see . */ +#include "game/ant/genes/ant-founding-mode-gene.hpp" #include "game/ant/genes/ant-gene-loader.hpp" #include #include -#include -#include "game/ant/genes/ant-founding-mode-gene.hpp" -#include -static void deserialize_ant_founding_mode_phene(ant_founding_mode_phene& phene, const json& phene_element, resource_manager& resource_manager) +namespace { + +void load_ant_founding_mode_phene(ant_founding_mode_phene& phene, ::resource_manager& resource_manager, deserialize_context& ctx) { } +} // namespace + template <> std::unique_ptr resource_loader::load(::resource_manager& resource_manager, deserialize_context& ctx) { - // Load JSON data - auto json_data = resource_loader::load(resource_manager, ctx); - - // Validate gene file - auto founding_mode_element = json_data->find("founding_mode"); - if (founding_mode_element == json_data->end()) - throw std::runtime_error("Invalid founding_mode gene."); - - // Allocate gene - std::unique_ptr founding_mode = std::make_unique(); + std::unique_ptr gene = std::make_unique(); - // Deserialize gene - deserialize_ant_gene(*founding_mode, &deserialize_ant_founding_mode_phene, *founding_mode_element, resource_manager); + load_ant_gene(*gene, resource_manager, ctx, &load_ant_founding_mode_phene); - return founding_mode; + return gene; } diff --git a/src/game/ant/genes/ant-founding-mode-gene.hpp b/src/game/ant/genes/ant-founding-mode-gene.hpp index b30c9b1..657b2e8 100644 --- a/src/game/ant/genes/ant-founding-mode-gene.hpp +++ b/src/game/ant/genes/ant-founding-mode-gene.hpp @@ -20,7 +20,7 @@ #ifndef ANTKEEPER_GAME_ANT_FOUNDING_MODE_GENE_HPP #define ANTKEEPER_GAME_ANT_FOUNDING_MODE_GENE_HPP -#include "game/ant/genes/monophenic-ant-gene.hpp" +#include "game/ant/genes/ant-gene.hpp" #include /** @@ -40,7 +40,13 @@ enum class ant_founding_mode_phene: std::uint8_t fission }; -/// Monophenic founding mode gene. -using ant_founding_mode_gene = monophenic_ant_gene; +/// Ant founding mode gene. +using ant_founding_mode_gene = ant_gene; + +template <> +inline constexpr ant_gene_type ant_founding_mode_gene::type() const noexcept +{ + return ant_gene_type::founding_mode; +} #endif // ANTKEEPER_GAME_ANT_FOUNDING_MODE_GENE_HPP diff --git a/src/game/ant/genes/ant-gaster-gene.cpp b/src/game/ant/genes/ant-gaster-gene.cpp index 35ece07..b2df155 100644 --- a/src/game/ant/genes/ant-gaster-gene.cpp +++ b/src/game/ant/genes/ant-gaster-gene.cpp @@ -17,44 +17,34 @@ * along with Antkeeper source code. If not, see . */ +#include "game/ant/genes/ant-gaster-gene.hpp" #include "game/ant/genes/ant-gene-loader.hpp" #include #include -#include -#include "game/ant/genes/ant-gaster-gene.hpp" #include -#include -static void deserialize_ant_gaster_phene(ant_gaster_phene& phene, const json& phene_element, resource_manager& resource_manager) +namespace { + +void load_ant_gaster_phene(ant_gaster_phene& phene, ::resource_manager& resource_manager, deserialize_context& ctx) { - phene.model = nullptr; - phene.phragmosis = 0.0f; + ctx.read32(reinterpret_cast(&phene.phragmosis), 1); - // Load gaster model - if (auto element = phene_element.find("model"); element != phene_element.end()) - phene.model = resource_manager.load(element->get()); + std::uint8_t model_filename_length{0}; + ctx.read8(reinterpret_cast(&model_filename_length), 1); + std::string model_filename(model_filename_length, '\0'); + ctx.read8(reinterpret_cast(model_filename.data()), model_filename_length); - // Parse phragmosis - if (auto element = phene_element.find("phragmosis"); element != phene_element.end()) - phene.phragmosis = element->get(); + phene.model = resource_manager.load(model_filename); } +} // namespace + template <> std::unique_ptr resource_loader::load(::resource_manager& resource_manager, deserialize_context& ctx) { - // Load JSON data - auto json_data = resource_loader::load(resource_manager, ctx); - - // Validate gene file - auto gaster_element = json_data->find("gaster"); - if (gaster_element == json_data->end()) - throw std::runtime_error("Invalid gaster gene."); - - // Allocate gene - std::unique_ptr gaster = std::make_unique(); + std::unique_ptr gene = std::make_unique(); - // Deserialize gene - deserialize_ant_gene(*gaster, &deserialize_ant_gaster_phene, *gaster_element, resource_manager); + load_ant_gene(*gene, resource_manager, ctx, &load_ant_gaster_phene); - return gaster; + return gene; } diff --git a/src/game/ant/genes/ant-gaster-gene.hpp b/src/game/ant/genes/ant-gaster-gene.hpp index 172f414..1d9b27c 100644 --- a/src/game/ant/genes/ant-gaster-gene.hpp +++ b/src/game/ant/genes/ant-gaster-gene.hpp @@ -20,7 +20,7 @@ #ifndef ANTKEEPER_GAME_ANT_GASTER_GENE_HPP #define ANTKEEPER_GAME_ANT_GASTER_GENE_HPP -#include "game/ant/genes/polyphenic-ant-gene.hpp" +#include "game/ant/genes/ant-gene.hpp" #include #include @@ -31,14 +31,20 @@ */ struct ant_gaster_phene { + /// Degree of phragmosis. + float phragmosis{0.0f}; + /// 3D model of the gaster. std::shared_ptr model; - - /// Degree of phragmosis. - float phragmosis; }; /// Ant gaster gene. -using ant_gaster_gene = polyphenic_ant_gene; +using ant_gaster_gene = ant_gene; + +template <> +inline constexpr ant_gene_type ant_gaster_gene::type() const noexcept +{ + return ant_gene_type::gaster; +} #endif // ANTKEEPER_GAME_ANT_GASTER_GENE_HPP diff --git a/src/game/ant/genes/ant-gene-loader.hpp b/src/game/ant/genes/ant-gene-loader.hpp index 488d822..2f66138 100644 --- a/src/game/ant/genes/ant-gene-loader.hpp +++ b/src/game/ant/genes/ant-gene-loader.hpp @@ -20,74 +20,96 @@ #ifndef ANTKEEPER_GAME_ANT_GENE_LOADER_HPP #define ANTKEEPER_GAME_ANT_GENE_LOADER_HPP -#include "game/ant/genes/monophenic-ant-gene.hpp" -#include "game/ant/genes/polyphenic-ant-gene.hpp" -#include +#include "game/ant/genes/ant-gene.hpp" #include +#include +#include /** - * Deserializes an ant gene. + * Loads an ant gene. * - * @tparam T Ant phene type. + * @tparam T Phene type. * - * @param gene Ant gene to deserialize. - * @param deserialize_phene Ant phene deserialization function. - * @param gene_element JSON element containing an ant gene definition. + * @param gene Gene to load. * @param resource_manager Resource manager. + * @param ctx Deserialize context. + * @param load_phene Pointer to phene load function. */ -/// @{ template -void deserialize_ant_gene(monophenic_ant_gene& gene, void (*deserialize_phene)(T&, const json&, resource_manager&), const json& gene_element, resource_manager& resource_manager) +void load_ant_gene(ant_gene& gene, resource_manager& resource_manager, deserialize_context& ctx, void (*load_phene)(T&, ::resource_manager&, deserialize_context&)) { - // Read gene name - if (auto element = gene_element.find("name"); element != gene_element.end()) + // Read file format identifier + std::uint32_t format_identifier{0}; + ctx.read32(reinterpret_cast(&format_identifier), 1); + + // Validate file format identifier + if (format_identifier != 0xaca79ff0) { - gene.name = element->get(); + throw deserialize_error("Invalid ant gene file"); } - // Deserialize phene - if (auto element = gene_element.find("phene"); element != gene_element.end()) + // Read file format version + std::uint16_t format_version{0}; + ctx.read16(reinterpret_cast(&format_version), 1); + + // Validate file format version + if (format_version != 1) { - deserialize_phene(gene.phene, *element, resource_manager); + throw deserialize_error("Unsupported ant gene format"); } -} - -template -void deserialize_ant_gene(polyphenic_ant_gene& gene, void (*deserialize_phene)(T&, const json&, resource_manager&), const json& gene_element, resource_manager& resource_manager) -{ - // Read gene name - if (auto element = gene_element.find("name"); element != gene_element.end()) + + // Read gene type + ant_gene_type gene_type{0}; + ctx.read8(reinterpret_cast(&gene_type), 1); + + // Validate gene type + if (gene_type != gene.type()) { - gene.name = element->get(); + throw deserialize_error("Mismatched ant gene type"); } - // Deserialize phenes - if (auto phenes_element = gene_element.find("phenes"); phenes_element != gene_element.end()) + // Read gene name + ctx.read32(reinterpret_cast(&gene.name), 1); + + // Read phene count + std::uint8_t phene_count{0}; + ctx.read8(reinterpret_cast(&phene_count), 1); + + // Allocate phenes + gene.phenes.resize(phene_count); + + // Load phenes + for (auto& phene: gene.phenes) { - if (auto element = phenes_element->find("female"); element != phenes_element->end()) - { - deserialize_phene(gene.phenes[ant_caste::queen], *element, resource_manager); - deserialize_phene(gene.phenes[ant_caste::worker], *element, resource_manager); - deserialize_phene(gene.phenes[ant_caste::soldier], *element, resource_manager); - } - if (auto element = phenes_element->find("male"); element != phenes_element->end()) - { - deserialize_phene(gene.phenes[ant_caste::male], *element, resource_manager); - } - if (auto element = phenes_element->find("queen"); element != phenes_element->end()) - { - deserialize_phene(gene.phenes[ant_caste::queen], *element, resource_manager); - } - if (auto element = phenes_element->find("worker"); element != phenes_element->end()) + // Read phene caste flags + std::uint8_t caste_flags{0}; + ctx.read8(reinterpret_cast(&caste_flags), 1); + + // Load phene + load_phene(phene, resource_manager, ctx); + + // Map flagged castes to phene + int caste_count = std::popcount(caste_flags); + if (caste_count == 1) { - deserialize_phene(gene.phenes[ant_caste::worker], *element, resource_manager); + gene.phene_map[static_cast(caste_flags)] = &phene; } - if (auto element = phenes_element->find("soldier"); element != phenes_element->end()) + else { - deserialize_phene(gene.phenes[ant_caste::soldier], *element, resource_manager); + for (std::uint8_t i = 0; i < 8; ++i) + { + const std::uint8_t caste_mask = 1 << i; + if (caste_flags & caste_mask) + { + gene.phene_map[static_cast(caste_mask)] = &phene; + if (--caste_count; !caste_count) + { + break; + } + } + } } } } -/// @} #endif // ANTKEEPER_GAME_ANT_GENE_LOADER_HPP diff --git a/src/game/ant/genes/monophenic-ant-gene.hpp b/src/game/ant/genes/ant-gene-type.hpp similarity index 65% rename from src/game/ant/genes/monophenic-ant-gene.hpp rename to src/game/ant/genes/ant-gene-type.hpp index ebcaa55..aee325b 100644 --- a/src/game/ant/genes/monophenic-ant-gene.hpp +++ b/src/game/ant/genes/ant-gene-type.hpp @@ -17,24 +17,38 @@ * along with Antkeeper source code. If not, see . */ -#ifndef ANTKEEPER_GAME_MONOPHENIC_ANT_GENE_HPP -#define ANTKEEPER_GAME_MONOPHENIC_ANT_GENE_HPP +#ifndef ANTKEEPER_GAME_ANT_GENE_TYPE_HPP +#define ANTKEEPER_GAME_ANT_GENE_TYPE_HPP -#include +#include /** - * Ant gene with a single phene. - * - * @tparam T Ant phene type. + * Ant gene types. */ -template -struct monophenic_ant_gene +enum class ant_gene_type: std::uint8_t { - /// Gene name. - std::string name; - - /// Phene definition. - T phene; + antennae = 1, + body_size, + cocoon, + diet, + egg, + eyes, + foraging_time, + founding_mode, + gaster, + head, + larva, + legs, + mandibles, + mesosoma, + nest_site, + ocelli, + pigmentation, + pilosity, + sculpturing, + sting, + waist, + wings }; -#endif // ANTKEEPER_GAME_MONOPHENIC_ANT_GENE_HPP +#endif // ANTKEEPER_GAME_ANT_GENE_TYPE_HPP diff --git a/src/game/ant/genes/polyphenic-ant-gene.hpp b/src/game/ant/genes/ant-gene.hpp similarity index 56% rename from src/game/ant/genes/polyphenic-ant-gene.hpp rename to src/game/ant/genes/ant-gene.hpp index 64fa6a5..16266f4 100644 --- a/src/game/ant/genes/polyphenic-ant-gene.hpp +++ b/src/game/ant/genes/ant-gene.hpp @@ -17,12 +17,26 @@ * along with Antkeeper source code. If not, see . */ -#ifndef ANTKEEPER_GAME_POLYPHENIC_ANT_GENE_HPP -#define ANTKEEPER_GAME_POLYPHENIC_ANT_GENE_HPP +#ifndef ANTKEEPER_GAME_ANT_GENE_HPP +#define ANTKEEPER_GAME_ANT_GENE_HPP -#include "game/ant/ant-caste.hpp" -#include +#include "game/ant/ant-caste-type.hpp" +#include "game/ant/genes/ant-gene-type.hpp" +#include #include +#include + +/** + * Abstract base class for ant genes. + */ +struct ant_gene_base +{ + /// Returns the ant gene type. + [[nodiscard]] virtual constexpr ant_gene_type type() const noexcept = 0; + + /// 32-bit FNV-1a hash of gene name. + hash::fnv1a32_t name; +}; /** * Ant gene with caste-specific phenes. @@ -32,13 +46,15 @@ * @see https://en.wikipedia.org/wiki/Polyphenism */ template -struct polyphenic_ant_gene +struct ant_gene: public ant_gene_base { - /// Gene name. - std::string name; + [[nodiscard]] constexpr ant_gene_type type() const noexcept override; + + /// Phene definitions + std::vector phenes; - /// Caste-specific phene definitions. - std::unordered_map phenes; + /// Map of ant caste types to phenes. + std::unordered_map phene_map; }; -#endif // ANTKEEPER_GAME_POLYPHENIC_ANT_GENE_HPP +#endif // ANTKEEPER_GAME_ANT_GENE_HPP diff --git a/src/game/ant/genes/ant-head-gene.cpp b/src/game/ant/genes/ant-head-gene.cpp index ee24e97..c51b400 100644 --- a/src/game/ant/genes/ant-head-gene.cpp +++ b/src/game/ant/genes/ant-head-gene.cpp @@ -17,54 +17,36 @@ * along with Antkeeper source code. If not, see . */ +#include "game/ant/genes/ant-head-gene.hpp" #include "game/ant/genes/ant-gene-loader.hpp" #include #include -#include -#include "game/ant/genes/ant-head-gene.hpp" #include -#include -static void deserialize_ant_head_phene(ant_head_phene& phene, const json& phene_element, resource_manager& resource_manager) +namespace { + +void load_ant_head_phene(ant_head_phene& phene, ::resource_manager& resource_manager, deserialize_context& ctx) { - phene.model = nullptr; - phene.length = 0.0f; - phene.width = 0.0f; - phene.phragmosis = 0.0f; - - // Load head model - if (auto element = phene_element.find("model"); element != phene_element.end()) - phene.model = resource_manager.load(element->get()); + ctx.read32(reinterpret_cast(&phene.length), 1); + ctx.read32(reinterpret_cast(&phene.width), 1); + ctx.read32(reinterpret_cast(&phene.phragmosis), 1); - // Parse length - if (auto element = phene_element.find("length"); element != phene_element.end()) - phene.length = element->get(); + std::uint8_t model_filename_length{0}; + ctx.read8(reinterpret_cast(&model_filename_length), 1); + std::string model_filename(model_filename_length, '\0'); + ctx.read8(reinterpret_cast(model_filename.data()), model_filename_length); - // Parse width - if (auto element = phene_element.find("width"); element != phene_element.end()) - phene.width = element->get(); - - // Parse phragmosis - if (auto element = phene_element.find("phragmosis"); element != phene_element.end()) - phene.phragmosis = element->get(); + phene.model = resource_manager.load(model_filename); } +} // namespace + template <> std::unique_ptr resource_loader::load(::resource_manager& resource_manager, deserialize_context& ctx) { - // Load JSON data - auto json_data = resource_loader::load(resource_manager, ctx); - - // Validate gene file - auto head_element = json_data->find("head"); - if (head_element == json_data->end()) - throw std::runtime_error("Invalid head gene."); - - // Allocate gene - std::unique_ptr head = std::make_unique(); + std::unique_ptr gene = std::make_unique(); - // Deserialize gene - deserialize_ant_gene(*head, &deserialize_ant_head_phene, *head_element, resource_manager); + load_ant_gene(*gene, resource_manager, ctx, &load_ant_head_phene); - return head; + return gene; } diff --git a/src/game/ant/genes/ant-head-gene.hpp b/src/game/ant/genes/ant-head-gene.hpp index 439f842..05a1770 100644 --- a/src/game/ant/genes/ant-head-gene.hpp +++ b/src/game/ant/genes/ant-head-gene.hpp @@ -20,7 +20,7 @@ #ifndef ANTKEEPER_GAME_ANT_HEAD_GENE_HPP #define ANTKEEPER_GAME_ANT_HEAD_GENE_HPP -#include "game/ant/genes/polyphenic-ant-gene.hpp" +#include "game/ant/genes/ant-gene.hpp" #include #include @@ -32,20 +32,26 @@ */ struct ant_head_phene { - /// 3D model of the head. - std::shared_ptr model; - /// Head length, in mesosomal lengths. - float length; + float length{0.0f}; /// Head width, in mesosomal lengths. - float width; + float width{0.0f}; /// Degree of phragmosis. - float phragmosis; + float phragmosis{0.0f}; + + /// 3D model of the head. + std::shared_ptr model; }; -/// Polyphenic head gene. -using ant_head_gene = polyphenic_ant_gene; +/// Ant head gene. +using ant_head_gene = ant_gene; + +template <> +inline constexpr ant_gene_type ant_head_gene::type() const noexcept +{ + return ant_gene_type::head; +} #endif // ANTKEEPER_GAME_ANT_HEAD_GENE_HPP diff --git a/src/game/ant/genes/ant-larva-gene.cpp b/src/game/ant/genes/ant-larva-gene.cpp index eece30d..74b63fe 100644 --- a/src/game/ant/genes/ant-larva-gene.cpp +++ b/src/game/ant/genes/ant-larva-gene.cpp @@ -17,44 +17,34 @@ * along with Antkeeper source code. If not, see . */ +#include "game/ant/genes/ant-larva-gene.hpp" #include "game/ant/genes/ant-gene-loader.hpp" #include #include -#include -#include "game/ant/genes/ant-larva-gene.hpp" #include -#include -static void deserialize_ant_larva_phene(ant_larva_phene& phene, const json& phene_element, resource_manager& resource_manager) +namespace { + +void load_ant_larva_phene(ant_larva_phene& phene, ::resource_manager& resource_manager, deserialize_context& ctx) { - phene.model = nullptr; - phene.instar_count = 0; + ctx.read8(reinterpret_cast(&phene.instar_count), 1); - // Load larva model - if (auto element = phene_element.find("model"); element != phene_element.end()) - phene.model = resource_manager.load(element->get()); + std::uint8_t model_filename_length{0}; + ctx.read8(reinterpret_cast(&model_filename_length), 1); + std::string model_filename(model_filename_length, '\0'); + ctx.read8(reinterpret_cast(model_filename.data()), model_filename_length); - // Parse instar count - if (auto element = phene_element.find("instar_count"); element != phene_element.end()) - phene.instar_count = element->get(); + phene.model = resource_manager.load(model_filename); } +} // namespace + template <> std::unique_ptr resource_loader::load(::resource_manager& resource_manager, deserialize_context& ctx) { - // Load JSON data - auto json_data = resource_loader::load(resource_manager, ctx); - - // Validate gene file - auto larva_element = json_data->find("larva"); - if (larva_element == json_data->end()) - throw std::runtime_error("Invalid larva gene."); - - // Allocate gene - std::unique_ptr larva = std::make_unique(); + std::unique_ptr gene = std::make_unique(); - // Deserialize gene - deserialize_ant_gene(*larva, &deserialize_ant_larva_phene, *larva_element, resource_manager); + load_ant_gene(*gene, resource_manager, ctx, &load_ant_larva_phene); - return larva; + return gene; } diff --git a/src/game/ant/genes/ant-larva-gene.hpp b/src/game/ant/genes/ant-larva-gene.hpp index 2e079c2..1c5dd7e 100644 --- a/src/game/ant/genes/ant-larva-gene.hpp +++ b/src/game/ant/genes/ant-larva-gene.hpp @@ -20,7 +20,7 @@ #ifndef ANTKEEPER_GAME_ANT_LARVA_GENE_HPP #define ANTKEEPER_GAME_ANT_LARVA_GENE_HPP -#include "game/ant/genes/monophenic-ant-gene.hpp" +#include "game/ant/genes/ant-gene.hpp" #include #include #include @@ -30,14 +30,20 @@ */ struct ant_larva_phene { + /// Number of larval instars before pupation. + std::uint8_t instar_count{0}; + /// 3D model of the larva. std::shared_ptr model; - - /// Number of larval instars before pupation. - std::uint8_t instar_count; }; /// Ant larva gene. -using ant_larva_gene = monophenic_ant_gene; +using ant_larva_gene = ant_gene; + +template <> +inline constexpr ant_gene_type ant_larva_gene::type() const noexcept +{ + return ant_gene_type::larva; +} #endif // ANTKEEPER_GAME_ANT_LARVA_GENE_HPP diff --git a/src/game/ant/genes/ant-legs-gene.cpp b/src/game/ant/genes/ant-legs-gene.cpp index c1ff0ac..cb2b117 100644 --- a/src/game/ant/genes/ant-legs-gene.cpp +++ b/src/game/ant/genes/ant-legs-gene.cpp @@ -17,49 +17,35 @@ * along with Antkeeper source code. If not, see . */ +#include "game/ant/genes/ant-legs-gene.hpp" #include "game/ant/genes/ant-gene-loader.hpp" #include #include -#include -#include "game/ant/genes/ant-legs-gene.hpp" #include -#include -static void deserialize_ant_legs_phene(ant_legs_phene& phene, const json& phene_element, resource_manager& resource_manager) +namespace { + +void load_ant_legs_phene(ant_legs_phene& phene, ::resource_manager& resource_manager, deserialize_context& ctx) { - phene.model = nullptr; - phene.speed = 0.0f; - phene.grip = 0.0f; - - // Load legs model - if (auto element = phene_element.find("model"); element != phene_element.end()) - phene.model = resource_manager.load(element->get()); + ctx.read32(reinterpret_cast(&phene.speed), 1); + ctx.read32(reinterpret_cast(&phene.grip), 1); - // Parse speed - if (auto element = phene_element.find("speed"); element != phene_element.end()) - phene.speed = element->get(); + std::uint8_t model_filename_length{0}; + ctx.read8(reinterpret_cast(&model_filename_length), 1); + std::string model_filename(model_filename_length, '\0'); + ctx.read8(reinterpret_cast(model_filename.data()), model_filename_length); - // Parse grip - if (auto element = phene_element.find("grip"); element != phene_element.end()) - phene.grip = element->get(); + phene.model = resource_manager.load(model_filename); } +} // namespace + template <> std::unique_ptr resource_loader::load(::resource_manager& resource_manager, deserialize_context& ctx) { - // Load JSON data - auto json_data = resource_loader::load(resource_manager, ctx); - - // Validate gene file - auto legs_element = json_data->find("legs"); - if (legs_element == json_data->end()) - throw std::runtime_error("Invalid legs gene."); - - // Allocate gene - std::unique_ptr legs = std::make_unique(); + std::unique_ptr gene = std::make_unique(); - // Deserialize gene - deserialize_ant_gene(*legs, &deserialize_ant_legs_phene, *legs_element, resource_manager); + load_ant_gene(*gene, resource_manager, ctx, &load_ant_legs_phene); - return legs; + return gene; } diff --git a/src/game/ant/genes/ant-legs-gene.hpp b/src/game/ant/genes/ant-legs-gene.hpp index 8a6aea9..4d7b73c 100644 --- a/src/game/ant/genes/ant-legs-gene.hpp +++ b/src/game/ant/genes/ant-legs-gene.hpp @@ -20,7 +20,7 @@ #ifndef ANTKEEPER_GAME_ANT_LEGS_GENE_HPP #define ANTKEEPER_GAME_ANT_LEGS_GENE_HPP -#include "game/ant/genes/polyphenic-ant-gene.hpp" +#include "game/ant/genes/ant-gene.hpp" #include #include @@ -31,17 +31,23 @@ */ struct ant_legs_phene { - /// 3D model of the legs. - std::shared_ptr model; - /// Running speed, in mesosomal lengths per second. - float speed; + float speed{0.0f}; /// Grip factor. - float grip; + float grip{0.0f}; + + /// 3D model of the legs. + std::shared_ptr model; }; -/// Polyphenic legs gene. -using ant_legs_gene = polyphenic_ant_gene; +/// Ant legs gene. +using ant_legs_gene = ant_gene; + +template <> +inline constexpr ant_gene_type ant_legs_gene::type() const noexcept +{ + return ant_gene_type::legs; +} #endif // ANTKEEPER_GAME_ANT_LEGS_GENE_HPP diff --git a/src/game/ant/genes/ant-mandibles-gene.cpp b/src/game/ant/genes/ant-mandibles-gene.cpp index 3403654..ce3112e 100644 --- a/src/game/ant/genes/ant-mandibles-gene.cpp +++ b/src/game/ant/genes/ant-mandibles-gene.cpp @@ -17,54 +17,36 @@ * along with Antkeeper source code. If not, see . */ +#include "game/ant/genes/ant-mandibles-gene.hpp" #include "game/ant/genes/ant-gene-loader.hpp" #include #include -#include -#include "game/ant/genes/ant-mandibles-gene.hpp" #include -#include -static void deserialize_ant_mandibles_phene(ant_mandibles_phene& phene, const json& phene_element, resource_manager& resource_manager) +namespace { + +void load_ant_mandibles_phene(ant_mandibles_phene& phene, ::resource_manager& resource_manager, deserialize_context& ctx) { - phene.model = nullptr; - phene.length = 0.0f; - phene.apical_dental_count = 0; - phene.basal_dental_count = 0; - - // Load mandibles model - if (auto element = phene_element.find("model"); element != phene_element.end()) - phene.model = resource_manager.load(element->get()); + ctx.read32(reinterpret_cast(&phene.length), 1); + ctx.read8(reinterpret_cast(&phene.apical_dental_count), 1); + ctx.read8(reinterpret_cast(&phene.basal_dental_count), 1); - // Parse length - if (auto element = phene_element.find("length"); element != phene_element.end()) - phene.length = element->get(); + std::uint8_t model_filename_length{0}; + ctx.read8(reinterpret_cast(&model_filename_length), 1); + std::string model_filename(model_filename_length, '\0'); + ctx.read8(reinterpret_cast(model_filename.data()), model_filename_length); - // Parse apical dental count count - if (auto element = phene_element.find("apical_dental_count"); element != phene_element.end()) - phene.apical_dental_count = element->get(); - - // Parse basal dental count count - if (auto element = phene_element.find("basal_dental_count"); element != phene_element.end()) - phene.basal_dental_count = element->get(); + phene.model = resource_manager.load(model_filename); } +} // namespace + template <> std::unique_ptr resource_loader::load(::resource_manager& resource_manager, deserialize_context& ctx) { - // Load JSON data - auto json_data = resource_loader::load(resource_manager, ctx); - - // Validate gene file - auto mandibles_element = json_data->find("mandibles"); - if (mandibles_element == json_data->end()) - throw std::runtime_error("Invalid mandibles gene."); - - // Allocate gene - std::unique_ptr mandibles = std::make_unique(); + std::unique_ptr gene = std::make_unique(); - // Deserialize gene - deserialize_ant_gene(*mandibles, &deserialize_ant_mandibles_phene, *mandibles_element, resource_manager); + load_ant_gene(*gene, resource_manager, ctx, &load_ant_mandibles_phene); - return mandibles; + return gene; } diff --git a/src/game/ant/genes/ant-mandibles-gene.hpp b/src/game/ant/genes/ant-mandibles-gene.hpp index 4c718cc..6d8532b 100644 --- a/src/game/ant/genes/ant-mandibles-gene.hpp +++ b/src/game/ant/genes/ant-mandibles-gene.hpp @@ -20,9 +20,10 @@ #ifndef ANTKEEPER_GAME_ANT_MANDIBLES_GENE_HPP #define ANTKEEPER_GAME_ANT_MANDIBLES_GENE_HPP -#include "game/ant/genes/polyphenic-ant-gene.hpp" +#include "game/ant/genes/ant-gene.hpp" #include #include +#include /** * Ant mandibles phene. @@ -33,20 +34,26 @@ */ struct ant_mandibles_phene { - /// 3D model of the mandibles. - std::shared_ptr model; - /// Mandible length at closure, in mesosomal lengths. - float length; + float length{0.0f}; /// Number of teeth and denticles on the masticatory (apical) margin of the mandible. - int apical_dental_count; + std::uint8_t apical_dental_count{0}; /// Number of teeth and denticles on the basal margin of the mandible. - int basal_dental_count; + std::uint8_t basal_dental_count{0}; + + /// 3D model of the mandibles. + std::shared_ptr model; }; /// Ant mandibles gene. -using ant_mandibles_gene = polyphenic_ant_gene; +using ant_mandibles_gene = ant_gene; + +template <> +inline constexpr ant_gene_type ant_mandibles_gene::type() const noexcept +{ + return ant_gene_type::mandibles; +} #endif // ANTKEEPER_GAME_ANT_MANDIBLES_GENE_HPP diff --git a/src/game/ant/genes/ant-mesosoma-gene.cpp b/src/game/ant/genes/ant-mesosoma-gene.cpp index 73ab8b2..7a98339 100644 --- a/src/game/ant/genes/ant-mesosoma-gene.cpp +++ b/src/game/ant/genes/ant-mesosoma-gene.cpp @@ -17,59 +17,37 @@ * along with Antkeeper source code. If not, see . */ +#include "game/ant/genes/ant-mesosoma-gene.hpp" #include "game/ant/genes/ant-gene-loader.hpp" #include #include -#include -#include "game/ant/genes/ant-mesosoma-gene.hpp" #include -#include -static void deserialize_ant_mesosoma_phene(ant_mesosoma_phene& phene, const json& phene_element, resource_manager& resource_manager) +namespace { + +void load_ant_mesosoma_phene(ant_mesosoma_phene& phene, ::resource_manager& resource_manager, deserialize_context& ctx) { - phene.model = nullptr; - phene.pronotum_width = 0.0f; - phene.pronotum_spinescence = 0.0f; - phene.mesonotum_spinescence = 0.0f; - phene.propodeum_spinescence = 0.0f; - - // Load mesosoma model - if (auto element = phene_element.find("model"); element != phene_element.end()) - phene.model = resource_manager.load(element->get()); - - // Parse pronotum width - if (auto element = phene_element.find("pronotum_width"); element != phene_element.end()) - phene.pronotum_width = element->get(); + ctx.read32(reinterpret_cast(&phene.pronotum_width), 1); + ctx.read32(reinterpret_cast(&phene.pronotum_spinescence), 1); + ctx.read32(reinterpret_cast(&phene.mesonotum_spinescence), 1); + ctx.read32(reinterpret_cast(&phene.propodeum_spinescence), 1); - // Parse pronotum spinescence - if (auto element = phene_element.find("pronotum_spinescence"); element != phene_element.end()) - phene.pronotum_spinescence = element->get(); + std::uint8_t model_filename_length{0}; + ctx.read8(reinterpret_cast(&model_filename_length), 1); + std::string model_filename(model_filename_length, '\0'); + ctx.read8(reinterpret_cast(model_filename.data()), model_filename_length); - // Parse mesonotum spinescence - if (auto element = phene_element.find("mesonotum_spinescence"); element != phene_element.end()) - phene.mesonotum_spinescence = element->get(); - - // Parse propodeum spinescence - if (auto element = phene_element.find("propodeum_spinescence"); element != phene_element.end()) - phene.propodeum_spinescence = element->get(); + phene.model = resource_manager.load(model_filename); } +} // namespace + template <> std::unique_ptr resource_loader::load(::resource_manager& resource_manager, deserialize_context& ctx) { - // Load JSON data - auto json_data = resource_loader::load(resource_manager, ctx); - - // Validate gene file - auto mesosoma_element = json_data->find("mesosoma"); - if (mesosoma_element == json_data->end()) - throw std::runtime_error("Invalid mesosoma gene."); - - // Allocate gene - std::unique_ptr mesosoma = std::make_unique(); + std::unique_ptr gene = std::make_unique(); - // Deserialize gene - deserialize_ant_gene(*mesosoma, &deserialize_ant_mesosoma_phene, *mesosoma_element, resource_manager); + load_ant_gene(*gene, resource_manager, ctx, &load_ant_mesosoma_phene); - return mesosoma; + return gene; } diff --git a/src/game/ant/genes/ant-mesosoma-gene.hpp b/src/game/ant/genes/ant-mesosoma-gene.hpp index 9d81732..e19de33 100644 --- a/src/game/ant/genes/ant-mesosoma-gene.hpp +++ b/src/game/ant/genes/ant-mesosoma-gene.hpp @@ -20,7 +20,7 @@ #ifndef ANTKEEPER_GAME_ANT_MESOSOMA_GENE_HPP #define ANTKEEPER_GAME_ANT_MESOSOMA_GENE_HPP -#include "game/ant/genes/polyphenic-ant-gene.hpp" +#include "game/ant/genes/ant-gene.hpp" #include #include @@ -31,23 +31,29 @@ */ struct ant_mesosoma_phene { - /// 3D model of the mesosoma. - std::shared_ptr model; - /// Pronotum width, in mesosomal lengths. - float pronotum_width; + float pronotum_width{0.0f}; /// Degree of spinescence on the pronotum. - float pronotum_spinescence; + float pronotum_spinescence{0.0f}; /// Degree of spinescence on the mesonotum. - float mesonotum_spinescence; + float mesonotum_spinescence{0.0f}; /// Degree of spinescence on the propodeum. - float propodeum_spinescence; + float propodeum_spinescence{0.0f}; + + /// 3D model of the mesosoma. + std::shared_ptr model; }; /// Ant mesosoma gene. -using ant_mesosoma_gene = polyphenic_ant_gene; +using ant_mesosoma_gene = ant_gene; + +template <> +inline constexpr ant_gene_type ant_mesosoma_gene::type() const noexcept +{ + return ant_gene_type::mesosoma; +} #endif // ANTKEEPER_GAME_ANT_MESOSOMA_GENE_HPP diff --git a/src/game/ant/genes/ant-nest-site-gene.cpp b/src/game/ant/genes/ant-nest-site-gene.cpp index 243421f..12b1490 100644 --- a/src/game/ant/genes/ant-nest-site-gene.cpp +++ b/src/game/ant/genes/ant-nest-site-gene.cpp @@ -17,34 +17,26 @@ * along with Antkeeper source code. If not, see . */ +#include "game/ant/genes/ant-nest-site-gene.hpp" #include "game/ant/genes/ant-gene-loader.hpp" #include #include -#include -#include "game/ant/genes/ant-nest-site-gene.hpp" -#include -static void deserialize_ant_nest_site_phene(ant_nest_site_phene& phene, const json& phene_element, resource_manager& resource_manager) +namespace { + +void load_ant_nest_site_phene(ant_nest_site_phene& phene, ::resource_manager& resource_manager, deserialize_context& ctx) { - + } +} // namespace + template <> std::unique_ptr resource_loader::load(::resource_manager& resource_manager, deserialize_context& ctx) { - // Load JSON data - auto json_data = resource_loader::load(resource_manager, ctx); - - // Validate gene file - auto nest_site_element = json_data->find("nest_site"); - if (nest_site_element == json_data->end()) - throw std::runtime_error("Invalid nest_site gene."); - - // Allocate gene - std::unique_ptr nest_site = std::make_unique(); + std::unique_ptr gene = std::make_unique(); - // Deserialize gene - deserialize_ant_gene(*nest_site, &deserialize_ant_nest_site_phene, *nest_site_element, resource_manager); + load_ant_gene(*gene, resource_manager, ctx, &load_ant_nest_site_phene); - return nest_site; + return gene; } diff --git a/src/game/ant/genes/ant-nest-site-gene.hpp b/src/game/ant/genes/ant-nest-site-gene.hpp index e2b34dc..7e657cc 100644 --- a/src/game/ant/genes/ant-nest-site-gene.hpp +++ b/src/game/ant/genes/ant-nest-site-gene.hpp @@ -20,7 +20,7 @@ #ifndef ANTKEEPER_GAME_ANT_NEST_SITE_GENE_HPP #define ANTKEEPER_GAME_ANT_NEST_SITE_GENE_HPP -#include "game/ant/genes/monophenic-ant-gene.hpp" +#include "game/ant/genes/ant-gene.hpp" #include /** @@ -33,6 +33,12 @@ enum class ant_nest_site_phene: std::uint8_t }; /// Ant nest site gene. -using ant_nest_site_gene = monophenic_ant_gene; +using ant_nest_site_gene = ant_gene; + +template <> +inline constexpr ant_gene_type ant_nest_site_gene::type() const noexcept +{ + return ant_gene_type::nest_site; +} #endif // ANTKEEPER_GAME_ANT_NEST_SITE_GENE_HPP diff --git a/src/game/ant/genes/ant-ocelli-gene.cpp b/src/game/ant/genes/ant-ocelli-gene.cpp index 7eb0328..819aa0d 100644 --- a/src/game/ant/genes/ant-ocelli-gene.cpp +++ b/src/game/ant/genes/ant-ocelli-gene.cpp @@ -17,70 +17,59 @@ * along with Antkeeper source code. If not, see . */ +#include "game/ant/genes/ant-ocelli-gene.hpp" #include "game/ant/genes/ant-gene-loader.hpp" #include #include -#include -#include "game/ant/genes/ant-ocelli-gene.hpp" #include -#include -static void deserialize_ant_ocelli_phene(ant_ocelli_phene& phene, const json& phene_element, resource_manager& resource_manager) +namespace { + +void load_ant_ocelli_phene(ant_ocelli_phene& phene, ::resource_manager& resource_manager, deserialize_context& ctx) { - phene.lateral_ocelli_present = false; - phene.median_ocellus_present = false; - phene.lateral_ocelli_model = nullptr; - phene.median_ocellus_model = nullptr; - phene.width = 0.0f; - phene.height = 0.0f; + std::uint8_t lateral_ocelli_present{0}; + ctx.read8(reinterpret_cast(&lateral_ocelli_present), 1); + phene.lateral_ocelli_present = static_cast(lateral_ocelli_present); - // Parse lateral ocelli present - if (auto element = phene_element.find("lateral_ocelli_present"); element != phene_element.end()) - phene.lateral_ocelli_present = element->get(); + ctx.read32(reinterpret_cast(&phene.lateral_ocelli_width), 1); + ctx.read32(reinterpret_cast(&phene.lateral_ocelli_height), 1); - // Parse median ocelli present - if (auto element = phene_element.find("median_ocellus_present"); element != phene_element.end()) - phene.median_ocellus_present = element->get(); + std::uint8_t lateral_ocelli_model_filename_length{0}; + ctx.read8(reinterpret_cast(&lateral_ocelli_model_filename_length), 1); + std::string lateral_ocelli_model_filename(lateral_ocelli_model_filename_length, '\0'); + ctx.read8(reinterpret_cast(lateral_ocelli_model_filename.data()), lateral_ocelli_model_filename_length); - // Parse width - if (auto element = phene_element.find("width"); element != phene_element.end()) - phene.width = element->get(); - - // Parse height - if (auto element = phene_element.find("height"); element != phene_element.end()) - phene.height = element->get(); - - // Load lateral ocelli model, if present if (phene.lateral_ocelli_present) { - if (auto element = phene_element.find("lateral_ocelli_model"); element != phene_element.end()) - phene.lateral_ocelli_model = resource_manager.load(element->get()); + phene.lateral_ocelli_model = resource_manager.load(lateral_ocelli_model_filename); } - // Load median ocellus model, if present + std::uint8_t median_ocellus_present{0}; + ctx.read8(reinterpret_cast(&median_ocellus_present), 1); + phene.median_ocellus_present = static_cast(median_ocellus_present); + + ctx.read32(reinterpret_cast(&phene.median_ocellus_width), 1); + ctx.read32(reinterpret_cast(&phene.median_ocellus_height), 1); + + std::uint8_t median_ocellus_model_filename_length{0}; + ctx.read8(reinterpret_cast(&median_ocellus_model_filename_length), 1); + std::string median_ocellus_model_filename(median_ocellus_model_filename_length, '\0'); + ctx.read8(reinterpret_cast(median_ocellus_model_filename.data()), median_ocellus_model_filename_length); + if (phene.median_ocellus_present) { - if (auto element = phene_element.find("median_ocellus_model"); element != phene_element.end()) - phene.median_ocellus_model = resource_manager.load(element->get()); + phene.median_ocellus_model = resource_manager.load(median_ocellus_model_filename); } } +} // namespace + template <> std::unique_ptr resource_loader::load(::resource_manager& resource_manager, deserialize_context& ctx) { - // Load JSON data - auto json_data = resource_loader::load(resource_manager, ctx); - - // Validate gene file - auto ocelli_element = json_data->find("ocelli"); - if (ocelli_element == json_data->end()) - throw std::runtime_error("Invalid ocelli gene."); - - // Allocate gene - std::unique_ptr ocelli = std::make_unique(); + std::unique_ptr gene = std::make_unique(); - // Deserialize gene - deserialize_ant_gene(*ocelli, &deserialize_ant_ocelli_phene, *ocelli_element, resource_manager); + load_ant_gene(*gene, resource_manager, ctx, &load_ant_ocelli_phene); - return ocelli; + return gene; } diff --git a/src/game/ant/genes/ant-ocelli-gene.hpp b/src/game/ant/genes/ant-ocelli-gene.hpp index 2a5e01a..3aa9ed7 100644 --- a/src/game/ant/genes/ant-ocelli-gene.hpp +++ b/src/game/ant/genes/ant-ocelli-gene.hpp @@ -20,7 +20,7 @@ #ifndef ANTKEEPER_GAME_ANT_PHENE_OCELLI_GENE_HPP #define ANTKEEPER_GAME_ANT_PHENE_OCELLI_GENE_HPP -#include "game/ant/genes/polyphenic-ant-gene.hpp" +#include "game/ant/genes/ant-gene.hpp" #include #include @@ -29,26 +29,38 @@ */ struct ant_ocelli_phene { - /// 3D model of the lateral ocelli, if present. - std::shared_ptr lateral_ocelli_model; + /// Lateral ocelli present. + bool lateral_ocelli_present{false}; - /// 3D model of the median ocellus, if present. - std::shared_ptr median_ocellus_model; + /// Lateral ocelli width, in mesosomal lengths. + float lateral_ocelli_width{0.0f}; - /// Lateral ocelli present. - bool lateral_ocelli_present; + /// Lateral ocelli height, in mesosomal lengths. + float lateral_ocelli_height{0.0f}; + + /// 3D model of the lateral ocelli, if present. + std::shared_ptr lateral_ocelli_model; /// Median ocellus present. - bool median_ocellus_present; + bool median_ocellus_present{false}; - /// Ocellus width, in mesosomal lengths. - float width; + /// Median ocellus width, in mesosomal lengths. + float median_ocellus_width{0.0f}; - /// Ocellus height, in mesosomal lengths. - float height; + /// Median ocellus height, in mesosomal lengths. + float median_ocellus_height{0.0f}; + + /// 3D model of the median ocellus, if present. + std::shared_ptr median_ocellus_model; }; /// Ant ocelli gene. -using ant_ocelli_gene = polyphenic_ant_gene; +using ant_ocelli_gene = ant_gene; + +template <> +inline constexpr ant_gene_type ant_ocelli_gene::type() const noexcept +{ + return ant_gene_type::ocelli; +} #endif // ANTKEEPER_GAME_ANT_PHENE_OCELLI_GENE_HPP diff --git a/src/game/ant/genes/ant-pigmentation-gene.cpp b/src/game/ant/genes/ant-pigmentation-gene.cpp index d891fad..efab7ef 100644 --- a/src/game/ant/genes/ant-pigmentation-gene.cpp +++ b/src/game/ant/genes/ant-pigmentation-gene.cpp @@ -17,39 +17,32 @@ * along with Antkeeper source code. If not, see . */ +#include "game/ant/genes/ant-pigmentation-gene.hpp" #include "game/ant/genes/ant-gene-loader.hpp" #include #include -#include -#include "game/ant/genes/ant-pigmentation-gene.hpp" #include -#include -static void deserialize_ant_pigmentation_phene(ant_pigmentation_phene& phene, const json& phene_element, resource_manager& resource_manager) +namespace { + +void load_ant_pigmentation_phene(ant_pigmentation_phene& phene, ::resource_manager& resource_manager, deserialize_context& ctx) { - phene.material = nullptr; + std::uint8_t material_filename_length{0}; + ctx.read8(reinterpret_cast(&material_filename_length), 1); + std::string material_filename(material_filename_length, '\0'); + ctx.read8(reinterpret_cast(material_filename.data()), material_filename_length); - // Load pigmentation material - if (auto element = phene_element.find("material"); element != phene_element.end()) - phene.material = resource_manager.load(element->get()); + phene.material = resource_manager.load(material_filename); } +} // namespace + template <> std::unique_ptr resource_loader::load(::resource_manager& resource_manager, deserialize_context& ctx) { - // Load JSON data - auto json_data = resource_loader::load(resource_manager, ctx); - - // Validate gene file - auto pigmentation_element = json_data->find("pigmentation"); - if (pigmentation_element == json_data->end()) - throw std::runtime_error("Invalid pigmentation gene."); - - // Allocate gene - std::unique_ptr pigmentation = std::make_unique(); + std::unique_ptr gene = std::make_unique(); - // Deserialize gene - deserialize_ant_gene(*pigmentation, &deserialize_ant_pigmentation_phene, *pigmentation_element, resource_manager); + load_ant_gene(*gene, resource_manager, ctx, &load_ant_pigmentation_phene); - return pigmentation; + return gene; } diff --git a/src/game/ant/genes/ant-pigmentation-gene.hpp b/src/game/ant/genes/ant-pigmentation-gene.hpp index fc1c17a..0820680 100644 --- a/src/game/ant/genes/ant-pigmentation-gene.hpp +++ b/src/game/ant/genes/ant-pigmentation-gene.hpp @@ -20,7 +20,7 @@ #ifndef ANTKEEPER_GAME_ANT_PIGMENTATION_GENE_HPP #define ANTKEEPER_GAME_ANT_PIGMENTATION_GENE_HPP -#include "game/ant/genes/polyphenic-ant-gene.hpp" +#include "game/ant/genes/ant-gene.hpp" #include #include @@ -34,6 +34,12 @@ struct ant_pigmentation_phene }; /// Ant pigmentation gene. -using ant_pigmentation_gene = polyphenic_ant_gene; +using ant_pigmentation_gene = ant_gene; + +template <> +inline constexpr ant_gene_type ant_pigmentation_gene::type() const noexcept +{ + return ant_gene_type::pigmentation; +} #endif // ANTKEEPER_GAME_ANT_PIGMENTATION_GENE_HPP diff --git a/src/game/ant/genes/ant-pilosity-gene.cpp b/src/game/ant/genes/ant-pilosity-gene.cpp index b65946c..4dc4e36 100644 --- a/src/game/ant/genes/ant-pilosity-gene.cpp +++ b/src/game/ant/genes/ant-pilosity-gene.cpp @@ -17,38 +17,26 @@ * along with Antkeeper source code. If not, see . */ +#include "game/ant/genes/ant-pilosity-gene.hpp" #include "game/ant/genes/ant-gene-loader.hpp" #include #include -#include -#include "game/ant/genes/ant-pilosity-gene.hpp" -#include -static void deserialize_ant_pilosity_phene(ant_pilosity_phene& phene, const json& phene_element, resource_manager& resource_manager) +namespace { + +void load_ant_pilosity_phene(ant_pilosity_phene& phene, ::resource_manager& resource_manager, deserialize_context& ctx) { - phene.density = 0.0f; - - // Parse density - if (auto element = phene_element.find("density"); element != phene_element.end()) - phene.density = element->get(); + ctx.read32(reinterpret_cast(&phene.density), 1); } +} // namespace + template <> std::unique_ptr resource_loader::load(::resource_manager& resource_manager, deserialize_context& ctx) { - // Load JSON data - auto json_data = resource_loader::load(resource_manager, ctx); - - // Validate gene file - auto pilosity_element = json_data->find("pilosity"); - if (pilosity_element == json_data->end()) - throw std::runtime_error("Invalid pilosity gene."); - - // Allocate gene - std::unique_ptr pilosity = std::make_unique(); + std::unique_ptr gene = std::make_unique(); - // Deserialize gene - deserialize_ant_gene(*pilosity, &deserialize_ant_pilosity_phene, *pilosity_element, resource_manager); + load_ant_gene(*gene, resource_manager, ctx, &load_ant_pilosity_phene); - return pilosity; + return gene; } diff --git a/src/game/ant/genes/ant-pilosity-gene.hpp b/src/game/ant/genes/ant-pilosity-gene.hpp index d7618c8..1ac793c 100644 --- a/src/game/ant/genes/ant-pilosity-gene.hpp +++ b/src/game/ant/genes/ant-pilosity-gene.hpp @@ -20,7 +20,7 @@ #ifndef ANTKEEPER_GAME_ANT_PILOSITY_GENE_HPP #define ANTKEEPER_GAME_ANT_PILOSITY_GENE_HPP -#include "game/ant/genes/polyphenic-ant-gene.hpp" +#include "game/ant/genes/ant-gene.hpp" /** * Ant pilosity phene. @@ -28,10 +28,16 @@ struct ant_pilosity_phene { /// Hair density. - float density; + float density{0.0f}; }; /// Ant pilosity gene. -using ant_pilosity_gene = polyphenic_ant_gene; +using ant_pilosity_gene = ant_gene; + +template <> +inline constexpr ant_gene_type ant_pilosity_gene::type() const noexcept +{ + return ant_gene_type::pilosity; +} #endif // ANTKEEPER_GAME_ANT_PILOSITY_GENE_HPP diff --git a/src/game/ant/genes/ant-sculpturing-gene.cpp b/src/game/ant/genes/ant-sculpturing-gene.cpp index 097a4c6..36c5412 100644 --- a/src/game/ant/genes/ant-sculpturing-gene.cpp +++ b/src/game/ant/genes/ant-sculpturing-gene.cpp @@ -17,44 +17,34 @@ * along with Antkeeper source code. If not, see . */ +#include "game/ant/genes/ant-sculpturing-gene.hpp" #include "game/ant/genes/ant-gene-loader.hpp" #include #include -#include -#include "game/ant/genes/ant-sculpturing-gene.hpp" #include -#include -static void deserialize_ant_sculpturing_phene(ant_sculpturing_phene& phene, const json& phene_element, resource_manager& resource_manager) +namespace { + +void load_ant_sculpturing_phene(ant_sculpturing_phene& phene, ::resource_manager& resource_manager, deserialize_context& ctx) { - phene.normal_map = nullptr; - phene.roughness = 0.0f; + ctx.read32(reinterpret_cast(&phene.roughness), 1); - // Load normal map - if (auto element = phene_element.find("normal_map"); element != phene_element.end()) - phene.normal_map = resource_manager.load(element->get()); + std::uint8_t normal_map_filename_length{0}; + ctx.read8(reinterpret_cast(&normal_map_filename_length), 1); + std::string normal_map_filename(normal_map_filename_length, '\0'); + ctx.read8(reinterpret_cast(normal_map_filename.data()), normal_map_filename_length); - // Parse roughness - if (auto element = phene_element.find("roughness"); element != phene_element.end()) - phene.roughness = element->get(); + phene.normal_map = resource_manager.load(normal_map_filename); } +} // namespace + template <> std::unique_ptr resource_loader::load(::resource_manager& resource_manager, deserialize_context& ctx) { - // Load JSON data - auto json_data = resource_loader::load(resource_manager, ctx); - - // Validate gene file - auto sculpturing_element = json_data->find("sculpturing"); - if (sculpturing_element == json_data->end()) - throw std::runtime_error("Invalid sculpturing gene."); - - // Allocate gene - std::unique_ptr sculpturing = std::make_unique(); + std::unique_ptr gene = std::make_unique(); - // Deserialize gene - deserialize_ant_gene(*sculpturing, &deserialize_ant_sculpturing_phene, *sculpturing_element, resource_manager); + load_ant_gene(*gene, resource_manager, ctx, &load_ant_sculpturing_phene); - return sculpturing; + return gene; } diff --git a/src/game/ant/genes/ant-sculpturing-gene.hpp b/src/game/ant/genes/ant-sculpturing-gene.hpp index 25132b3..9a71dd4 100644 --- a/src/game/ant/genes/ant-sculpturing-gene.hpp +++ b/src/game/ant/genes/ant-sculpturing-gene.hpp @@ -20,7 +20,7 @@ #ifndef ANTKEEPER_GAME_ANT_SCULPTURING_GENE_HPP #define ANTKEEPER_GAME_ANT_SCULPTURING_GENE_HPP -#include "game/ant/genes/polyphenic-ant-gene.hpp" +#include "game/ant/genes/ant-gene.hpp" #include #include @@ -30,13 +30,19 @@ struct ant_sculpturing_phene { /// Surface roughness. - float roughness; + float roughness{0.0f}; /// Surface culpturing normal map. std::shared_ptr normal_map; }; -/// Polyphenic sculpturing gene. -using ant_sculpturing_gene = polyphenic_ant_gene; +/// Ant sculpturing gene. +using ant_sculpturing_gene = ant_gene; + +template <> +inline constexpr ant_gene_type ant_sculpturing_gene::type() const noexcept +{ + return ant_gene_type::sculpturing; +} #endif // ANTKEEPER_GAME_ANT_SCULPTURING_GENE_HPP diff --git a/src/game/ant/genes/ant-sting-gene.cpp b/src/game/ant/genes/ant-sting-gene.cpp index cbbcf75..d2e840e 100644 --- a/src/game/ant/genes/ant-sting-gene.cpp +++ b/src/game/ant/genes/ant-sting-gene.cpp @@ -17,47 +17,39 @@ * along with Antkeeper source code. If not, see . */ +#include "game/ant/genes/ant-sting-gene.hpp" #include "game/ant/genes/ant-gene-loader.hpp" #include #include -#include -#include "game/ant/genes/ant-sting-gene.hpp" #include -#include -static void deserialize_ant_sting_phene(ant_sting_phene& phene, const json& phene_element, resource_manager& resource_manager) +namespace { + +void load_ant_sting_phene(ant_sting_phene& phene, ::resource_manager& resource_manager, deserialize_context& ctx) { - phene.present = false; - phene.model = nullptr; + std::uint8_t present{0}; + ctx.read8(reinterpret_cast(&present), 1); + phene.present = static_cast(present); - // Parse present - if (auto element = phene_element.find("present"); element != phene_element.end()) - phene.present = element->get(); + std::uint8_t model_filename_length{0}; + ctx.read8(reinterpret_cast(&model_filename_length), 1); + std::string model_filename(model_filename_length, '\0'); + ctx.read8(reinterpret_cast(model_filename.data()), model_filename_length); if (phene.present) { - // Load sting model - if (auto element = phene_element.find("model"); element != phene_element.end()) - phene.model = resource_manager.load(element->get()); + phene.model = resource_manager.load(model_filename); } } +} // namespace + template <> std::unique_ptr resource_loader::load(::resource_manager& resource_manager, deserialize_context& ctx) { - // Load JSON data - auto json_data = resource_loader::load(resource_manager, ctx); - - // Validate gene file - auto sting_element = json_data->find("sting"); - if (sting_element == json_data->end()) - throw std::runtime_error("Invalid sting gene."); - - // Allocate gene - std::unique_ptr sting = std::make_unique(); + std::unique_ptr gene = std::make_unique(); - // Deserialize gene - deserialize_ant_gene(*sting, &deserialize_ant_sting_phene, *sting_element, resource_manager); + load_ant_gene(*gene, resource_manager, ctx, &load_ant_sting_phene); - return sting; + return gene; } diff --git a/src/game/ant/genes/ant-sting-gene.hpp b/src/game/ant/genes/ant-sting-gene.hpp index f533e9f..6fb5529 100644 --- a/src/game/ant/genes/ant-sting-gene.hpp +++ b/src/game/ant/genes/ant-sting-gene.hpp @@ -20,7 +20,7 @@ #ifndef ANTKEEPER_GAME_ANT_STING_GENE_HPP #define ANTKEEPER_GAME_ANT_STING_GENE_HPP -#include "game/ant/genes/polyphenic-ant-gene.hpp" +#include "game/ant/genes/ant-gene.hpp" #include #include @@ -30,13 +30,19 @@ struct ant_sting_phene { /// Indicates whether a sting present or not. - bool present; + bool present{false}; /// 3D model of the sting. std::shared_ptr model; }; -/// Polyphenic sting gene. -using ant_sting_gene = polyphenic_ant_gene; +/// Ant sting gene. +using ant_sting_gene = ant_gene; + +template <> +inline constexpr ant_gene_type ant_sting_gene::type() const noexcept +{ + return ant_gene_type::sting; +} #endif // ANTKEEPER_GAME_ANT_STING_GENE_HPP diff --git a/src/game/ant/genes/ant-waist-gene.cpp b/src/game/ant/genes/ant-waist-gene.cpp index 959f8de..e4066aa 100644 --- a/src/game/ant/genes/ant-waist-gene.cpp +++ b/src/game/ant/genes/ant-waist-gene.cpp @@ -17,95 +17,50 @@ * along with Antkeeper source code. If not, see . */ +#include "game/ant/genes/ant-waist-gene.hpp" #include "game/ant/genes/ant-gene-loader.hpp" #include #include -#include -#include "game/ant/genes/ant-waist-gene.hpp" #include -#include -static void deserialize_ant_waist_phene(ant_waist_phene& phene, const json& phene_element, resource_manager& resource_manager) +namespace { + +void load_ant_waist_phene(ant_waist_phene& phene, ::resource_manager& resource_manager, deserialize_context& ctx) { - phene.model = nullptr; - phene.petiole_present = false; - phene.petiole_length = 0.0f; - phene.petiole_width = 0.0f; - phene.petiole_height = 0.0f; - phene.petiole_spinescence = 0.0f; - phene.postpetiole_present = false; - phene.postpetiole_length = 0.0f; - phene.postpetiole_width = 0.0f; - phene.postpetiole_height = 0.0f; - phene.postpetiole_spinescence = 0.0f; + std::uint8_t petiole_present{0}; + ctx.read8(reinterpret_cast(&petiole_present), 1); + phene.petiole_present = static_cast(petiole_present); - // Load waist model - if (auto element = phene_element.find("model"); element != phene_element.end()) - phene.model = resource_manager.load(element->get()); + ctx.read32(reinterpret_cast(&phene.petiole_length), 1); + ctx.read32(reinterpret_cast(&phene.petiole_width), 1); + ctx.read32(reinterpret_cast(&phene.petiole_height), 1); + ctx.read32(reinterpret_cast(&phene.petiole_spinescence), 1); - // Parse petiole present - if (auto element = phene_element.find("petiole_present"); element != phene_element.end()) - phene.petiole_present = element->get(); + std::uint8_t postpetiole_present{0}; + ctx.read8(reinterpret_cast(&postpetiole_present), 1); + phene.postpetiole_present = static_cast(postpetiole_present); - // Parse postpetiole present - if (auto element = phene_element.find("postpetiole_present"); element != phene_element.end()) - phene.postpetiole_present = element->get(); + ctx.read32(reinterpret_cast(&phene.postpetiole_length), 1); + ctx.read32(reinterpret_cast(&phene.postpetiole_width), 1); + ctx.read32(reinterpret_cast(&phene.postpetiole_height), 1); + ctx.read32(reinterpret_cast(&phene.postpetiole_spinescence), 1); - if (phene.petiole_present) - { - // Parse petiole length - if (auto element = phene_element.find("petiole_length"); element != phene_element.end()) - phene.petiole_length = element->get(); - - // Parse petiole width - if (auto element = phene_element.find("petiole_width"); element != phene_element.end()) - phene.petiole_width = element->get(); - - // Parse petiole height - if (auto element = phene_element.find("petiole_height"); element != phene_element.end()) - phene.petiole_height = element->get(); - - // Parse petiole spinescence - if (auto element = phene_element.find("petiole_spinescence"); element != phene_element.end()) - phene.petiole_spinescence = element->get(); - } + std::uint8_t model_filename_length{0}; + ctx.read8(reinterpret_cast(&model_filename_length), 1); + std::string model_filename(model_filename_length, '\0'); + ctx.read8(reinterpret_cast(model_filename.data()), model_filename_length); - if (phene.postpetiole_present) - { - // Parse postpetiole length - if (auto element = phene_element.find("postpetiole_length"); element != phene_element.end()) - phene.postpetiole_length = element->get(); - - // Parse postpetiole width - if (auto element = phene_element.find("postpetiole_width"); element != phene_element.end()) - phene.postpetiole_width = element->get(); - - // Parse postpetiole height - if (auto element = phene_element.find("postpetiole_height"); element != phene_element.end()) - phene.postpetiole_height = element->get(); - - // Parse postpetiole spinescence - if (auto element = phene_element.find("postpetiole_spinescence"); element != phene_element.end()) - phene.postpetiole_spinescence = element->get(); - } + phene.model = resource_manager.load(model_filename); } +} // namespace + template <> std::unique_ptr resource_loader::load(::resource_manager& resource_manager, deserialize_context& ctx) { - // Load JSON data - auto json_data = resource_loader::load(resource_manager, ctx); - - // Validate gene file - auto waist_element = json_data->find("waist"); - if (waist_element == json_data->end()) - throw std::runtime_error("Invalid waist gene."); - - // Allocate gene - std::unique_ptr waist = std::make_unique(); + std::unique_ptr gene = std::make_unique(); - // Deserialize gene - deserialize_ant_gene(*waist, &deserialize_ant_waist_phene, *waist_element, resource_manager); + load_ant_gene(*gene, resource_manager, ctx, &load_ant_waist_phene); - return waist; + return gene; } diff --git a/src/game/ant/genes/ant-waist-gene.hpp b/src/game/ant/genes/ant-waist-gene.hpp index 648cb71..be26a36 100644 --- a/src/game/ant/genes/ant-waist-gene.hpp +++ b/src/game/ant/genes/ant-waist-gene.hpp @@ -20,7 +20,7 @@ #ifndef ANTKEEPER_GAME_ANT_WAIST_GENE_HPP #define ANTKEEPER_GAME_ANT_WAIST_GENE_HPP -#include "game/ant/genes/polyphenic-ant-gene.hpp" +#include "game/ant/genes/ant-gene.hpp" #include #include @@ -31,41 +31,47 @@ */ struct ant_waist_phene { - /// 3D model of the waist. - std::shared_ptr model; - //// Petiole presence. - bool petiole_present; + bool petiole_present{false}; /// Petiole length, in mesosomal lengths. - float petiole_length; + float petiole_length{0.0f}; /// Petiole width, in mesosomal lengths. - float petiole_width; + float petiole_width{0.0f}; /// Petiole height, in mesosomal lengths. - float petiole_height; + float petiole_height{0.0f}; /// Degree of petiole spinescence. - float petiole_spinescence; + float petiole_spinescence{0.0f}; /// Postpetiole presence. - bool postpetiole_present; + bool postpetiole_present{false}; /// Postpetiole length, in mesosomal lengths. - float postpetiole_length; + float postpetiole_length{0.0f}; /// Postpetiole width, in mesosomal lengths. - float postpetiole_width; + float postpetiole_width{0.0f}; /// Postpetiole height, in mesosomal lengths. - float postpetiole_height; + float postpetiole_height{0.0f}; /// Degree of postpetiole spinescence - float postpetiole_spinescence; + float postpetiole_spinescence{0.0f}; + + /// 3D model of the waist. + std::shared_ptr model; }; -/// Polyphenic waist gene. -using ant_waist_gene = polyphenic_ant_gene; +/// Ant waist gene. +using ant_waist_gene = ant_gene; + +template <> +inline constexpr ant_gene_type ant_waist_gene::type() const noexcept +{ + return ant_gene_type::waist; +} #endif // ANTKEEPER_GAME_ANT_WAIST_GENE_HPP diff --git a/src/game/ant/genes/ant-wings-gene.cpp b/src/game/ant/genes/ant-wings-gene.cpp index 195c4e6..2c3f622 100644 --- a/src/game/ant/genes/ant-wings-gene.cpp +++ b/src/game/ant/genes/ant-wings-gene.cpp @@ -17,82 +17,57 @@ * along with Antkeeper source code. If not, see . */ +#include "game/ant/genes/ant-wings-gene.hpp" #include "game/ant/genes/ant-gene-loader.hpp" #include #include -#include -#include "game/ant/genes/ant-wings-gene.hpp" #include -#include -static void deserialize_ant_wings_phene(ant_wings_phene& phene, const json& phene_element, resource_manager& resource_manager) +namespace { + +void load_ant_wings_phene(ant_wings_phene& phene, ::resource_manager& resource_manager, deserialize_context& ctx) { - phene.present = false; - phene.forewings_model = nullptr; - phene.hindwings_model = nullptr; - phene.forewing_length = 0.0f; - phene.forewing_width = 0.0f; - phene.forewing_venation = 0.0f; - phene.hindwing_length = 0.0f; - phene.hindwing_width = 0.0f; - phene.hindwing_venation = 0.0f; + std::uint8_t present{0}; + ctx.read8(reinterpret_cast(&present), 1); + phene.present = static_cast(present); + + ctx.read32(reinterpret_cast(&phene.forewing_length), 1); + ctx.read32(reinterpret_cast(&phene.forewing_width), 1); + ctx.read32(reinterpret_cast(&phene.forewing_venation), 1); - // Parse present - if (auto element = phene_element.find("present"); element != phene_element.end()) - phene.present = element->get(); + std::uint8_t forewings_model_filename_length{0}; + ctx.read8(reinterpret_cast(&forewings_model_filename_length), 1); + std::string forewings_model_filename(forewings_model_filename_length, '\0'); + ctx.read8(reinterpret_cast(forewings_model_filename.data()), forewings_model_filename_length); if (phene.present) { - // Load forewings model - if (auto element = phene_element.find("forewings_model"); element != phene_element.end()) - phene.forewings_model = resource_manager.load(element->get()); - - // Load hindwings model - if (auto element = phene_element.find("hindwings_model"); element != phene_element.end()) - phene.hindwings_model = resource_manager.load(element->get()); - - // Parse forewing length - if (auto element = phene_element.find("forewing_length"); element != phene_element.end()) - phene.forewing_length = element->get(); - - // Parse forewing width - if (auto element = phene_element.find("forewing_width"); element != phene_element.end()) - phene.forewing_width = element->get(); - - // Parse forewing venation - if (auto element = phene_element.find("forewing_venation"); element != phene_element.end()) - phene.forewing_venation = element->get(); - - // Parse hindwing length - if (auto element = phene_element.find("hindwing_length"); element != phene_element.end()) - phene.hindwing_length = element->get(); - - // Parse hindwing width - if (auto element = phene_element.find("hindwing_width"); element != phene_element.end()) - phene.hindwing_width = element->get(); - - // Parse hindwing venation - if (auto element = phene_element.find("hindwing_venation"); element != phene_element.end()) - phene.hindwing_venation = element->get(); + phene.forewings_model = resource_manager.load(forewings_model_filename); + } + + ctx.read32(reinterpret_cast(&phene.hindwing_length), 1); + ctx.read32(reinterpret_cast(&phene.hindwing_width), 1); + ctx.read32(reinterpret_cast(&phene.hindwing_venation), 1); + + std::uint8_t hindwings_model_filename_length{0}; + ctx.read8(reinterpret_cast(&hindwings_model_filename_length), 1); + std::string hindwings_model_filename(hindwings_model_filename_length, '\0'); + ctx.read8(reinterpret_cast(hindwings_model_filename.data()), hindwings_model_filename_length); + + if (phene.present) + { + phene.hindwings_model = resource_manager.load(hindwings_model_filename); } } +} // namespace + template <> std::unique_ptr resource_loader::load(::resource_manager& resource_manager, deserialize_context& ctx) { - // Load JSON data - auto json_data = resource_loader::load(resource_manager, ctx); - - // Validate gene file - auto wings_element = json_data->find("wings"); - if (wings_element == json_data->end()) - throw std::runtime_error("Invalid wings gene."); - - // Allocate gene - std::unique_ptr wings = std::make_unique(); + std::unique_ptr gene = std::make_unique(); - // Deserialize gene - deserialize_ant_gene(*wings, &deserialize_ant_wings_phene, *wings_element, resource_manager); + load_ant_gene(*gene, resource_manager, ctx, &load_ant_wings_phene); - return wings; + return gene; } diff --git a/src/game/ant/genes/ant-wings-gene.hpp b/src/game/ant/genes/ant-wings-gene.hpp index d4c3688..c979493 100644 --- a/src/game/ant/genes/ant-wings-gene.hpp +++ b/src/game/ant/genes/ant-wings-gene.hpp @@ -20,7 +20,7 @@ #ifndef ANTKEEPER_GAME_ANT_WINGS_GENE_HPP #define ANTKEEPER_GAME_ANT_WINGS_GENE_HPP -#include "game/ant/genes/polyphenic-ant-gene.hpp" +#include "game/ant/genes/ant-gene.hpp" #include #include @@ -29,35 +29,41 @@ */ struct ant_wings_phene { - /// 3D model of the forewings. - std::shared_ptr forewings_model; - - /// 3D model of the hindwings. - std::shared_ptr hindwings_model; - /// Wings presence. - bool present; + bool present{false}; /// Forewing length, in mesosomal lengths. - float forewing_length; + float forewing_length{0.0f}; /// Forewing width, in mesosomal lengths. - float forewing_width; + float forewing_width{0.0f}; /// Degree of forewing venation. A value of `1.0` indicates a highly-developed venation pattern, while `0.0` indicates a complete absence of visible venation. - float forewing_venation; + float forewing_venation{0.0f}; - /// Forewing length, in mesosomal lengths. - float hindwing_length; + /// 3D model of the forewings. + std::shared_ptr forewings_model; - /// Forewing width, in mesosomal lengths. - float hindwing_width; + /// Hindwing length, in mesosomal lengths. + float hindwing_length{0.0f}; + + /// Hindwing width, in mesosomal lengths. + float hindwing_width{0.0f}; /// Degree of hindwing venation. A value of `1.0` indicates a highly-developed venation pattern, while `0.0` indicates a complete absence of visible venation. - float hindwing_venation; + float hindwing_venation{0.0f}; + + /// 3D model of the hindwings. + std::shared_ptr hindwings_model; }; -/// Polyphenic wings gene. -using ant_wings_gene = polyphenic_ant_gene; +/// Ant wings gene. +using ant_wings_gene = ant_gene; + +template <> +inline constexpr ant_gene_type ant_wings_gene::type() const noexcept +{ + return ant_gene_type::wings; +} #endif // ANTKEEPER_GAME_ANT_WINGS_GENE_HPP diff --git a/src/game/components/ant-caste-component.hpp b/src/game/components/ant-caste-component.hpp index 8d8e59c..05fd88c 100644 --- a/src/game/components/ant-caste-component.hpp +++ b/src/game/components/ant-caste-component.hpp @@ -20,12 +20,12 @@ #ifndef ANTKEEPER_GAME_ANT_CASTE_COMPONENT_HPP #define ANTKEEPER_GAME_ANT_CASTE_COMPONENT_HPP -#include "game/ant/ant-caste.hpp" +#include "game/ant/ant-caste-type.hpp" struct ant_caste_component { /// Caste type. - ant_caste type; + ant_caste_type caste_type; /// Subcaste type. //ant_subcaste subtype; diff --git a/src/game/game.hpp b/src/game/game.hpp index 8441e3f..08cce7a 100644 --- a/src/game/game.hpp +++ b/src/game/game.hpp @@ -358,7 +358,7 @@ public: double3 rgb_wavelengths; - const ecoregion* active_ecoregion; + std::shared_ptr active_ecoregion; render::anti_aliasing_method anti_aliasing_method; diff --git a/src/game/spawn.cpp b/src/game/spawn.cpp index 5cacdec..e056d91 100644 --- a/src/game/spawn.cpp +++ b/src/game/spawn.cpp @@ -37,7 +37,7 @@ entity::id spawn_ant_egg(::game& ctx, const ant_genome& genome, bool fertilized, // Construct model component model_component model_component; - model_component.render_model = genome.egg->phene.model; + model_component.render_model = genome.egg->phenes.front().model; model_component.instance_count = 0; model_component.layers = ~0; ctx.entity_registry->emplace<::model_component>(egg_eid, model_component); @@ -60,7 +60,7 @@ entity::id spawn_ant_larva(::game& ctx, const ant_genome& genome, const float3& // Construct model component model_component model_component; - model_component.render_model = genome.larva->phene.model; + model_component.render_model = genome.larva->phenes.front().model; model_component.instance_count = 0; model_component.layers = ~0; ctx.entity_registry->emplace<::model_component>(larva_eid, model_component); diff --git a/src/game/states/main-menu-state.cpp b/src/game/states/main-menu-state.cpp index 7111da7..361689d 100644 --- a/src/game/states/main-menu-state.cpp +++ b/src/game/states/main-menu-state.cpp @@ -131,9 +131,9 @@ main_menu_state::main_menu_state(::game& ctx, bool fade_in): [&ctx]() { ctx.state_machine.pop(); - ctx.state_machine.emplace(std::make_unique(ctx)); + //ctx.state_machine.emplace(std::make_unique(ctx)); //ctx.state_machine.emplace(std::make_unique(ctx)); - //ctx.state_machine.emplace(std::make_unique(ctx)); + ctx.state_machine.emplace(std::make_unique(ctx)); } ); }; diff --git a/src/game/states/nest-selection-state.cpp b/src/game/states/nest-selection-state.cpp index 54bb701..6aff80b 100644 --- a/src/game/states/nest-selection-state.cpp +++ b/src/game/states/nest-selection-state.cpp @@ -79,7 +79,9 @@ nest_selection_state::nest_selection_state(::game& ctx): // Create observer ::world::create_observer(ctx); } - ::world::enter_ecoregion(ctx, *ctx.resource_manager->load<::ecoregion>("seedy-scrub.eco")); + + ctx.active_ecoregion = ctx.resource_manager->load<::ecoregion>("seedy-scrub.eco"); + ::world::enter_ecoregion(ctx, *ctx.active_ecoregion); debug::log::trace("Generating genome..."); std::random_device rng; @@ -87,7 +89,7 @@ nest_selection_state::nest_selection_state(::game& ctx): debug::log::trace("Generated genome"); debug::log::trace("Building worker phenome..."); - ant_phenome worker_phenome = ant_phenome(*genome, ant_caste::worker); + ant_phenome worker_phenome = ant_phenome(*genome, ant_caste_type::worker); debug::log::trace("Built worker phenome..."); debug::log::trace("Generating worker model..."); @@ -98,7 +100,7 @@ nest_selection_state::nest_selection_state(::game& ctx): entity::id worker_eid = ctx.entity_registry->create(); transform_component worker_transform_component; worker_transform_component.local = math::transform::identity; - worker_transform_component.local.translation = {0, 0, -20}; + worker_transform_component.local.translation = {0, 0, -4}; worker_transform_component.world = worker_transform_component.local; worker_transform_component.warp = true; ctx.entity_registry->emplace(worker_eid, worker_transform_component); diff --git a/src/game/states/nuptial-flight-state.cpp b/src/game/states/nuptial-flight-state.cpp index e0805a9..1c716c1 100644 --- a/src/game/states/nuptial-flight-state.cpp +++ b/src/game/states/nuptial-flight-state.cpp @@ -121,7 +121,7 @@ nuptial_flight_state::nuptial_flight_state(::game& ctx): ( [&](entity::id entity_id, const auto& caste) { - if (caste.type == ant_caste::male) + if (caste.caste_type == ant_caste_type::male) { ctx.entity_registry->emplace_or_replace ( @@ -971,21 +971,21 @@ void nuptial_flight_state::select_entity(entity::id entity_id) const auto& name = ctx.entity_registry->get<::name_component>(selected_eid).name; std::string format_string; - switch (caste.type) + switch (caste.caste_type) { - case ::ant_caste::queen: + case ::ant_caste_type::queen: format_string = ::get_string(ctx, "named_queen_label_format"); break; - case ::ant_caste::worker: + case ::ant_caste_type::worker: format_string = ::get_string(ctx, "named_worker_label_format"); break; - case ::ant_caste::soldier: + case ::ant_caste_type::soldier: format_string = ::get_string(ctx, "named_soldier_label_format"); break; - case ::ant_caste::male: + case ::ant_caste_type::male: format_string = ::get_string(ctx, "named_male_label_format"); break; @@ -998,21 +998,21 @@ void nuptial_flight_state::select_entity(entity::id entity_id) } else { - switch (caste.type) + switch (caste.caste_type) { - case ::ant_caste::queen: + case ::ant_caste_type::queen: selection_text.set_content(get_string(ctx, "queen_caste_name")); break; - case ::ant_caste::worker: + case ::ant_caste_type::worker: selection_text.set_content(get_string(ctx, "worker_caste_name")); break; - case ::ant_caste::soldier: + case ::ant_caste_type::soldier: selection_text.set_content(get_string(ctx, "soldier_caste_name")); break; - case ::ant_caste::male: + case ::ant_caste_type::male: selection_text.set_content(get_string(ctx, "male_caste_name")); break; diff --git a/src/game/world.cpp b/src/game/world.cpp index f61fbb4..fffad26 100644 --- a/src/game/world.cpp +++ b/src/game/world.cpp @@ -524,7 +524,7 @@ void enter_ecoregion(::game& ctx, const ecoregion& ecoregion) debug::log::trace("Entering ecoregion {}...", ecoregion.name); { // Set active ecoregion - ctx.active_ecoregion = &ecoregion; + //ctx.active_ecoregion = &ecoregion; // Set location ::world::set_location(ctx, ecoregion.elevation, ecoregion.latitude, ecoregion.longitude);