class_name BattleScene extends Node3D @export var actionBox:ActionBox = null @export var battleFighterScenes:Node @export var cursorScenes:Node signal neverEmitted func _init() ->void: BATTLE.battleScene = self BATTLE.battleStarted.connect(onBattleStarted) func onBattleStarted() -> void: pass func getBattleDecisions(fighters:Array[BattleFighter]) -> Array[BattleDecision]: var decisions:Array[BattleDecision] = [] while fighters.size() > decisions.size(): var fighter = fighters[decisions.size()] var decision:BattleDecision = null # Simulate walking forward animation like in Final Fantasy await get_tree().create_timer(0.5).timeout # Until decision made... while decision == null: # Get the selected action actionBox.visible = true var action = await self.actionBox.getAction(fighter) # Go back to previous fighter if action == ActionBox.Action.BACK: decisions.pop_back() actionBox.visible = false break elif action == ActionBox.Action.ATTACK: var targets = await _getTargets(fighter, fighter.movePrimary) # Get cursor if decision != null: decisions.append(decision) # Return the made decision return decisions func _getTargets(fighter:BattleFighter, move:BattleAction) -> Array[BattleFighter]: # Determine possible targets and whether to blink or not var possiblePositions:Array[BattleSingleton.BattlePosition] = [ BattleSingleton.BattlePosition.RIGHT_TOP_FRONT, BattleSingleton.BattlePosition.RIGHT_MIDDLE_FRONT, BattleSingleton.BattlePosition.RIGHT_BOTTOM_FRONT ] # Should not be possible to have no possible targets here assert(possiblePositions.size() > 0) var activePositions:Array[BattleSingleton.BattlePosition] = [] var selectedPositions:Array[BattleSingleton.BattlePosition] = [] # If there's only one possible target, auto-select it if possiblePositions.size() == 1: selectedPositions.append(possiblePositions[0]) # Here we wait for a selection to be confirmed. while selectedPositions.size() == 0: var blink = activePositions.size() > 1 activePositions.clear() # activePositions.append(possiblePositions[0]) # For now, just single target # Sake of testing just showing all blinking blink = true for pos in possiblePositions: activePositions.append(pos) # Show cursors for cursor in cursorScenes.get_children(): if !(cursor is BattleCursorIcon): continue if cursor.battlePosition in activePositions: if blink: cursor.mode = BattleCursorIcon.Mode.BLINKING else: cursor.mode = BattleCursorIcon.Mode.ACTIVE else: cursor.mode = BattleCursorIcon.Mode.INACTIVE # TODO: Allow movement here, wait for selection, etc. # Wait 1 second for now and select all possible targets await get_tree().create_timer(1.0).timeout selectedPositions = possiblePositions # By this point selection has been made, hide all cursors for cursor in cursorScenes.get_children(): if !(cursor is BattleCursorIcon): continue cursor.mode = BattleCursorIcon.Mode.INACTIVE # Convert selected positions to fighters var targets:Array[BattleFighter] = [] for pos in selectedPositions: var targetFighter = BATTLE.getFighterAtPosition(pos) if targetFighter != null: targets.append(targetFighter) # Should not be possible to have no targets here assert(targets.size() > 0) return targets func getFighterSceneAtPosition(pos:BattleSingleton.BattlePosition) -> BattleFighterScene: for fighterScene in battleFighterScenes.get_children(): if !(fighterScene is BattleFighterScene): continue if fighterScene.battlePosition == pos: return fighterScene return null func getBattleCursorAtPosition(pos:BattleSingleton.BattlePosition) -> BattleCursorIcon: for cursorScene in cursorScenes.get_children(): if !(cursorScene is BattleCursorIcon): continue if cursorScene.battlePosition == pos: return cursorScene return null