using Cal; using System; using System.Collections.Generic; using Cal.DataTable; namespace ET { public enum NumTargetType { Self, Target } public static class BattleHelper { public static void GetNumType(ValueCalculate valueCalculate, NumTargetType numTargetType, NumericComponent _num, NumericComponent _numTarget, out NumericComponent num, out NumericType numericType) { num = numTargetType switch { NumTargetType.Self => _num, NumTargetType.Target => _numTarget ?? throw new Exception("numTarget is null ,baseOriType 类型错误!"), _ => throw new Exception("baseOriType 类型错误!"), }; numericType = valueCalculate.calculateType switch { ValueCalculateType.物理攻击力x系数 => NumericType.PhyAtk, ValueCalculateType.精神攻击力x系数 => NumericType.SpiAtk, ValueCalculateType.生命值上限x系数 => NumericType.MaxHp, ValueCalculateType.当前生命值x系数 => NumericType.Hp, _ => throw new Exception("basePercEffectType 类型错误!") }; } /// /// 计算伤害 /// /// /// /// /// /// /// internal static void Calculate(SkillDamageType damageType, ISkillSender skillSender, Unit target, ValueCalculate damageCalculate_Self, ValueCalculate damageCalculate_Target, out BallisticData data) { if (damageCalculate_Self == null && damageCalculate_Target == null) { data = default; return; } NumericComponent num = skillSender.caster.GetComponent(); NumericComponent numTarget = target.GetComponent(); switch (damageType) { default: case SkillDamageType.None: data = default; break; case SkillDamageType.物理伤害: PhyBuffDamageCalculate.Calculate(num, numTarget, damageCalculate_Self, damageCalculate_Target, skillSender.skillLogic.skillConfigId, out data); break; case SkillDamageType.精神伤害: SpiBuffDamageCalculate.Calculate(num, numTarget, damageCalculate_Self, damageCalculate_Target, skillSender.skillLogic.skillConfigId, out data); break; case SkillDamageType.真实伤害: RealBuffDamageCalculate.Calculate(num, numTarget, damageCalculate_Self, damageCalculate_Target, skillSender.skillLogic.skillConfigId, out data); break; case SkillDamageType.护盾治疗: TreatBuffDamageCalculate.Calculate(num, numTarget, damageCalculate_Self, damageCalculate_Target, skillSender.skillLogic.skillConfigId, out data); break; } } internal static void SetTargets(CopyBattle battle, IEnumerable teamList, IEnumerable targetTeamList) { foreach (Unit unit in teamList) { try { unit.BattleId = battle.Id; unit.GetComponent().Clear(); TargetableUnitComponent targetUnits = unit.GetComponent(); targetUnits.Clear(); targetUnits.AddEnermy(targetTeamList); targetUnits.AddTeam(teamList); //!战斗开始添加技能,现在添加合适吗 SkillMgrComponent skillMgr = unit.GetComponent(); UnitSkillComponent skillComponent = unit.GetComponent(); foreach (UnitSkill unitSkill in skillComponent.GetLearnedSkills()) { skillMgr.AddSkill(unit, unitSkill); } } catch (Exception e) { Log.Error(e); } } foreach (Unit unit in targetTeamList) { try { unit.BattleId = battle.Id; unit.GetComponent().Clear(); TargetableUnitComponent targetUnits = unit.GetComponent(); targetUnits.Clear(); targetUnits.AddEnermy(teamList); targetUnits.AddTeam(targetTeamList); //!战斗开始添加技能,现在添加合适吗 SkillMgrComponent skillMgr = unit.GetComponent(); UnitSkillComponent skillComponent = unit.GetComponent(); foreach (UnitSkill unitSkill in skillComponent.GetLearnedSkills()) { skillMgr.AddSkill(unit, unitSkill); } } catch (Exception e) { Log.Error(e); } } return; } //!玩家释放技能 public static void PlayerSkill(Unit unit, long now) { if (!unit.IsAlive) return; if (unit.GetComponent().IsAutoSkill) { SkillAI ai = unit.GetComponent(); ai.canSkill = true; ai.PlayAutoSkill(now); } } //!怪物释放技能 public static void MonsterSkill(Unit unit) { if (!unit.IsAlive) return; SkillAI ai = unit.GetComponent(); ai.PlaySkill(); } public static void UpdateChangeMapTaskStateEvent(UnitScene unitScene, IEnumerable teamList) { foreach (Unit u in teamList) { Game.EventSystem.Publish(new EventType.UpdateTaskState { unit = u, type = TaskTargetType.ChangeMapTask, value = unitScene.MapId }) .Coroutine(); } } private static async ETVoid BrocastReword(IEnumerable teamList, UnOrderMultiMapComponent rewordMap) { using ListComponent listComponent = ListComponent.Create(); foreach (KeyValuePair> kp in rewordMap.MultiMap.GetDictionary()) { long unitId = kp.Key; User user = await UserHelper.Query(unitId); foreach ((int id, int count) in kp.Value) { listComponent.List.Add($"[color=#ffff00]【{user?.NickName}】[/color]获得了[color=#226655]{BagHelper.GetName(id)}x{count}[/color]"); } } foreach (Unit unit in teamList) { Chat.Instance.SendSystemCahtNoBrocast(unit, listComponent.List); } rewordMap.Dispose(); } public static async ETVoid UnitDead(CopyBattle self, Unit unit) { try { if (!unit) Log.Error($"unit is invalid which Id = {unit?.Id}"); //!触发死亡事件 if (unit.UnitType != UnitType.Player) { UnitEnermy unitInfo = unit.GetComponent(); Unit attackerUnit = unitInfo.unit; int monsterId = unitInfo.MonsterId; await Game.EventSystem.Publish(new EventType.UpdateTaskState { type = TaskTargetType.KillSpecialTask, unit = attackerUnit, value = monsterId }); await Game.EventSystem.Publish(new EventType.UpdateTaskState { type = TaskTargetType.KillAnyTask, unit = attackerUnit, value = monsterId }); } LinkedList teamList = self.team.GetUnits(); if (self.team.Contains(unit.Id)) { Log.Info($"【{UserComponent.Instance.Get(unit.Id)?.NickName} ({unit.Id})】战斗死亡了!"); } //!给客户端广播怪物死亡消息 IActorMessage deadMessage = new M2C_UnitDead() { UnitId = unit.Id }; BrocastComponent brocastComponent = unit.GetComponent(); brocastComponent.BrocastInterval(deadMessage); } catch (Exception e) { Log.Error(e); } } internal static async ETTask VictoryOption(CopyBattle self, Team team, long configid = 0) { try { LinkedList teamList = team.GetUnits(); team.ChangeState(TeamState.None); //!战斗结束事件(回血,奖励) UnOrderMultiMapComponent rewordMapComponent = UnOrderMultiMapComponent.Create(); foreach (Unit u in teamList) { await Game.EventSystem.Publish(new EventType.BattleEnd_Reword { unit = u, rewordMap = rewordMapComponent.MultiMap, battleType = self.battleType, configid = configid }); u.Live(); Game.EventSystem.Publish(new EventType.BattleEnd { unit = u, team = team }).Coroutine(); Game.EventSystem.Publish(new EventType.BattleEnd_AddHp { unit = u }).Coroutine(); } BattleHelper.BrocastReword(teamList, rewordMapComponent).Coroutine(); //!移除不在线玩家 await TeamComponent.Instance.RemoveAllOffLineId(team); } catch (Exception e) { Log.Error(e); } } internal static async ETTask DefeatOption(CopyBattle self, Team team, bool hasReward = false) { try { LinkedList teamList = team.GetUnits(); team.ChangeState(TeamState.None); foreach (Unit u in teamList) { MessageHelper.SendActor(u, new M2C_BattleDefeat { BattleType = (int) self.battleType }); } UnOrderMultiMapComponent rewordMapComponent = null; if (hasReward) rewordMapComponent = UnOrderMultiMapComponent.Create(); foreach (Unit u in teamList) { if (u.IsTeamLeader) { Game.EventSystem.Publish(new EventType.BackMainCity { unit = u, isForce = true }).Coroutine(); } if (hasReward) { await Game.EventSystem.Publish(new EventType.BattleEnd_Reword { unit = u, rewordMap = rewordMapComponent.MultiMap, battleType = self.battleType, configid = self.configId }); } u.Live(); //!战斗结束事件(回血) Game.EventSystem.Publish(new EventType.BattleEnd { unit = u, team = team }).Coroutine(); Game.EventSystem.Publish(new EventType.BattleEnd_AddHp { unit = u }).Coroutine(); } if (hasReward) BattleHelper.BrocastReword(teamList, rewordMapComponent).Coroutine(); //!移除不在线玩家 await TeamComponent.Instance.RemoveAllOffLineId(team); } catch (Exception e) { Log.Error(e); } } public static string SelectFixedTarget(this CopyBattle self, Unit unit, long unitId, Team targetTeam, TeamType teamType) { try { AttackComponent attacker = unit.GetComponent(); TargetableUnitComponent targetComponent = unit.GetComponent(); switch (teamType) { case TeamType.Self: Team team = self.team; Unit targetUnit = team.Get(unitId); if (targetUnit == null) { return "系统错误"; } targetComponent.selectedTeamMember = targetUnit; break; case TeamType.Target: team = targetTeam; targetUnit = team.Get(unitId); if (targetUnit == null) { return "系统错误"; } targetComponent.selectedEnermy = targetUnit; break; default: break; } } catch (Exception e) { Log.Error(e); } return null; } public static void FamilyBossAddProperty(CopyBattle self, Unit unit) { FamilyBossConfig familyBossConfig = FamilyBossConfigCategory.Instance.Get(self.configId); float additional = familyBossConfig.CharacterAdd; NumericComponent num = unit.GetComponent(); int atk = MathHelper.RoundToInt(num.GetAsInt(NumericType.PhyAtkBase) * additional); num.AddSet(NumericType.PhyAtk, atk); atk = MathHelper.RoundToInt(num.GetAsInt(NumericType.SpiAtkBase) * additional); num.AddSet(NumericType.SpiAtk, atk); int def = MathHelper.RoundToInt(num.GetAsInt(NumericType.PhyDefBase) * additional); num.AddSet(NumericType.PhyDef, def); def = MathHelper.RoundToInt(num.GetAsInt(NumericType.SpiDefBase) * additional); num.AddSet(NumericType.SpiDef, def); } public static Team GetAnotherTeam(this CopyBattle self, Team team) { try { if (team.Id == self.team.Id) return self.targetTeam; return self.team; } catch (Exception e) { Log.Error(e); } return null; } public static void StartCopy(Unit unit, string name) { Scene scene = MapFactory.CreateMap(unit.DomainZone(), name); } public static int GetAliveCount(Team team) { int count = 0; foreach (Unit item in team.GetUnits()) { if (item.IsAlive) count++; } return count; } } }