diff --git a/extension/deps/openvic-simulation b/extension/deps/openvic-simulation
index 12157ce8..81305613 160000
--- a/extension/deps/openvic-simulation
+++ b/extension/deps/openvic-simulation
@@ -1 +1 @@
-Subproject commit 12157ce86d6a1a1637f9ef5f7feabe5650b7a993
+Subproject commit 813056134e39518275dd67e318e8262b90b5c082
diff --git a/extension/doc_classes/MapItemSingleton.xml b/extension/doc_classes/MapItemSingleton.xml
index 1f72849e..27c55502 100644
--- a/extension/doc_classes/MapItemSingleton.xml
+++ b/extension/doc_classes/MapItemSingleton.xml
@@ -12,11 +12,6 @@
-
-
-
-
-
@@ -27,6 +22,11 @@
+
+
+
+
+
diff --git a/extension/src/openvic-extension/singletons/MapItemSingleton.cpp b/extension/src/openvic-extension/singletons/MapItemSingleton.cpp
index b96b5786..d1145d6e 100644
--- a/extension/src/openvic-extension/singletons/MapItemSingleton.cpp
+++ b/extension/src/openvic-extension/singletons/MapItemSingleton.cpp
@@ -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);
@@ -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);
@@ -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(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;
@@ -69,11 +70,9 @@ bool MapItemSingleton::add_billboard_dict(std::string_view name, TypedArray MapItemSingleton::get_billboards() const {
GameSingleton const* game_singleton = GameSingleton::get_singleton();
@@ -100,30 +98,41 @@ TypedArray 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);
@@ -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;
@@ -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;
-}
\ No newline at end of file
+}
diff --git a/extension/src/openvic-extension/singletons/MapItemSingleton.hpp b/extension/src/openvic-extension/singletons/MapItemSingleton.hpp
index 479e9cec..867ac8d3 100644
--- a/extension/src/openvic-extension/singletons/MapItemSingleton.hpp
+++ b/extension/src/openvic-extension/singletons/MapItemSingleton.hpp
@@ -28,13 +28,11 @@ namespace OpenVic {
bool add_billboard_dict(std::string_view name, godot::TypedArray& billboard_dict_array) const;
godot::TypedArray 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;
-
};
-
-}
\ No newline at end of file
+}
diff --git a/game/src/Game/GameSession/BillboardManager.gd b/game/src/Game/GameSession/BillboardManager.gd
index 8b317715..f14986b8 100644
--- a/game/src/Game/GameSession/BillboardManager.gd
+++ b/game/src/Game/GameSession/BillboardManager.gd
@@ -1,32 +1,48 @@
extends MultiMeshInstance3D
-#given a name: get the index for the texture in the shader
-# this is to reduce the number of magic indeces in the code
-# to get the proper billboard image
-var billboard_names : Dictionary = {}
-
@export var _map_view : MapView
-const SCALE_FACTOR : float = 1.0/96.0
-
-enum ProvinceBillboards { NONE, INVISIBLE, RGO, CRIME, NATIONAL_FOCUS }
+const SCALE_FACTOR : float = 1.0 / 96.0
+
+enum BillboardType { NONE, RGO, CRIME, NATIONAL_FOCUS, CAPITAL }
+const BILLBOARD_NAMES : Dictionary = {
+ BillboardType.RGO: &"tradegoods",
+ BillboardType.CRIME: &"crimes",
+ BillboardType.NATIONAL_FOCUS: &"national_focus",
+ BillboardType.CAPITAL: &"capital"
+}
+const BILLBOARD_DIMS : Dictionary = {
+ # Should be 0.8, but something else seems to be contributing to vertical
+ # stretching so we use 0.7 to account for that.
+ BillboardType.RGO: Vector2(1.0, 0.7),
+
+ BillboardType.CRIME: Vector2(1.0, 1.0),
+ BillboardType.NATIONAL_FOCUS: Vector2(1.0, 1.0),
+ BillboardType.CAPITAL: Vector2(1.0, 1.0)
+}
enum MapModes { REVOLT_RISK = 2, INFRASTRUCTURE = 5, COLONIAL = 6, NATIONAL_FOCUS = 9, RGO_OUTPUT = 10 }
var provinces_size : int = 0
var total_capitals_size : int = 0
-var textures : Array[Texture2D] = []
-var frames : Array[int] = []
-var scales : Array[float] = []
+# Given a BillboardType, get the index for the texture in the shader.
+# This is to reduce the number of magic indeces in the code
+# to get the proper billboard image
+var billboard_type_to_index : Dictionary
+
+var textures : Array[Texture2D]
+var frames : PackedByteArray
+var scales : PackedVector2Array
-var current_province_billboard : ProvinceBillboards = ProvinceBillboards.NONE
+var current_province_billboard : BillboardType = BillboardType.NONE
+var province_billboards_visible : bool = true
# ============== Billboards =============
# Billboards are displayed using a multimesh (batch drawn mesh)
# with positions set to every province and every nation capital.
# A shader controls which billboard and frame from icon strips are displayed
# at each province. It also makes billboards "look at" the camera
-# To ensure billboards are displayed ontop of the map and units, it is contained in
+# To ensure billboards are displayed ontop of the map and units, it is contained in
# a subviewport which renders above the main viewport, with a camera set to follow the primary camera
# multimesh only lets us send custom data to the shader as a single float vec4/Color variable
@@ -38,125 +54,141 @@ var current_province_billboard : ProvinceBillboards = ProvinceBillboards.NONE
# w: unused
# "Province billboards" refer to billboards positioned on every province
-# for map modes such as RGO output, while "Capital billboards" refers to the
+# for map modes such as RGO output, while "Capital billboards" refers to the
# to country capitals.
func _ready() -> void:
const name_key : StringName = &"name"
const texture_key : StringName = &"texture"
const scale_key : StringName = &"scale"
- const noOfFrames_key : StringName = &"noFrames"
-
- var billboards : Array[Dictionary] = MapItemSingleton.get_billboards()
- for j : int in billboards.size():
- var billboard : Dictionary = billboards[j]
-
- var billboard_name : String = billboard[name_key]
- var texture_name : String = billboard[texture_key]
+ const no_of_frames_key : StringName = &"noFrames"
+
+ for billboard : Dictionary in MapItemSingleton.get_billboards():
+ var billboard_name : StringName = billboard[name_key]
+
+ var billboard_type : BillboardType = BillboardType.NONE
+ for key : BillboardType in BILLBOARD_NAMES:
+ if billboard_name == BILLBOARD_NAMES[key]:
+ billboard_type = key
+ break
+
+ if billboard_type == BillboardType.NONE:
+ continue
+
+ var texture_name : StringName = billboard[texture_key]
var billboard_scale : float = billboard[scale_key]
- var noFrames : int = billboard[noOfFrames_key]
-
+ var no_of_frames : int = billboard[no_of_frames_key]
+
#fix the alpha edges of the billboard textures
- var texture : Texture2D = AssetManager.get_texture(texture_name)
+ var texture : ImageTexture = AssetManager.get_texture(texture_name)
+ if texture == null:
+ push_error("Texture for billboard \"", billboard_name, "\" was null!")
+ continue
var image : Image = texture.get_image()
image.fix_alpha_edges()
texture.set_image(image)
-
+
+ # We use the texture array size (which will be the same as frames and scales' sizes)
+ # rather than billboard_index as the former only counts billboards we're actually using,
+ # while the latter counts all billboards defined in the game's GFX files
+ billboard_type_to_index[billboard_type] = textures.size()
+
textures.push_back(texture)
- frames.push_back(noFrames)
- scales.push_back(billboard_scale*SCALE_FACTOR)
- billboard_names[billboard_name] = j
-
+ frames.push_back(no_of_frames)
+ scales.push_back(BILLBOARD_DIMS[billboard_type] * billboard_scale * SCALE_FACTOR)
+
var material : ShaderMaterial = multimesh.mesh.surface_get_material(0)
if material == null:
push_error("ShaderMaterial for billboards was null")
return
-
- material.set_shader_parameter("billboards",textures)
- material.set_shader_parameter("numframes",frames)
- material.set_shader_parameter("sizes",scales)
- multimesh.mesh.surface_set_material(0,material)
-
+
+ material.set_shader_parameter(&"billboards", textures)
+ material.set_shader_parameter(&"numframes", frames)
+ material.set_shader_parameter(&"sizes", scales)
+ multimesh.mesh.surface_set_material(0, material)
+
var positions : PackedVector2Array = MapItemSingleton.get_province_positions()
provinces_size = positions.size()
- total_capitals_size = MapItemSingleton.get_capital_count()
-
+ total_capitals_size = MapItemSingleton.get_max_capital_count()
+
# 1) setting instance_count clears and resizes the buffer
# so we want to find the max size once and leave it
# 2) resize must occur after setting the transform format
multimesh.instance_count = provinces_size + total_capitals_size
- multimesh.visible_instance_count = provinces_size + total_capitals_size
-
- set_capitals()
- var map_positions : PackedVector3Array = to_map_coords(positions)
+ if _map_view == null:
+ push_error("MapView export varible for BillboardManager must be set!")
+ return
- for i : int in positions.size():
- multimesh.set_instance_transform(i + total_capitals_size, Transform3D(Basis(),
- map_positions[i]
- ))
+ for province_index : int in provinces_size:
+ multimesh.set_instance_transform(
+ province_index + total_capitals_size,
+ Transform3D(Basis(), _map_view._map_to_world_coords(positions[province_index]))
+ )
+ # These signals will trigger and update capitals and province icons right
+ # at the beginning of (as well as later throughout) the game session
GameSingleton.mapmode_changed.connect(_on_map_mode_changed)
GameSingleton.gamestate_updated.connect(_on_game_state_changed)
-#TODO: Get rid of the vertical stretch, proper capitals placement
-
-#fetch the nation capitals and setup billboards for them
+# Fetch the nation capitals and setup billboards for them
func set_capitals() -> void:
- var positions : PackedVector2Array = MapItemSingleton.get_capital_positions()
- var capital_positions : PackedVector3Array = to_map_coords(positions)
- var image_index : int = billboard_names["capital"]
-
- #multimesh.visible_instance_count = capitals_begin_index + capital_positions.size()
- for i : int in capital_positions.size():
- multimesh.set_instance_transform(i,Transform3D(Basis(),
- capital_positions[i]
- ))
-
- #capital image, frame=1 ,2x unused
- #frame=1 because frame=0 would cause capitals not to show
- #and as an index its fine, since the shader UVs will wrap around
+ var capital_positions : PackedVector2Array = MapItemSingleton.get_capital_positions()
+ var capitals_size : int = capital_positions.size()
+ var image_index : int = billboard_type_to_index[BillboardType.CAPITAL]
+
+ for capital_index : int in capitals_size:
+ multimesh.set_instance_transform(
+ capital_index,
+ Transform3D(Basis(), _map_view._map_to_world_coords(capital_positions[capital_index]))
+ )
+
+ # capital image, frame=1, 2x unused
+ # frame=1 because frame=0 would cause capitals not to show
+ # and as an index its fine, since the shader UVs will wrap around
# 1.0 to 2.0 --> 0.0 to 1.0 so the capital image is preserved
- multimesh.set_instance_custom_data(i,Color(#capital_index,Color(
- image_index,1.0,0,0
- ))
+ multimesh.set_instance_custom_data(
+ capital_index,
+ Color(image_index, 1.0, 0.0, 0.0)
+ )
+
# For every country that doesn't exist, make the capital invisible
- for i : int in total_capitals_size - capital_positions.size():
- multimesh.set_instance_custom_data(capital_positions.size() + i, Color(
- image_index,0.0,0,0
- ))
-
-# should provinces display RGO, crime, ..., or no billboard
-func set_province_billboards(display : ProvinceBillboards = ProvinceBillboards.INVISIBLE) -> void:
- var image_index : int = 0
- var icons : PackedByteArray = PackedByteArray()
- icons.resize(provinces_size)
- icons.fill(0) #by default, display nothing (invisible)
- match display:
- ProvinceBillboards.RGO:
- image_index = billboard_names["tradegoods"]
- icons = MapItemSingleton.get_rgo_icons()
- current_province_billboard = display
- ProvinceBillboards.CRIME:
- image_index = billboard_names["crimes"]
- icons = MapItemSingleton.get_crime_icons()
- current_province_billboard = display
- ProvinceBillboards.NATIONAL_FOCUS:
- image_index = billboard_names["national_focus"]
- icons = MapItemSingleton.get_national_focus_icons()
- current_province_billboard = display
- ProvinceBillboards.NONE:
- current_province_billboard = display
- _: #display nothing, but keep the current billboard setting
- pass
- # capitals are first in the array, so start iterating after them
- for i : int in provinces_size:
- multimesh.set_instance_custom_data(i + total_capitals_size,Color(
- image_index,icons[i],0,0
- ))
+ for capital_index : int in range(capitals_size, total_capitals_size):
+ multimesh.set_instance_custom_data(
+ capital_index,
+ Color(image_index, 0.0, 0.0, 0.0)
+ )
+
+# Should provinces display RGO, crime, ..., or no billboard
+func update_province_billboards() -> void:
+ # If current_province_billboard is NONE then image_index will fall back to -1
+ var image_index : int = billboard_type_to_index.get(current_province_billboard, -1)
+ if not province_billboards_visible or image_index < 0:
+ multimesh.visible_instance_count = total_capitals_size
+ else:
+ var icons : PackedByteArray
+ match current_province_billboard:
+ BillboardType.RGO:
+ icons = MapItemSingleton.get_rgo_icons()
+ BillboardType.CRIME:
+ icons = MapItemSingleton.get_crime_icons()
+ BillboardType.NATIONAL_FOCUS:
+ icons = MapItemSingleton.get_national_focus_icons()
+ _:
+ push_error("Invalid province billboard type: ", current_province_billboard)
+ return
+
+ # Capitals are first in the array, so start iterating after them
+ for province_index : int in provinces_size:
+ multimesh.set_instance_custom_data(
+ province_index + total_capitals_size,
+ Color(image_index, icons[province_index], 0.0, 0.0)
+ )
+
+ multimesh.visible_instance_count = total_capitals_size + provinces_size
func _on_game_state_changed() -> void:
- set_province_billboards(current_province_billboard)
+ update_province_billboards()
set_capitals()
# There are essentially 3 visibility states we can be in
@@ -166,33 +198,20 @@ func _on_game_state_changed() -> void:
# So set_visible here is essentially to toggle the visibility of capitals
func detailed_map(visible : bool) -> void:
- if visible:
- set_visible(true)
- set_province_billboards(current_province_billboard)
- else:
- set_visible(true)
- set_province_billboards()
+ province_billboards_visible = visible
+ update_province_billboards()
func parchment_view(is_parchment : bool) -> void:
- if is_parchment:
- set_visible(false)
- else:
- detailed_map(false)
+ set_visible(not is_parchment)
func _on_map_mode_changed(map_mode : int) -> void:
match map_mode:
MapModes.INFRASTRUCTURE, MapModes.COLONIAL, MapModes.RGO_OUTPUT:
- set_province_billboards(ProvinceBillboards.RGO)
+ current_province_billboard = BillboardType.RGO
MapModes.REVOLT_RISK:
- set_province_billboards(ProvinceBillboards.CRIME)
+ current_province_billboard = BillboardType.CRIME
MapModes.NATIONAL_FOCUS:
- set_province_billboards(ProvinceBillboards.NATIONAL_FOCUS)
+ current_province_billboard = BillboardType.NATIONAL_FOCUS
_:
- set_province_billboards(ProvinceBillboards.NONE)
-
-func to_map_coords(positions : PackedVector2Array) -> PackedVector3Array:
- var map_positions : PackedVector3Array = PackedVector3Array()
- for pos_in : Vector2 in positions:
- var pos : Vector3 = _map_view._map_to_world_coords(pos_in)
- map_positions.push_back(pos)
- return map_positions
+ current_province_billboard = BillboardType.NONE
+ update_province_billboards()
diff --git a/game/src/Game/GameSession/billboard.gdshader b/game/src/Game/GameSession/billboard.gdshader
index 417cedf4..bf15d2cd 100644
--- a/game/src/Game/GameSession/billboard.gdshader
+++ b/game/src/Game/GameSession/billboard.gdshader
@@ -4,11 +4,13 @@ shader_type spatial;
//3d space.
render_mode unshaded, depth_test_disabled;
-//vic2 only ever loads a max of 12 BillboardType
-//Of these, only 4 are actually used
-uniform sampler2D billboards[12] : source_color;
-uniform uint numframes[12];
-uniform float sizes[12];
+// Vic2 only ever loads a max of 12 BillboardType
+// Of these, only 4 are actually used
+const uint BILLBOARD_COUNT = 4u;
+
+uniform sampler2D billboards[BILLBOARD_COUNT] : source_color;
+uniform uint numframes[BILLBOARD_COUNT];
+uniform vec2 sizes[BILLBOARD_COUNT];
//COLOR/INSTANCE_CUSTOM is our custom data, used as follows:
// x=image index
@@ -17,8 +19,8 @@ uniform float sizes[12];
void vertex() {
COLOR = INSTANCE_CUSTOM; //send instance_custom info to fragment
- float size = sizes[uint(COLOR.x + 0.5)];
- VERTEX = (vec4(VERTEX * size, 1.0) * VIEW_MATRIX).xyz;
+ VERTEX.xy *= sizes[uint(COLOR.x + 0.5)];
+ VERTEX = (vec4(VERTEX, 1.0) * VIEW_MATRIX).xyz;
}
void fragment() {