aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--extension/src/openvic-extension/singletons/ModelSingleton.cpp96
-rw-r--r--extension/src/openvic-extension/singletons/ModelSingleton.hpp6
-rw-r--r--game/src/Game/GameSession/GameSession.gd1
-rw-r--r--game/src/Game/GameSession/ModelManager.gd19
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"