using System.Collections.Generic; using System.Linq; using ET.EventType; using ET.FUIBattle; using ET.FUIMain; using ET.FUIUnitName; using UnityEngine; namespace ET { public class BattleManagerComponentAwakeSystem : AwakeSystem { public override void Awake(BattleManagerComponent self) { self.Awake(); } } public class BattleManagerComponentUpdateSystem : UpdateSystem { public override void Update(BattleManagerComponent self) { self.Update(); } } public class BattleManagerComponentDestroySystem : DestroySystem { public override void Destroy(BattleManagerComponent self) { self.Destroy(); } } [FriendClass(typeof(BattleManagerComponent))] [FriendClass(typeof(OperationComponent))] [FriendClass(typeof(Battle))] [FriendClass(typeof(Fighter))] [FriendClass(typeof(BattleActionSegment))] [FriendClass(typeof(BattleUnitViewComponent))] public static class BattleManagerComponentSystem { public static void Awake(this BattleManagerComponent self) { } public static void Init(this BattleManagerComponent self, Battle battle) { self.BattleInfo = battle; // 设置好相机位置 var cameraComp = self.ZoneScene().CurrentScene().GetComponent(); cameraComp.StoreCameraInfo(); var cameraPos = cameraComp.GetCameraPos(); cameraComp.SetCameraPos(new Vector3(0, 0, cameraPos.z)); cameraComp.SetOrthoSize(5); // 禁用正常地图操作 self.ZoneScene().CurrentScene().GetComponent().Enabled = false; var gameSceneComp = self.ZoneScene().CurrentScene().GetComponent(); gameSceneComp.Hide(GameSceneType.Main); gameSceneComp.Show(GameSceneType.Battle); var fuiComp = self.ZoneScene().GetComponent(); fuiComp.HideUI(FUIMain.FUI_Main.UIResName); fuiComp.HideUI(FUI_UnitNamePanel.UIResName); // 双方战斗位置 // 初始化我方人员 foreach (var keyValuePair in battle.FighterDic) { var fighter = keyValuePair.Value; var comp = fighter.AddComponent(); comp.Init(fighter.Pos - 1, true); } // 初始化敌方人员 foreach (var keyValuePair in battle.EnemyDic) { var fighter = keyValuePair.Value; var comp = fighter.AddComponent(); comp.Init(fighter.Pos - 1, false); } // for (int i = 0; i < 9; i++) // { // var comp = self.AddChild(); // comp.Init(i, false); // self.EnemyUnits.Add(comp); // } self.DieBattleUnitIds.Clear(); self.DropInfoDict.Clear(); // show battle ui var battleComp = fuiComp.ShowUI(FUI_BattleMain.UIPackageName); battleComp.Init(battle); } public static BattleUnitViewComponent GetFighterViewComponentByPos(this BattleManagerComponent self, int pos) { if (self.BattleInfo.FighterPosDic.TryGetValue(pos, out Fighter fighter)) { return fighter.GetComponent(); } return null; } public static BattleUnitViewComponent GetEnemyViewComponentByPos(this BattleManagerComponent self, int pos) { if (self.BattleInfo.EnemyPosDic.TryGetValue(pos, out Fighter fighter)) { return fighter.GetComponent(); } return null; } public static void Update(this BattleManagerComponent self) { if (self.OneTurnStart && self.CurBASegment != null) { self.CurActionPassedTime += Time.deltaTime; if (self.CurActionPassedTime >= self.CurBASegment.TotalTime) { self.CurActionPassedTime = 0; self.CurBASegment?.Dispose(); self.CurBASegment = null; if (self.BASegmentInfos.Count > 0) { self.ExecuteNextActionSegment(); } else { self.OnOneTurnEnd(); } } } } public static void AddActionSegmentInfo(this BattleManagerComponent self, BattleActionSegmentInfo info) { self.BASegmentInfos.Enqueue(info); } public static void ExecuteNextActionSegment(this BattleManagerComponent self) { if (self.BASegmentInfos.Count > 0) { self.CurActionPassedTime = 0; self.CurBASegment = BattleActionSegmentFactory.Create(self, self.BASegmentInfos.Dequeue()); } } public static void StartOneTurn(this BattleManagerComponent self) { if (self.BASegmentInfos.Count > 0 && !self.OneTurnStart) { self.OneTurnStart = true; self.ExecuteNextActionSegment(); } } public static void OnOneTurnEnd(this BattleManagerComponent self) { self.OneTurnStart = false; Log.Info("OneRoundEnd"); // check battle unit state // self.CheckAllFighterState(); var fuiComp = self.ZoneScene().GetComponent(); var battleComp = fuiComp.GetUI(FUI_BattleMain.UIResName) as FUIBattleMainComponent; battleComp.RefreshUI(); if (self.BattleInfo.BattleState == ConstBattleState.BATTLE_STATE_WIN) { self.OnBattleEnd(true); } else if (self.BattleInfo.BattleState == ConstBattleState.BATTLE_STATE_FAIL) { self.OnBattleEnd(false); } else { self.DieBattleUnitIds.Clear(); self.DropInfoDict.Clear(); var unit = UnitHelper.GetMyUnitFromZoneScene(self.ZoneScene()); BattleHelper.BattleAtkOver(unit).Coroutine(); } } public static void CheckAllFighterState(this BattleManagerComponent self) { foreach (var keyValuePair in self.BattleInfo.FighterDic) { var fighter = keyValuePair.Value; var comp = fighter.GetComponent(); comp.CheckState(); } // 初始化敌方人员 foreach (var keyValuePair in self.BattleInfo.EnemyDic) { var fighter = keyValuePair.Value; var comp = fighter.GetComponent(); comp.CheckState(); } } public static BattleUnitViewComponent GetFighterViewComponent(this BattleManagerComponent self, long fighterId) { var fighter = self.BattleInfo.GetFighter(fighterId); if (fighter == null) { Log.Error($"Can't find attakcer: {fighterId}"); return null; } return fighter.GetComponent(); } private static void CreateMoveToTargetActionSegment(this BattleManagerComponent self, AtkInfo atkInfo,ref List needMoveBackAtkInfos) { var attakerView = self.GetFighterViewComponent(atkInfo.AtkId); var targetView = self.GetFighterViewComponent(atkInfo.TargetId); self.SetFighterStateMsg(attakerView.Fighter, atkInfo); var config = SkillSonConfigCategory.Instance.Get(atkInfo.SonSkillId); if (atkInfo.AtkType == ConstAtkType.ATK_ACTIVE || atkInfo.AtkType == ConstAtkType.ATK_HUNT) { // 攻击,追击,近战都需要跑过去 if (config.CastPosition != ConstCastPosition.ORIGINAL_POS) { var baInfo = new BattleActionSegmentInfo(); baInfo.CastPosition = config.CastPosition; baInfo.Source = attakerView; baInfo.Target = targetView; baInfo.Type = BattleActionSegemntType.MoveToTarget; self.AddActionSegmentInfo(baInfo); needMoveBackAtkInfos.Add(atkInfo); } } } private static void CreateAttackActionSegment(this BattleManagerComponent self, AtkInfo atkInfo) { var attakerView = self.GetFighterViewComponent(atkInfo.AtkId); var targetView = self.GetFighterViewComponent(atkInfo.TargetId); var baInfo = new BattleActionSegmentInfo(); baInfo.Source = attakerView; baInfo.Target = targetView; baInfo.Type = BattleActionSegemntType.Attack; baInfo.SonSkillId = atkInfo.SonSkillId; baInfo.AtkInfo = atkInfo; foreach (HurtInfo hurtInfo in atkInfo.HurtList) { var hurtInfoView = new HurtInfoView(); var hurtTarget = self.BattleInfo.GetFighter(hurtInfo.HurtId); var hurtTargetView = hurtTarget?.GetComponent(); if (hurtTargetView != null) { hurtInfoView.Target = hurtTargetView; } hurtInfoView.DamageValue = hurtInfo.Damage; hurtInfoView.IsCritical = atkInfo.IsCrit; baInfo.HurtInfoViews.Add(hurtInfoView); } self.AddActionSegmentInfo(baInfo); } private static void CreateAttackBackActionSegment(this BattleManagerComponent self, AtkInfo atkInfo) { var attakerView = self.GetFighterViewComponent(atkInfo.AtkId); var targetView = self.GetFighterViewComponent(atkInfo.TargetId); self.SetFighterStateMsg(attakerView.Fighter, atkInfo); var baInfo = new BattleActionSegmentInfo(); var config = SkillSonConfigCategory.Instance.Get(atkInfo.SonSkillId); baInfo.CastPosition = config.CastPosition; baInfo.Source = attakerView; baInfo.Target = targetView; baInfo.Type = BattleActionSegemntType.Attack; foreach (HurtInfo hurtInfo in atkInfo.HurtList) { var hurtInfoView = new HurtInfoView(); var hurtTarget = self.BattleInfo.GetFighter(hurtInfo.HurtId); var hurtTargetView = hurtTarget?.GetComponent(); if (hurtTargetView != null) { hurtInfoView.Target = hurtTargetView; } hurtInfoView.DamageValue = hurtInfo.Damage; hurtInfoView.IsCritical = atkInfo.IsCrit; baInfo.HurtInfoViews.Add(hurtInfoView); } self.AddActionSegmentInfo(baInfo); } private static void CreateMoveBackActionSegment(this BattleManagerComponent self, AtkInfo atkInfo) { var attakerView = self.GetFighterViewComponent(atkInfo.AtkId); var targetView = self.GetFighterViewComponent(atkInfo.TargetId); self.SetFighterStateMsg(attakerView.Fighter, atkInfo); if (atkInfo.AtkType == ConstAtkType.ATK_ACTIVE || atkInfo.AtkType == ConstAtkType.ATK_HUNT) { var config = SkillSonConfigCategory.Instance.Get(atkInfo.SonSkillId); // 追击,近战都需要跑过去 if (config.CastPosition != ConstCastPosition.ORIGINAL_POS) { var baInfo = new BattleActionSegmentInfo(); baInfo.Source = attakerView; baInfo.Target = targetView; baInfo.Type = BattleActionSegemntType.MoveBack; self.AddActionSegmentInfo(baInfo); } } } public static void CreateActionSegmentByRoundInfo(this BattleManagerComponent self, TurnInfo turnInfo) { self.TurnInfos.Add(turnInfo); var atkList = turnInfo.AtkList; if (atkList.Count <= 0) { Log.Warning("No attackInfo"); return; } Queue atkQueue = new Queue(atkList); // 存储需要跑回去的相关攻击信息 List needMoveBackAtkInfos = new List(); while (atkQueue.Count > 0) { var atkInfo = atkQueue.Dequeue(); self.CreateMoveToTargetActionSegment(atkInfo, ref needMoveBackAtkInfos); self.CreateAttackActionSegment(atkInfo); if (atkQueue.Count > 0) { // 反击动作需要插入到近战攻击者跑回去之前 // 查看下一个动作是否是反击 var nextAtkInfo = atkQueue.Peek(); if (nextAtkInfo.AtkType == ConstAtkType.ATK_BACK) { nextAtkInfo = atkQueue.Dequeue(); self.CreateAttackBackActionSegment(nextAtkInfo); } } } // 一个攻击回合结束后,将跑出去的目标归位 foreach (AtkInfo needMoveBackAtkInfo in needMoveBackAtkInfos) { self.CreateMoveBackActionSegment(needMoveBackAtkInfo); } } public static void SetFighterStateMsg(this BattleManagerComponent self, Fighter fighter, AtkInfo atkInfo) { BattleViewHelper.ShowBattleUnitStateMsg(fighter.GetComponent(), atkInfo); } public static void Destroy(this BattleManagerComponent self) { if (self.Parent == null) { return; } self.Exit(); } public static void OnBattleEnd(this BattleManagerComponent self, bool isWin) { self.CurBASegment?.Dispose(); self.CurBASegment = null; self.BASegmentInfos.Clear(); var unit = UnitHelper.GetMyUnitFromZoneScene(self.ZoneScene()); Game.EventSystem.Publish(new EventType.BattleEnd() { Unit = unit, IsWin = isWin}); } public static void Exit(this BattleManagerComponent self) { if (self.ZoneScene() == null) { return; } var cameraComp = self.ZoneScene().CurrentScene().GetComponent(); cameraComp.RestoreCameraInfo(); // 恢复地图操作 self.ZoneScene().CurrentScene().GetComponent().Enabled = true; var gameSceneComp = self.ZoneScene().CurrentScene().GetComponent(); gameSceneComp.Show(GameSceneType.Main); gameSceneComp.Hide(GameSceneType.Battle); var fuiComp = self.ZoneScene().GetComponent(); fuiComp.ShowUI(FUIMain.FUI_Main.UIResName); fuiComp.ShowUI(FUI_UnitNamePanel.UIResName); fuiComp.HideUI(FUI_BattleMain.UIResName); } public static void AddDropItemInfo(this BattleManagerComponent self, BattleUnitDrop dropInfo) { self.DropInfoDict.Add(dropInfo.BattleUnitId, dropInfo); } public static void AddDieBattleUnit(this BattleManagerComponent self, long id) { self.DieBattleUnitIds.Add(id); } public static void OnAttackActionEnd(this BattleManagerComponent self, AttackActionEnd actionInfo) { var fuiComp = self.ZoneScene().GetComponent(); var battleMain = fuiComp.GetUI(FUI_BattleMain.UIResName) as FUIBattleMainComponent; battleMain.RefreshBattleUnitUI(actionInfo.AttackerId); battleMain.RefreshBattleUnitUI(actionInfo.TargetId); battleMain.RefreshAllFightSpirit(); // check die battleunit var targetId = actionInfo.TargetId; if (self.DieBattleUnitIds.Contains(targetId)) { var fighter = self.GetFighterViewComponent(targetId); fighter.CheckState(); // TODO: 可以放到死亡动画播放完再调用 self.OnBattleUnitDie(targetId); self.DieBattleUnitIds.Remove(targetId); } } public static void OnBattleUnitDie(this BattleManagerComponent self, long id) { if (self.DropInfoDict.ContainsKey(id)) { var dropInfo = self.DropInfoDict[id]; var fuiComp = self.ZoneScene().GetComponent(); var battleMain = fuiComp.GetUI(FUI_BattleMain.UIResName) as FUIBattleMainComponent; battleMain.ShowDropItem(id, dropInfo.ItemId, dropInfo.ItemNum); self.DropInfoDict.Remove(id); } } } }