Skip to content

Commit

Permalink
Merge pull request #322 from OpenVicProject/billboard-scale-fix
Browse files Browse the repository at this point in the history
Fix province icon scaling
  • Loading branch information
Hop311 authored Dec 12, 2024
2 parents d663d8e + 9f3791b commit aa26315
Show file tree
Hide file tree
Showing 6 changed files with 241 additions and 197 deletions.
10 changes: 5 additions & 5 deletions extension/doc_classes/MapItemSingleton.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,6 @@
<description>
</description>
</method>
<method name="get_capital_count" qualifiers="const">
<return type="int" />
<description>
</description>
</method>
<method name="get_capital_positions" qualifiers="const">
<return type="PackedVector2Array" />
<description>
Expand All @@ -27,6 +22,11 @@
<description>
</description>
</method>
<method name="get_max_capital_count" qualifiers="const">
<return type="int" />
<description>
</description>
</method>
<method name="get_national_focus_icons" qualifiers="const">
<return type="PackedByteArray" />
<description>
Expand Down
145 changes: 85 additions & 60 deletions extension/src/openvic-extension/singletons/MapItemSingleton.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ using namespace OpenVic;
void MapItemSingleton::_bind_methods() {
OV_BIND_METHOD(MapItemSingleton::get_billboards);
OV_BIND_METHOD(MapItemSingleton::get_province_positions);
OV_BIND_METHOD(MapItemSingleton::get_capital_count);
OV_BIND_METHOD(MapItemSingleton::get_max_capital_count);
OV_BIND_METHOD(MapItemSingleton::get_capital_positions);
OV_BIND_METHOD(MapItemSingleton::get_crime_icons);
OV_BIND_METHOD(MapItemSingleton::get_rgo_icons);
Expand All @@ -46,7 +46,6 @@ MapItemSingleton::~MapItemSingleton() {
}

// Get the billboard object from the loaded objects

GFX::Billboard const* MapItemSingleton::get_billboard(std::string_view name, bool error_on_fail) const {
GameSingleton const* game_singleton = GameSingleton::get_singleton();
ERR_FAIL_NULL_V(game_singleton, nullptr);
Expand All @@ -55,7 +54,9 @@ GFX::Billboard const* MapItemSingleton::get_billboard(std::string_view name, boo
game_singleton->get_definition_manager().get_ui_manager().get_cast_object_by_identifier<GFX::Billboard>(name);

if (error_on_fail) {
ERR_FAIL_NULL_V_MSG(billboard, nullptr, vformat("Failed to find billboard \"%s\"", Utilities::std_to_godot_string(name)));
ERR_FAIL_NULL_V_MSG(
billboard, nullptr, vformat("Failed to find billboard \"%s\"", Utilities::std_to_godot_string(name))
);
}

return billboard;
Expand All @@ -69,11 +70,9 @@ bool MapItemSingleton::add_billboard_dict(std::string_view name, TypedArray<Dict
static const StringName scale_key = "scale";
static const StringName noOfFrames_key = "noFrames";

GFX::Billboard const* billboard = get_billboard(name,false);
GFX::Billboard const* billboard = get_billboard(name, false);

ERR_FAIL_NULL_V_MSG(
billboard, false, "Failed to find billboard"
);
ERR_FAIL_NULL_V_MSG(billboard, false, vformat("Failed to find billboard \"%s\"", Utilities::std_to_godot_string(name)));

Dictionary dict;

Expand All @@ -87,7 +86,6 @@ bool MapItemSingleton::add_billboard_dict(std::string_view name, TypedArray<Dict
return true;
}


//get an array of all the billboard dictionnaries
TypedArray<Dictionary> MapItemSingleton::get_billboards() const {
GameSingleton const* game_singleton = GameSingleton::get_singleton();
Expand All @@ -100,30 +98,41 @@ TypedArray<Dictionary> MapItemSingleton::get_billboards() const {
add_billboard_dict(obj->get_name(), ret);
}
}

return ret;
}

// We assume GameSingleton isn't null when this is being called
static Vector2 get_billboard_pos(ProvinceDefinition const& province) {
return Utilities::to_godot_fvec2(province.get_city_position()) / GameSingleton::get_singleton()->get_map_dims();
}

PackedVector2Array MapItemSingleton::get_province_positions() const {
GameSingleton const* game_singleton = GameSingleton::get_singleton();
ERR_FAIL_NULL_V(game_singleton, PackedVector2Array());
ERR_FAIL_NULL_V(game_singleton, {});

MapDefinition const& map_definition = game_singleton->get_definition_manager().get_map_definition();

PackedVector2Array billboard_pos {};

for(ProvinceDefinition const& prov : game_singleton->get_definition_manager().get_map_definition().get_province_definitions()){
if(prov.is_water()) continue; //billboards dont appear over water, skip

fvec2_t city_pos = prov.get_city_position();
Vector2 pos = Utilities::to_godot_fvec2(city_pos) / game_singleton->get_map_dims();
billboard_pos.push_back(pos);
billboard_pos.resize(map_definition.get_land_province_count());

int64_t index = 0;

for (ProvinceDefinition const& prov : map_definition.get_province_definitions()) {
if (prov.is_water()) {
// billboards dont appear over water, skip
continue;
}

billboard_pos[index++] = get_billboard_pos(prov);
}

return billboard_pos;
}

//includes non-existent countries, used for setting the billboard buffer size
int32_t MapItemSingleton::get_capital_count() const {
int32_t MapItemSingleton::get_max_capital_count() const {
GameSingleton const* game_singleton = GameSingleton::get_singleton();
ERR_FAIL_NULL_V(game_singleton, 0);

Expand All @@ -132,68 +141,84 @@ int32_t MapItemSingleton::get_capital_count() const {

PackedVector2Array MapItemSingleton::get_capital_positions() const {
GameSingleton const* game_singleton = GameSingleton::get_singleton();
ERR_FAIL_NULL_V(game_singleton, PackedVector2Array());
ERR_FAIL_NULL_V(game_singleton, {});

InstanceManager const* instance_manager = game_singleton->get_instance_manager();
ERR_FAIL_NULL_V(instance_manager, PackedVector2Array());
ERR_FAIL_NULL_V(instance_manager, {});

CountryInstanceManager const& country_instance_manager = instance_manager->get_country_instance_manager();

PackedVector2Array billboard_pos {};

for(CountryInstance const& country : instance_manager->get_country_instance_manager().get_country_instances()){
if(!country.exists()) continue; //skip non-existant countries
billboard_pos.resize(country_instance_manager.get_country_instance_count());

fvec2_t city_pos = country.get_capital()->get_province_definition().get_city_position();
Vector2 pos = Utilities::to_godot_fvec2(city_pos) / game_singleton->get_map_dims();
billboard_pos.push_back(pos);
int64_t index = 0;

for (CountryInstance const& country : country_instance_manager.get_country_instances()) {
if (!country.exists() || country.get_capital() == nullptr) {
//skip non-existent or capital-less countries
continue;
}

billboard_pos[index++] = get_billboard_pos(country.get_capital()->get_province_definition());
}

billboard_pos.resize(index);

return billboard_pos;
}

PackedByteArray MapItemSingleton::get_crime_icons() const {
GameSingleton const* game_singleton = GameSingleton::get_singleton();
ERR_FAIL_NULL_V(game_singleton, PackedByteArray());
ERR_FAIL_NULL_V(game_singleton, {});

InstanceManager const* instance_manager = game_singleton->get_instance_manager();
ERR_FAIL_NULL_V(instance_manager, PackedByteArray());
ERR_FAIL_NULL_V(instance_manager, {});

MapInstance const& map_instance = instance_manager->get_map_instance();

PackedByteArray icons {};

for(ProvinceInstance const& prov_inst : instance_manager->get_map_instance().get_province_instances()){
if (prov_inst.get_province_definition().is_water()) continue; //billboards dont appear over water, skip
icons.resize(map_instance.get_map_definition().get_land_province_count());

if(prov_inst.get_crime() == nullptr){
icons.push_back(0); //no crime on the province
}
else {
icons.push_back(prov_inst.get_crime()->get_icon());
int64_t index = 0;

for (ProvinceInstance const& prov_inst : map_instance.get_province_instances()) {
if (prov_inst.get_province_definition().is_water()) {
// billboards dont appear over water, skip
continue;
}


Crime const* crime = prov_inst.get_crime();
icons[index++] = crime != nullptr ? crime->get_icon() : 0; // 0 if no crime in the province
}

return icons;

}

PackedByteArray MapItemSingleton::get_rgo_icons() const {
GameSingleton const* game_singleton = GameSingleton::get_singleton();
ERR_FAIL_NULL_V(game_singleton, PackedByteArray());
ERR_FAIL_NULL_V(game_singleton, {});

InstanceManager const* instance_manager = game_singleton->get_instance_manager();
ERR_FAIL_NULL_V(instance_manager, PackedByteArray());
ERR_FAIL_NULL_V(instance_manager, {});

MapInstance const& map_instance = instance_manager->get_map_instance();

PackedByteArray icons {};

for(ProvinceInstance const& prov_inst : instance_manager->get_map_instance().get_province_instances()){
if (prov_inst.get_province_definition().is_water()) continue; //billboards dont appear over water, skip
icons.resize(map_instance.get_map_definition().get_land_province_count());

if(prov_inst.get_rgo_good() == nullptr){
icons.push_back(0); //no good on the province
}
else{
icons.push_back(prov_inst.get_rgo_good()->get_index()+1);
int64_t index = 0;

for (ProvinceInstance const& prov_inst : map_instance.get_province_instances()) {
if (prov_inst.get_province_definition().is_water()) {
// billboards dont appear over water, skip
continue;
}

GoodDefinition const* rgo_good = prov_inst.get_rgo_good();
icons[index++] = rgo_good != nullptr ? rgo_good->get_index() + 1 : 0; // 0 if no rgo good in the province
}

return icons;
Expand All @@ -210,28 +235,28 @@ TODO: National focus isn't implemented yet. It could be done at the country inst

PackedByteArray MapItemSingleton::get_national_focus_icons() const {
GameSingleton const* game_singleton = GameSingleton::get_singleton();
ERR_FAIL_NULL_V(game_singleton, PackedByteArray());
ERR_FAIL_NULL_V(game_singleton, {});

InstanceManager const* instance_manager = game_singleton->get_instance_manager();
ERR_FAIL_NULL_V(instance_manager, PackedByteArray());
ERR_FAIL_NULL_V(instance_manager, {});

MapInstance const& map_instance = instance_manager->get_map_instance();

PackedByteArray icons {};

for(ProvinceInstance const& prov_inst : instance_manager->get_map_instance().get_province_instances()){
if (prov_inst.get_province_definition().is_water()) continue; //billboards dont appear over water, skip
icons.resize(map_instance.get_map_definition().get_land_province_count());

State const* state = prov_inst.get_state();
if (state == nullptr) {
icons.push_back(0);
UtilityFunctions::push_warning(
"State for province ", Utilities::std_to_godot_string(prov_inst.get_identifier()), " was null"
);
} else if (&prov_inst == state->get_capital()) {
icons.push_back(1);
} else {
icons.push_back(0);
int64_t index = 0;

for (ProvinceInstance const& prov_inst : map_instance.get_province_instances()) {
if (prov_inst.get_province_definition().is_water()) {
// billboards dont appear over water, skip
continue;
}

State const* state = prov_inst.get_state();
icons[index++] = state != nullptr && &prov_inst == state->get_capital() ? 1 : 0;
}

return icons;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,11 @@ namespace OpenVic {
bool add_billboard_dict(std::string_view name, godot::TypedArray<godot::Dictionary>& billboard_dict_array) const;
godot::TypedArray<godot::Dictionary> get_billboards() const;
godot::PackedVector2Array get_province_positions() const;
int32_t get_capital_count() const;
int32_t get_max_capital_count() const;
godot::PackedVector2Array get_capital_positions() const;

godot::PackedByteArray get_crime_icons() const;
godot::PackedByteArray get_rgo_icons() const;
godot::PackedByteArray get_national_focus_icons() const;

};

}
}
Loading

0 comments on commit aa26315

Please sign in to comment.