From b09eee0805631b3272b56a5c6e8e69c527fef8fb Mon Sep 17 00:00:00 2001 From: Luca Junge Date: Sun, 29 Sep 2024 11:10:46 +0200 Subject: [PATCH] fixes saving of party monsters, adds display of monster stats in battle ui --- entities/monster/monster.gd | 20 ++-- entities/player/player.gd | 47 +++++--- game.gd | 2 +- globals/Utils.gd | 8 ++ resources/monster_data.gd | 7 +- ui/battle_ui/battle_ui.gd | 15 ++- ui/battle_ui/battle_ui.tscn | 160 ++++++++++++++++++++++---- ui/ingame_controls/camera_controls.gd | 2 - ui/ui.gd | 1 + 9 files changed, 201 insertions(+), 61 deletions(-) diff --git a/entities/monster/monster.gd b/entities/monster/monster.gd index 399f959..9ad958e 100644 --- a/entities/monster/monster.gd +++ b/entities/monster/monster.gd @@ -10,6 +10,7 @@ var spawn_point: Vector3 = Vector3(0, 0, 0) @onready var frequency: float = 1.0 @onready var amplitude: float = 0.5 var in_battle: bool = false +var idle: bool = false # Called when the node enters the scene tree for the first time. func _ready() -> void: @@ -28,7 +29,11 @@ func _physics_process(delta: float) -> void: var x_movement = sin(time * frequency) * amplitude var y_movement = sin(time * 25) * 4.0 var z_movement = cos(time * frequency) * amplitude - velocity = Vector3(x_movement, y_movement, z_movement) + + if not idle: + velocity = Vector3(x_movement, y_movement, z_movement) + else: + velocity = Vector3(0, y_movement, 0) # if move_and_slide reports collisions if move_and_slide(): @@ -39,15 +44,4 @@ func _physics_process(delta: float) -> void: if collider.name == "Player": velocity = Vector3.ZERO in_battle = true - - # calculate players new position - # from the camera 3 units backwards - var camera = collider.find_child("Camera3D") - - # local z axis of the camera - var local_z = camera.global_transform.basis.z - - var new_player_position = camera.global_transform.origin + local_z * 3 - - collider.start_battle(self, new_player_position) - #rotate_toward(rotation.z, collider.rotation.z, 1.0) + collider.start_battle(self) diff --git a/entities/player/player.gd b/entities/player/player.gd index 412fb85..c19cca7 100644 --- a/entities/player/player.gd +++ b/entities/player/player.gd @@ -2,9 +2,13 @@ extends CharacterBody3D @onready var animated_mesh = $GobotSkin var in_battle: bool = false +var enemy: MonsterData = null const SPEED = 5.0 const JUMP_VELOCITY = 4.5 +func _ready() -> void: + Utils.set_player(self) + func on_save_game(saved_data : Array[SavedData]): var data = SavedData.new() data.position = global_position @@ -17,6 +21,9 @@ func on_before_load_game(): func on_load_game(saved_data: SavedData): global_position = saved_data.position + + # Update the global reference to the player + Utils.set_player(self) func _physics_process(delta: float) -> void: if in_battle == true: @@ -76,29 +83,37 @@ func _physics_process(delta: float) -> void: # the player is positioned (mostly somewhere else than the current position) # ui changes # music changes -func start_battle(enemy: Node3D, player_position: Vector3) -> void: - position = Vector3(player_position.x, position.y, player_position.z) +func start_battle(p_enemy: Node3D) -> void: + enemy = p_enemy.data + var camera: Camera3D = $CameraRoot/SpringArm3D/Camera3D + # local z axis of the camera + var local_z = camera.global_transform.basis.z + var new_player_position = camera.global_transform.origin + local_z * 3 + var monster_position = camera.global_transform.origin + local_z * 2 + position = Vector3(new_player_position.x, position.y, new_player_position.z) + in_battle = true velocity = Vector3.ZERO animated_mesh.idle() UI.show_battle_ui(true) UI.show_ingame_controls(false) + # Spawn player monster + var monster_data : MonsterData = SaveManager.current_save.party[0] + var monster = Monster.new() + monster.data = monster_data + monster.idle = true + print("%s (%s), Lv. %s, %s XP" % [monster.data.name, monster.data.nickname, monster.data.level, monster.data.xp]) + monster.position = Vector3(monster_position.x, position.y + 1, monster_position.z) + add_child(monster) + camera.look_at(monster.position, Vector3.UP, false) + + # How to attack and finish the battle? - await get_tree().create_timer(2.0).timeout + + await get_tree().create_timer(5.0).timeout print("Battle over") + remove_child(monster) + monster.queue_free() in_battle = false - -func save() -> Dictionary: - var save_dict = { - "player_transform": { - "pos_x": global_position.x, - "pos_y": global_position.y, - "pos_z": global_position.z, - "rot_x": global_rotation.x, - "rot_y": global_rotation.y, - "rot_z": global_rotation.z - } - } - return save_dict diff --git a/game.gd b/game.gd index 2589d66..1962d0c 100644 --- a/game.gd +++ b/game.gd @@ -37,7 +37,7 @@ func start_new_game() -> void: # Give the player a monster var monster = MonsterData.new() - monster.set_data("debuggy") + monster.set_values("debuggy", { "current_health": 12 }, 5) SaveManager.current_save.party.push_back(monster) # Update the UI once diff --git a/globals/Utils.gd b/globals/Utils.gd index 7e7e727..cbe3966 100644 --- a/globals/Utils.gd +++ b/globals/Utils.gd @@ -1,5 +1,7 @@ extends Node +var player: Node3D = null + # Called when the node enters the scene tree for the first time. func _ready() -> void: @@ -14,3 +16,9 @@ func load_base_monster_data(p_unique_id) -> MonsterData: else: printerr("Monster.gd: No monster with the ID %s found" % p_unique_id) return null + +func set_player(p_player) -> void: + player = p_player + +func get_player() -> Node3D: + return player diff --git a/resources/monster_data.gd b/resources/monster_data.gd index 3923fc2..ec44e7b 100644 --- a/resources/monster_data.gd +++ b/resources/monster_data.gd @@ -25,13 +25,13 @@ signal on_level_up @export var defense: int = 1 @export var tempo: int = 1 @export var level: int = 1 -@export var xp: int = 1 +@export var xp: int = 0 @export var nickname: String = "" @export var xp_for_levelup: int = 1 # The ID is the filename of the monster from res://entities/monsters/.tres -func set_data(p_unique_id = "", current_values: Dictionary = {}, p_level: int = 1) -> void: +func set_values(p_unique_id = "", current_values: Dictionary = {}, p_level: int = 1) -> void: if p_unique_id.is_empty(): printerr("Monster.gd: No ID given") return @@ -61,7 +61,8 @@ func set_data(p_unique_id = "", current_values: Dictionary = {}, p_level: int = return # else, set custom values here - # TODO + for key in current_values: + self[key] = current_values[key] ## This sets the monster to the specified level func set_level(p_level: int) -> void: diff --git a/ui/battle_ui/battle_ui.gd b/ui/battle_ui/battle_ui.gd index 187ffe6..28e8279 100644 --- a/ui/battle_ui/battle_ui.gd +++ b/ui/battle_ui/battle_ui.gd @@ -7,8 +7,21 @@ func _ready() -> void: self.visible = false for i in range(4): var button = move_button.instantiate() - $MarginContainer/HBoxContainer/BattleMovesMenu.add_child(button) + %BattleMovesMenu.add_child(button) +func update() -> void: + var player = Utils.get_player() + var player_fighter = SaveManager.current_save.party[0] as MonsterData + + %PartyFighterLevel.text = "Lv. %s" % str(player_fighter.level) + %PartyFighterName.text = player_fighter.nickname if not player_fighter.nickname.is_empty() else player_fighter.name + %PartyFighterHealthbar.max_value = player_fighter.health + %PartyFighterHealthbar.value = player_fighter.current_health + + %EnemyMonsterLevel.text = "Lv. %s" % player.enemy.level + %EnemyMonsterName.text = player.enemy.name + %EnemyMonsterHealthbar.max_value = player.enemy.health + %EnemyMonsterHealthbar.value = player.enemy.current_health func _on_battle_button_pressed() -> void: print("attack here") diff --git a/ui/battle_ui/battle_ui.tscn b/ui/battle_ui/battle_ui.tscn index 579dd28..f1223d9 100644 --- a/ui/battle_ui/battle_ui.tscn +++ b/ui/battle_ui/battle_ui.tscn @@ -74,7 +74,113 @@ grow_vertical = 2 mouse_filter = 2 script = ExtResource("1_jyqir") -[node name="MarginContainer" type="MarginContainer" parent="."] +[node name="TopMarginContainer" type="MarginContainer" parent="."] +layout_mode = 1 +anchors_preset = 10 +anchor_right = 1.0 +grow_horizontal = 2 +theme_override_constants/margin_left = 30 +theme_override_constants/margin_top = 50 +theme_override_constants/margin_right = 30 + +[node name="EnemyContainer" type="HBoxContainer" parent="TopMarginContainer"] +layout_mode = 2 +size_flags_vertical = 8 +theme_override_constants/separation = 16 +alignment = 2 + +[node name="PartyAliveStatus" type="VBoxContainer" parent="TopMarginContainer/EnemyContainer"] +layout_mode = 2 + +[node name="PartyAliveStatus1" type="TextureRect" parent="TopMarginContainer/EnemyContainer/PartyAliveStatus"] +custom_minimum_size = Vector2(32, 32) +layout_mode = 2 +size_flags_horizontal = 0 +texture = ExtResource("2_keyyt") +expand_mode = 2 + +[node name="PartyAliveStatus2" type="TextureRect" parent="TopMarginContainer/EnemyContainer/PartyAliveStatus"] +self_modulate = Color(1, 1, 1, 0.392157) +custom_minimum_size = Vector2(32, 32) +layout_mode = 2 +size_flags_horizontal = 0 +texture = ExtResource("2_keyyt") +expand_mode = 2 + +[node name="PartyAliveStatus3" type="TextureRect" parent="TopMarginContainer/EnemyContainer/PartyAliveStatus"] +self_modulate = Color(1, 1, 1, 0.392157) +custom_minimum_size = Vector2(32, 32) +layout_mode = 2 +size_flags_horizontal = 0 +texture = ExtResource("2_keyyt") +expand_mode = 2 + +[node name="PartyAliveStatus4" type="TextureRect" parent="TopMarginContainer/EnemyContainer/PartyAliveStatus"] +self_modulate = Color(1, 1, 1, 0.392157) +custom_minimum_size = Vector2(32, 32) +layout_mode = 2 +size_flags_horizontal = 0 +texture = ExtResource("2_keyyt") +expand_mode = 2 + +[node name="PartyAliveStatus5" type="TextureRect" parent="TopMarginContainer/EnemyContainer/PartyAliveStatus"] +self_modulate = Color(1, 1, 1, 0.392157) +custom_minimum_size = Vector2(32, 32) +layout_mode = 2 +size_flags_horizontal = 0 +texture = ExtResource("2_keyyt") +expand_mode = 2 + +[node name="PartyAliveStatus6" type="TextureRect" parent="TopMarginContainer/EnemyContainer/PartyAliveStatus"] +self_modulate = Color(1, 1, 1, 0.392157) +custom_minimum_size = Vector2(32, 32) +layout_mode = 2 +size_flags_horizontal = 0 +texture = ExtResource("2_keyyt") +expand_mode = 2 + +[node name="PartyFighterInfo" type="VBoxContainer" parent="TopMarginContainer/EnemyContainer"] +layout_mode = 2 +size_flags_vertical = 0 +theme_override_constants/separation = 10 + +[node name="LevelAndGender" type="HBoxContainer" parent="TopMarginContainer/EnemyContainer/PartyFighterInfo"] +layout_mode = 2 + +[node name="Level" type="PanelContainer" parent="TopMarginContainer/EnemyContainer/PartyFighterInfo/LevelAndGender"] +layout_mode = 2 +theme_override_styles/panel = SubResource("StyleBoxFlat_6o8cs") + +[node name="EnemyMonsterLevel" type="Label" parent="TopMarginContainer/EnemyContainer/PartyFighterInfo/LevelAndGender/Level"] +unique_name_in_owner = true +layout_mode = 2 +text = "Lv. 99" +label_settings = SubResource("LabelSettings_38ujs") + +[node name="EnemyMonsterGender" type="TextureRect" parent="TopMarginContainer/EnemyContainer/PartyFighterInfo/LevelAndGender"] +unique_name_in_owner = true +self_modulate = Color(0.450091, 0.470517, 0.93375, 1) +custom_minimum_size = Vector2(12, 12) +layout_mode = 2 +texture = ExtResource("3_fa6tk") +expand_mode = 2 +stretch_mode = 4 + +[node name="EnemyMonsterName" type="Label" parent="TopMarginContainer/EnemyContainer/PartyFighterInfo"] +unique_name_in_owner = true +layout_mode = 2 +text = "Monstername" +label_settings = SubResource("LabelSettings_kcdfy") + +[node name="EnemyMonsterHealthbar" type="ProgressBar" parent="TopMarginContainer/EnemyContainer/PartyFighterInfo"] +unique_name_in_owner = true +layout_mode = 2 +theme_override_styles/background = SubResource("StyleBoxFlat_auqmk") +theme_override_styles/fill = SubResource("StyleBoxFlat_84eln") +value = 50.0 +show_percentage = false + +[node name="BottomMarginContainer" type="MarginContainer" parent="."] layout_mode = 1 anchors_preset = 12 anchor_top = 1.0 @@ -87,25 +193,25 @@ theme_override_constants/margin_left = 30 theme_override_constants/margin_right = 30 theme_override_constants/margin_bottom = 50 -[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer"] +[node name="HBoxContainer" type="HBoxContainer" parent="BottomMarginContainer"] layout_mode = 2 -[node name="Left" type="HBoxContainer" parent="MarginContainer/HBoxContainer"] +[node name="PartyFighterContainer" type="HBoxContainer" parent="BottomMarginContainer/HBoxContainer"] layout_mode = 2 size_flags_vertical = 8 theme_override_constants/separation = 16 -[node name="PartyAliveStatus" type="VBoxContainer" parent="MarginContainer/HBoxContainer/Left"] +[node name="PartyAliveStatus" type="VBoxContainer" parent="BottomMarginContainer/HBoxContainer/PartyFighterContainer"] layout_mode = 2 -[node name="Monster1" type="TextureRect" parent="MarginContainer/HBoxContainer/Left/PartyAliveStatus"] +[node name="PartyAliveStatus1" type="TextureRect" parent="BottomMarginContainer/HBoxContainer/PartyFighterContainer/PartyAliveStatus"] custom_minimum_size = Vector2(32, 32) layout_mode = 2 size_flags_horizontal = 0 texture = ExtResource("2_keyyt") expand_mode = 2 -[node name="Monster2" type="TextureRect" parent="MarginContainer/HBoxContainer/Left/PartyAliveStatus"] +[node name="PartyAliveStatus2" type="TextureRect" parent="BottomMarginContainer/HBoxContainer/PartyFighterContainer/PartyAliveStatus"] self_modulate = Color(1, 1, 1, 0.392157) custom_minimum_size = Vector2(32, 32) layout_mode = 2 @@ -113,7 +219,7 @@ size_flags_horizontal = 0 texture = ExtResource("2_keyyt") expand_mode = 2 -[node name="Monster3" type="TextureRect" parent="MarginContainer/HBoxContainer/Left/PartyAliveStatus"] +[node name="PartyAliveStatus3" type="TextureRect" parent="BottomMarginContainer/HBoxContainer/PartyFighterContainer/PartyAliveStatus"] self_modulate = Color(1, 1, 1, 0.392157) custom_minimum_size = Vector2(32, 32) layout_mode = 2 @@ -121,7 +227,7 @@ size_flags_horizontal = 0 texture = ExtResource("2_keyyt") expand_mode = 2 -[node name="Monster4" type="TextureRect" parent="MarginContainer/HBoxContainer/Left/PartyAliveStatus"] +[node name="PartyAliveStatus4" type="TextureRect" parent="BottomMarginContainer/HBoxContainer/PartyFighterContainer/PartyAliveStatus"] self_modulate = Color(1, 1, 1, 0.392157) custom_minimum_size = Vector2(32, 32) layout_mode = 2 @@ -129,7 +235,7 @@ size_flags_horizontal = 0 texture = ExtResource("2_keyyt") expand_mode = 2 -[node name="Monster5" type="TextureRect" parent="MarginContainer/HBoxContainer/Left/PartyAliveStatus"] +[node name="PartyAliveStatus5" type="TextureRect" parent="BottomMarginContainer/HBoxContainer/PartyFighterContainer/PartyAliveStatus"] self_modulate = Color(1, 1, 1, 0.392157) custom_minimum_size = Vector2(32, 32) layout_mode = 2 @@ -137,7 +243,7 @@ size_flags_horizontal = 0 texture = ExtResource("2_keyyt") expand_mode = 2 -[node name="Monster6" type="TextureRect" parent="MarginContainer/HBoxContainer/Left/PartyAliveStatus"] +[node name="PartyAliveStatus6" type="TextureRect" parent="BottomMarginContainer/HBoxContainer/PartyFighterContainer/PartyAliveStatus"] self_modulate = Color(1, 1, 1, 0.392157) custom_minimum_size = Vector2(32, 32) layout_mode = 2 @@ -145,24 +251,26 @@ size_flags_horizontal = 0 texture = ExtResource("2_keyyt") expand_mode = 2 -[node name="PartyFighterInfo" type="VBoxContainer" parent="MarginContainer/HBoxContainer/Left"] +[node name="PartyFighterInfo" type="VBoxContainer" parent="BottomMarginContainer/HBoxContainer/PartyFighterContainer"] layout_mode = 2 size_flags_vertical = 0 theme_override_constants/separation = 10 -[node name="LevelAndGender" type="HBoxContainer" parent="MarginContainer/HBoxContainer/Left/PartyFighterInfo"] +[node name="LevelAndGender" type="HBoxContainer" parent="BottomMarginContainer/HBoxContainer/PartyFighterContainer/PartyFighterInfo"] layout_mode = 2 -[node name="Level" type="PanelContainer" parent="MarginContainer/HBoxContainer/Left/PartyFighterInfo/LevelAndGender"] +[node name="Level" type="PanelContainer" parent="BottomMarginContainer/HBoxContainer/PartyFighterContainer/PartyFighterInfo/LevelAndGender"] layout_mode = 2 theme_override_styles/panel = SubResource("StyleBoxFlat_6o8cs") -[node name="Label" type="Label" parent="MarginContainer/HBoxContainer/Left/PartyFighterInfo/LevelAndGender/Level"] +[node name="PartyFighterLevel" type="Label" parent="BottomMarginContainer/HBoxContainer/PartyFighterContainer/PartyFighterInfo/LevelAndGender/Level"] +unique_name_in_owner = true layout_mode = 2 text = "Lv. 99" label_settings = SubResource("LabelSettings_38ujs") -[node name="Gender" type="TextureRect" parent="MarginContainer/HBoxContainer/Left/PartyFighterInfo/LevelAndGender"] +[node name="PartyFighterGender" type="TextureRect" parent="BottomMarginContainer/HBoxContainer/PartyFighterContainer/PartyFighterInfo/LevelAndGender"] +unique_name_in_owner = true self_modulate = Color(0.450091, 0.470517, 0.93375, 1) custom_minimum_size = Vector2(12, 12) layout_mode = 2 @@ -170,29 +278,31 @@ texture = ExtResource("3_fa6tk") expand_mode = 2 stretch_mode = 4 -[node name="MonsterName" type="Label" parent="MarginContainer/HBoxContainer/Left/PartyFighterInfo"] +[node name="PartyFighterName" type="Label" parent="BottomMarginContainer/HBoxContainer/PartyFighterContainer/PartyFighterInfo"] +unique_name_in_owner = true layout_mode = 2 text = "Monstername" label_settings = SubResource("LabelSettings_kcdfy") -[node name="ProgressBar" type="ProgressBar" parent="MarginContainer/HBoxContainer/Left/PartyFighterInfo"] +[node name="PartyFighterHealthbar" type="ProgressBar" parent="BottomMarginContainer/HBoxContainer/PartyFighterContainer/PartyFighterInfo"] +unique_name_in_owner = true layout_mode = 2 theme_override_styles/background = SubResource("StyleBoxFlat_auqmk") theme_override_styles/fill = SubResource("StyleBoxFlat_84eln") value = 50.0 show_percentage = false -[node name="Spacer" type="Control" parent="MarginContainer/HBoxContainer"] +[node name="Spacer" type="Control" parent="BottomMarginContainer/HBoxContainer"] layout_mode = 2 size_flags_horizontal = 3 size_flags_stretch_ratio = 0.5 -[node name="MainBattleMenu" type="VBoxContainer" parent="MarginContainer/HBoxContainer"] +[node name="MainBattleMenu" type="VBoxContainer" parent="BottomMarginContainer/HBoxContainer"] unique_name_in_owner = true layout_mode = 2 size_flags_horizontal = 3 -[node name="BattleButton" type="Button" parent="MarginContainer/HBoxContainer/MainBattleMenu"] +[node name="BattleButton" type="Button" parent="BottomMarginContainer/HBoxContainer/MainBattleMenu"] layout_mode = 2 theme_override_constants/h_separation = 18 theme_override_constants/icon_max_width = 20 @@ -212,7 +322,7 @@ text = "Battle" icon = ExtResource("4_saqy8") alignment = 0 -[node name="PartyButton" type="Button" parent="MarginContainer/HBoxContainer/MainBattleMenu"] +[node name="PartyButton" type="Button" parent="BottomMarginContainer/HBoxContainer/MainBattleMenu"] layout_mode = 2 theme_override_constants/h_separation = 18 theme_override_constants/icon_max_width = 20 @@ -232,7 +342,7 @@ text = "Party" icon = ExtResource("5_pnobx") alignment = 0 -[node name="ItemsButton" type="Button" parent="MarginContainer/HBoxContainer/MainBattleMenu"] +[node name="ItemsButton" type="Button" parent="BottomMarginContainer/HBoxContainer/MainBattleMenu"] layout_mode = 2 theme_override_constants/h_separation = 18 theme_override_constants/icon_max_width = 20 @@ -252,7 +362,7 @@ text = "Items" icon = ExtResource("6_ikm1n") alignment = 0 -[node name="RunButton" type="Button" parent="MarginContainer/HBoxContainer/MainBattleMenu"] +[node name="RunButton" type="Button" parent="BottomMarginContainer/HBoxContainer/MainBattleMenu"] layout_mode = 2 theme_override_constants/h_separation = 18 theme_override_constants/icon_max_width = 20 @@ -272,10 +382,10 @@ text = "Run" icon = ExtResource("7_tihhr") alignment = 0 -[node name="BattleMovesMenu" type="VBoxContainer" parent="MarginContainer/HBoxContainer"] +[node name="BattleMovesMenu" type="VBoxContainer" parent="BottomMarginContainer/HBoxContainer"] unique_name_in_owner = true visible = false layout_mode = 2 size_flags_horizontal = 3 -[connection signal="pressed" from="MarginContainer/HBoxContainer/MainBattleMenu/BattleButton" to="." method="_on_battle_button_pressed"] +[connection signal="pressed" from="BottomMarginContainer/HBoxContainer/MainBattleMenu/BattleButton" to="." method="_on_battle_button_pressed"] diff --git a/ui/ingame_controls/camera_controls.gd b/ui/ingame_controls/camera_controls.gd index 7c35e52..f30e9d6 100644 --- a/ui/ingame_controls/camera_controls.gd +++ b/ui/ingame_controls/camera_controls.gd @@ -8,8 +8,6 @@ var damping_factor: float = 0.08 func _process(delta: float) -> void: simulate_joystick_motion(JOY_AXIS_RIGHT_X, delta_position.x * delta * speed, 0) - print(delta_position) - #delta_position *= 0.92 delta_position *= (1 - damping_factor) func _gui_input(event: InputEvent) -> void: diff --git a/ui/ui.gd b/ui/ui.gd index 5323b62..1d81cec 100644 --- a/ui/ui.gd +++ b/ui/ui.gd @@ -32,6 +32,7 @@ func show_ingame_controls(p_visible = true) -> void: func show_battle_ui(p_visible = true) -> void: battle_ui.visible = p_visible + battle_ui.update() func _on_ingame_controls_menu_button_clicked() -> void: ingame_menu.visible = true