using Godot; using System; using System.Collections.Generic; using System.Linq; using Babushka.scripts.CSharp.Common.Fight; using Babushka.scripts.CSharp.Common.Fight.ActionDetails; using Babushka.scripts.CSharp.Common.Util; public partial class AllFightersVisual : Node { [ExportCategory("References")] [Export] private Node2D _allyFighters = null!; [Export] private Node2D _enemyFighters = null!; [ExportCategory("Fighter Visual Scenes")] [Export] private PackedScene _blobFighterVisual = null!; [Export] private PackedScene _bigBlobFighterVisual = null!; [Export] private PackedScene _mavkaFighterVisual = null!; [Export] private PackedScene _yourMomFighterVisual = null!; [Export] private PackedScene _vesnaFighterVisual = null!; [ExportCategory("Settings")] [Export(PropertyHint.ArrayType)] private float[] _positionDistanceFromCenter = [10, 20, 30]; private Dictionary _fighterVisuals = new(); #region Shortcuts private FightWorld.FightHappeningData HappeningData => FightWorld.Instance.fightHappeningData ?? throw new NoFightHappeningException(); #endregion #region State Reactions public void FightHappeningStateChange(FightHappening.FightState from, FightHappening.FightState to) { if (to == FightHappening.FightState.FightersEnterAnim) { EnterFighter(); } if (to == FightHappening.FightState.InputActionDetail) { if (HappeningData.actionStaging!.CurrentDetail() is TargetSelectActionDetail targetDetail) { ShowTargetSelect(targetDetail); } } if (from == FightHappening.FightState.InputActionDetail) { HideTargetSelect(); } } public void EnterFighter() { if (HappeningData.fightersEnterStaging == null) return; if (!HappeningData.fightersEnterStaging.HasAnyToExecute()) return; foreach (var fighter in HappeningData.fightersEnterStaging.enteringEnemyFighters) { var packedScene = fighter.type switch { FightWorld.Fighter.Type.Blob => _blobFighterVisual, FightWorld.Fighter.Type.BigBlob => _bigBlobFighterVisual, FightWorld.Fighter.Type.Mavka => _mavkaFighterVisual, FightWorld.Fighter.Type.YourMom => _yourMomFighterVisual, FightWorld.Fighter.Type.Vesna => _vesnaFighterVisual, _ => throw new ArgumentOutOfRangeException() }; var fighterVisual = packedScene.Instantiate(); fighterVisual.Initialize(fighter); _enemyFighters.AddChild(fighterVisual); fighterVisual.Position = new Vector2(_positionDistanceFromCenter[_enemyFighters.GetChildCount() - 1], 0); _fighterVisuals.Add(fighter, fighterVisual); } foreach (var fighter in HappeningData.fightersEnterStaging.enteringAllyFighters) { var packedScene = fighter.type switch { FightWorld.Fighter.Type.Blob => _blobFighterVisual, FightWorld.Fighter.Type.BigBlob => _bigBlobFighterVisual, FightWorld.Fighter.Type.Mavka => _mavkaFighterVisual, FightWorld.Fighter.Type.YourMom => _yourMomFighterVisual, FightWorld.Fighter.Type.Vesna => _vesnaFighterVisual, _ => throw new ArgumentOutOfRangeException() }; var fighterVisual = packedScene.Instantiate(); fighterVisual.Initialize(fighter); _allyFighters.AddChild(fighterVisual); fighterVisual.Position = new Vector2(-_positionDistanceFromCenter[_allyFighters.GetChildCount() - 1], 0); _fighterVisuals.Add(fighter, fighterVisual); } } private void ShowTargetSelect(TargetSelectActionDetail targetDetail) { if (targetDetail.selectEnemy) _fighterVisuals.Where(kv => kv.Key.isEnemy).ForEach(kv => kv.Value.SetTargetSelectionActive(true)); if (targetDetail.selectAlly) _fighterVisuals.Where(kv => !kv.Key.isEnemy).ForEach(kv => kv.Value.SetTargetSelectionActive(true)); } private void HideTargetSelect() { foreach (var visual in _fighterVisuals.Values) { visual.SetTargetSelectionActive(false); } } #endregion public FighterVisual GetVisualForFighter(FightWorld.Fighter fighter) { return _fighterVisuals.TryGetValue(fighter, out var visual) ? visual : throw new InvalidOperationException("No visual for this fighter"); } }