diff --git a/battle/Battle.gd b/battle/Battle.gd index 232cb48..a4c20f3 100644 --- a/battle/Battle.gd +++ b/battle/Battle.gd @@ -1,5 +1,4 @@ class_name BattleSingleton extends Node -const BattleCutsceneAction = preload("res://cutscene/battle/BattleCutsceneAction.gd") enum BattlePosition { LEFT_TOP_BACK, @@ -17,6 +16,17 @@ enum BattlePosition { RIGHT_BOTTOM_FRONT } +static func isPositionRight(battlePos:BattlePosition) -> bool: + return battlePos in [ + BattlePosition.RIGHT_TOP_BACK, + BattlePosition.RIGHT_TOP_FRONT, + BattlePosition.RIGHT_MIDDLE_BACK, + BattlePosition.RIGHT_MIDDLE_FRONT, + BattlePosition.RIGHT_BOTTOM_BACK, + BattlePosition.RIGHT_BOTTOM_FRONT + ] + + # Battle State var active:bool = false var fighterMap:Dictionary[BattlePosition, BattleFighter] = {} diff --git a/battle/fighter/BattleFighterScene.gd b/battle/fighter/BattleFighterScene.gd index 3216721..6c56d8f 100644 --- a/battle/fighter/BattleFighterScene.gd +++ b/battle/fighter/BattleFighterScene.gd @@ -3,6 +3,7 @@ class_name BattleFighterScene extends Node3D @export var battlePosition:BattleSingleton.BattlePosition = BattleSingleton.BattlePosition.LEFT_MIDDLE_FRONT @export var damageLabels:Node3D @export var damageLabelPreset:PackedScene +@export var sprite:AnimatedSprite3D var currentFighter:BattleFighter = null @@ -22,6 +23,13 @@ func _updateFighter() -> void: currentFighter.healthChanged.connect(onDamageTaken) self.visible = true + # Update left/right orientation + if sprite != null: + if BattleSingleton.isPositionRight(battlePosition): + sprite.flip_h = true + else: + sprite.flip_h = false + func _enter_tree() -> void: BATTLE.battleFightersChanged.connect(onFightersChanged) self._updateFighter() diff --git a/battle/fighter/BattleFighterScene.tscn b/battle/fighter/BattleFighterScene.tscn index 6d1c80d..986a70d 100644 --- a/battle/fighter/BattleFighterScene.tscn +++ b/battle/fighter/BattleFighterScene.tscn @@ -9,10 +9,11 @@ [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_e55p4"] shading_mode = 0 -[node name="BattleFighterScene" type="Node3D" node_paths=PackedStringArray("damageLabels")] +[node name="BattleFighterScene" type="Node3D" node_paths=PackedStringArray("damageLabels", "sprite")] script = ExtResource("1_veb1i") damageLabels = NodePath("Labels") damageLabelPreset = ExtResource("2_lciku") +sprite = NodePath("AnimatedSprite3D") metadata/_custom_type_script = "uid://bgycdhsouwhwt" [node name="MeshInstance3D" type="MeshInstance3D" parent="."] diff --git a/cutscene/battle/BattleCutsceneAction.gd b/cutscene/battle/BattleCutsceneAction.gd index cd774d4..a4c5b1f 100644 --- a/cutscene/battle/BattleCutsceneAction.gd +++ b/cutscene/battle/BattleCutsceneAction.gd @@ -1,7 +1,8 @@ class_name BattleCutsceneAction static func battleDecisionCallable(_params:Dictionary) -> int: - print("Battle action executed.") + print("Executing battle action...") + await UI.TEXTBOX.setTextAndWait("Performing battle decision") return Cutscene.CUTSCENE_CONTINUE @@ -12,6 +13,30 @@ static func getBattleDecisionCallable(decision:BattleDecision) -> Dictionary: } static func playerDecisionCallable(_params:Dictionary) -> int: + # First, are all enemies, or all players, defeated? + var allPlayersDead:bool = false + var allEnemiesDead:bool = false + for fighter:BattleFighter in BATTLE.fighterMap.values(): + if fighter == null: + continue + if fighter.status != BattleFighter.Status.DEAD: + continue + if fighter.isPlayerControlled(): + allPlayersDead = false + else: + allEnemiesDead = false + + # If all players are dead, game over unfortunately. + if allPlayersDead: + print("All players defeated! Game Over.") + assert(false) + + # If all enemies are dead, victory! + if allEnemiesDead: + print("All enemies defeated! Victory!") + assert(false) + + # OK we are actually fighting. var decisions:Array[BattleDecision] = [] for fighter:BattleFighter in BATTLE.fighterMap.values(): @@ -52,7 +77,11 @@ static func playerDecisionCallable(_params:Dictionary) -> int: # Turn into cutscene actions. for decision in decisions: + print("Adding decision to cutscene: %s" % decision) _params['cutscene'].addCallable(BattleCutsceneAction.getBattleDecisionCallable(decision)) + + # Then send to next decision + _params['cutscene'].addCallable(BattleCutsceneAction.getPlayerDecisionCallable()) return Cutscene.CUTSCENE_CONTINUE diff --git a/overworld/entity/Entity.gd b/overworld/entity/Entity.gd index c5a58e1..821408b 100644 --- a/overworld/entity/Entity.gd +++ b/overworld/entity/Entity.gd @@ -12,7 +12,8 @@ enum InteractType { NONE, CONVERSATION, ONE_TIME_ITEM, - CUTSCENE + CUTSCENE, + BATTLE_TEST, }; @export_category("Identification") diff --git a/overworld/entity/EntityInteractableArea.gd b/overworld/entity/EntityInteractableArea.gd index ff8381f..8feb044 100644 --- a/overworld/entity/EntityInteractableArea.gd +++ b/overworld/entity/EntityInteractableArea.gd @@ -30,6 +30,9 @@ func isInteractable() -> bool: if entity.oneTimeItem.item == Item.Id.NULL: return false return true + + if entity.interactType == Entity.InteractType.BATTLE_TEST: + return true return false @@ -63,6 +66,18 @@ func onInteract(other:Entity) -> void: entity.cutscene.queue(cutscene) cutscene.start() return + + Entity.InteractType.BATTLE_TEST: + var testEnemy = BattleFighter.new({ + 'controller': BattleFighter.FighterController.AI + }) + var cutscene:Cutscene = Cutscene.new() + cutscene.addCallable(BattleStartAction.getStartBattleCallable({ + BATTLE.BattlePosition.RIGHT_MIDDLE_FRONT: PartySingleton.PARTY_JOHN, + BATTLE.BattlePosition.LEFT_MIDDLE_FRONT: testEnemy + })) + cutscene.start() + return _: pass diff --git a/overworld/map/TestMap.tscn b/overworld/map/TestMap.tscn index df23bfe..a38e253 100644 --- a/overworld/map/TestMap.tscn +++ b/overworld/map/TestMap.tscn @@ -32,6 +32,11 @@ entityId = "bcabec96-8d33-4c16-a997-3bb3b0562b33" interactType = 1 conversation = Array[ExtResource("3_p7git")]([SubResource("Resource_xf0pb")]) +[node name="NotPlayer4" parent="." instance=ExtResource("2_jmygs")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 4.68074, 1.11219, 0.0142021) +entityId = "bcabec96-8d33-4c16-a997-3bb3b0562b33" +interactType = 4 + [node name="NotPlayer2" parent="." instance=ExtResource("2_jmygs")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.00883961, 1.11219, 4.34543) entityId = "ad5a1504-7fbf-45d6-b1bf-6e7af6314066" diff --git a/scene/RootScene.gd b/scene/RootScene.gd index 344f8a2..61de209 100644 --- a/scene/RootScene.gd +++ b/scene/RootScene.gd @@ -7,23 +7,8 @@ class_name RootScene extends Node3D @export var currentScene:Node = null func _enter_tree() -> void: - # SCENE.sceneChanged.connect(onSceneChange) - # SCENE.setScene(SceneSingleton.SceneType.INITIAL) - - SCENE.setScene(SceneSingleton.SceneType.BATTLE) - # Wait a frame - await get_tree().process_frame - - var testEnemy = BattleFighter.new({ - 'controller': BattleFighter.FighterController.AI - }) - BATTLE.startBattle({ - 'fighters': { - # Test fighters - BATTLE.BattlePosition.RIGHT_MIDDLE_FRONT: PartySingleton.PARTY_JOHN, - BATTLE.BattlePosition.LEFT_MIDDLE_FRONT: testEnemy - } - }) + SCENE.sceneChanged.connect(onSceneChange) + SCENE.setScene(SceneSingleton.SceneType.INITIAL) func _exit_tree() -> void: push_error("RootScene should not be removed from the scene tree. This is a bug.") diff --git a/scene/RootScene.tscn b/scene/RootScene.tscn index 2ff2244..02280a8 100644 --- a/scene/RootScene.tscn +++ b/scene/RootScene.tscn @@ -31,4 +31,3 @@ visible = false [node name="CurrentScene" type="Node" parent="."] [node name="RootUI" parent="." instance=ExtResource("6_ajii0")] -visible = false