diff options
4 files changed, 122 insertions, 0 deletions
diff --git a/extension/src/openvic-extension/singletons/ModelSingleton.cpp b/extension/src/openvic-extension/singletons/ModelSingleton.cpp index 349d336..88a69c9 100644 --- a/extension/src/openvic-extension/singletons/ModelSingleton.cpp +++ b/extension/src/openvic-extension/singletons/ModelSingleton.cpp @@ -20,6 +20,7 @@ void ModelSingleton::_bind_methods() { OV_BIND_METHOD(ModelSingleton::get_cultural_gun_model, { "culture" }); OV_BIND_METHOD(ModelSingleton::get_cultural_helmet_model, { "culture" }); OV_BIND_METHOD(ModelSingleton::get_flag_model, { "floating" }); + OV_BIND_METHOD(ModelSingleton::get_buildings); } ModelSingleton* ModelSingleton::get_singleton() { @@ -360,3 +361,98 @@ Dictionary ModelSingleton::get_flag_model(bool floating) const { return make_model_dict(*actor); } + +bool ModelSingleton::add_building_dict( + BuildingInstance const& building, Province const& province, TypedArray<Dictionary>& building_array +) const { + GameSingleton const* game_singleton = GameSingleton::get_singleton(); + ERR_FAIL_NULL_V(game_singleton, false); + + static const StringName model_key = "model"; + static const StringName position_key = "position"; + static const StringName rotation_key = "rotation"; + + std::string suffix; + + if ( + &building.get_building_type() == + game_singleton->get_game_manager().get_economy_manager().get_building_type_manager().get_port_building_type() + ) { + /* Port */ + if (!province.has_port()) { + return true; + } + + if (building.get_level() > 0) { + suffix = std::to_string(building.get_level()); + } + + if (!province.get_navies().empty()) { + suffix += "_ships"; + } + } else if (building.get_identifier() == "fort") { + /* Fort */ + if (building.get_level() < 1) { + return true; + } + + if (building.get_level() > 1) { + suffix = std::to_string(building.get_level()); + } + } else { + // TODO - railroad (trainstations) + return true; + } + + fvec2_t const* position_ptr = province.get_building_position(&building.get_building_type()); + const float rotation = province.get_building_rotation(&building.get_building_type()); + + const std::string actor_name = StringUtils::append_string_views("building_", building.get_identifier(), suffix); + + GFX::Actor const* actor = get_actor(actor_name); + ERR_FAIL_NULL_V_MSG( + actor, false, vformat( + "Failed to find \"%s\" actor for building \"%s\" in province \"%s\"", + std_to_godot_string(actor_name), std_view_to_godot_string(building.get_identifier()), + std_view_to_godot_string(province.get_identifier()) + ) + ); + + Dictionary dict; + + dict[model_key] = make_model_dict(*actor); + + dict[position_key] = + game_singleton->map_position_to_world_coords(position_ptr != nullptr ? *position_ptr : province.get_centre()); + + if (rotation != 0.0f) { + dict[rotation_key] = rotation; + } + + // TODO - move dict into unit_array ? + building_array.push_back(dict); + + return true; +} + +TypedArray<Dictionary> ModelSingleton::get_buildings() const { + GameSingleton const* game_singleton = GameSingleton::get_singleton(); + ERR_FAIL_NULL_V(game_singleton, {}); + + TypedArray<Dictionary> ret; + + for (Province const& province : game_singleton->get_game_manager().get_map().get_provinces()) { + if (!province.is_water()) { + for (BuildingInstance const& building : province.get_buildings()) { + if (!add_building_dict(building, province, ret)) { + UtilityFunctions::push_error( + "Error adding building \"", std_view_to_godot_string(building.get_identifier()), "\" to province \"", + std_view_to_godot_string(province.get_identifier()), "\"" + ); + } + } + } + } + + return ret; +} diff --git a/extension/src/openvic-extension/singletons/ModelSingleton.hpp b/extension/src/openvic-extension/singletons/ModelSingleton.hpp index 9ec163e..17c2dd0 100644 --- a/extension/src/openvic-extension/singletons/ModelSingleton.hpp +++ b/extension/src/openvic-extension/singletons/ModelSingleton.hpp @@ -32,11 +32,17 @@ namespace OpenVic { template<utility::is_derived_from_specialization_of<UnitInstanceGroup> T> bool add_unit_dict(ordered_set<T*> const& units, godot::TypedArray<godot::Dictionary>& unit_array) const; + bool add_building_dict( + BuildingInstance const& building, Province const& province, godot::TypedArray<godot::Dictionary>& building_array + ) const; + public: godot::TypedArray<godot::Dictionary> get_units() const; godot::Dictionary get_cultural_gun_model(godot::String const& culture) const; godot::Dictionary get_cultural_helmet_model(godot::String const& culture) const; godot::Dictionary get_flag_model(bool floating) const; + + godot::TypedArray<godot::Dictionary> get_buildings() const; }; } diff --git a/game/src/Game/GameSession/GameSession.gd b/game/src/Game/GameSession/GameSession.gd index a07ce32..843ecd8 100644 --- a/game/src/Game/GameSession/GameSession.gd +++ b/game/src/Game/GameSession/GameSession.gd @@ -9,6 +9,7 @@ func _ready() -> void: push_error("Failed to setup game") _model_manager.generate_units() + _model_manager.generate_buildings() func _process(_delta : float) -> void: GameSingleton.try_tick() diff --git a/game/src/Game/GameSession/ModelManager.gd b/game/src/Game/GameSession/ModelManager.gd index 17d2c1e..8cec49d 100644 --- a/game/src/Game/GameSession/ModelManager.gd +++ b/game/src/Game/GameSession/ModelManager.gd @@ -61,6 +61,25 @@ func _generate_unit(unit_dict : Dictionary) -> void: add_child(model) +func generate_buildings() -> void: + for building : Dictionary in ModelSingleton.get_buildings(): + _generate_building(building) + +func _generate_building(building_dict : Dictionary) -> void: + const model_key : StringName = &"model" + const position_key : StringName = &"position" + const rotation_key : StringName = &"rotation" + + var model : Node3D = _generate_model(building_dict[model_key]) + if not model: + return + + model.scale *= MODEL_SCALE + model.rotate_y(PI + building_dict.get(rotation_key, 0.0)) + model.set_position(_map_view._map_to_world_coords(building_dict[position_key]) + Vector3(0, 0.1 * MODEL_SCALE, 0)) + + add_child(model) + func _generate_model(model_dict : Dictionary, culture : String = "", is_unit : bool = false) -> Node3D: const file_key : StringName = &"file" const scale_key : StringName = &"scale" |