aboutsummaryrefslogtreecommitdiff
path: root/game
diff options
context:
space:
mode:
Diffstat (limited to 'game')
-rw-r--r--game/src/Game/GameSession/GameSession.gd3
-rw-r--r--game/src/Game/GameSession/GameSession.tscn11
-rw-r--r--game/src/Game/GameSession/MapView.tscn6
-rw-r--r--game/src/Game/GameSession/ModelManager.gd131
4 files changed, 149 insertions, 2 deletions
diff --git a/game/src/Game/GameSession/GameSession.gd b/game/src/Game/GameSession/GameSession.gd
index f085073..a07ce32 100644
--- a/game/src/Game/GameSession/GameSession.gd
+++ b/game/src/Game/GameSession/GameSession.gd
@@ -1,5 +1,6 @@
extends Control
+@export var _model_manager : ModelManager
@export var _game_session_menu : Control
func _ready() -> void:
@@ -7,6 +8,8 @@ func _ready() -> void:
if GameSingleton.setup_game(0) != OK:
push_error("Failed to setup game")
+ _model_manager.generate_units()
+
func _process(_delta : float) -> void:
GameSingleton.try_tick()
diff --git a/game/src/Game/GameSession/GameSession.tscn b/game/src/Game/GameSession/GameSession.tscn
index 343ddfe..d54970f 100644
--- a/game/src/Game/GameSession/GameSession.tscn
+++ b/game/src/Game/GameSession/GameSession.tscn
@@ -1,9 +1,10 @@
-[gd_scene load_steps=18 format=3 uid="uid://bgnupcshe1m7r"]
+[gd_scene load_steps=19 format=3 uid="uid://bgnupcshe1m7r"]
[ext_resource type="Script" path="res://src/Game/GameSession/GameSession.gd" id="1_eklvp"]
[ext_resource type="PackedScene" uid="uid://cvl76duuym1wq" path="res://src/Game/MusicConductor/MusicPlayer.tscn" id="2_kt6aa"]
[ext_resource type="PackedScene" uid="uid://g524p8lr574w" path="res://src/Game/GameSession/MapControlPanel/MapControlPanel.tscn" id="3_afh6d"]
[ext_resource type="PackedScene" uid="uid://dvdynl6eir40o" path="res://src/Game/GameSession/GameSessionMenu.tscn" id="3_bvmqh"]
+[ext_resource type="Script" path="res://src/Game/GameSession/ModelManager.gd" id="3_qwk4j"]
[ext_resource type="Script" path="res://src/Game/GameSession/Topbar.gd" id="4_2kbih"]
[ext_resource type="PackedScene" uid="uid://dkehmdnuxih2r" path="res://src/Game/GameSession/MapView.tscn" id="4_xkg5j"]
[ext_resource type="Script" path="res://src/Game/GameSession/NationManagementScreen/ProductionMenu.gd" id="5_16755"]
@@ -18,7 +19,7 @@
[ext_resource type="Script" path="res://src/Game/GameSession/NationManagementScreen/DiplomacyMenu.gd" id="11_fu7ys"]
[ext_resource type="Script" path="res://src/Game/GameSession/NationManagementScreen/MilitaryMenu.gd" id="12_6h6nc"]
-[node name="GameSession" type="Control" node_paths=PackedStringArray("_game_session_menu")]
+[node name="GameSession" type="Control" node_paths=PackedStringArray("_model_manager", "_game_session_menu")]
editor_description = "SS-102, UI-546"
layout_mode = 3
anchors_preset = 15
@@ -28,10 +29,15 @@ grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
script = ExtResource("1_eklvp")
+_model_manager = NodePath("ModelManager")
_game_session_menu = NodePath("UICanvasLayer/UI/GameSessionMenu")
[node name="MapView" parent="." instance=ExtResource("4_xkg5j")]
+[node name="ModelManager" type="Node3D" parent="." node_paths=PackedStringArray("_map_view")]
+script = ExtResource("3_qwk4j")
+_map_view = NodePath("../MapView")
+
[node name="UICanvasLayer" type="CanvasLayer" parent="."]
[node name="UI" type="Control" parent="UICanvasLayer"]
@@ -143,6 +149,7 @@ offset_left = -150.0
offset_right = 0.0
grow_horizontal = 0
+[connection signal="detailed_view_changed" from="MapView" to="ModelManager" method="set_visible"]
[connection signal="map_view_camera_changed" from="MapView" to="UICanvasLayer/UI/MapControlPanel" method="_on_map_view_camera_changed"]
[connection signal="game_session_menu_button_pressed" from="UICanvasLayer/UI/MapControlPanel" to="." method="_on_game_session_menu_button_pressed"]
[connection signal="minimap_clicked" from="UICanvasLayer/UI/MapControlPanel" to="MapView" method="_on_minimap_clicked"]
diff --git a/game/src/Game/GameSession/MapView.tscn b/game/src/Game/GameSession/MapView.tscn
index dff02a6..385a24d 100644
--- a/game/src/Game/GameSession/MapView.tscn
+++ b/game/src/Game/GameSession/MapView.tscn
@@ -50,4 +50,10 @@ mesh = SubResource("MapMesh_3gtsd")
transform = Transform3D(10, 0, 0, 0, 10, 0, 0, 0, 10, 0, -1, 0)
mesh = SubResource("PlaneMesh_fnhgl")
+[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, 0.707107, 0.707107, 0, -0.707107, 0.707107, 0, 10, 10)
+light_energy = 1.5
+light_bake_mode = 0
+sky_mode = 1
+
[connection signal="detailed_view_changed" from="." to="MapText" method="set_visible"]
diff --git a/game/src/Game/GameSession/ModelManager.gd b/game/src/Game/GameSession/ModelManager.gd
new file mode 100644
index 0000000..17d2c1e
--- /dev/null
+++ b/game/src/Game/GameSession/ModelManager.gd
@@ -0,0 +1,131 @@
+class_name ModelManager
+extends Node3D
+
+@export var _map_view : MapView
+
+const MODEL_SCALE : float = 1.0 / 256.0
+
+func generate_units() -> void:
+ XACLoader.setup_flag_shader()
+
+ for unit : Dictionary in ModelSingleton.get_units():
+ _generate_unit(unit)
+
+func _generate_unit(unit_dict : Dictionary) -> void:
+ const culture_key : StringName = &"culture"
+ const model_key : StringName = &"model"
+ const mount_model_key : StringName = &"mount_model"
+ const mount_attach_node_key : StringName = &"mount_attach_node"
+ const flag_index_key : StringName = &"flag_index"
+ const flag_floating_key : StringName = &"flag_floating"
+ const position_key : StringName = &"position"
+ const rotation_key : StringName = &"rotation"
+ const primary_colour_key : StringName = &"primary_colour"
+ const secondary_colour_key : StringName = &"secondary_colour"
+ const tertiary_colour_key : StringName = &"tertiary_colour"
+
+ var model : Node3D = _generate_model(unit_dict[model_key], unit_dict[culture_key])
+ if not model:
+ return
+
+ if mount_model_key in unit_dict and mount_attach_node_key in unit_dict:
+ # This must be a UnitModel so we can attach the rider to it
+ var mount_model : Node3D = _generate_model(unit_dict[mount_model_key], unit_dict[culture_key], true)
+ if mount_model:
+ mount_model.attach_model(unit_dict[mount_attach_node_key], model)
+ model = mount_model
+
+ var rotation : float = unit_dict.get(rotation_key, 0.0)
+
+ var flag_dict : Dictionary = ModelSingleton.get_flag_model(unit_dict.get(flag_floating_key, false))
+ if flag_dict:
+ var flag_model : UnitModel = _generate_model(flag_dict, "", true)
+ if flag_model:
+ flag_model.set_flag_index(unit_dict[flag_index_key])
+ flag_model.current_anim = UnitModel.Anim.IDLE
+ flag_model.scale /= model.scale
+ flag_model.rotate_y(-rotation)
+
+ model.add_child(flag_model)
+
+ model.scale *= MODEL_SCALE
+ model.rotate_y(PI + rotation)
+ model.set_position(_map_view._map_to_world_coords(unit_dict[position_key]) + Vector3(0, 0.1 * MODEL_SCALE, 0))
+
+ if model is UnitModel:
+ model.current_anim = UnitModel.Anim.IDLE
+
+ model.primary_colour = unit_dict[primary_colour_key]
+ model.secondary_colour = unit_dict[secondary_colour_key]
+ model.tertiary_colour = unit_dict[tertiary_colour_key]
+
+ 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"
+ const idle_key : StringName = &"idle"
+ const move_key : StringName = &"move"
+ const attack_key : StringName = &"attack"
+ const attachments_key : StringName = &"attachments"
+
+ const animation_file_key : StringName = &"file"
+ const animation_time_key : StringName = &"time"
+
+ const attachment_node_key : StringName = &"node"
+ const attachment_model_key : StringName = &"model"
+
+ # Model
+ is_unit = is_unit or (
+ # Needed for animations
+ idle_key in model_dict or move_key in model_dict or attack_key in model_dict
+ # Currently needs UnitModel's attach_model helper function
+ or attachments_key in model_dict
+ )
+
+ var model : Node3D = XACLoader.get_xac_model(model_dict[file_key], is_unit)
+ if not model:
+ return null
+ model.scale *= model_dict[scale_key]
+
+ if model is UnitModel:
+ # Animations
+ var idle_dict : Dictionary = model_dict.get(idle_key, {})
+ if idle_dict:
+ model.idle_anim = XSMLoader.get_xsm_animation(idle_dict[animation_file_key])
+ model.scroll_speed_idle = idle_dict[animation_time_key]
+
+ var move_dict : Dictionary = model_dict.get(move_key, {})
+ if move_dict:
+ model.move_anim = XSMLoader.get_xsm_animation(move_dict[animation_file_key])
+ model.scroll_speed_move = move_dict[animation_time_key]
+
+ var attack_dict : Dictionary = model_dict.get(attack_key, {})
+ if attack_dict:
+ model.attack_anim = XSMLoader.get_xsm_animation(attack_dict[animation_file_key])
+ model.scroll_speed_attack = attack_dict[animation_time_key]
+
+ # Attachments
+ for attachment_dict : Dictionary in model_dict.get(attachments_key, []):
+ var attachment_model : Node3D = _generate_model(attachment_dict[attachment_model_key], culture)
+ if attachment_model:
+ model.attach_model(attachment_dict[attachment_node_key], attachment_model)
+
+ if culture:
+ const gun_bone_name : String = "GunNode"
+ if model.has_bone(gun_bone_name):
+ var gun_dict : Dictionary = ModelSingleton.get_cultural_gun_model(culture)
+ if gun_dict:
+ var gun_model : Node3D = _generate_model(gun_dict, culture)
+ if gun_model:
+ model.attach_model(gun_bone_name, gun_model)
+
+ const helmet_bone_name : String = "HelmetNode"
+ if model.has_bone(helmet_bone_name):
+ var helmet_dict : Dictionary = ModelSingleton.get_cultural_helmet_model(culture)
+ if helmet_dict:
+ var helmet_model : Node3D = _generate_model(helmet_dict, culture)
+ if helmet_model:
+ model.attach_model(helmet_bone_name, helmet_model)
+
+ return model