1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
|
extends GUINode
# Header
var _province_name_label : GUILabel
var _state_name_label : GUILabel
var _slave_status_icon : TextureRect
var _colony_status_button : Button
var _colony_status_button_texture : GFXSpriteTexture
var _administrative_percentage_label : GUILabel
var _owner_percentage_label : GUILabel
var _province_modifiers_overlapping_elements_box : GUIOverlappingElementsBox
var _terrain_type_texture : GFXSpriteTexture
var _life_rating_bar : TextureProgressBar
var _controller_flag_texture : GFXMaskedFlagTexture
# Statistics
var _rgo_icon_texture : GFXSpriteTexture
var _rgo_produced_label : GUILabel
var _rgo_income_label : GUILabel
var _rgo_employment_percentage_texture : GFXSpriteTexture
var _rgo_employment_population_label : GUILabel
var _rgo_employment_percentage_label : GUILabel
var _crime_name_label : GUILabel
var _crime_icon_texture : GFXSpriteTexture
var _crime_fighting_label : GUILabel
var _total_population_label : GUILabel
var _migration_label : GUILabel
var _population_growth_label : GUILabel
var _pop_types_piechart : GFXPieChartTexture
var _pop_ideologies_piechart : GFXPieChartTexture
var _pop_cultures_piechart : GFXPieChartTexture
var _supply_limit_label : GUILabel
var _cores_overlapping_elements_box : GUIOverlappingElementsBox
# Buildings
var _buildings_panel : Panel
var _building_slots : Array[BuildingSlot]
# REQUIREMENTS:
# * UI-183, UI-185, UI-186, UI-765, UI-187, UI-188, UI-189
# * UI-191, UI-193, UI-194, UI-766, UI-195, UI-196, UI-197
# * UI-199, UI-201, UI-202, UI-767, UI-203, UI-204, UI-205
class BuildingSlot:
var _slot_index : int
var _slot_node : Control
var _building_icon : GFXSpriteTexture
var _expand_button : Button
var _expanding_icon : TextureRect
var _expanding_progress_bar : TextureProgressBar
var _expanding_label : GUILabel
func _init(new_slot_index : int, new_slot_node : Control) -> void:
if new_slot_index < 0:
push_error("Invalid building slot index: ", new_slot_index)
return
_slot_index = new_slot_index
if not new_slot_node:
push_error("Invalid building slot node: null!")
return
_slot_node = new_slot_node
for icon_index : int in MenuSingleton.get_province_building_count():
var icon := _slot_node.get_node("build_icon%d" % icon_index)
if icon:
if icon_index == _slot_index:
_building_icon = GUINode.get_gfx_sprite_texture_from_node(icon)
else:
icon.hide()
var building_name := GUINode.get_gui_label_from_node(_slot_node.get_node(^"./description"))
if building_name:
building_name.text = MenuSingleton.get_province_building_identifier(_slot_index)
_expand_button = GUINode.get_button_from_node(_slot_node.get_node(^"./expand"))
if _expand_button:
_expand_button.pressed.connect(func() -> void: MenuSingleton.expand_selected_province_building(_slot_index))
_expanding_icon = GUINode.get_texture_rect_from_node(_slot_node.get_node(^"./underconstruction_icon"))
_expanding_progress_bar = GUINode.get_progress_bar_from_node(_slot_node.get_node(^"./building_progress"))
if _expanding_progress_bar:
_expanding_progress_bar.max_value = 1.0
_expanding_progress_bar.step = _expanding_progress_bar.max_value / 100
_expanding_label = GUINode.get_gui_label_from_node(_slot_node.get_node(^"./expand_text"))
enum ExpansionState { CannotExpand, CanExpand, Preparing, Expanding }
func update_info(info : Dictionary) -> void:
const building_info_level_key : StringName = &"level"
const building_info_expansion_state_key : StringName = &"expansion_state"
const building_info_start_date_key : StringName = &"start_date"
const building_info_end_date_key : StringName = &"end_date"
const building_info_expansion_progress_key : StringName = &"expansion_progress"
if _building_icon:
_building_icon.set_icon_index(info.get(building_info_level_key, 0) + 1)
var expansion_state : int = info.get(building_info_expansion_state_key, ExpansionState.CannotExpand)
var expansion_in_progress : bool = expansion_state == ExpansionState.Preparing or expansion_state == ExpansionState.Expanding
if _expand_button:
_expand_button.visible = not expansion_in_progress
_expand_button.disabled = expansion_state != ExpansionState.CanExpand
if _expanding_icon:
_expanding_icon.visible = expansion_in_progress
if _expanding_progress_bar:
_expanding_progress_bar.visible = expansion_in_progress
_expanding_progress_bar.value = info.get(building_info_expansion_progress_key, 0)
if _expanding_label:
_expanding_label.visible = expansion_in_progress
var _selected_index : int:
get: return _selected_index
set(v):
_selected_index = v
_update_info()
var _province_info : Dictionary
func _ready() -> void:
GameSingleton.province_selected.connect(_on_province_selected)
GameSingleton.gamestate_updated.connect(_update_info)
if add_gui_element("province_interface", "province_view") != OK:
push_error("Failed to generate province overview panel!")
return
# Disables all consuming invisible panel
var prov_view := get_panel_from_nodepath(^"./province_view")
if prov_view:
prov_view.mouse_filter = Control.MOUSE_FILTER_IGNORE
set_click_mask_from_nodepaths([^"./province_view/background"])
var close_button : Button = get_button_from_nodepath(^"./province_view/close_button")
if close_button:
close_button.pressed.connect(_on_close_button_pressed)
# Header
_province_name_label = get_gui_label_from_nodepath(^"./province_view/province_view_header/province_name")
_state_name_label = get_gui_label_from_nodepath(^"./province_view/province_view_header/state_name")
if _state_name_label:
# State names are already translated in the MenuSingleton
_state_name_label.auto_translate = false
_slave_status_icon = get_texture_rect_from_nodepath(^"./province_view/province_view_header/slave_state_icon")
var slave_status_icon_texture : GFXSpriteTexture = get_gfx_sprite_texture_from_nodepath(^"./province_view/province_view_header/slave_state_icon")
if slave_status_icon_texture:
slave_status_icon_texture.set_icon_index(MenuSingleton.get_slave_pop_icon_index())
_colony_status_button = get_button_from_nodepath(^"./province_view/province_view_header/colony_button")
_colony_status_button_texture = get_gfx_sprite_texture_from_nodepath(^"./province_view/province_view_header/colony_button")
var admin_icon_texture : GFXSpriteTexture = get_gfx_sprite_texture_from_nodepath(^"./province_view/province_view_header/admin_icon")
if admin_icon_texture:
admin_icon_texture.set_icon_index(MenuSingleton.get_administrative_pop_icon_index())
_administrative_percentage_label = get_gui_label_from_nodepath(^"./province_view/province_view_header/admin_efficiency")
_owner_percentage_label = get_gui_label_from_nodepath(^"./province_view/province_view_header/owner_presence")
_province_modifiers_overlapping_elements_box = get_gui_overlapping_elements_box_from_nodepath(^"./province_view/province_view_header/province_modifiers")
if _province_modifiers_overlapping_elements_box and _province_modifiers_overlapping_elements_box.set_gui_child_element_name("province_interface", "prov_state_modifier") != OK:
_province_modifiers_overlapping_elements_box = null # hide province modifiers box since we can't do anything with it
_terrain_type_texture = get_gfx_sprite_texture_from_nodepath(^"./province_view/province_view_header/prov_terrain")
_life_rating_bar = get_progress_bar_from_nodepath(^"./province_view/province_view_header/liferating")
_controller_flag_texture = get_gfx_masked_flag_texture_from_nodepath(^"./province_view/province_view_header/controller_flag")
# Statistics
_rgo_icon_texture = get_gfx_sprite_texture_from_nodepath(^"./province_view/province_statistics/goods_type")
_rgo_produced_label = get_gui_label_from_nodepath(^"./province_view/province_statistics/produced")
_rgo_income_label = get_gui_label_from_nodepath(^"./province_view/province_statistics/income")
_rgo_employment_percentage_texture = get_gfx_sprite_texture_from_nodepath(^"./province_view/province_statistics/employment_ratio")
_rgo_employment_population_label = get_gui_label_from_nodepath(^"./province_view/province_statistics/rgo_population")
_rgo_employment_percentage_label = get_gui_label_from_nodepath(^"./province_view/province_statistics/rgo_percent")
_crime_name_label = get_gui_label_from_nodepath(^"./province_view/province_statistics/crime_name")
_crime_icon_texture = get_gfx_sprite_texture_from_nodepath(^"./province_view/province_statistics/crime_icon")
_crime_fighting_label = get_gui_label_from_nodepath(^"./province_view/province_statistics/crimefight_percent")
_total_population_label = get_gui_label_from_nodepath(^"./province_view/province_statistics/total_population")
_migration_label = get_gui_label_from_nodepath(^"./province_view/province_statistics/migration")
_population_growth_label = get_gui_label_from_nodepath(^"./province_view/province_statistics/growth")
_pop_types_piechart = get_gfx_pie_chart_texture_from_nodepath(^"./province_view/province_statistics/workforce_chart")
_pop_ideologies_piechart = get_gfx_pie_chart_texture_from_nodepath(^"./province_view/province_statistics/ideology_chart")
_pop_cultures_piechart = get_gfx_pie_chart_texture_from_nodepath(^"./province_view/province_statistics/culture_chart")
var population_menu_button : Button = get_button_from_nodepath(^"./province_view/province_statistics/open_popscreen")
if population_menu_button:
population_menu_button.pressed.connect(
func() -> void:
MenuSingleton.population_menu_select_province(_selected_index)
_on_close_button_pressed()
Events.NationManagementScreens.open_nation_management_screen(NationManagement.Screen.POPULATION)
)
_supply_limit_label = get_gui_label_from_nodepath(^"./province_view/province_statistics/supply_limit_label")
_cores_overlapping_elements_box = get_gui_overlapping_elements_box_from_nodepath(^"./province_view/province_statistics/core_icons")
if _cores_overlapping_elements_box and _cores_overlapping_elements_box.set_gui_child_element_name("province_interface", "province_core") != OK:
_cores_overlapping_elements_box = null # hide cores box since we can't do anything with it
_buildings_panel = get_panel_from_nodepath(^"./province_view/province_buildings")
if _buildings_panel:
var target_slot_count : int = MenuSingleton.get_province_building_count()
var slot_y : float = 0.0
for current_slot_count : int in target_slot_count:
var slot := GUINode.generate_gui_element("province_interface", "building", "building_slot_%d" % current_slot_count)
if slot:
_buildings_panel.add_child(slot)
slot.set_position(Vector2(0.0, slot_y))
slot_y += slot.get_size().y
_building_slots.push_back(BuildingSlot.new(current_slot_count, slot))
else:
push_error("Failed to generate building slot ", current_slot_count, " / ", target_slot_count)
break
hide_nodes([
^"./province_view/province_view_header/state_modifiers",
^"./province_view/province_view_header/occupation_progress",
^"./province_view/province_view_header/occupation_icon",
^"./province_view/province_view_header/occupation_flag",
^"./province_view/province_colony",
^"./province_view/province_other",
^"./province_view/province_buildings/army_size",
^"./province_view/province_buildings/army_text",
^"./province_view/province_buildings/navy_text",
^"./province_view/national_focus_window",
])
_update_info()
func _notification(what : int) -> void:
match what:
NOTIFICATION_TRANSLATION_CHANGED:
_update_info()
enum ColonyStatus { STATE, PROTECTORATE, COLONY }
# This assumes _cores_overlapping_elements_box is non-null
func _set_core_flag(core_index : int, country : String) -> void:
var core_flag_texture : GFXMaskedFlagTexture = GUINode.get_gfx_masked_flag_texture_from_node(
_cores_overlapping_elements_box.get_child(core_index).get_node(^"./country_flag")
)
if core_flag_texture:
core_flag_texture.set_flag_country_name(country)
func _update_info() -> void:
const _province_info_province_key : StringName = &"province"
const _province_info_state_key : StringName = &"state"
const _province_info_slave_status_key : StringName = &"slave_status"
const _province_info_colony_status_key : StringName = &"colony_status"
const _province_info_terrain_type_key : StringName = &"terrain_type"
const _province_info_life_rating_key : StringName = &"life_rating"
const _province_info_controller_key : StringName = &"controller"
const _province_info_rgo_name_key : StringName = &"rgo_name"
const _province_info_rgo_icon_key : StringName = &"rgo_icon"
const _province_info_crime_name_key : StringName = &"crime_name"
const _province_info_crime_icon_key : StringName = &"crime_icon"
const _province_info_total_population_key : StringName = &"total_population"
const _province_info_pop_types_key : StringName = &"pop_types"
const _province_info_pop_ideologies_key : StringName = &"pop_ideologies"
const _province_info_pop_cultures_key : StringName = &"pop_cultures"
const _province_info_cores_key : StringName = &"cores"
const _province_info_buildings_key : StringName = &"buildings"
const _missing_suffix : String = "_MISSING"
_province_info = MenuSingleton.get_province_info_from_index(_selected_index)
if _province_info:
# Header
if _province_name_label:
_province_name_label.text = GUINode.format_province_name(_province_info.get(_province_info_province_key, _missing_suffix))
if _state_name_label:
_state_name_label.text = _province_info.get(_province_info_state_key, tr(_province_info_state_key + _missing_suffix))
if _slave_status_icon:
_slave_status_icon.visible = _province_info.get(_province_info_slave_status_key, false)
var colony_status : ColonyStatus = _province_info.get(_province_info_colony_status_key, 0)
if _colony_status_button:
if colony_status == ColonyStatus.STATE:
_colony_status_button.hide()
else:
if _colony_status_button_texture:
_colony_status_button_texture.set_icon_index(colony_status)
_colony_status_button.show()
if _administrative_percentage_label:
pass
if _owner_percentage_label:
pass
if _province_modifiers_overlapping_elements_box:
# TODO - replace example icons with those from the province's list of modifier instances
_province_modifiers_overlapping_elements_box.set_child_count(8)
for i : int in _province_modifiers_overlapping_elements_box.get_child_count():
var icon : GFXSpriteTexture = GUINode.get_gfx_sprite_texture_from_node(
_province_modifiers_overlapping_elements_box.get_child(i).get_node(^"./modifier")
)
if icon:
icon.set_icon_index(2 * i + (i & 1) + 1)
if _terrain_type_texture:
var terrain_type : String = _province_info.get(_province_info_terrain_type_key, "")
if terrain_type:
const _terrain_type_prefix : String = "GFX_terrainimg_"
if _terrain_type_texture.set_gfx_texture_sprite_name(_terrain_type_prefix + terrain_type) != OK:
push_error("Failed to set terrain type texture: ", terrain_type)
if _life_rating_bar:
_life_rating_bar.value = _province_info.get(_province_info_life_rating_key, 0) / 100.0
if _controller_flag_texture:
_controller_flag_texture.set_flag_country_name(_province_info.get(_province_info_controller_key, ""))
# Statistics
if _rgo_icon_texture:
_rgo_icon_texture.set_icon_index(_province_info.get(_province_info_rgo_icon_key, -1) + 2)
if _rgo_produced_label:
# TODO - replace name with amount produced
_rgo_produced_label.text = _province_info.get(_province_info_rgo_name_key, _province_info_rgo_name_key + _missing_suffix)
if _rgo_income_label:
# TODO - add £ sign and replace placeholder with actual value
_rgo_income_label.text = "%s¤" % GUINode.float_to_string_dp(12.34567, 3)
if _rgo_employment_percentage_texture:
pass
if _rgo_employment_population_label:
# TODO - replace placeholder with actual value
_rgo_employment_population_label.text = GUINode.int_to_string_suffixed(_province_info.get(_province_info_total_population_key, 0) / 10)
if _rgo_employment_percentage_label:
pass
if _crime_name_label:
_crime_name_label.text = _province_info.get(_province_info_crime_name_key, "")
if _crime_icon_texture:
_crime_icon_texture.set_icon_index(_province_info.get(_province_info_crime_icon_key, 0) + 1)
if _crime_fighting_label:
pass
if _total_population_label:
_total_population_label.text = GUINode.int_to_string_suffixed(_province_info.get(_province_info_total_population_key, 0))
if _migration_label:
pass
if _population_growth_label:
pass
if _pop_types_piechart:
_pop_types_piechart.set_slices_array(_province_info.get(_province_info_pop_types_key, []))
if _pop_ideologies_piechart:
_pop_ideologies_piechart.set_slices_array(_province_info.get(_province_info_pop_ideologies_key, []))
if _pop_cultures_piechart:
_pop_cultures_piechart.set_slices_array(_province_info.get(_province_info_pop_cultures_key, []))
if _supply_limit_label:
pass
if _cores_overlapping_elements_box:
var cores : PackedStringArray = _province_info.get(_province_info_cores_key, [])
_cores_overlapping_elements_box.set_child_count(cores.size())
for core_index : int in min(cores.size(), _cores_overlapping_elements_box.get_child_count()):
_set_core_flag(core_index, cores[core_index])
for core_index : int in range(cores.size(), _cores_overlapping_elements_box.get_child_count()):
_set_core_flag(core_index, "")
# Buildings
if _buildings_panel:
var buildings : Array[Dictionary] = _province_info.get(_province_info_buildings_key, [] as Array[Dictionary])
for slot_index : int in min(buildings.size(), _building_slots.size()):
_building_slots[slot_index].update_info(buildings[slot_index])
for slot_index : int in range(buildings.size(), _building_slots.size()):
_building_slots[slot_index].update_info({})
show()
else:
hide()
mouse_exited.emit()
func _on_province_selected(index : int) -> void:
_selected_index = index
func _on_close_button_pressed() -> void:
GameSingleton.unset_selected_province()
|