You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

470 lines
18 KiB

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<BattleManagerComponent>
{
public override void Awake(BattleManagerComponent self)
{
self.Awake();
}
}
public class BattleManagerComponentUpdateSystem : UpdateSystem<BattleManagerComponent>
{
public override void Update(BattleManagerComponent self)
{
self.Update();
}
}
public class BattleManagerComponentDestroySystem : DestroySystem<BattleManagerComponent>
{
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<CameraComponent>();
cameraComp.StoreCameraInfo();
var cameraPos = cameraComp.GetCameraPos();
cameraComp.SetCameraPos(new Vector3(0, 0, cameraPos.z));
cameraComp.SetOrthoSize(5);
// 禁用正常地图操作
self.ZoneScene().CurrentScene().GetComponent<OperationComponent>().Enabled = false;
var gameSceneComp = self.ZoneScene().CurrentScene().GetComponent<GameSceneManagerComponent>();
gameSceneComp.Hide(GameSceneType.Main);
gameSceneComp.Show(GameSceneType.Battle);
var fuiComp = self.ZoneScene().GetComponent<FUIComponent>();
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<BattleUnitViewComponent>();
comp.Init(fighter.Pos - 1, true);
}
// 初始化敌方人员
foreach (var keyValuePair in battle.EnemyDic)
{
var fighter = keyValuePair.Value;
var comp = fighter.AddComponent<BattleUnitViewComponent>();
comp.Init(fighter.Pos - 1, false);
}
// for (int i = 0; i < 9; i++)
// {
// var comp = self.AddChild<BattleUnitViewComponent>();
// comp.Init(i, false);
// self.EnemyUnits.Add(comp);
// }
self.DieBattleUnitIds.Clear();
self.DropInfoDict.Clear();
// show battle ui
var battleComp = fuiComp.ShowUI<FUI_BattleMain, FUIBattleMainComponent>(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<BattleUnitViewComponent>();
}
return null;
}
public static BattleUnitViewComponent GetEnemyViewComponentByPos(this BattleManagerComponent self, int pos)
{
if (self.BattleInfo.EnemyPosDic.TryGetValue(pos, out Fighter fighter))
{
return fighter.GetComponent<BattleUnitViewComponent>();
}
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<FUIComponent>();
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<BattleUnitViewComponent>();
comp.CheckState();
}
// 初始化敌方人员
foreach (var keyValuePair in self.BattleInfo.EnemyDic)
{
var fighter = keyValuePair.Value;
var comp = fighter.GetComponent<BattleUnitViewComponent>();
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<BattleUnitViewComponent>();
}
private static void CreateMoveToTargetActionSegment(this BattleManagerComponent self, AtkInfo atkInfo,ref List<AtkInfo> 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<BattleUnitViewComponent>();
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<BattleUnitViewComponent>();
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<AtkInfo> atkQueue = new Queue<AtkInfo>(atkList);
// 存储需要跑回去的相关攻击信息
List<AtkInfo> needMoveBackAtkInfos = new List<AtkInfo>();
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<BattleUnitViewComponent>(), 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<CameraComponent>();
cameraComp.RestoreCameraInfo();
// 恢复地图操作
self.ZoneScene().CurrentScene().GetComponent<OperationComponent>().Enabled = true;
var gameSceneComp = self.ZoneScene().CurrentScene().GetComponent<GameSceneManagerComponent>();
gameSceneComp.Show(GameSceneType.Main);
gameSceneComp.Hide(GameSceneType.Battle);
var fuiComp = self.ZoneScene().GetComponent<FUIComponent>();
fuiComp.ShowUI<FUI_Main, FUIMainComponent>(FUIMain.FUI_Main.UIResName);
fuiComp.ShowUI<FUI_UnitNamePanel, FUIUnitNamePanelComponent>(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<FUIComponent>();
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<FUIComponent>();
var battleMain = fuiComp.GetUI(FUI_BattleMain.UIResName) as FUIBattleMainComponent;
battleMain.ShowDropItem(id, dropInfo.ItemId, dropInfo.ItemNum);
self.DropInfoDict.Remove(id);
}
}
}
}