430 lines
15 KiB
C#
430 lines
15 KiB
C#
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
using Cal;
|
|||
|
using Cal.DataTable;
|
|||
|
|
|||
|
namespace ET
|
|||
|
{
|
|||
|
public class CopyBattleAwakeSystem: AwakeSystem<CopyBattle>
|
|||
|
{
|
|||
|
public override void Awake(CopyBattle self)
|
|||
|
{
|
|||
|
self.Awake();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public class CopyBattleUpdateSystem: UpdateSystem<CopyBattle>
|
|||
|
{
|
|||
|
public override void Update(CopyBattle self)
|
|||
|
{
|
|||
|
self.Update();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public class CopyBattleDestroySystem: DestroySystem<CopyBattle>
|
|||
|
{
|
|||
|
public override void Destroy(CopyBattle self)
|
|||
|
{
|
|||
|
self.Destroy();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public static class CopyBattleSystem
|
|||
|
{
|
|||
|
public static void Awake(this CopyBattle self)
|
|||
|
{
|
|||
|
self.bossDamageMap = new BossDamageMap();
|
|||
|
self.isRunning = false;
|
|||
|
self.quitBattleAction = OnQuitBattle;
|
|||
|
}
|
|||
|
|
|||
|
public static void Update(this CopyBattle self)
|
|||
|
{
|
|||
|
if (!self.isRunning) return;
|
|||
|
long now = TimeHelper.ClientNow();
|
|||
|
int maxTime = self.battleType switch
|
|||
|
{
|
|||
|
BattleType.MainStory => ConstDefine.MainStoryBattleTime,
|
|||
|
BattleType.TrialCopy => ConstDefine.TrialCopyBattleTime,
|
|||
|
BattleType.Boss => ConstDefine.BossBattleTime,
|
|||
|
BattleType.IdleBattle => ConstDefine.MainStoryBattleTime,
|
|||
|
BattleType.FamilyBoss => ConstDefine.FamilyBossBattleTime,
|
|||
|
BattleType.ManulEquip => ConstDefine.ManulEquipBattleTime,
|
|||
|
BattleType.PK => ConstDefine.PKBattleTime,
|
|||
|
BattleType.PersonalPvp => ConstDefine.PKBattleTime,
|
|||
|
_ => ConstDefine.DefaultBattleTime
|
|||
|
};
|
|||
|
var dTime = now - self.startTime;
|
|||
|
|
|||
|
if (dTime < ConstDefine.BattleStartTime)
|
|||
|
return;
|
|||
|
if (dTime > maxTime)
|
|||
|
{
|
|||
|
Defeat(self).Coroutine();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
int checkRet = CheckCanEnd(self);
|
|||
|
if (checkRet != 0)
|
|||
|
{
|
|||
|
switch (checkRet)
|
|||
|
{
|
|||
|
case 1:
|
|||
|
Victory(self).Coroutine();
|
|||
|
break;
|
|||
|
case 2:
|
|||
|
Defeat(self).Coroutine();
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
CheckCanStartSkill(self, now);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private static async ETVoid Defeat(CopyBattle self)
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
//对方赢了
|
|||
|
await OnDefeat(self, self.team);
|
|||
|
if (self.isPvp)
|
|||
|
{
|
|||
|
await OnVictory(self, self.targetTeam);
|
|||
|
}
|
|||
|
}
|
|||
|
catch (Exception e)
|
|||
|
{
|
|||
|
Log.Error(e);
|
|||
|
}
|
|||
|
finally
|
|||
|
{
|
|||
|
BattleMgrCompnent.Instance.RemoveBattle(self);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private static async ETVoid Victory(CopyBattle self)
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
//己方赢了
|
|||
|
await OnVictory(self, self.team);
|
|||
|
if (self.isPvp)
|
|||
|
{
|
|||
|
await OnDefeat(self, self.targetTeam);
|
|||
|
}
|
|||
|
}
|
|||
|
catch (Exception e)
|
|||
|
{
|
|||
|
Log.Error(e);
|
|||
|
}
|
|||
|
finally
|
|||
|
{
|
|||
|
BattleMgrCompnent.Instance.RemoveBattle(self);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private static int CheckCanEnd(CopyBattle self)
|
|||
|
{
|
|||
|
int count = BattleHelper.GetAliveCount(self.team);
|
|||
|
if (count == 0)
|
|||
|
{
|
|||
|
return 2;
|
|||
|
}
|
|||
|
|
|||
|
count = BattleHelper.GetAliveCount(self.targetTeam);
|
|||
|
if (count != 0)
|
|||
|
{
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
return 1;
|
|||
|
}
|
|||
|
|
|||
|
private static void CheckCanStartSkill(CopyBattle self, long now)
|
|||
|
{
|
|||
|
foreach (Unit unit in self.team.GetUnits())
|
|||
|
{
|
|||
|
if (!unit.IsAlive) continue;
|
|||
|
if (unit.GetComponent<SkillAI>().CheckCD(now))
|
|||
|
{
|
|||
|
BattleHelper.PlayerSkill(unit, now);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
foreach (Unit unit in self.targetTeam.GetUnits())
|
|||
|
{
|
|||
|
if (!unit.IsAlive) continue;
|
|||
|
if (unit.GetComponent<SkillAI>().CheckCD(now))
|
|||
|
{
|
|||
|
BattleHelper.MonsterSkill(unit);
|
|||
|
if (self.battleType == BattleType.FamilyBoss)
|
|||
|
BattleHelper.FamilyBossAddProperty(self, unit);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public static void Destroy(this CopyBattle self)
|
|||
|
{
|
|||
|
self.team.ChangeState(TeamState.None);
|
|||
|
self.targetTeam.ChangeState(TeamState.None);
|
|||
|
self.team = null;
|
|||
|
if (!self.isPvp)
|
|||
|
{
|
|||
|
foreach (Unit item in self.targetTeam.GetUnits())
|
|||
|
{
|
|||
|
if (item.UnitType == UnitType.Player)
|
|||
|
continue;
|
|||
|
item.GetMap()?.Leave(item);
|
|||
|
item.Dispose();
|
|||
|
}
|
|||
|
self.targetTeam.Dispose();
|
|||
|
}
|
|||
|
self.targetTeam = null;
|
|||
|
self.copyConfigId = 0;
|
|||
|
self.configId = 0;
|
|||
|
}
|
|||
|
|
|||
|
public static void Init(this CopyBattle self, Team team, Team targetTeam, int copyConfigId, long configId)
|
|||
|
{
|
|||
|
self.copyConfigId = copyConfigId;
|
|||
|
self.configId = (int) configId;
|
|||
|
self.team = team;
|
|||
|
self.targetTeam = targetTeam;
|
|||
|
self.ReadyBeforeStart();
|
|||
|
}
|
|||
|
|
|||
|
private static void ReadyBeforeStart(this CopyBattle self)
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
Team team = self.team;
|
|||
|
team.ChangeState(TeamState.Fight);
|
|||
|
CopyConfig copyConfig = CopyConfigCategory.Instance.Get(self.copyConfigId);
|
|||
|
if (copyConfig == null)
|
|||
|
{
|
|||
|
BattleMgrCompnent.Instance.RemoveBattle(self);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
LinkedList<Unit> teamList = team.GetUnits();
|
|||
|
|
|||
|
Unit leader = team.GetLeader();
|
|||
|
BattleType battleType = (BattleType) copyConfig.BattleType;
|
|||
|
self.isPvp = copyConfig.IsPVP;
|
|||
|
self.battleType = battleType;
|
|||
|
if (self.battleType == BattleType.FamilyBoss)
|
|||
|
{
|
|||
|
self.bossDamageMap = new BossDamageMap();
|
|||
|
foreach (Unit unit in team.GetUnits())
|
|||
|
{
|
|||
|
self.bossDamageMap.DamageList.Add(new BossDamagePerMemberMap
|
|||
|
{
|
|||
|
Id = unit.Id, Name = UserComponent.Instance.Get(unit.Id)?.NickName,
|
|||
|
});
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//!+设置每个人的状态
|
|||
|
foreach (Unit u in teamList)
|
|||
|
{
|
|||
|
u.GetComponent<BattleComponent>().BattleType = battleType;
|
|||
|
if (battleType is not BattleType.MainStory or BattleType.IdleBattle) continue;
|
|||
|
PlayerData playerData = u.GetComponent<PlayerData>();
|
|||
|
if (leader.isAI && (!playerData.HasMainstoryAITime() && !playerData.HasMainstoryVIPAITime()))
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
NumericComponent component = u.GetComponent<NumericComponent>();
|
|||
|
int num = component.GetAsInt(NumericType.Energy);
|
|||
|
if (num <= 0)
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
int num2 = num;
|
|||
|
num -= copyConfig.NeedEnergy;
|
|||
|
component.Set(NumericType.Energy, num);
|
|||
|
StatisticsHelper.AddEnergyCost(u.Id, "EnergyCostType_MainStory", num2 - num);
|
|||
|
}
|
|||
|
|
|||
|
// self.SendMonsterInfo();
|
|||
|
//!+设置目标/技能信息
|
|||
|
LinkedList<Unit> monsterTeamList = self.targetTeam.GetUnits();
|
|||
|
Game.EventSystem
|
|||
|
.Publish(new EventType.BattleStart { teamList = teamList, targetTeamList = monsterTeamList, isPvp = copyConfig.IsPVP })
|
|||
|
.Coroutine();
|
|||
|
|
|||
|
foreach (Unit item in monsterTeamList)
|
|||
|
{
|
|||
|
CharacterHelper.SyncNumeric(item);
|
|||
|
CharacterHelper.RecoverUnit(item);
|
|||
|
}
|
|||
|
|
|||
|
BattleHelper.SetTargets(self, teamList, monsterTeamList);
|
|||
|
//!+保存主怪Id
|
|||
|
// MainStoryMap.Instance.GetBattleInteractiveInfo(team.LeaderId).LeaderMonsterId = mainStory.Monster_1Arr[0].Monster_1_Id;
|
|||
|
|
|||
|
if (copyConfig.IsFobbidenPotion)
|
|||
|
{
|
|||
|
foreach (Unit u in teamList)
|
|||
|
{
|
|||
|
ModifierContainerComponent modifierContainerComponent = u.GetComponent<ModifierContainerComponent>();
|
|||
|
modifierContainerComponent.AddState(ModifierStateType.禁用药水);
|
|||
|
}
|
|||
|
|
|||
|
foreach (Unit u in monsterTeamList)
|
|||
|
{
|
|||
|
ModifierContainerComponent modifierContainerComponent = u.GetComponent<ModifierContainerComponent>();
|
|||
|
modifierContainerComponent.AddState(ModifierStateType.禁用药水);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
Log.Info($"\n{team.GetMemberName()}开始战斗 {battleType} *************");
|
|||
|
|
|||
|
self.isRunning = true;
|
|||
|
self.startTime = TimeHelper.ClientNow();
|
|||
|
self.SendMonsterInfo();
|
|||
|
}
|
|||
|
catch (Exception e)
|
|||
|
{
|
|||
|
BattleMgrCompnent.Instance.RemoveBattle(self);
|
|||
|
Log.Error(e);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private static void SendMonsterInfo(this CopyBattle self)
|
|||
|
{
|
|||
|
if (self.isPvp)
|
|||
|
{
|
|||
|
Team team = self.team;
|
|||
|
Team targetTeam = self.targetTeam;
|
|||
|
//!同步血量
|
|||
|
Game.EventSystem.Publish(new EventType.ChangeAllUnitCharacter { team = team, targetTeam = targetTeam }).Coroutine();
|
|||
|
//!给双方通知
|
|||
|
M2C_SendStartPK sendProto = new() { battleType = (int) self.battleType };
|
|||
|
sendProto.TargetIdList.AddRange(targetTeam.GetUnitIds());
|
|||
|
foreach (Unit unit in team.GetUnits())
|
|||
|
{
|
|||
|
MessageHelper.SendActor(unit, sendProto);
|
|||
|
}
|
|||
|
|
|||
|
sendProto = new() { battleType = (int) self.battleType };
|
|||
|
sendProto.TargetIdList.AddRange(team.GetUnitIds());
|
|||
|
foreach (Unit unit in targetTeam.GetUnits())
|
|||
|
{
|
|||
|
MessageHelper.SendActor(unit, sendProto);
|
|||
|
}
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
M2C_MainStoryMonsterInfo m2C_MainStoryMonsterInfo = new() { battleType = (int) self.battleType };
|
|||
|
foreach (Unit unitMonster in self.targetTeam.GetUnits())
|
|||
|
{
|
|||
|
//!给玩家返回怪物信息
|
|||
|
MonsterUnitInfo retUnitInfo = new() { Id = unitMonster.Id, MonsterId = unitMonster.GetComponent<MonsterInfo>().monsterId };
|
|||
|
|
|||
|
m2C_MainStoryMonsterInfo.MonsterUnitInfoList.Add(retUnitInfo);
|
|||
|
}
|
|||
|
|
|||
|
foreach (Unit u in self.team.GetUnits())
|
|||
|
{
|
|||
|
MessageHelper.SendActor(u, m2C_MainStoryMonsterInfo);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public static void ReSendMonsterInfo(this CopyBattle self, Unit unit)
|
|||
|
{
|
|||
|
if (self.isPvp)
|
|||
|
{
|
|||
|
Team team = self.team;
|
|||
|
Team targetTeam = self.targetTeam;
|
|||
|
|
|||
|
M2C_SendStartPK sendProto = new() { battleType = (int) self.battleType };
|
|||
|
sendProto.TargetIdList.AddRange(targetTeam.GetUnitIds());
|
|||
|
sendProto.TargetIdList.AddRange(team.GetUnitIds());
|
|||
|
MessageHelper.SendActor(unit, sendProto);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
M2C_ReMainStoryMonsterInfo m2C_MainStoryMonsterInfo = new() { battleType = (int) self.battleType };
|
|||
|
foreach (Unit unitMonster in self.targetTeam.GetUnits())
|
|||
|
{
|
|||
|
//!给玩家返回怪物信息
|
|||
|
NumericComponent num = unitMonster.GetComponent<NumericComponent>();
|
|||
|
ReMonsterUnitInfo retUnitInfo = new()
|
|||
|
{
|
|||
|
Id = unitMonster.Id,
|
|||
|
MonsterId = unitMonster.GetComponent<MonsterInfo>().monsterId,
|
|||
|
Hp = num.GetAsInt(NumericType.Hp),
|
|||
|
MaxHp = num.GetAsInt(NumericType.MaxHp),
|
|||
|
};
|
|||
|
|
|||
|
m2C_MainStoryMonsterInfo.MonsterUnitInfoList.Add(retUnitInfo);
|
|||
|
}
|
|||
|
|
|||
|
MessageHelper.SendActor(unit, m2C_MainStoryMonsterInfo);
|
|||
|
}
|
|||
|
|
|||
|
private static async ETTask OnVictory(CopyBattle self, Team team)
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
if (self == null)
|
|||
|
{
|
|||
|
Log.Error($"battle == null");
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
if (!self.isPvp && !self.isRunning) return;
|
|||
|
self.isRunning = false;
|
|||
|
CopyConfig copyConfig = CopyConfigCategory.Instance.Get(self.copyConfigId);
|
|||
|
await GlobalMethodHelper.Call(copyConfig.VictoryCopyReword, new CopyBattleArgs { copyBattle = self, team = team });
|
|||
|
}
|
|||
|
catch (Exception e)
|
|||
|
{
|
|||
|
Log.Error(e);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private static async ETTask OnDefeat(CopyBattle self, Team team)
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
if (self == null)
|
|||
|
{
|
|||
|
Log.Error($"battle == null");
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
if (!self.isPvp && !self.isRunning) return;
|
|||
|
self.isRunning = false;
|
|||
|
CopyConfig copyConfig = CopyConfigCategory.Instance.Get(self.copyConfigId);
|
|||
|
await GlobalMethodHelper.Call(copyConfig.DefeatCopyReword, new CopyBattleArgs { copyBattle = self, team = team });
|
|||
|
}
|
|||
|
catch (Exception e)
|
|||
|
{
|
|||
|
Log.Error(e);
|
|||
|
}
|
|||
|
}
|
|||
|
private static void OnQuitBattle(CopyBattle self, Team team,long Id)
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
if (team.AddVote(Id))
|
|||
|
{
|
|||
|
Defeat(self).Coroutine();
|
|||
|
}
|
|||
|
}
|
|||
|
catch (Exception e)
|
|||
|
{
|
|||
|
Log.Error(e);
|
|||
|
BattleMgrCompnent.Instance.RemoveBattle(self);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|