125 【战斗】战斗系统 战斗系统迭代 协议接入 阵容部分代码
24 文件已复制
43个文件已修改
28个文件已添加
3个文件已删除
1 文件已重命名
| | |
| | | using System; |
| | | using System.Collections; |
| | | using System.Collections.Generic; |
| | | using Spine.Unity; |
| | | using UnityEngine; |
| | | using Spine; |
| | | |
| | | public class EffectPlayer : MonoBehaviour |
| | | { |
| | | public int effectId; |
| | | public int effectId; |
| | | |
| | | public bool autoDestroy = false; |
| | | public bool autoDestroy = false; |
| | | |
| | | public float destroyDelay = 0f; |
| | | public float destroyDelay = 0f; |
| | | |
| | | [HideInInspector] public Canvas canvas = null; |
| | | public Action<EffectPlayer> onDestroy; |
| | | |
| | | [HideInInspector] public Canvas canvas = null; |
| | | |
| | | [HideInInspector] public GameObject effectTarget = null; |
| | | |
| | | protected EffectPenetrationBlocker blocker = null; |
| | | |
| | | protected void Start() |
| | | { |
| | | { |
| | | ReStart(); |
| | | } |
| | | |
| | | public void Stop() |
| | | { |
| | | { |
| | | if (null != effectTarget) |
| | | { |
| | | DestroyImmediate(effectTarget); |
| | |
| | | |
| | | public void Play() |
| | | { |
| | | if (!isActiveAndEnabled) |
| | | { |
| | | gameObject.SetActive(true); |
| | | } |
| | | ReStart(); |
| | | } |
| | | |
| | | |
| | | |
| | | protected void ReStart() |
| | |
| | | } |
| | | |
| | | // 添加特效穿透阻挡器 |
| | | EffectPenetrationBlocker blocker = effectTarget.AddComponent<EffectPenetrationBlocker>(); |
| | | blocker = effectTarget.AddMissingComponent<EffectPenetrationBlocker>(); |
| | | blocker.parentCanvas = canvas; |
| | | |
| | | // 延迟一帧才生效 |
| | |
| | | } |
| | | } |
| | | |
| | | public void SetSortingOrderOffset(int offset) |
| | | { |
| | | // 被Destroy之后effectTarget == null 为 true 但是访问内容会报错 |
| | | if (blocker != null && effectTarget != null) |
| | | { |
| | | blocker.sortingOrderOffset = offset; |
| | | blocker.UpdateSortingOrder(); |
| | | } |
| | | else |
| | | { |
| | | blocker = null; |
| | | effectTarget = null; |
| | | } |
| | | } |
| | | |
| | | protected void OnDestroy() |
| | | { |
| | | if (onDestroy != null) |
| | | { |
| | | onDestroy.Invoke(this); |
| | | onDestroy = null; |
| | | } |
| | | } |
| | | |
| | | // 创建后的特效会自动隐藏 需要手动调用Play才能播放 |
| | | public static EffectPlayer Create(int effectId, Transform parent, bool createNewChild = false, bool _autoDestroy = true, float _destroyDelay = 5f) |
| | | { |
| | | EffectPlayer effectPlayer = null; |
| | | |
| | | if (createNewChild) |
| | | { |
| | | GameObject newGo = new GameObject("EffectPlayer_" + effectId); |
| | | newGo.transform.SetParent(parent, false); |
| | | effectPlayer = newGo.AddComponent<EffectPlayer>(); |
| | | } |
| | | else |
| | | { |
| | | effectPlayer = parent.AddMissingComponent<EffectPlayer>(); |
| | | effectPlayer.effectId = effectId; |
| | | effectPlayer.autoDestroy = _autoDestroy; |
| | | effectPlayer.destroyDelay = _destroyDelay; |
| | | } |
| | | effectPlayer.SetActive(false); |
| | | return effectPlayer; |
| | | } |
| | | |
| | | public void Pause() |
| | | { |
| | | if (effectTarget == null) return; |
| | | |
| | | // Spine动画 |
| | | var spineGraphics = effectTarget.GetComponentsInChildren<SkeletonGraphic>(true); |
| | | foreach (var sg in spineGraphics) |
| | | { |
| | | sg.timeScale = 0f; |
| | | } |
| | | |
| | | // Animator动画 |
| | | var animators = effectTarget.GetComponentsInChildren<Animator>(true); |
| | | foreach (var animator in animators) |
| | | { |
| | | animator.speed = 0f; |
| | | } |
| | | |
| | | // 粒子特效 |
| | | var particles = effectTarget.GetComponentsInChildren<ParticleSystem>(true); |
| | | foreach (var ps in particles) |
| | | { |
| | | ps.Pause(); |
| | | } |
| | | } |
| | | |
| | | public void Resume() |
| | | { |
| | | if (effectTarget == null) return; |
| | | |
| | | // Spine动画 |
| | | var spineGraphics = effectTarget.GetComponentsInChildren<SkeletonGraphic>(true); |
| | | foreach (var sg in spineGraphics) |
| | | { |
| | | sg.timeScale = 1f; |
| | | } |
| | | |
| | | // Animator动画 |
| | | var animators = effectTarget.GetComponentsInChildren<Animator>(true); |
| | | foreach (var animator in animators) |
| | | { |
| | | animator.speed = 1f; |
| | | } |
| | | |
| | | // 粒子特效 |
| | | var particles = effectTarget.GetComponentsInChildren<ParticleSystem>(true); |
| | | foreach (var ps in particles) |
| | | { |
| | | ps.Play(); |
| | | } |
| | | } |
| | | |
| | | public bool IsFinish() |
| | | { |
| | | if (effectTarget == null) return true; |
| | | |
| | | // Spine动画 |
| | | var spineGraphics = effectTarget.GetComponentsInChildren<SkeletonGraphic>(true); |
| | | foreach (var sg in spineGraphics) |
| | | { |
| | | if (!sg.AnimationState.GetCurrent(0).IsComplete) |
| | | { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | // Animator动画 |
| | | var animators = effectTarget.GetComponentsInChildren<Animator>(true); |
| | | foreach (var animator in animators) |
| | | { |
| | | AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(0); |
| | | |
| | | // 循环动画不考虑结束的问题 |
| | | if (!stateInfo.loop && stateInfo.normalizedTime < 1f) |
| | | { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | // 粒子特效 |
| | | var particles = effectTarget.GetComponentsInChildren<ParticleSystem>(true); |
| | | foreach (var ps in particles) |
| | | { |
| | | if (ps.IsAlive()) |
| | | { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | return true; |
| | | } |
| | | } |
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: Friday, June 27, 2025 |
| | | // [ Date ]: 2025年7月17日 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | |
| | | public string IconName; |
| | | public string Description; |
| | | public string BuffDescription; |
| | | public int Skillactmark; |
| | | public int BuffDisplay; |
| | | public int CastPosition; |
| | | public int CastDistance; |
| | | public int[] TriggerFrames; |
| | | public int[][] DamageDivide; |
| | | public string SkillMotionName; |
| | | public int EffectId; |
| | | public int ExplotionEffectId; |
| | | public float FlyTime; |
| | | |
| | | public override int LoadKey(string _key) |
| | | { |
| | |
| | | |
| | | BuffDescription = tables[71]; |
| | | |
| | | int.TryParse(tables[72],out Skillactmark); |
| | | int.TryParse(tables[72],out BuffDisplay); |
| | | |
| | | int.TryParse(tables[73],out BuffDisplay); |
| | | int.TryParse(tables[73],out CastPosition); |
| | | |
| | | int.TryParse(tables[74],out CastPosition); |
| | | int.TryParse(tables[74],out CastDistance); |
| | | |
| | | if (tables[75].Contains("[")) |
| | | { |
| | | TriggerFrames = JsonMapper.ToObject<int[]>(tables[75]); |
| | | } |
| | | else |
| | | { |
| | | string[] TriggerFramesStringArray = tables[75].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries); |
| | | TriggerFrames = new int[TriggerFramesStringArray.Length]; |
| | | for (int i=0;i<TriggerFramesStringArray.Length;i++) |
| | | { |
| | | int.TryParse(TriggerFramesStringArray[i],out TriggerFrames[i]); |
| | | } |
| | | } |
| | | |
| | | DamageDivide = JsonMapper.ToObject<int[][]>(tables[76].Replace("(", "[").Replace(")", "]")); |
| | | |
| | | SkillMotionName = tables[77]; |
| | | |
| | | int.TryParse(tables[78],out EffectId); |
| | | |
| | | int.TryParse(tables[79],out ExplotionEffectId); |
| | | |
| | | float.TryParse(tables[80],out FlyTime); |
| | | } |
| | | catch (Exception exception) |
| | | { |
New file |
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年7月11日 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | | using System.IO; |
| | | using System.Threading; |
| | | using System; |
| | | using UnityEngine; |
| | | using LitJson; |
| | | |
| | | public partial class SkillConfig : ConfigBase<int, SkillConfig> |
| | | { |
| | | public SkillType skillType; |
| | | public SkillCastMode castMode; |
| | | public SkillEffectType effectType; |
| | | public SkillEffectAnchor effectAnchor; |
| | | |
| | | public MotionName GetMotionName() |
| | | { |
| | | return Enum.Parse<MotionName>(SkillMotionName); |
| | | } |
| | | } |
copy from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta
copy to Main/Config/PartialConfigs/SkillConfig.Partial.cs.meta
File was copied from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 0c39e10c6d11822409ee2e39b684f89d |
| | | guid: 80ceeaf1ce130d946a2e79320bdc9919 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | |
| | | public override void Done(GameNetPackBasic vNetPack) { |
| | | base.Done(vNetPack); |
| | | H0407_tagNPCDisappear vNetData = vNetPack as H0407_tagNPCDisappear; |
| | | |
| | | //玩家主动点击休息时,后端会回收创建的战斗主阵容武将实例,前端收到//04 07 NPC消失#tagNPCDisappear时进行解绑 |
| | | |
| | | BattleField battleField = BattleManager.Instance.GetBattleField(vNetPack.packUID); |
| | | |
| | | // 提前结束战斗 删除NPCID()实际上是对象的ObjID |
| | | battleField.FinishBattleInAdvance(vNetData.NPCID); |
| | | |
| | | } |
| | | } |
| | |
| | | using System.Collections; |
| | | using static UnityEditor.Experimental.GraphView.GraphView; |
| | | |
| | | //04 18 周围对象刷新#tagObjInfoRefresh
|
| | |
|
| | | public class DTC0418_tagObjInfoRefresh : DtcBasic {
|
| | | public override void Done(GameNetPackBasic vNetPack) {
|
| | | base.Done(vNetPack);
|
| | | H0418_tagObjInfoRefresh vNetData = vNetPack as H0418_tagObjInfoRefresh;
|
| | | Update0418(vNetData);
|
| | | }
|
| | |
|
| | |
|
| | | //04 18 周围对象刷新#tagObjInfoRefresh |
| | | |
| | | public class DTC0418_tagObjInfoRefresh : DtcBasic { |
| | | public override void Done(GameNetPackBasic vNetPack) { |
| | | base.Done(vNetPack); |
| | | H0418_tagObjInfoRefresh vNetData = vNetPack as H0418_tagObjInfoRefresh; |
| | | |
| | | // 1 - 玩家(主公) |
| | | // 2 - NPC(武将或怪物) |
| | | |
| | | switch (vNetData.ObjType) |
| | | { |
| | | case 1: |
| | | Update0418(vNetData); |
| | | break; |
| | | case 2: |
| | | UpdateBattleField(vNetData); |
| | | break; |
| | | default: |
| | | Debug.LogError("DTC0418_tagObjInfoRefresh 服务端同步了一个未知类型的ObjType的刷新 " + vNetData.ObjType); |
| | | break; |
| | | } |
| | | } |
| | | |
| | | |
| | | public static void Update0418(H0418_tagObjInfoRefresh vNetData) |
| | | {
|
| | | { |
| | | if (PlayerDatas.Instance.PlayerId == vNetData.ObjID) |
| | | { |
| | | |
| | |
| | | //其他玩家数据,如果需要同场景处理 |
| | | //_player.UpdateData(vNetData); |
| | | } |
| | | }
|
| | | }
|
| | | } |
| | | |
| | | public static void UpdateBattleField(H0418_tagObjInfoRefresh vNetData) |
| | | { |
| | | BattleField battleField = BattleManager.Instance.GetBattleField(vNetData.packUID); |
| | | battleField.ObjInfoRefresh(vNetData); |
| | | } |
| | | } |
| | |
| | | public override void Done(GameNetPackBasic vNetPack) { |
| | | base.Done(vNetPack); |
| | | H0423_tagObjPropertyRefreshView vNetData = vNetPack as H0423_tagObjPropertyRefreshView; |
| | | |
| | | // public uint ObjID; //对象ID |
| | | // public byte ObjType; //对象类型 |
| | | // public uint SkillID; //技能ID |
| | | // public uint DiffValue; //值 |
| | | // public uint DiffValueEx; //超亿值 |
| | | // public byte AttackType; //攻击类型 |
| | | // public uint SrcObjID; //飘血来源 |
| | | // public byte SrcObjType; |
| | | // public uint HP; //剩余血量 |
| | | // public uint HPEx; //剩余血量 亿 |
| | | BattleField battleField = BattleManager.Instance.GetBattleField(vNetPack.packUID); |
| | | battleField.ObjPropertyRefreshView(vNetData); |
| | | } |
| | | } |
| | |
| | | public override void Done(GameNetPackBasic vNetPack) { |
| | | base.Done(vNetPack); |
| | | H0604_tagUseSkillAttack vNetData = vNetPack as H0604_tagUseSkillAttack; |
| | | |
| | | |
| | | // public uint ObjID; |
| | | // public byte ObjType; |
| | | // public byte BattleType; //物理/魔法 |
| | | // public ushort SkillID; |
| | | // public uint AttackID; //主攻击目标 |
| | | // public byte AttackObjType; //主攻击目标 |
| | | // public ushort HurtCount; //伤害数目 |
| | | // public tagSkillHurtObj[] HurtList; //size = HurtCount |
| | | |
| | | // ObjType类型的ObjID使用BattleType类技能SkillID攻击了AttackObjType类型的AttackID 伤害数字是HurtList |
| | | |
| | | BattleField battleField = BattleManager.Instance.GetBattleField(vNetPack.packUID); |
| | | |
| | | battleField.ProcessUseSkillAttack(vNetData); |
| | | |
| | | |
| | | } |
| | | } |
| | |
| | | using UnityEngine; |
| | | using System.Collections; |
| | | |
| | | using UnityEngine;
|
| | | using System.Collections;
|
| | |
|
| | | //06 05 对象增加Buf#tagObjAddBuff
|
| | |
|
| | | public class DTC0605_tagObjAddBuff : DtcBasic {
|
| | | public override void Done(GameNetPackBasic vNetPack) {
|
| | | public override void Done(GameNetPackBasic vNetPack)
|
| | | {
|
| | | base.Done(vNetPack);
|
| | | H0605_tagObjAddBuff vNetData = vNetPack as H0605_tagObjAddBuff;
|
| | |
|
| | | BattleField battleField = BattleManager.Instance.GetBattleField(vNetData.packUID);
|
| | |
|
| | | BattleObject vBattleObject = battleField.battleObjMgr.GetBattleObject((int)vNetData.ObjID);
|
| | |
|
| | | if (null == vBattleObject)
|
| | | {
|
| | | return;
|
| | | }
|
| | |
|
| | | vBattleObject.buffMgr.AddBuff(vNetData); |
| | | }
|
| | | }
|
| | |
| | | using UnityEngine; |
| | | using System.Collections; |
| | | using LitJson; |
| | | |
| | | // B4 20 回合制战斗状态 #tagMCTurnFightState |
| | | |
| | |
| | | public override void Done(GameNetPackBasic vNetPack) { |
| | | base.Done(vNetPack); |
| | | HB420_tagMCTurnFightState vNetData = vNetPack as HB420_tagMCTurnFightState; |
| | | BattleField battleField = BattleManager.Instance.GetBattleField(vNetPack.packUID); |
| | | |
| | | // MapID; // 自定义地图ID,可用于绑定战斗地图场景功能(如主线关卡、主线boss、爬塔、竞技场等) |
| | | // FuncLineID; // MapID对应的扩展值,如具体某个关卡等 章节*10000+关卡编号*100+第x波,如第一章,第10关卡的boss值 = 11001 |
| | | // State; // 0-起始状态标记;1-准备完毕;2-战斗中;3-战斗结束;4-结算奖励;5-结束状态标记 |
| | | // TurnNum; // 当前轮次 |
| | | // Len; |
| | | // Msg; //size = Len |
| | | JsonData extendData = JsonMapper.ToObject(vNetData.Msg); |
| | | battleField.OnTurnFightState(vNetData.TurnNum, vNetData.State, (int)vNetData.FuncLineID, extendData); |
| | | } |
| | | } |
| | |
| | | using UnityEngine; |
| | | using System.Collections; |
| | | using LitJson; |
| | | |
| | | // B4 21 回合战斗对象开始行动 #tagMCTurnFightObjAction |
| | | |
| | |
| | | public override void Done(GameNetPackBasic vNetPack) { |
| | | base.Done(vNetPack); |
| | | HB421_tagMCTurnFightObjAction vNetData = vNetPack as HB421_tagMCTurnFightObjAction; |
| | | BattleField battleField = BattleManager.Instance.GetBattleField(vNetPack.packUID); |
| | | battleField.OnTurnFightObjAction(vNetData.TurnNum, (int)vNetData.ObjID); |
| | | // BattleManager.Instance.OnTurnFightObjAction(vNetData.TurnNum, (int)vNetData.ObjID); |
| | | } |
| | | } |
| | |
| | | public override void Done(GameNetPackBasic vNetPack) { |
| | | base.Done(vNetPack); |
| | | HB422_tagMCTurnFightObjDead vNetData = vNetPack as HB422_tagMCTurnFightObjDead; |
| | | |
| | | BattleField battleField = BattleManager.Instance.GetBattleField(vNetPack.packUID); |
| | | |
| | | battleField.OnObjDead((int)vNetData.ObjID); |
| | | } |
| | | } |
| | |
| | | public class DTCB423_tagMCTurnFightObjReborn : DtcBasic { |
| | | public override void Done(GameNetPackBasic vNetPack) { |
| | | base.Done(vNetPack); |
| | | |
| | | // 服务端说暂时没做到这边 暂放 TODO YYL |
| | | |
| | | HB423_tagMCTurnFightObjReborn vNetData = vNetPack as HB423_tagMCTurnFightObjReborn; |
| | | BattleField battleField = BattleManager.Instance.GetBattleField(vNetPack.packUID); |
| | | // battleField.OnObjReborn(vNetData.ObjID); |
| | | } |
| | | } |
| | |
| | | // FactionCnt; |
| | | // FactionList; // 阵营列表,通常固定只有两个阵营 |
| | | |
| | | |
| | | |
| | | uint chapter = vNetData.FuncLineID / 10000; |
| | | uint wave = vNetData.MapID == 1 ? vNetData.FuncLineID % 100 : 1;//第几波怪 |
| | | uint level = (vNetData.FuncLineID % 10000) / 100; |
| | | JsonData extendData = JsonMapper.ToObject(vNetData.Msg); |
| | | |
| | | List<TeamBase> redTeamList = new List<TeamBase>(); |
| | | List<TeamBase> blueTeamList = new List<TeamBase>(); |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | |
| | | // 主线 |
| | | // if (vNetData.MapID <= 2) |
| | | // { |
| | | // int chapter = (int)vNetData.FuncLineID / 10000; |
| | | // int wave = (int)(vNetData.MapID == 1 ? vNetData.FuncLineID % 100 : 1);//第几波怪 |
| | | // int level = (int)(vNetData.FuncLineID % 10000) / 100; |
| | | JsonData extendData = JsonMapper.ToObject(vNetData.Msg); |
| | | |
| | | // BattleManager.Instance.CreateStoryBattle(chapter, wave, level, extendData, redTeamList[0], blueTeamList[0]); |
| | | // } |
| | | |
| | | string guid = BattleManager.Instance.GetGUID(vNetPack.packUID); |
| | | |
| | | BattleManager.Instance.CreateBattleField(guid, (int)vNetData.MapID, (int)vNetData.FuncLineID, extendData, redTeamList, blueTeamList); |
| | | } |
| | | } |
| | |
| | | public override void Done(GameNetPackBasic vNetPack) { |
| | | base.Done(vNetPack); |
| | | HB425_tagSCTurnFightReportSign vNetData = vNetPack as HB425_tagSCTurnFightReportSign; |
| | | |
| | | |
| | | // 截断 PackageRegedit Distribute 里的封包 |
| | | |
| | | // 直到sign = 1; |
| | | } |
| | | |
| | | public static bool IsCorrectType(GameNetPackBasic vNetPack) |
| | | { |
| | | return vNetPack is HB425_tagSCTurnFightReportSign; |
| | | } |
| | | } |
| | |
| | | using UnityEngine; |
| | | using System.Collections; |
| | | |
| | | using System; |
| | | // B4 30 查看战报结果 #tagSCTurnFightReportRet |
| | | |
| | | |
| | | public class DTCB430_tagSCTurnFightReport : DtcBasic { |
| | | public override void Done(GameNetPackBasic vNetPack) { |
| | | private static GameNetEncode encoder = new GameNetEncode(); |
| | | |
| | | static byte[] vCmdBytes = new byte[2]; |
| | | |
| | | public override void Done(GameNetPackBasic vNetPack) |
| | | { |
| | | base.Done(vNetPack); |
| | | HB430_tagSCTurnFightReport vNetData = vNetPack as HB430_tagSCTurnFightReport; |
| | | |
| | | // 战报结果 |
| | | string guid = vNetData.GUID; |
| | | |
| | | try |
| | | { |
| | | byte[] reportBytes = GameNetPackBasic.StrEncoding.GetBytes(vNetData.Report); |
| | | |
| | | int vReadIndex = 0; |
| | | byte[] vPackBytes; |
| | | int vLeavingLeng = 0; |
| | | int vBodyLeng = 0; |
| | | int vTotalLeng = reportBytes.Length; |
| | | |
| | | while (vReadIndex < vTotalLeng) |
| | | { |
| | | if (vLeavingLeng < 6) |
| | | { |
| | | Debug.LogError("DTCB430_tagSCTurnFightReport: vLeavingLeng < 6 解包失败"); |
| | | break; |
| | | } |
| | | |
| | | vBodyLeng = BitConverter.ToInt32(reportBytes, vReadIndex + 2); |
| | | if (vBodyLeng > vLeavingLeng - 6)// 未完整的包 报错 |
| | | { |
| | | Debug.LogError("DTCB430_tagSCTurnFightReport: vBodyLeng > vLeavingLeng - 6 解包失败"); |
| | | break; |
| | | } |
| | | |
| | | vPackBytes = new byte[vBodyLeng]; |
| | | Array.Copy(reportBytes, vReadIndex + 6, vPackBytes, 0, vBodyLeng); |
| | | vPackBytes = encoder.BaseXorSub(vPackBytes); |
| | | |
| | | Array.Copy(vPackBytes, 0, vCmdBytes, 0, 2); |
| | | var cmd = (ushort)((ushort)(vCmdBytes[0] << 8) + vCmdBytes[1]); |
| | | bool isRegist = false; // 未注册封包处理 |
| | | |
| | | if (PackageRegedit.Contain(cmd)) |
| | | { |
| | | GameNetPackBasic vNetpack = PackageRegedit.TransPack(ServerType.Main, cmd, vPackBytes); |
| | | if (vNetpack != null) |
| | | { |
| | | BattleManager.Instance.PushPackage(guid, vNetpack); |
| | | isRegist = true; |
| | | } |
| | | } |
| | | |
| | | vReadIndex += 6 + vBodyLeng; |
| | | |
| | | // 未注册封包处理 |
| | | if (!isRegist) |
| | | { |
| | | #if UNITY_EDITOR |
| | | PackageRegedit.TransPack(ServerType.Main, cmd, vPackBytes); |
| | | #endif |
| | | } |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | Debug.LogErrorFormat("DTCB430_tagSCTurnFightReport 解包异常:{0}", e); |
| | | } |
| | | } |
| | | } |
| | |
| | | using UnityEngine; |
| | | using System; |
| | | using System.Collections; |
| | | using System.Collections.Generic; |
| | | //using ILCrossBinding; |
| | | |
| | | public class PackageRegedit |
| | | { |
| | |
| | | |
| | | public static void Init() |
| | | { |
| | | // 登记相应的数据体及对应的数据转逻辑类 |
| | | // 登记相应的数据体及对应的数据转逻辑类(去重后) |
| | | Register(typeof(H0102_tagCDBPlayer), typeof(DTC0102_tagCDBPlayer)); |
| | | Register(typeof(HA004_tagServerDateTime), typeof(DTCA004_tagServerDateTime)); |
| | | Register(typeof(HA005_tagOpenServerDay), typeof(DTCA005_tagOpenServerDay)); |
| | |
| | | Register(typeof(HA921_tagUpdatePlayerNameResult), typeof(DTCA921_tagUpdatePlayerNameResult)); |
| | | Register(typeof(H3202_tagServerResponse), typeof(DTC3202_tagServerResponse)); |
| | | Register(typeof(HA130_tagMCViewBillboardRet), typeof(DTCA130_tagMCViewBillboardRet)); |
| | | |
| | | Register(typeof(HB420_tagMCTurnFightState), typeof(DTCB420_tagMCTurnFightState)); |
| | | Register(typeof(HB421_tagMCTurnFightObjAction), typeof(DTCB421_tagMCTurnFightObjAction)); |
| | | Register(typeof(HB422_tagMCTurnFightObjDead), typeof(DTCB422_tagMCTurnFightObjDead)); |
| | | Register(typeof(HB423_tagMCTurnFightObjReborn), typeof(DTCB423_tagMCTurnFightObjReborn)); |
| | | Register(typeof(HB424_tagSCTurnFightInit), typeof(DTCB424_tagSCTurnFightInit)); |
| | | Register(typeof(HB425_tagSCTurnFightReportSign), typeof(DTCB425_tagSCTurnFightReportSign)); |
| | | Register(typeof(HB430_tagSCTurnFightReport), typeof(DTCB430_tagSCTurnFightReport)); |
| | | Register(typeof(H0407_tagNPCDisappear), typeof(DTC0407_tagNPCDisappear)); |
| | | Register(typeof(H0423_tagObjPropertyRefreshView), typeof(DTC0423_tagObjPropertyRefreshView)); |
| | | Register(typeof(H0604_tagUseSkillAttack), typeof(DTC0604_tagUseSkillAttack)); |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | //主工程注册封包 |
| | | public static void Register(Type _pack, Type _business) |
| | |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | public static bool Contain(ushort _cmd) |
| | | { |
| | | return packToBusinessTable.ContainsKey(_cmd); |
| | |
| | | try |
| | | { |
| | | //执行主工程的封包 |
| | | if (packToBusinessTable.ContainsKey(_package.cmd)) |
| | | if (packToBusinessTable.ContainsKey(_package.cmd) && BattleManager.Instance.IsCanDistributePackage(_package)) |
| | | packToBusinessTable[_package.cmd].Done(_package); |
| | | |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | |
| | | |
| | | } |
| | | } |
| | |
| | | public class GameNetPackBasic |
| | | { |
| | | |
| | | static ulong AutoIncreaseUID = 0; |
| | | |
| | | public ulong packUID |
| | | { |
| | | get; |
| | | private set; |
| | | } |
| | | |
| | | public GameNetPackBasic() |
| | | { |
| | | packUID = AutoIncreaseUID++; |
| | | } |
| | | |
| | | |
| | | |
| | | public ServerType socketType = ServerType.Main; //默认且唯一 |
| | | |
| | | /** 协议号 */ |
New file |
| | |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using UnityEngine; |
| | | |
| | | public class BattleEffectMgr : MonoBehaviour |
| | | { |
| | | private BattleField battleField; |
| | | |
| | | private Dictionary<int, List<EffectPlayer>> effectDict = new Dictionary<int, List<EffectPlayer>>(); |
| | | |
| | | public void Init(BattleField _battleField) |
| | | { |
| | | battleField = _battleField; |
| | | } |
| | | |
| | | public void PauseGame() |
| | | { |
| | | foreach (KeyValuePair<int, List<EffectPlayer>> kvPair in effectDict) |
| | | { |
| | | foreach (EffectPlayer effectPlayer in kvPair.Value) |
| | | { |
| | | if (effectPlayer != null) |
| | | { |
| | | effectPlayer.Pause(); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | public void ResumeGame() |
| | | { |
| | | foreach (KeyValuePair<int, List<EffectPlayer>> kvPair in effectDict) |
| | | { |
| | | foreach (EffectPlayer effectPlayer in kvPair.Value) |
| | | { |
| | | if (effectPlayer != null) |
| | | { |
| | | effectPlayer.Resume(); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | public EffectPlayer PlayEffect(int ObjID, int effectId, Transform parent) |
| | | { |
| | | if (!effectDict.ContainsKey(effectId)) |
| | | { |
| | | effectDict[effectId] = new List<EffectPlayer>(); |
| | | } |
| | | |
| | | EffectPlayer effectPlayer = EffectPlayer.Create(effectId, parent, true, false); |
| | | effectPlayer.onDestroy = OnEffectDestroy; |
| | | if (effectPlayer != null) |
| | | { |
| | | effectDict[effectId].Add(effectPlayer); |
| | | effectPlayer.Play(); |
| | | } |
| | | return effectPlayer; |
| | | } |
| | | |
| | | public void RemoveEffect(int effectId, EffectPlayer effectPlayer) |
| | | { |
| | | List<EffectPlayer> effectPlayers = null; |
| | | |
| | | if (effectDict.TryGetValue(effectId, out effectPlayers)) |
| | | { |
| | | effectPlayers.Remove(effectPlayer); |
| | | GameObject.DestroyImmediate(effectPlayer.gameObject); |
| | | effectPlayer = null; |
| | | } |
| | | else |
| | | { |
| | | Debug.LogError("could not find effect in list, effectid : " + effectId); |
| | | } |
| | | } |
| | | |
| | | protected void OnEffectDestroy(EffectPlayer effectPlayer) |
| | | { |
| | | if (effectDict.ContainsKey(effectPlayer.effectId)) |
| | | { |
| | | effectDict[effectPlayer.effectId].Remove(effectPlayer); |
| | | if (effectDict[effectPlayer.effectId].Count == 0) |
| | | { |
| | | effectDict.Remove(effectPlayer.effectId); |
| | | } |
| | | } |
| | | } |
| | | } |
copy from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta
copy to Main/System/Battle/BattleEffectMgr.cs.meta
File was copied from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 0c39e10c6d11822409ee2e39b684f89d |
| | | guid: 3b551bfee6a101744995645eecf86bb8 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | |
| | | using System.Collections.Generic; |
| | | using UnityEngine; |
| | | using System; |
| | | using LitJson; |
| | | using DG.Tweening; |
| | | |
| | | public class BattleField |
| | | { |
| | | public BattleObjMgr battleObjMgr; |
| | | |
| | | public BattleEffectMgr battleEffectMgr; |
| | | |
| | | public BattleTweenMgr battleTweenMgr; |
| | | |
| | | public RecordPlayer recordPlayer; |
| | | |
| | | public IOperationAgent operationAgent; |
| | | |
| | | public int round = 0; |
| | | |
| | | public string guid = string.Empty; |
| | | |
| | | public int MapID = 0; |
| | | |
| | | public int FuncLineID = 0; |
| | | |
| | | public JsonData extendData; |
| | | |
| | | public bool IsActive |
| | | { |
| | |
| | | |
| | | public Action<bool> OnBattlePause; |
| | | |
| | | public virtual void Init(TeamBase _redTeam, TeamBase _blueTeam) |
| | | protected List<TeamBase> redTeamList = null; |
| | | |
| | | protected List<TeamBase> blueTeamList = null; |
| | | |
| | | protected int redTeamIndex = 0; |
| | | |
| | | protected int blueTeamIndex = 0; |
| | | |
| | | public BattleField(string _guid) |
| | | { |
| | | guid = _guid; |
| | | } |
| | | |
| | | public virtual void Init(int _MapID, int _FuncLineID, JsonData _extendData, |
| | | List<TeamBase> _redTeamList, List<TeamBase> _blueTeamList) |
| | | { |
| | | MapID = _MapID; |
| | | redTeamList = _redTeamList; |
| | | blueTeamList = _blueTeamList; |
| | | FuncLineID = _FuncLineID; |
| | | extendData = _extendData; |
| | | |
| | | redTeamIndex = 0; |
| | | blueTeamIndex = 0; |
| | | |
| | | GameObject go = ResManager.Instance.LoadAsset<GameObject>("Battle/Prefabs", "BattleRootNode"); |
| | | GameObject battleRootNodeGO = GameObject.Instantiate(go); |
| | | battleRootNode = battleRootNodeGO.GetComponent<BattleRootNode>(); |
| | | battleRootNodeGO.name = this.GetType().Name; |
| | | |
| | | battleObjMgr = new BattleObjMgr(); |
| | | battleObjMgr.Init(this, _redTeam, _blueTeam); |
| | | battleObjMgr.Init(this, redTeamList[redTeamIndex], blueTeamList[blueTeamIndex]); |
| | | battleEffectMgr = new BattleEffectMgr(); |
| | | battleEffectMgr.Init(this); |
| | | battleTweenMgr = new BattleTweenMgr(); |
| | | battleTweenMgr.Init(this); |
| | | |
| | | // 这里的Init交给各个子类的Init里去实现 |
| | | // battleObjMgr.Init(this, _redTeam, _blueTeam); |
| | | |
| | | recordPlayer = new RecordPlayer(); |
| | | recordPlayer.Init(this); |
| | |
| | | { |
| | | battleObjMgr.ResumeGame(); |
| | | recordPlayer.ResumeGame(); |
| | | battleEffectMgr.ResumeGame(); |
| | | battleTweenMgr.ResumeGame(); |
| | | } |
| | | |
| | | protected virtual void PauseGame() |
| | |
| | | |
| | | battleObjMgr.PauseGame(); |
| | | recordPlayer.PauseGame(); |
| | | battleEffectMgr.PauseGame(); |
| | | battleTweenMgr.PauseGame(); |
| | | } |
| | | |
| | | public virtual void TurnFightState(int TurnNum, int State, |
| | | uint FuncLineID, JsonData extendData) |
| | | { |
| | | round = TurnNum; |
| | | } |
| | | |
| | | public virtual void OnTurnFightObjAction(int turnNum, int ObjID) |
| | | { |
| | | |
| | | } |
| | | |
| | | public virtual void OnTurnFightState(int turnNum, int State, int FuncLineID, JsonData extendData) |
| | | { |
| | | |
| | | } |
| | | |
| | | public void ObjInfoRefresh(H0418_tagObjInfoRefresh _refreshInfo) |
| | | { |
| | | BattleObject battleObj = battleObjMgr.GetBattleObject((int)_refreshInfo.ObjID); |
| | | |
| | | if (null != battleObj) |
| | | { |
| | | battleObj.OnObjInfoRefresh(_refreshInfo); |
| | | } |
| | | } |
| | | |
| | | public void ObjPropertyRefreshView(H0423_tagObjPropertyRefreshView vNetData) |
| | | { |
| | | |
| | | } |
| | | |
| | | public virtual void OnObjDead(int ObjID) |
| | | { |
| | | DeathRecordAction recordAction = new DeathRecordAction(this, battleObjMgr.GetBattleObject(ObjID)); |
| | | recordPlayer.PlayRecord(recordAction); |
| | | } |
| | | |
| | | public virtual void Destroy() |
| | | { |
| | | // 销毁全部内容 |
| | | } |
| | | |
| | | public void FinishBattleInAdvance(uint[] ObjIDArr) |
| | | { |
| | | // 让npc隐藏后 左边播放睡觉动作 |
| | | |
| | | |
| | | } |
| | | |
| | | public virtual void ProcessUseSkillAttack(H0604_tagUseSkillAttack vNetData) |
| | | { |
| | | // H0604_tagUseSkillAttack |
| | | // public uint ObjID; |
| | | // public byte ObjType; |
| | | // public byte BattleType; //物理/魔法 |
| | | // public ushort SkillID; |
| | | // public uint AttackID; //主攻击目标 |
| | | // public byte AttackObjType; //主攻击目标 |
| | | // public ushort HurtCount; //伤害数目 |
| | | // public tagSkillHurtObj[] HurtList; //size = HurtCount |
| | | |
| | | // ObjType类型的ObjID使用BattleType类技能SkillID攻击了AttackObjType类型的AttackID 伤害数字是HurtList |
| | | // SkillAction skillAction = new SkillAction(); |
| | | |
| | | } |
| | | |
| | | public RectTransform GetTeamNode(BattleCamp battleCamp) |
| | | { |
| | | if (battleCamp == BattleCamp.Red) |
| | | { |
| | | return battleRootNode.redTeamNode; |
| | | } |
| | | else |
| | | { |
| | | return battleRootNode.blueTeamNode; |
| | | } |
| | | } |
| | | |
| | | |
| | | public bool IsRoundReachLimit() |
| | | { |
| | | // return round > xxx; |
| | |
| | | |
| | | public class BattleRootNode : MonoBehaviour |
| | | { |
| | | public RectTransform redTeamNode; |
| | | public List<GameObject> redTeamNodeList = new List<GameObject>(); |
| | | |
| | | public RectTransform blueTeamNode; |
| | | public List<GameObject> blueTeamNodeList = new List<GameObject>(); |
| | | |
| | | public RawImage imgBackground; |
| | | |
| | | void Awake() |
| | | { |
| | | if (redTeamNodeList.Count != TeamConst.MaxTeamSlotCount) |
| | | { |
| | | Debug.LogError("redTeamNodeList count is not equal to MaxTeamSlotCount: " + redTeamNodeList.Count); |
| | | } |
| | | |
| | | if (blueTeamNodeList.Count != TeamConst.MaxTeamSlotCount) |
| | | { |
| | | Debug.LogError("blueTeamNodeList count is not equal to MaxTeamSlotCount: " + blueTeamNodeList.Count); |
| | | } |
| | | DontDestroyOnLoad(gameObject); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | using UnityEngine; |
| | | using System.Collections.Generic; |
| | | |
| | | public class DeathRecordAction : RecordAction |
| | | { |
| | | |
| | | public DeathRecordAction(BattleField _battleField, BattleObject _battleObj) |
| | | : base(RecordActionType.Death, _battleField, _battleObj) |
| | | { |
| | | isFinish = false; |
| | | isRunOnce = false; |
| | | } |
| | | |
| | | public override bool IsFinished() |
| | | { |
| | | return isFinish; |
| | | } |
| | | |
| | | |
| | | public override void Run() |
| | | { |
| | | if (isRunOnce) |
| | | { |
| | | return; |
| | | } |
| | | base.Run(); |
| | | isRunOnce = true; |
| | | battleObject.OnDeath(OnDeathAnimationEnd); |
| | | } |
| | | |
| | | private void OnDeathAnimationEnd() |
| | | { |
| | | isFinish = true; |
| | | } |
| | | } |
copy from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta
copy to Main/System/Battle/BattleField/RecordActions/DeathRecordAction.cs.meta
File was copied from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 0c39e10c6d11822409ee2e39b684f89d |
| | | guid: 4db9e665fb4537244ad07b87755fbbc2 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
New file |
| | |
| | | // #if UNITY_EDITOR |
| | | // using UnityEngine; |
| | | // using System.Collections.Generic; |
| | | |
| | | // public class EditorSkillRecordAction : RecordAction |
| | | // { |
| | | // public int SkillId; |
| | | |
| | | // public SkillConfig skillConfig; |
| | | |
| | | // protected SkillBase skillBase; |
| | | |
| | | // protected List<Dictionary<int, List<int>>> damageList = new List<Dictionary<int, List<int>>>(); |
| | | |
| | | // private bool isCast = false; |
| | | |
| | | |
| | | // public EditorSkillRecordAction(int _SkillId, BattleField _battleField, BattleObject _battleObj) |
| | | // : base(RecordActionType.Skill, _battleField, _battleObj) |
| | | // { |
| | | // SkillId = _SkillId; |
| | | |
| | | // skillConfig = SkillConfig.Get(SkillId); |
| | | |
| | | // if (null == skillConfig) |
| | | // { |
| | | // Debug.LogError("找不到技能配置 " + SkillId); |
| | | // } |
| | | |
| | | // skillBase = SkillFactory.CreateSkill(skillConfig); |
| | | |
| | | // // _battleObj使用了SkillId的技能 |
| | | // damageList = skillBase.GetDamageList(battleObject, battleField); |
| | | // } |
| | | |
| | | // public EditorSkillRecordAction(int _SkillId, BattleField _battleField, BattleObject _battleObj, List<Dictionary<int, List<int>>> _damageList) |
| | | // : base(RecordActionType.Skill, _battleField, _battleObj) |
| | | // { |
| | | // SkillId = _SkillId; |
| | | |
| | | // skillConfig = SkillConfig.Get(SkillId); |
| | | |
| | | // if (null == skillConfig) |
| | | // { |
| | | // Debug.LogError("找不到技能配置 " + SkillId); |
| | | // } |
| | | |
| | | // skillBase = SkillFactory.CreateSkill(skillConfig); |
| | | |
| | | // damageList = _damageList; |
| | | // // _battleObj使用了SkillId的技能 |
| | | // } |
| | | |
| | | // public override bool IsFinished() |
| | | // { |
| | | // return skillBase.IsFinished(); |
| | | // } |
| | | |
| | | |
| | | // public override void Run() |
| | | // { |
| | | // base.Run(); |
| | | |
| | | // if (null == skillBase) |
| | | // { |
| | | // return; |
| | | // } |
| | | |
| | | // if (!skillBase.IsFinished()) |
| | | // { |
| | | // skillBase.Run(); |
| | | // } |
| | | |
| | | // if (isCast) |
| | | // return; |
| | | |
| | | // if (damageList.Count > 0) |
| | | // { |
| | | // skillBase.Cast(battleObject, battleField, damageList); |
| | | // } |
| | | // else |
| | | // { |
| | | // skillBase.ForceFinished(); |
| | | // } |
| | | |
| | | // isCast = true; |
| | | // } |
| | | // } |
| | | // #endif |
copy from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta
copy to Main/System/Battle/BattleField/RecordActions/EditorSkillRecordAction.cs.meta
File was copied from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 0c39e10c6d11822409ee2e39b684f89d |
| | | guid: eb0ee7684ec97d5479a7bf8d36a1673c |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | |
| | | |
| | | public class SkillRecordAction : RecordAction |
| | | { |
| | | public int SkillId; |
| | | |
| | | public SkillConfig skillConfig; |
| | | |
| | | protected SkillBase skillBase; |
| | | |
| | | protected List<Dictionary<int, List<int>>> damageList = new List<Dictionary<int, List<int>>>(); |
| | | |
| | | private bool isCast = false; |
| | | |
| | | |
| | | public SkillRecordAction(int _SkillId, BattleField _battleField, BattleObject _battleObj) |
| | | : base(RecordActionType.Skill, _battleField, _battleObj) |
| | | public SkillRecordAction(BattleField _battleField, BattleObject _caster, H0604_tagUseSkillAttack vNetData) |
| | | : base(RecordActionType.Skill, _battleField, _caster) |
| | | { |
| | | SkillId = _SkillId; |
| | | |
| | | skillConfig = SkillConfig.Get(SkillId); |
| | | |
| | | if (null == skillConfig) |
| | | { |
| | | Debug.LogError("找不到技能配置 " + SkillId); |
| | | } |
| | | |
| | | skillBase = SkillFactory.CreateSkill(skillConfig); |
| | | |
| | | // _battleObj使用了SkillId的技能 |
| | | damageList = skillBase.GetDamageList(battleObject, battleField); |
| | | } |
| | | |
| | | public SkillRecordAction(int _SkillId, BattleField _battleField, BattleObject _battleObj, List<Dictionary<int, List<int>>> _damageList) |
| | | : base(RecordActionType.Skill, _battleField, _battleObj) |
| | | { |
| | | SkillId = _SkillId; |
| | | |
| | | skillConfig = SkillConfig.Get(SkillId); |
| | | |
| | | if (null == skillConfig) |
| | | { |
| | | Debug.LogError("找不到技能配置 " + SkillId); |
| | | } |
| | | |
| | | skillBase = SkillFactory.CreateSkill(skillConfig); |
| | | |
| | | damageList = _damageList; |
| | | // _battleObj使用了SkillId的技能 |
| | | skillBase = SkillFactory.CreateSkill(_caster, vNetData, _battleField); |
| | | } |
| | | |
| | | public override bool IsFinished() |
| | |
| | | if (isCast) |
| | | return; |
| | | |
| | | if (damageList.Count > 0) |
| | | { |
| | | skillBase.Cast(battleObject, battleField, damageList); |
| | | } |
| | | else |
| | | { |
| | | skillBase.ForceFinished(); |
| | | } |
| | | skillBase.Cast(); |
| | | |
| | | isCast = true; |
| | | } |
| | |
| | | |
| | | |
| | | using System; |
| | | using LitJson; |
| | | using UnityEngine; |
| | | using System.Collections.Generic; |
| | | |
| | | public class StoryBattleField : BattleField |
| | | { |
| | | public override void Init(TeamBase _redTeam, TeamBase _blueTeam) |
| | | { |
| | | base.Init(_redTeam, _blueTeam); |
| | | protected int chapter;// 章节 |
| | | protected int wave;// 波数 |
| | | protected int level;// 关卡 |
| | | protected JsonData extendData; |
| | | |
| | | protected MainChapterConfig chapterConfig; |
| | | |
| | | protected MainLevelConfig levelConfig; |
| | | |
| | | public StoryBattleField() : base(string.Empty) |
| | | { |
| | | |
| | | } |
| | | |
| | | public override void Init(int MapID, int FuncLineID, JsonData _extendData, |
| | | List<TeamBase> _redTeamList, List<TeamBase> _blueTeamList) |
| | | { |
| | | base.Init(MapID, FuncLineID, extendData, _redTeamList, _blueTeamList); |
| | | |
| | | LoadBattleMode(); |
| | | |
| | | chapter = FuncLineID / 10000; |
| | | wave = MapID == 1 ? FuncLineID % 100 : 1;//第几波怪 |
| | | level = (FuncLineID % 10000) / 100; |
| | | |
| | | extendData = _extendData; |
| | | chapterConfig = MainChapterConfig.Get(chapter); |
| | | levelConfig = MainLevelConfig.Get(level); |
| | | |
| | | } |
| | | |
| | | protected void LoadBattleMode() |
| | | { |
| | | string savedStr = LocalSave.GetString("StoryBattleFieldBattleMode"); |
| | | if (string.IsNullOrEmpty(savedStr)) |
| | | { |
| | |
| | | SetBattleMode((BattleMode)Enum.Parse(typeof(BattleMode), savedStr)); |
| | | } |
| | | |
| | | public override void TurnFightState(int TurnNum, int State, |
| | | uint FuncLineID, JsonData extendData) |
| | | { |
| | | base.TurnFightState(TurnNum, State, FuncLineID, extendData); |
| | | |
| | | switch (State) |
| | | { |
| | | // 起始状态标记 |
| | | case 0: |
| | | break; |
| | | case 1://准备完毕 |
| | | break; |
| | | case 2://战斗中 |
| | | break; |
| | | case 3://战斗结束 |
| | | break; |
| | | case 4://结算奖励 |
| | | break; |
| | | case 5://结束状态标记 |
| | | break; |
| | | default: |
| | | Debug.LogError("recieve a unknown State"); |
| | | break; |
| | | } |
| | | } |
| | | |
| | | public override void OnTurnFightObjAction(int turnNum, int ObjID) |
| | | { |
| | | base.OnTurnFightObjAction(turnNum, ObjID); |
| | | } |
| | | |
| | | public override void OnTurnFightState(int turnNum, int State, int FuncLineID, JsonData extendData) |
| | | { |
| | | base.OnTurnFightState(turnNum, State, FuncLineID, extendData); |
| | | |
| | | } |
| | | |
| | | // public override void Run() |
| | | // { |
| | | // // 一定要记住这个 |
New file |
| | |
| | | using LitJson; |
| | | using System; |
| | | using System.Collections; |
| | | using System.Collections.Generic; |
| | | |
| | | |
| | | public static class BattleFieldFactory |
| | | { |
| | | |
| | | public static BattleField CreateBattleField(string guid, int MapID, int FuncLineID, JsonData extendData, List<TeamBase> redTeamList, List<TeamBase> blueTeamList) |
| | | { |
| | | BattleField battleField = null; |
| | | |
| | | |
| | | switch (MapID) |
| | | { |
| | | case 1: |
| | | case 2: |
| | | battleField = new StoryBattleField(); |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | |
| | | return battleField; |
| | | } |
| | | |
| | | |
| | | } |
copy from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta
copy to Main/System/Battle/BattleFieldFactory.cs.meta
File was copied from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 0c39e10c6d11822409ee2e39b684f89d |
| | | guid: 04ec4d20225cf8e4a8e9abfccf38e154 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | |
| | | using System.Collections.Generic; |
| | | using UnityEngine; |
| | | |
| | | using LitJson; |
| | | |
| | | |
| | | public class BattleManager : GameSystemManager<BattleManager> |
| | | { |
| | | public StoryBattleField storyBattleField = null; |
| | | |
| | | protected Dictionary<int, BattleField> battleFields = new Dictionary<int, BattleField>(); |
| | | // 同时只能有一场战斗在进行 guid, battlefield |
| | | protected Dictionary<string, BattleField> battleFields = new Dictionary<string, BattleField>(); |
| | | |
| | | protected LogicUpdate logicUpdate = new LogicUpdate(); |
| | | |
| | | public override void Init() |
| | | { |
| | | base.Init(); |
| | | StartStoryBattle(); |
| | | // StartStoryBattle(); |
| | | logicUpdate.Start(Run); |
| | | } |
| | | |
| | | public override void Release() |
| | | { |
| | | Debug.LogError("who release this one"); |
| | | base.Release(); |
| | | logicUpdate.Destroy(); |
| | | } |
| | | |
| | | public void StartStoryBattle() |
| | | public void CreateStoryBattle(int MapID, int FuncLineID, JsonData extendData, List<TeamBase> redTeamList, List<TeamBase> blueTeamList) |
| | | { |
| | | if (null == storyBattleField) |
| | | { |
| | | storyBattleField = new StoryBattleField(); |
| | | } |
| | | |
| | | TeamBase redTeam = GetStoryTeam();//TeamManager.Instance.GetTeam(TeamType.Story); |
| | | TeamBase blueTeam = GetStoryTeam(); |
| | | storyBattleField.Init(/*这里要加个创建背景的*/redTeam, blueTeam); |
| | | // storyBattleField.Start(); |
| | | storyBattleField.battleRootNode.transform.SetParent(Launch.Instance.transform); |
| | | storyBattleField.Init(MapID, FuncLineID, extendData, redTeamList, blueTeamList); |
| | | } |
| | | |
| | | |
| | | |
| | | public void OnBattleClose(BattleField _battleField) |
| | | { |
| | | |
| | | } |
| | | |
| | | |
| | | #region 截断网络派发包 只收入当前包的后续 |
| | | private bool allow = true; |
| | | |
| | | private Queue<GameNetPackBasic> packQueue = new Queue<GameNetPackBasic>(); |
| | | |
| | | public bool IsCanDistributePackage(GameNetPackBasic _package) |
| | | { |
| | | if (_package is HB425_tagSCTurnFightReportSign) |
| | | { |
| | | HB425_tagSCTurnFightReportSign pkg = _package as HB425_tagSCTurnFightReportSign; |
| | | |
| | | // 0-战报片段开始;1-战报片段结束; |
| | | if (pkg.Sign == 0) |
| | | { |
| | | allow = false; |
| | | } |
| | | else |
| | | { |
| | | allow = true; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | if (!allow) |
| | | { |
| | | packQueue.Enqueue(_package); |
| | | } |
| | | } |
| | | |
| | | return allow; |
| | | } |
| | | |
| | | public bool DistributeNextPackage() |
| | | { |
| | | if (packQueue.Count > 0) |
| | | { |
| | | GameNetPackBasic pack = packQueue.Dequeue(); |
| | | PackageRegedit.Distribute(pack); |
| | | return true; |
| | | } |
| | | else |
| | | { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | private TeamBase GetStoryTeam() |
| | | public void OnConnected() |
| | | { |
| | | TeamBase teamBase = new TeamBase(); |
| | | #if UNITY_EDITOR |
| | | teamBase.FillWithFakeData(); |
| | | #else |
| | | // YYL TODO |
| | | // 根据配表塞英雄 后面可能还要塞其他东西 先放在这里反正 做主线了再转移 |
| | | #endif |
| | | if (!allow) |
| | | { |
| | | allow = true; |
| | | packQueue.Clear(); |
| | | |
| | | return teamBase; |
| | | // 重新发送要上一组战斗包的请求 |
| | | // TODO YYL |
| | | } |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | #region 战报部分 |
| | | |
| | | protected Dictionary<string, Queue<GameNetPackBasic>> battleReportDict = new Dictionary<string, Queue<GameNetPackBasic>>(); |
| | | |
| | | protected Dictionary<string, List<ulong>> battlePackRelationList = new Dictionary<string, List<ulong>>(); |
| | | |
| | | public void PushPackage(string guid, GameNetPackBasic vNetPack) |
| | | { |
| | | Queue<GameNetPackBasic> queue = null; |
| | | |
| | | if (!battleReportDict.TryGetValue(guid, out queue)) |
| | | { |
| | | queue = new Queue<GameNetPackBasic>(); |
| | | } |
| | | |
| | | queue.Enqueue(vNetPack); |
| | | |
| | | List<ulong> uidList = null; |
| | | |
| | | if (!battlePackRelationList.TryGetValue(guid, out uidList)) |
| | | { |
| | | uidList = new List<ulong>(); |
| | | } |
| | | |
| | | uidList.Add(vNetPack.packUID); |
| | | } |
| | | |
| | | public BattleField GetBattleField(ulong packUID) |
| | | { |
| | | return GetBattleField(GetGUID(packUID)); |
| | | } |
| | | |
| | | public BattleField GetBattleField(string guid) |
| | | { |
| | | BattleField battleField = null; |
| | | battleFields.TryGetValue(guid, out battleField); |
| | | if (battleField == null) |
| | | { |
| | | battleField = storyBattleField; |
| | | } |
| | | return battleField; |
| | | } |
| | | |
| | | |
| | | |
| | | public string GetGUID(ulong packUID) |
| | | { |
| | | foreach (var kv in battlePackRelationList) |
| | | { |
| | | if (kv.Value.Contains(packUID)) |
| | | { |
| | | return kv.Key; |
| | | } |
| | | } |
| | | return string.Empty; |
| | | } |
| | | |
| | | |
| | | public void DistributeNextReportPackage(string guid) |
| | | { |
| | | Queue<GameNetPackBasic> queue = null; |
| | | |
| | | if (!battleReportDict.TryGetValue(guid, out queue)) |
| | | { |
| | | Debug.LogError("DistributeNextReportPackage could not find queue for guid : " + guid); |
| | | return; |
| | | } |
| | | |
| | | PackageRegedit.Distribute(queue.Dequeue()); |
| | | |
| | | if (queue.Count <= 0) |
| | | { |
| | | battleReportDict.Remove(guid); |
| | | battlePackRelationList.Remove(guid); |
| | | } |
| | | } |
| | | #endregion |
| | | |
| | | public BattleField CreateBattleField(string guid, int MapID, int FuncLineID, JsonData extendData, List<TeamBase> redTeamList, List<TeamBase> blueTeamList) |
| | | { |
| | | BattleField battleField = null; |
| | | |
| | | if (battleFields.TryGetValue(guid, out battleField)) |
| | | { |
| | | Debug.LogError("战场已存在 先进行销毁"); |
| | | battleField.Destroy(); |
| | | } |
| | | |
| | | |
| | | battleField = BattleFieldFactory.CreateBattleField(guid, MapID, FuncLineID, extendData, redTeamList, blueTeamList); |
| | | |
| | | battleFields.Add(guid, battleField); |
| | | |
| | | if (string.Empty == guid) |
| | | { |
| | | storyBattleField = battleField as StoryBattleField; |
| | | } |
| | | |
| | | return battleField; |
| | | } |
| | | |
| | | |
| | | // public void OnTurnFightObjAction(battleType, vNetData.TurnNum, (int)vNetData.ObjID) |
| | | |
| | | |
| | | public void Run() |
| | | { |
| | | if (null != storyBattleField) |
| | |
| | | battleField = _battleField; |
| | | CreateTeam(battleField.battleRootNode.redTeamNodeList, redCampDict, _redTeam, BattleCamp.Red); |
| | | CreateTeam(battleField.battleRootNode.blueTeamNodeList, blueCampDict, _blueTeam, BattleCamp.Blue); |
| | | } |
| | | } |
| | | |
| | | |
| | | protected void CreateTeam(List<GameObject> posNodeList, Dictionary<int, BattleObject> campDict, TeamBase teamBase, BattleCamp _Camp) |
| | | { |
| | |
| | | if (teamHero != null) |
| | | { |
| | | BattleObject battleObj = BattleObjectFactory.CreateBattleObject(battleField, posNodeList, teamHero, _Camp); |
| | | allBattleObjDict.Add(battleObj.BattleObjectId, battleObj); |
| | | campDict.Add(teamHero.heroIndex, battleObj); |
| | | allBattleObjDict.Add(battleObj.ObjID, battleObj); |
| | | campDict.Add(teamHero.positionNum, battleObj); |
| | | } |
| | | } |
| | | } |
| | | |
| | | public BattleObject GetBattleObject(int battleObjId) |
| | | public BattleObject GetBattleObject(int objId) |
| | | { |
| | | if (allBattleObjDict.TryGetValue(battleObjId, out BattleObject battleObj)) |
| | | if (allBattleObjDict.TryGetValue(objId, out BattleObject battleObj)) |
| | | { |
| | | return battleObj; |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | public List<BattleObject> GetBattleObjList(H0604_tagUseSkillAttack tagUseSkillAttack) |
| | | { |
| | | List<BattleObject> retList = new List<BattleObject>(); |
| | | foreach (var hurt in tagUseSkillAttack.HurtList) |
| | | { |
| | | BattleObject obj = GetBattleObject((int)hurt.ObjID); |
| | | if (null != obj) |
| | | { |
| | | retList.Add(obj); |
| | | } |
| | | } |
| | | |
| | | return retList; |
| | | } |
| | | |
| | | protected void DestroyTeam(Dictionary<int, BattleObject> campDict) |
| | |
| | | BattleObject battleObj = item.Value; |
| | | if (battleObj != null) |
| | | { |
| | | allBattleObjDict.Remove(battleObj.BattleObjectId); |
| | | allBattleObjDict.Remove(battleObj.ObjID); |
| | | BattleObjectFactory.DestroyBattleObject(item.Key, battleObj); |
| | | } |
| | | } |
| | |
| | | return blueCampList; |
| | | } |
| | | |
| | | #if UNITY_EDITOR |
| | | #if UNITY_EDITOR_STOP_USING |
| | | public void ReviveAll() |
| | | { |
| | | foreach (var kv in allBattleObjDict) |
| | |
| | | //暂时没有召唤物 |
| | | // 放在第7格的BOSS后排的。。位置放在正中间 |
| | | // a)前排,1、2、3号为前排,前排全部阵亡后,4、5、6号即是前排也是后排 7其实也是后排 |
| | | List<BattleObject> frontList = new List<BattleObject>(from BO in returnList where BO.teamHero.heroIndex < 3 && !BO.IsDead() select BO); |
| | | List<BattleObject> frontList = new List<BattleObject>(from BO in returnList where BO.teamHero.positionNum < 3 && !BO.IsDead() select BO); |
| | | if (frontList.Count == 0) |
| | | { |
| | | frontList.AddRange(returnList); |
| | |
| | | returnList = frontList; |
| | | break; |
| | | case SkillTargetRangeType.Back: |
| | | List<BattleObject> backList = new List<BattleObject>(from BO in returnList where BO.teamHero.heroIndex >= 3 && !BO.IsDead() select BO); |
| | | List<BattleObject> backList = new List<BattleObject>(from BO in returnList where BO.teamHero.positionNum >= 3 && !BO.IsDead() select BO); |
| | | if (backList.Count == 0) |
| | | { |
| | | backList.AddRange(returnList); |
| | |
| | | { |
| | | public BattleField battleField; |
| | | |
| | | public int BattleObjectId { get; set; } |
| | | public BattleObjectBuffMgr buffMgr; |
| | | |
| | | public int ObjID { get; set; } |
| | | |
| | | public BattleCamp Camp { get; protected set; } |
| | | |
| | |
| | | |
| | | // public BuffMgr buffMgr; |
| | | |
| | | protected MotionBase motionBase; |
| | | public MotionBase motionBase; |
| | | |
| | | public GameObject heroGo |
| | | { |
| | | get; |
| | | private set; |
| | | } |
| | | |
| | | protected Action onDeathAnimationComplete; |
| | | |
| | | protected Renderer[] renderers; |
| | | |
| | | public Transform effectNode; |
| | | |
| | | public BattleObject(BattleField _battleField) |
| | | { |
| | |
| | | Camp = _camp; |
| | | motionBase = new MotionBase(); |
| | | motionBase.Init(heroGo.GetComponentInChildren<SkeletonGraphic>(true)); |
| | | motionBase.onAnimationComplete += OnAnimationComplete; |
| | | |
| | | buffMgr.Init(this); |
| | | |
| | | renderers = heroGo.GetComponentsInChildren<Renderer>(true); |
| | | } |
| | | |
| | | |
| | |
| | | motionBase.Release(); |
| | | motionBase = null; |
| | | teamHero = null; |
| | | BattleObjectId = 0; |
| | | ObjID = 0; |
| | | motionBase.onAnimationComplete -= OnAnimationComplete; |
| | | } |
| | | |
| | | public void OnObjInfoRefresh(H0418_tagObjInfoRefresh _refreshInfo) |
| | | { |
| | | switch ((PlayerDataType)_refreshInfo.RefreshType) |
| | | { |
| | | case PlayerDataType.HP: |
| | | teamHero.curHp = GeneralDefine.GetFactValue(_refreshInfo.Value, _refreshInfo.ValueEx); |
| | | break; |
| | | case PlayerDataType.MaxHP: |
| | | teamHero.maxHp = GeneralDefine.GetFactValue(_refreshInfo.Value, _refreshInfo.ValueEx); |
| | | break; |
| | | case PlayerDataType.XP: |
| | | teamHero.rage = (int)GeneralDefine.GetFactValue(_refreshInfo.Value, _refreshInfo.ValueEx); |
| | | break; |
| | | default: |
| | | Debug.LogError("BattleObject.ObjInfoRefresh 出现意外类型 " + _refreshInfo.RefreshType.ToString()); |
| | | break; |
| | | } |
| | | } |
| | | |
| | | // 眩晕 |
| | |
| | | { |
| | | return teamHero.isStoned; |
| | | } |
| | | |
| | | // // 禁锢 |
| | | // public bool IsConfined() |
| | | // { |
| | | // return false; |
| | | // } |
| | | |
| | | // 被沉默 |
| | | public bool IsSlient() |
| | |
| | | return true; |
| | | } |
| | | |
| | | public virtual void TakeDamage(List<int> damageValues) |
| | | public virtual void Hurt(List<long> damageValues, int attackType) |
| | | { |
| | | if (IsDead()) |
| | | return; |
| | | |
| | | PopDamage(damageValues); |
| | | PopDamage(teamHero.curHp, damageValues, attackType); |
| | | |
| | | motionBase.PlayAnimation(MotionName.hit, false); |
| | | |
| | | // 计算伤害 |
| | | int totalDamage = 0; |
| | | long totalDamage = 0; |
| | | foreach (var damage in damageValues) |
| | | { |
| | | totalDamage += damage; |
| | | } |
| | | |
| | | |
| | | // 扣血 |
| | | teamHero.curHp -= totalDamage; |
| | | |
| | | // 其实这里应该是等服务器发death的action |
| | | // if (IsDead()) |
| | | // { |
| | | // OnDeath(); |
| | | // } |
| | | |
| | | } |
| | | |
| | | // 闪避开始 |
| | |
| | | { |
| | | float pingpongTime = 0.2f; |
| | | RectTransform rectTrans = heroGo.GetComponent<RectTransform>(); |
| | | rectTrans.DOAnchorPos(new Vector3(-50, 50, 0), pingpongTime) |
| | | var tween = rectTrans.DOAnchorPos(new Vector3(-50, 50, 0), pingpongTime) |
| | | .SetEase(Ease.OutCubic); |
| | | |
| | | battleField.battleTweenMgr.OnPlayTween(tween); |
| | | } |
| | | |
| | | // 闪避结束 |
| | |
| | | { |
| | | float pingpongTime = 0.2f; |
| | | RectTransform rectTrans = heroGo.GetComponent<RectTransform>(); |
| | | rectTrans.DOAnchorPos(Vector3.zero, pingpongTime) |
| | | |
| | | var tween = rectTrans.DOAnchorPos(Vector3.zero, pingpongTime) |
| | | .SetEase(Ease.OutCubic); |
| | | |
| | | battleField.battleTweenMgr.OnPlayTween(tween); |
| | | } |
| | | |
| | | protected virtual void OnDeath() |
| | | public virtual void OnDeath(Action _onDeathAnimationComplete) |
| | | { |
| | | motionBase.OnOtherAnimationComplete = OnOtherAnimationComplete; |
| | | onDeathAnimationComplete = _onDeathAnimationComplete; |
| | | motionBase.PlayAnimation(MotionName.dead, false); |
| | | } |
| | | |
| | | protected virtual void OnOtherAnimationComplete(MotionName motionName) |
| | | protected virtual void OnAnimationComplete(MotionName motionName) |
| | | { |
| | | if (motionName == MotionName.dead) |
| | | { |
| | | OnDeadAnimationComplete(); |
| | | onDeathAnimationComplete?.Invoke(); |
| | | onDeathAnimationComplete = null; |
| | | } |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | // 伤害还要看 是否闪避 暴击 and so on 需要有一个DamageType 服务器应该会给 |
| | | protected virtual void PopDamage(List<int> damageValues) |
| | | protected virtual void PopDamage(long curHp, List<long> damageValues, int attackType) |
| | | { |
| | | // 其实应该通知出去给UI界面解耦 让UI界面自己来显示的 YYL TODO |
| | | // 播放伤害数字 |
| | |
| | | Debug.Log($"Damage: {damage}"); |
| | | } |
| | | |
| | | EventBroadcast.Instance.Broadcast<BattleObject, List<int>>(EventName.BATTLE_DAMAGE_TAKEN, this, damageValues); |
| | | EventBroadcast.Instance.Broadcast(EventName.BATTLE_DAMAGE_TAKEN, battleField.guid, this, damageValues); |
| | | } |
| | | |
| | | public void PlaySkill(SkillConfig skillConfig, List<Dictionary<int, List<int>>> damageList, Action _onComplete) |
| | | public RectTransform GetAliasTeamNode() |
| | | { |
| | | bool moveToTarget = true; |
| | | |
| | | if (moveToTarget) |
| | | { |
| | | int targetId = damageList[0].First().Key; |
| | | BattleObject _targetObj = battleField.battleObjMgr.GetBattleObject(targetId); |
| | | |
| | | RectTransform selfRect = heroGo.GetComponent<RectTransform>(); |
| | | RectTransform targetRect = _targetObj.heroGo.GetComponent<RectTransform>(); |
| | | Vector2 curAnchoredPos = selfRect.anchoredPosition; |
| | | |
| | | MoveToTargetUI(selfRect, targetRect, new Vector2(100f, 0f), () => |
| | | { |
| | | PlaySkillAnimation(skillConfig, damageList, () => |
| | | { |
| | | // 回到原位置 |
| | | selfRect.DOAnchorPos(curAnchoredPos, 0.2f) |
| | | .SetEase(Ease.Linear) |
| | | .OnComplete(() => { |
| | | _onComplete?.Invoke(); |
| | | }); |
| | | }); |
| | | }); |
| | | } |
| | | else |
| | | { |
| | | PlaySkillAnimation(skillConfig, damageList, _onComplete); |
| | | } |
| | | return battleField.GetTeamNode(Camp); |
| | | } |
| | | |
| | | protected void MoveToTargetUI(RectTransform selfRect, RectTransform targetRect, Vector2 offset, Action _onComplete) |
| | | public RectTransform GetEnemyTeamNode() |
| | | { |
| | | // 1. 目标的本地坐标转为世界坐标 |
| | | Vector3 targetWorldPos = targetRect.TransformPoint(targetRect.anchoredPosition + offset); |
| | | |
| | | // 2. 世界坐标转为自己父节点下的本地坐标 |
| | | RectTransform parentRect = selfRect.parent as RectTransform; |
| | | Vector2 targetAnchoredPos; |
| | | RectTransformUtility.ScreenPointToLocalPointInRectangle( |
| | | parentRect, |
| | | RectTransformUtility.WorldToScreenPoint(null, targetWorldPos), |
| | | null, |
| | | out targetAnchoredPos); |
| | | |
| | | // 3. DOTween 移动 |
| | | selfRect.DOAnchorPos(targetAnchoredPos, 0.2f) |
| | | .SetEase(Ease.Linear) |
| | | .OnComplete(() => _onComplete?.Invoke()); |
| | | return battleField.GetTeamNode(Camp == BattleCamp.Red ? BattleCamp.Blue : BattleCamp.Red); |
| | | } |
| | | |
| | | |
| | | protected void PlaySkillAnimation(SkillConfig skillConfig, List<Dictionary<int, List<int>>> damageList, Action _onComplete) |
| | | { |
| | | |
| | | // 关键帧列表 |
| | | List<int> keyFrameList = new List<int>() { 15 }; |
| | | motionBase.OnAttackHitEvent = (int _frame) => |
| | | { |
| | | Dictionary<int, List<int>> oneRoundDamage = damageList[keyFrameList.IndexOf(_frame)]; |
| | | |
| | | foreach (var kvp in oneRoundDamage) |
| | | { |
| | | int targetId = kvp.Key; |
| | | List<int> damageValues = kvp.Value; |
| | | |
| | | BattleObject targetObj = battleField.battleObjMgr.GetBattleObject(targetId); |
| | | if (targetObj != null && !targetObj.IsDead()) |
| | | { |
| | | targetObj.TakeDamage(damageValues); |
| | | } |
| | | } |
| | | }; |
| | | |
| | | motionBase.OnAttackAnimationComplete = () => |
| | | { |
| | | _onComplete?.Invoke(); |
| | | |
| | | motionBase.OnAttackHitEvent = null; |
| | | motionBase.OnAttackAnimationComplete = null; |
| | | |
| | | // 死亡确定其实不应该在这里进行触发 应该由服务器下发 YYL TODO |
| | | |
| | | #if UNITY_EDITOR |
| | | // 暂时的处理 |
| | | HashSet<int> hitTargets = new HashSet<int>(); |
| | | |
| | | foreach (var dmgDict in damageList) |
| | | { |
| | | foreach (var kvp in dmgDict) |
| | | { |
| | | int targetId = kvp.Key; |
| | | hitTargets.Add(targetId); |
| | | } |
| | | } |
| | | |
| | | foreach (int targetId in hitTargets) |
| | | { |
| | | BattleObject targetObj = battleField.battleObjMgr.GetBattleObject(targetId); |
| | | if (targetObj != null && targetObj.IsDead()) |
| | | { |
| | | targetObj.OnDeath(); |
| | | } |
| | | } |
| | | #endif |
| | | }; |
| | | |
| | | motionBase.PlayAnimationEx(MotionName.attack, false, keyFrameList); |
| | | } |
| | | |
| | | #if UNITY_EDITOR |
| | | #if UNITY_EDITOR_STOP_USING |
| | | public void EditorRevive() |
| | | { |
| | | teamHero.curHp = 100; |
| | |
| | | using System.Collections.Generic; |
| | | using System; |
| | | using UnityEngine; |
| | | using Spine.Unity; |
| | | |
| | | public class BattleObjectFactory |
| | | { |
| | | // 本意是要在这里做池的内容的 但是想了一下 利用效率有点差 最多做一下红色方的缓存 蓝色方的即时用 即时删除 或者缓存上一次战斗的就行 |
| | | private static int AutoIncrementID = 100000; |
| | | // private static int AutoIncrementID = 100000; |
| | | |
| | | public static BattleObject CreateBattleObject(BattleField _battleField, List<GameObject> posNodeList, TeamHero teamHero, BattleCamp _Camp) |
| | | { |
| | | HeroSkinConfig skinCfg = teamHero.heroInfo.skinConfig; |
| | | HeroSkinConfig skinCfg = teamHero.skinConfig; |
| | | GameObject battleGO = ResManager.Instance.LoadAsset<GameObject>("Hero/SpineRes", "Hero_001"/*skinCfg.SpineRes*/); |
| | | GameObject goParent = posNodeList[teamHero.heroIndex]; |
| | | SkeletonGraphic skeletonGraphic = battleGO.GetComponent<SkeletonGraphic>(); |
| | | skeletonGraphic.skeletonDataAsset = ResManager.Instance.LoadAsset<SkeletonDataAsset>("Hero/SpineRes/", skinCfg.SpineRes); |
| | | skeletonGraphic.Initialize(true); |
| | | GameObject goParent = posNodeList[teamHero.positionNum]; |
| | | BattleObject battleObject = new BattleObject(_battleField); |
| | | battleObject.BattleObjectId = AutoIncrementID++; |
| | | battleGO.name = battleObject.BattleObjectId.ToString(); |
| | | battleObject.ObjID = teamHero.ObjID; |
| | | battleGO.name = battleObject.ObjID.ToString(); |
| | | battleObject.Init(GameObject.Instantiate(battleGO, goParent.transform), teamHero, _Camp); |
| | | return battleObject; |
| | | } |
New file |
| | |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using DG.Tweening; |
| | | using UnityEngine; |
| | | |
| | | public class BattleTweenMgr |
| | | { |
| | | private BattleField battleField; |
| | | |
| | | private List<Tween> tweenList = new List<Tween>(); |
| | | |
| | | public void Init(BattleField _battleField) |
| | | { |
| | | battleField = _battleField; |
| | | } |
| | | |
| | | public void PauseGame() |
| | | { |
| | | foreach (var tween in tweenList) |
| | | { |
| | | if (tween != null && !tween.IsComplete()) |
| | | { |
| | | tween.Pause(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | public void ResumeGame() |
| | | { |
| | | foreach (var tween in tweenList) |
| | | { |
| | | if (tween != null && !tween.IsComplete()) |
| | | { |
| | | tween.Play(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | public void OnPlayTween(Tween tween) |
| | | { |
| | | if (tween == null || tween.IsComplete()) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | tweenList.Add(tween); |
| | | tween.OnComplete(() => |
| | | { |
| | | tweenList.Remove(tween); |
| | | }); |
| | | |
| | | tween.Play(); |
| | | } |
| | | } |
File was renamed from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 0c39e10c6d11822409ee2e39b684f89d |
| | | guid: ee889e8a605a1904599601b289691889 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
New file |
| | |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using UnityEngine; |
| | | using UnityEngine.UI; |
| | | using DG.Tweening; |
| | | using DG.Tweening.Core; |
| | | |
| | | |
| | | public static class BattleUtility |
| | | { |
| | | // 其他通用的战斗工具方法可以放在这里 |
| | | |
| | | public static TweenerCore<Vector2, Vector2, DG.Tweening.Plugins.Options.VectorOptions> MoveToTarget(RectTransform transform, RectTransform target, Vector2 offset, float duration, Action onComplete = null) |
| | | { |
| | | Vector3 targetWorldPos = target.TransformPoint(target.anchoredPosition + offset); |
| | | |
| | | RectTransform parentRect = transform.parent as RectTransform; |
| | | |
| | | Vector2 targetAnchoredPos; |
| | | RectTransformUtility.ScreenPointToLocalPointInRectangle( |
| | | parentRect, |
| | | RectTransformUtility.WorldToScreenPoint(null, targetWorldPos), |
| | | null, |
| | | out targetAnchoredPos); |
| | | |
| | | // 3. DOTween 移动 |
| | | return transform.DOAnchorPos(targetAnchoredPos, duration) |
| | | .SetEase(Ease.Linear) |
| | | .OnComplete(() => onComplete?.Invoke()); |
| | | } |
| | | |
| | | } |
copy from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta
copy to Main/System/Battle/BattleUtility.cs.meta
File was copied from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 0c39e10c6d11822409ee2e39b684f89d |
| | | guid: f2c6020c5feefa04e8a7975071123f79 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
New file |
| | |
| | | using System.Collections.Generic; |
| | | using UnityEngine; |
| | | |
| | | |
| | | public class BattleObjectBuffMgr |
| | | { |
| | | // private Dictionary<BuffBase, EffectPlayer> buffDict = new Dictionary<BuffBase, EffectPlayer>(); |
| | | |
| | | private BattleObject battleObject; |
| | | |
| | | public void Init(BattleObject _battleObject) |
| | | { |
| | | battleObject = _battleObject; |
| | | } |
| | | |
| | | public void Release() |
| | | { |
| | | |
| | | } |
| | | |
| | | // 增加buff |
| | | public void AddBuff(H0605_tagObjAddBuff vNetData) |
| | | { |
| | | // BuffBase buffBase = BuffFactory.CreateBuff(vNetData, battleObject); |
| | | // if (null == buffBase) |
| | | // { |
| | | // return; |
| | | // } |
| | | |
| | | // buffBase.OnAdd(); |
| | | } |
| | | |
| | | // 删除buff |
| | | public void RemoveBuff(H0606_tagObjDelBuff vNetData) |
| | | { |
| | | |
| | | // buffBase.OnRemove(); |
| | | } |
| | | } |
copy from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta
copy to Main/System/Battle/Buff/BattleObjectBuffMgr.cs.meta
File was copied from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 0c39e10c6d11822409ee2e39b684f89d |
| | | guid: 1a6e63c004530d242982e4cdaddaa74d |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
New file |
| | |
| | | using UnityEngine; |
| | | |
| | | /// <summary> |
| | | /// Buff基类,所有Buff类型继承自此类 |
| | | /// </summary> |
| | | public abstract class BuffBase |
| | | { |
| | | // public int BuffId { get; protected set; } |
| | | // public BattleObject Owner { get; protected set; } |
| | | // public int DurationRound { get; protected set; } // 持续回合数 |
| | | // public int ElapsedRound { get; protected set; } // 已经过的回合数 |
| | | |
| | | protected H0605_tagObjAddBuff h0605_TagObjAddBuff; |
| | | |
| | | public BuffBase(H0605_tagObjAddBuff _h0605_TagObjAddBuff) |
| | | { |
| | | h0605_TagObjAddBuff = _h0605_TagObjAddBuff; |
| | | // BuffId = buffId; |
| | | // Owner = owner; |
| | | // DurationRound = durationRound; |
| | | // ElapsedRound = 0; |
| | | |
| | | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// Buff添加时调用 |
| | | /// </summary> |
| | | public virtual void OnAdd() |
| | | { |
| | | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// Buff移除时调用 |
| | | /// </summary> |
| | | public virtual void OnRemove() |
| | | { |
| | | |
| | | } |
| | | } |
copy from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta
copy to Main/System/Battle/Buff/BuffBase.cs.meta
File was copied from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 0c39e10c6d11822409ee2e39b684f89d |
| | | guid: 6afb02269964eb748bbe21d946a0ef7a |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
New file |
| | |
| | | using UnityEngine; |
| | | |
| | | /// <summary> |
| | | /// Buff工厂,根据数据创建对应的Buff实例 |
| | | /// </summary> |
| | | public static class BuffFactory |
| | | { |
| | | public static BuffBase CreateBuff(H0605_tagObjAddBuff vNetData, BattleObject owner) |
| | | { |
| | | // int buffId = vNetData.buffId; |
| | | // int durationRound = vNetData.durationRound; |
| | | |
| | | // 示例:根据buffId创建不同类型Buff |
| | | // switch (buffId) |
| | | // { |
| | | // // case 1: return new StunBuff(buffId, owner, durationRound); |
| | | // // case 2: return new PoisonBuff(buffId, owner, durationRound); |
| | | // // 继续添加其它具体Buff类型 |
| | | // default: |
| | | // return null; // 未知buff不创建 |
| | | // } |
| | | return null; |
| | | } |
| | | } |
copy from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta
copy to Main/System/Battle/Buff/BuffFactory.cs.meta
File was copied from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 0c39e10c6d11822409ee2e39b684f89d |
| | | guid: 6c080c000bb94344d94179aa6a0bfa3b |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 115fa1b85e4a51a4d9869f53fca7c35c |
| | | folderAsset: yes |
| | | DefaultImporter: |
| | | externalObjects: {} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | |
| | | |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using UnityEngine; |
| | | |
| | | public class Bullet |
| | | { |
| | | protected BattleObject caster; |
| | | |
| | | protected SkillConfig skillConfig; |
| | | |
| | | protected List<H0604_tagUseSkillAttack.tagSkillHurtObj> hurtList; |
| | | |
| | | protected BattleField battleField; |
| | | |
| | | protected Action onComplete; |
| | | |
| | | |
| | | protected int curFrame = 0; |
| | | |
| | | |
| | | public Bullet(BattleObject _caster, SkillConfig skillConfig, |
| | | List<H0604_tagUseSkillAttack.tagSkillHurtObj> hurtList, BattleField battleField, Action _onComplete) |
| | | { |
| | | this.caster = _caster; |
| | | this.skillConfig = skillConfig; |
| | | this.hurtList = hurtList; |
| | | this.battleField = battleField; |
| | | this.onComplete = _onComplete; |
| | | |
| | | } |
| | | |
| | | public virtual void Start() |
| | | { |
| | | |
| | | } |
| | | public virtual void Run() |
| | | { |
| | | |
| | | } |
| | | |
| | | protected virtual void PlayEffect(int effectId, SkillEffectAnchor target) |
| | | { |
| | | // 还需要SoAttackType来判断是怎样的特效 |
| | | |
| | | switch (target) |
| | | { |
| | | // 特效先不管 TODO YYL 等特效重新写过一遍后再写 |
| | | |
| | | case SkillEffectAnchor.Caster: |
| | | // caster.PlayEffect(effectId); |
| | | break; |
| | | case SkillEffectAnchor.Target: |
| | | // caster.teamHero.PlayEffectOnAllies(effectId); |
| | | break; |
| | | case SkillEffectAnchor.AlliesCenter: |
| | | // caster.teamHero.PlayEffectOnAlliesCenter(effectId); |
| | | break; |
| | | case SkillEffectAnchor.EnemiesCenter: |
| | | // caster.teamHero.PlayEffectOnEnemiesCenter(effectId); |
| | | break; |
| | | default: |
| | | Debug.LogWarning($"Unhandled effect target: {target}"); |
| | | break; |
| | | } |
| | | } |
| | | |
| | | |
| | | protected virtual void PlayAudio(int audioId) |
| | | { |
| | | SoundPlayer.Instance.PlayUIAudio(audioId); |
| | | } |
| | | |
| | | protected virtual void ShakeScreen(int intensity) |
| | | { |
| | | // Implement screen shaking logic here |
| | | Debug.Log($"Shaking screen with intensity: {intensity}"); |
| | | } |
| | | |
| | | protected virtual void PopDamage() |
| | | { |
| | | |
| | | } |
| | | |
| | | protected virtual void OnSkillComplete() |
| | | { |
| | | onComplete?.Invoke(); |
| | | } |
| | | |
| | | protected virtual void PlaySkill(int skillId) |
| | | { |
| | | |
| | | } |
| | | } |
copy from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta
copy to Main/System/Battle/Bullet/Bullet.cs.meta
File was copied from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 0c39e10c6d11822409ee2e39b684f89d |
| | | guid: 8d4d5668dea0ef64da48bab26e795fac |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
New file |
| | |
| | | |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using UnityEngine; |
| | | |
| | | public static class BulletFactory |
| | | { |
| | | public static Bullet CreateBullet(BattleObject _caster, SkillConfig skillConfig, List<H0604_tagUseSkillAttack.tagSkillHurtObj> hurtList, BattleField battleField, Action _onComplete) |
| | | { |
| | | return null; |
| | | } |
| | | } |
copy from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta
copy to Main/System/Battle/Bullet/BulletFactory.cs.meta
File was copied from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 0c39e10c6d11822409ee2e39b684f89d |
| | | guid: b007b1040446daf4db9c2a14b6d25b1d |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
New file |
| | |
| | | |
| | | |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using UnityEngine; |
| | | |
| | | // 近战攻击 |
| | | public class CloseCombatBullet : Bullet |
| | | { |
| | | |
| | | protected int keyFrameIndex = 0; |
| | | |
| | | protected int frame = 0; |
| | | |
| | | public CloseCombatBullet(BattleObject _caster, SkillConfig _skillConfig, List<H0604_tagUseSkillAttack.tagSkillHurtObj> _hurtList, BattleField _battleField, Action _onComplete) |
| | | : base(_caster, _skillConfig, _hurtList, _battleField, _onComplete) |
| | | { |
| | | |
| | | } |
| | | |
| | | |
| | | public override void Start() |
| | | { |
| | | base.Start(); |
| | | |
| | | // 用skillconfig.xp来判断不保险 |
| | | MotionName motionName = GetMotionName(skillConfig.SkillMotionName); |
| | | caster.motionBase.PlayAnimation(motionName, false); |
| | | } |
| | | |
| | | public MotionName GetMotionName(string strMotionName) |
| | | { |
| | | return Enum.Parse<MotionName>(strMotionName); |
| | | } |
| | | |
| | | |
| | | protected override void OnSkillComplete() |
| | | { |
| | | foreach (var hurtObj in hurtList) |
| | | { |
| | | BattleObject targetObj = battleField.battleObjMgr.GetBattleObject((int)hurtObj.ObjID); |
| | | if (targetObj != null) |
| | | { |
| | | long curHP = GeneralDefine.GetFactValue(hurtObj.CurHP, hurtObj.CurHPEx); |
| | | targetObj.teamHero.curHp = curHP; |
| | | } |
| | | } |
| | | base.OnSkillComplete(); |
| | | |
| | | } |
| | | |
| | | |
| | | protected override void PopDamage() |
| | | { |
| | | if (keyFrameIndex >= skillConfig.DamageDivide.Length) |
| | | { |
| | | Debug.LogError("CloseCombatBullet PopDamage keyFrameIndex out of range: " + keyFrameIndex); |
| | | return; |
| | | } |
| | | |
| | | int[] tenKDamagePercentArray = skillConfig.DamageDivide[keyFrameIndex++]; |
| | | |
| | | foreach (var hurtObj in hurtList) |
| | | { |
| | | long factDamage = GeneralDefine.GetFactValue(hurtObj.HurtHP, hurtObj.HurtHPEx); |
| | | List<long> damageList = new List<long>(); |
| | | for (int i = 0; i < tenKDamagePercentArray.Length; i++) |
| | | { |
| | | long damage = (long)(Mathf.Round(factDamage * tenKDamagePercentArray[i] / 10000.0f)); |
| | | damageList.Add(damage); |
| | | } |
| | | |
| | | BattleObject targetObj = battleField.battleObjMgr.GetBattleObject((int)hurtObj.ObjID); |
| | | if (targetObj != null) |
| | | { |
| | | // 播放受击动作 |
| | | targetObj.Hurt(damageList, hurtObj.AttackType); |
| | | } |
| | | } |
| | | } |
| | | } |
copy from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta
copy to Main/System/Battle/Bullet/CloseCombatBullet.cs.meta
File was copied from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 0c39e10c6d11822409ee2e39b684f89d |
| | | guid: a21315aaaa6e8f6448f864298b4516c0 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
copy from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta
copy to Main/System/Battle/Bullet/TrajectoryBullet.cs.meta
File was copied from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 0c39e10c6d11822409ee2e39b684f89d |
| | | guid: 3d40a22572b07c24e9eefb52db0bfd87 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
New file |
| | |
| | | |
| | | |
| | | public enum BattleType |
| | | { |
| | | MainLevelMobs = 1, //主线小怪 |
| | | MainLevelBoss = 2, //主线boss |
| | | } |
copy from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta
copy to Main/System/Battle/Define/BattleType.cs.meta
File was copied from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 0c39e10c6d11822409ee2e39b684f89d |
| | | guid: ca8a7ce9d3982ee40bec8c3ea869a461 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
New file |
| | |
| | | |
| | | |
| | | public enum PlayEffectType |
| | | { |
| | | None = 0, |
| | | SkillStart, // 技能开始 |
| | | AttackHit, // 攻击命中 |
| | | } |
copy from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta
copy to Main/System/Battle/Define/PlayEffectType.cs.meta
File was copied from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 0c39e10c6d11822409ee2e39b684f89d |
| | | guid: ae351bd17066a3040a5e423c69aa28eb |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | |
| | | /// </summary> |
| | | public class MotionBase |
| | | { |
| | | public class WaitingTask |
| | | public static List<string> AttackMotionList = new List<string> |
| | | { |
| | | public List<int> triggerFrame; |
| | | public MotionName motionName; |
| | | public int currentFrame; |
| | | public Action<MotionName, int> callback; |
| | | MotionName.attack.ToString(), |
| | | MotionName.angerSkill.ToString(), |
| | | MotionName.passiveSkill.ToString(), |
| | | }; |
| | | |
| | | public WaitingTask(List<int> triggerFrame, MotionName motionName, Action<MotionName, int> _callback) |
| | | { |
| | | this.triggerFrame = new List<int>(triggerFrame); |
| | | this.motionName = motionName; |
| | | this.currentFrame = 0; |
| | | this.callback = _callback; |
| | | } |
| | | |
| | | public bool IsFinished() |
| | | { |
| | | return triggerFrame.Count <= 0; |
| | | } |
| | | |
| | | public void Run() |
| | | { |
| | | if (triggerFrame.Count > 0) |
| | | { |
| | | currentFrame ++; |
| | | |
| | | if (currentFrame >= triggerFrame[0]) |
| | | { |
| | | int frame = triggerFrame[0]; |
| | | triggerFrame.RemoveAt(0); |
| | | callback?.Invoke(motionName, frame); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | private Dictionary<Spine.TrackEntry, Action> trackEntryCompleteDict = new Dictionary<Spine.TrackEntry, Action>(); |
| | | |
| | | // 动画事件 |
| | | public Action OnAttackAnimationComplete; |
| | | public Action OnHitAnimationComplete; |
| | | public Action<MotionName> OnOtherAnimationComplete; |
| | | public Action<int> OnAttackHitEvent; //trigger index |
| | | public Action<MotionName> onAnimationComplete; |
| | | |
| | | #region 组件引用 |
| | | |
| | |
| | | protected float defaultMixDuration = 0f; |
| | | |
| | | #endregion |
| | | |
| | | protected List<WaitingTask> waitingTaskList = new List<WaitingTask>(); |
| | | protected List<WaitingTask> removeList = new List<WaitingTask>(); |
| | | |
| | | private Spine.TrackEntry currentTrackEntry; |
| | | |
| | |
| | | skeletonGraphic = null; |
| | | skeleton = null; |
| | | currentTrackEntry = null; |
| | | |
| | | waitingTaskList.Clear(); |
| | | removeList.Clear(); |
| | | } |
| | | |
| | | |
| | | #endregion |
| | | |
| | | #region 动画控制 |
| | |
| | | /// </summary> |
| | | /// <param name="motionName">动画枚举</param> |
| | | /// <param name="loop">是否循环</param> |
| | | /// <param name="_onComplete">动画播放完成回调</param> |
| | | /// <returns>动画轨道条目</returns> |
| | | public virtual Spine.TrackEntry PlayAnimation(MotionName motionName, bool loop) |
| | | public virtual Spine.TrackEntry PlayAnimation(MotionName motionName, bool loop, Action _onComplete = null) |
| | | { |
| | | if (spineAnimationState == null) return null; |
| | | |
| | | // 如果当前动画未完成 |
| | | if (currentTrackEntry != null && !currentTrackEntry.IsComplete) |
| | | { |
| | | if (trackEntryCompleteDict.TryGetValue(currentTrackEntry, out var __onComplete)) |
| | | { |
| | | __onComplete?.Invoke(); |
| | | trackEntryCompleteDict.Remove(currentTrackEntry); |
| | | } |
| | | currentTrackEntry = null; |
| | | } |
| | | |
| | | // 直接使用 ToString() 而不是调用 GetAnimationName |
| | | currentTrackEntry = spineAnimationState.SetAnimation(0, motionName.ToString(), loop); |
| | | |
| | | // 绑定回调 |
| | | if (_onComplete != null && currentTrackEntry != null) |
| | | { |
| | | trackEntryCompleteDict[currentTrackEntry] = _onComplete; |
| | | } |
| | | |
| | | return currentTrackEntry; |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 设置动画事件监听 |
| | |
| | | protected virtual void SetupAnimationHandlers() |
| | | { |
| | | if (spineAnimationState == null) return; |
| | | |
| | | |
| | | // 监听动画完成事件 |
| | | spineAnimationState.Complete += OnAnimationComplete; |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 动画完成事件处理 |
| | | /// </summary> |
| | | protected virtual void OnAnimationComplete(Spine.TrackEntry trackEntry) |
| | | { |
| | | string animation = trackEntry.Animation.Name; |
| | | |
| | | |
| | | // 攻击动画完成后恢复到待机状态 |
| | | if (animation == MotionName.attack.ToString() || |
| | | animation == MotionName.angerSkill.ToString()) |
| | | if (AttackMotionList.Contains(animation)) |
| | | { |
| | | OnAttackAnimationComplete?.Invoke(); |
| | | PlayAnimation(MotionName.idle, true); |
| | | } |
| | | // 受伤动画完成后恢复到待机状态 |
| | | // 受伤动画完成后恢复到待机状态 可能触发多次 因为有多段攻击的存在 |
| | | else if (animation == MotionName.hit.ToString()) |
| | | { |
| | | OnHitAnimationComplete?.Invoke(); |
| | | PlayAnimation(MotionName.idle, true); |
| | | } |
| | | else |
| | | onAnimationComplete?.Invoke((MotionName)Enum.Parse(typeof(MotionName), animation)); |
| | | |
| | | // 只调用本次TrackEntry的回调 |
| | | if (trackEntryCompleteDict.TryGetValue(trackEntry, out var cb)) |
| | | { |
| | | OnOtherAnimationComplete?.Invoke((MotionName)Enum.Parse(typeof(MotionName), animation)); |
| | | cb?.Invoke(); |
| | | trackEntryCompleteDict.Remove(trackEntry); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 动画事件处理 |
| | | /// </summary> |
| | | protected virtual void OnTriggerHitEvent(MotionName motionName, int hitIndex) |
| | | { |
| | | OnAttackHitEvent?.Invoke(hitIndex); |
| | | } |
| | | |
| | | // 拓展了播放动画方法,添加了触发帧的功能,在攻击动画中多段攻击的触发帧 |
| | | // 例如:攻击动画有三段,第一段攻击在第1帧触发,第二段攻击在第10帧触发,第三段攻击在第20帧触发 |
| | | // 那么triggerFrame就应该是[1, 10, 20] |
| | | public virtual void PlayAnimationEx(MotionName motionName, bool loop, List<int> triggerFrame = null) |
| | | { |
| | | PlayAnimation(motionName, loop); |
| | | if (triggerFrame != null && triggerFrame.Count >= 0) |
| | | { |
| | | AddWaitingTask(triggerFrame, motionName); |
| | | } |
| | | } |
| | | |
| | | protected void AddWaitingTask(List<int> triggerFrame, MotionName motionName) |
| | | { |
| | | if (triggerFrame != null && triggerFrame.Count > 0) |
| | | { |
| | | WaitingTask waitingTask = new WaitingTask(triggerFrame, motionName, OnTriggerHitEvent); |
| | | waitingTaskList.Add(waitingTask); |
| | | } |
| | | } |
| | | |
| | | public virtual void Run() |
| | | { |
| | | foreach (WaitingTask waitingTask in waitingTaskList) |
| | | { |
| | | waitingTask.Run(); |
| | | |
| | | if (waitingTask.IsFinished()) |
| | | { |
| | | removeList.Add(waitingTask); |
| | | } |
| | | } |
| | | |
| | | foreach (WaitingTask waitingTask in removeList) |
| | | { |
| | | waitingTaskList.Remove(waitingTask); |
| | | } |
| | | |
| | | removeList.Clear(); |
| | | } |
| | | |
| | | public virtual void Pause() |
| | |
| | | dead,//死亡 |
| | | angerSkill,//怒气技能 |
| | | attack,//普攻 |
| | | passiveSkill,//被动技能 |
| | | } |
| | |
| | | { |
| | | protected BattleField battleField; |
| | | |
| | | // 本次Action的主角 |
| | | protected BattleObject battleObject; |
| | | |
| | | // 给子类用的 并不代表事件的结束与否 |
| | | protected bool isFinish = false; |
| | | |
| | | protected bool isRunOnce = false; |
| | | |
| | | public RecordAction(RecordActionType _actionType, BattleField _battleField, BattleObject _battleObj) |
| | | { |
| | | actionType = _actionType; |
| | |
| | | |
| | | using System.Collections.Generic; |
| | | using UnityEngine; |
| | | using System; |
| | | using System.Linq; |
| | | |
| | | public class DirectlyDamageSkill : SkillBase |
| | | { |
| | | |
| | | public DirectlyDamageSkill(SkillConfig _skillCfg) : base(_skillCfg) |
| | | |
| | | public DirectlyDamageSkill(BattleObject _caster, SkillConfig _skillCfg, |
| | | H0604_tagUseSkillAttack vNetData, BattleField _battleField) : base(_caster, _skillCfg, vNetData, _battleField) |
| | | { |
| | | |
| | | |
| | | } |
| | | |
| | | public override void Run() |
| | | { |
| | | { |
| | | base.Run(); |
| | | |
| | | } |
| | | |
| | | public override void Cast(BattleObject _caster, BattleField _battleField, List<Dictionary<int, List<int>>> damageList) |
| | | protected override void OnTriggerEvent(int triggerIndex, int triggerFrame) |
| | | { |
| | | if (0 == triggerIndex) |
| | | { |
| | | List<BattleObject> targetList = GetTargetList(); |
| | | // 子类实现具体的技能逻辑 |
| | | SkillEffect effect = SkillEffectFactory.CreateSkillEffect(caster, skillConfig, tagUseSkillAttack); |
| | | if (null != effect) |
| | | { |
| | | // 如果是子弹类型的 |
| | | effect.Play((hitIndex, hurList) => |
| | | { |
| | | for (int i = 0; i < hurList.Count; i++) |
| | | { |
| | | var hurt = hurList[i]; |
| | | BattleObject target = caster.battleField.battleObjMgr.GetBattleObject((int)hurt.ObjID); |
| | | |
| | | List<long> damageList = new List<long>(); |
| | | // 计算伤害 分段的话 |
| | | if (hitIndex >= skillConfig.DamageDivide.Length) |
| | | { |
| | | Debug.LogError("DamageDivide有问题 需要检查 只显示一段伤害 取triggerFrames的"); |
| | | long totalDamage = GeneralDefine.GetFactValue(hurt.HurtHP, hurt.HurtHPEx) / (skillConfig.TriggerFrames.Length == 0 ? 1 : skillConfig.TriggerFrames.Length); |
| | | damageList.Add(totalDamage); |
| | | } |
| | | else |
| | | { |
| | | long totalDamage = GeneralDefine.GetFactValue(hurt.HurtHP, hurt.HurtHPEx); |
| | | |
| | | if (hitIndex >= skillConfig.DamageDivide.Length) |
| | | { |
| | | int[] tenKDamagePercentArray = skillConfig.DamageDivide[hitIndex]; |
| | | long factDamage = totalDamage; |
| | | for (int j = 0; j < tenKDamagePercentArray.Length; j++) |
| | | { |
| | | long damage = (long)(Mathf.Round(factDamage * tenKDamagePercentArray[j] / 10000.0f)); |
| | | damageList.Add(damage); |
| | | } |
| | | } |
| | | } |
| | | target.Hurt(damageList, hurt.AttackType); |
| | | } |
| | | }); |
| | | } |
| | | } |
| | | } |
| | | |
| | | protected override void DoSkillLogic(Action _onComplete = null) |
| | | { |
| | | _caster.PlaySkill(skillConfig, damageList, OnSkillAnimationFinished); |
| | | // 开始记录帧数 |
| | | startCounting = true; |
| | | } |
| | | |
| | | protected void OnSkillAnimationFinished() |
| | | { |
| | | isFinished = true; |
| | | } |
| | | |
| | | #if UNITY_EDITOR |
| | | #if UNITY_EDITOR_STOP_USING |
| | | // 伤害列表理应由服务器发给客户端 这边只做粗浅模拟 |
| | | public override List<Dictionary<int, List<int>>> GetDamageList(BattleObject _caster, BattleField battleField) |
| | | public override List<Dictionary<int, List<int>>> GetDamageList(BattleField battleField) |
| | | { |
| | | List<Dictionary<int, List<int>>> damageList = new List<Dictionary<int, List<int>>>(); |
| | | |
| | | List<BattleObject> affectList = GetTargetList(_caster, battleField); |
| | | List<BattleObject> affectList = GetTargetList(battleField); |
| | | |
| | | Dictionary<int, List<int>> oneRoundDamage = new Dictionary<int, List<int>>(); |
| | | |
| | | for (int j = 0; j < affectList.Count; j++) |
| | | { |
| | | BattleObject obj = affectList[j]; |
| | | List<int> tryDmgList = _caster.TryAttack(obj, skillConfig); |
| | | oneRoundDamage.Add(obj.BattleObjectId, tryDmgList); |
| | | List<int> tryDmgList = caster.TryAttack(obj, skillConfig); |
| | | oneRoundDamage.Add(obj.ObjID, tryDmgList); |
| | | } |
| | | |
| | | damageList.Add(oneRoundDamage); |
| | |
| | | using System.Collections.Generic; |
| | | using UnityEngine; |
| | | using System; |
| | | using DG.Tweening; |
| | | using Spine; |
| | | |
| | | |
| | | public class SkillBase |
| | | { |
| | | protected H0604_tagUseSkillAttack tagUseSkillAttack; |
| | | |
| | | protected SkillConfig skillConfig; |
| | | |
| | | protected bool isFinished = false; |
| | | |
| | | public SkillBase(SkillConfig _skillCfg) |
| | | protected BattleField battleField = null; // 战场 |
| | | |
| | | protected RectTransform targetNode = null; // 目标节点 |
| | | |
| | | protected BattleObject caster = null; // 施法者 |
| | | |
| | | protected bool startCounting = false; |
| | | |
| | | protected bool pauseState = false; |
| | | |
| | | protected int curFrame = 0; |
| | | |
| | | protected List<int> triggerFrames = new List<int>(); |
| | | |
| | | public SkillBase(BattleObject _caster, SkillConfig _skillCfg, H0604_tagUseSkillAttack vNetData, BattleField _battleField = null) |
| | | { |
| | | caster = _caster; |
| | | skillConfig = _skillCfg; |
| | | tagUseSkillAttack = vNetData; |
| | | battleField = _battleField; |
| | | |
| | | triggerFrames.Clear(); |
| | | triggerFrames.AddRange(skillConfig.TriggerFrames); |
| | | } |
| | | |
| | | public virtual void Run() |
| | | { |
| | | |
| | | if (startCounting) |
| | | { |
| | | curFrame++; |
| | | |
| | | if (triggerFrames.Contains(curFrame)) |
| | | { |
| | | OnTriggerEvent(triggerFrames.IndexOf(curFrame), curFrame); |
| | | } |
| | | } |
| | | } |
| | | |
| | | public virtual void Cast(BattleObject _caster, BattleField battleField, List<Dictionary<int, List<int>>> damageList) |
| | | protected virtual void OnTriggerEvent(int triggerIndex, int triggerFrame) |
| | | { |
| | | Debug.LogError("SkillBase Cast should be overridden by derived class"); |
| | | |
| | | } |
| | | |
| | | public void Pause() |
| | | { |
| | | pauseState = startCounting; |
| | | startCounting = false; |
| | | } |
| | | |
| | | public void Resume() |
| | | { |
| | | startCounting = pauseState; |
| | | } |
| | | |
| | | // 0·移动到距离目标n码,的距离释放(可配置,9999即原地释放,负数则是移动到人物背面,人物要转身) |
| | | // 1·移动到距离阵容位置n码的距离(如2号位,5号位)释放(即战场中央此类) |
| | | public virtual void Cast() |
| | | { |
| | | // 高亮所有本次技能相关的目标 |
| | | HighLightAllTargets(); |
| | | |
| | | switch (skillConfig.castMode) |
| | | { |
| | | case SkillCastMode.StandCast: |
| | | PlayCastAnimation(() => DoSkillLogic(OnSkillFinished)); |
| | | break; |
| | | case SkillCastMode.MoveToTarget: |
| | | MoveToTarget(_onComplete: () => TurnBack(() => PlayCastAnimation(() => DoSkillLogic(() => { BackToOrigin(OnSkillFinished); })))); |
| | | break; |
| | | case SkillCastMode.DashCast: |
| | | DashToTarget(() => BackToOrigin(OnSkillFinished)); |
| | | break; |
| | | default: |
| | | Debug.LogError("暂时不支持其他的方式释放 有需求请联系策划"); |
| | | break; |
| | | } |
| | | } |
| | | |
| | | // 冲刺的技能 动作 跟移动 是同时进行的 移动到目标的一瞬间就要进行技能逻辑 |
| | | protected void DashToTarget(Action _onComplete) |
| | | { |
| | | TrackEntry entry = PlayCastAnimation(); |
| | | // 做一个微微的提前 |
| | | MoveToTarget(entry.TrackTime - 0.05f, () => DoSkillLogic(_onComplete)); |
| | | } |
| | | |
| | | protected void GetTargetNode() |
| | | { |
| | | targetNode = null; |
| | | |
| | | if (skillConfig.castMode == SkillCastMode.StandCast) |
| | | { |
| | | // 原地施法 |
| | | targetNode = caster.heroGo.transform as RectTransform; |
| | | } |
| | | else if (skillConfig.castMode == SkillCastMode.MoveToTarget || skillConfig.castMode == SkillCastMode.DashCast) |
| | | { |
| | | if (tagUseSkillAttack.AttackID <= 0) |
| | | { |
| | | Debug.LogError("技能没有指定目标"); |
| | | return; |
| | | } |
| | | |
| | | // 移动到目标位置施法 |
| | | BattleObject _mainTarget = battleField.battleObjMgr.GetBattleObject((int)tagUseSkillAttack.AttackID); |
| | | if (_mainTarget == null) |
| | | { |
| | | Debug.LogError("技能指定的目标不存在"); |
| | | return; |
| | | } |
| | | |
| | | targetNode = _mainTarget.heroGo.transform as RectTransform; |
| | | } |
| | | else if (skillConfig.castMode == SkillCastMode.MoveToFormation) |
| | | { |
| | | // TODO YYL |
| | | targetNode = /*caster.GetEnemyTeamNode();*/ battleField.GetTeamNode(caster.Camp == BattleCamp.Blue ? BattleCamp.Red : BattleCamp.Blue); |
| | | } |
| | | else |
| | | { |
| | | Debug.LogError("未知的施法方式 技能id:" + skillConfig.SkillID); |
| | | return; |
| | | } |
| | | } |
| | | |
| | | protected List<BattleObject> GetTargetList() |
| | | { |
| | | return battleField.battleObjMgr.GetBattleObjList(tagUseSkillAttack); |
| | | } |
| | | |
| | | protected virtual void DoSkillLogic(Action _onComplete = null) |
| | | { |
| | | // 子类实现具体的技能逻辑 |
| | | } |
| | | |
| | | protected TrackEntry PlayCastAnimation(Action onComplete = null) |
| | | { |
| | | // 播放施法动作 |
| | | MotionName motionName = skillConfig.GetMotionName(); |
| | | TrackEntry trackEntry = caster.motionBase.PlayAnimation(motionName, false, onComplete); |
| | | return trackEntry; |
| | | } |
| | | |
| | | public void MoveToTarget(float duration = 0.2f, Action _onComplete = null) |
| | | { |
| | | GetTargetNode(); |
| | | Vector2 offset = new Vector2(skillConfig.CastDistance, 0); |
| | | RectTransform selfRect = caster.heroGo.transform as RectTransform; |
| | | RectTransform targetRect = targetNode; |
| | | |
| | | var tweener = BattleUtility.MoveToTarget(selfRect, targetRect, offset, duration, _onComplete); |
| | | battleField.battleTweenMgr.OnPlayTween(tweener); |
| | | } |
| | | |
| | | public void TurnBack(Action _onComplete) |
| | | { |
| | | if (skillConfig.CastDistance < 0) |
| | | { |
| | | caster.heroGo.transform.localScale = new Vector3(-1, 1, 1); |
| | | } |
| | | _onComplete?.Invoke(); |
| | | } |
| | | |
| | | public void BackToOrigin(Action _onComplete = null) |
| | | { |
| | | RectTransform selfRect = caster.heroGo.transform as RectTransform; |
| | | Vector2 targetAnchoredPos = Vector2.zero; |
| | | var tween = selfRect.DOAnchorPos(targetAnchoredPos, 0.2f) |
| | | .SetEase(Ease.Linear) |
| | | .OnComplete(() => |
| | | { |
| | | caster.heroGo.transform.localScale = Vector3.one; |
| | | _onComplete?.Invoke(); |
| | | }); |
| | | |
| | | battleField.battleTweenMgr.OnPlayTween(tween); |
| | | } |
| | | |
| | | protected void HighLightAllTargets() |
| | | { |
| | | // 高亮所有目标 |
| | | HashSet<BattleObject> highlightList = new HashSet<BattleObject>(battleField.battleObjMgr.GetBattleObjList(tagUseSkillAttack)); |
| | | highlightList.Add(caster); |
| | | |
| | | |
| | | |
| | | // 把这些BO全高亮 或者说把除了这些的都放在遮罩后面 |
| | | // YYL TODO |
| | | } |
| | | |
| | | public virtual bool IsFinished() |
| | |
| | | isFinished = true; |
| | | } |
| | | |
| | | #if UNITY_EDITOR |
| | | public virtual List<BattleObject> GetTargetList(BattleObject _caster, BattleField battleField) |
| | | public void OnSkillFinished() |
| | | { |
| | | isFinished = true; |
| | | } |
| | | |
| | | #if UNITY_EDITOR_STOP_USING |
| | | public virtual List<BattleObject> GetTargetList(BattleField _battleField) |
| | | { |
| | | SkillTargetType targetType = SkillTargetType.Enemy; |
| | | SkillTargetRangeType rangeType = SkillTargetRangeType.LowestHP; |
| | | |
| | | List<BattleObject> affectList = battleField.battleObjMgr.GetTargetList(_caster, targetType, rangeType); |
| | | List<BattleObject> affectList = _battleField.battleObjMgr.GetTargetList(caster, targetType, rangeType); |
| | | return affectList; |
| | | } |
| | | |
| | | public virtual List<Dictionary<int, List<int>>> GetDamageList(BattleObject _caster, BattleField battleField) |
| | | |
| | | public virtual List<Dictionary<int, List<int>>> GetDamageList(BattleField _battleField) |
| | | { |
| | | Debug.LogError("SkillBase GetDamageList should be overridden by derived class"); |
| | | return null; |
New file |
| | |
| | | |
| | | |
| | | public enum SkillCastMode |
| | | { |
| | | StandCast, // 原地释放 |
| | | MoveToTarget, // 跑到目标面前释放再回来 |
| | | DashCast, // 原地动作但角色会冲到目标面前 |
| | | MoveToFormation, // 移动到阵容位置施法 |
| | | } |
copy from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta
copy to Main/System/Battle/Skill/SkillCastMode.cs.meta
File was copied from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 0c39e10c6d11822409ee2e39b684f89d |
| | | guid: f9281a48533a94f4ba2a84bc44bbe18d |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
New file |
| | |
| | | public enum SkillEffectAnchor |
| | | { |
| | | Caster, //在施法者上 |
| | | Target, //在目标上 |
| | | AlliesCenter,// 在友方中心 |
| | | EnemiesCenter,// 在敌方中心 |
| | | } |
copy from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta
copy to Main/System/Battle/Skill/SkillEffectAnchor.cs.meta
File was copied from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 0c39e10c6d11822409ee2e39b684f89d |
| | | guid: 8c9269b4bdb75f042b97225006214939 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
New file |
| | |
| | | public enum SkillEffectType |
| | | { |
| | | Bullet, // 子弹类型 |
| | | Direct, // 直接伤害 |
| | | BuffEffect, // Buff |
| | | StageEffect, // 场景技 |
| | | } |
copy from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta
copy to Main/System/Battle/Skill/SkillEffectType.cs.meta
File was copied from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 0c39e10c6d11822409ee2e39b684f89d |
| | | guid: 0e224e8034be71b4d8571bb3adba5ecf |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | |
| | | |
| | | |
| | | |
| | | public static SkillBase CreateSkill(SkillConfig _skillConfig) |
| | | public static SkillBase CreateSkill(BattleObject _caster, H0604_tagUseSkillAttack vNetData, BattleField battleField) |
| | | { |
| | | SkillConfig skillConfig = SkillConfig.Get(vNetData.SkillID); |
| | | |
| | | SkillBase skill = null; |
| | | switch (_skillConfig.SkillType) |
| | | switch (skillConfig.SkillType) |
| | | { |
| | | case 1: |
| | | skill = new DirectlyDamageSkill(_skillConfig); |
| | | // 先实现一个攻击的 后续有再慢慢增加 |
| | | skill = new DirectlyDamageSkill(_caster, skillConfig, vNetData, battleField); |
| | | break; |
| | | case 2: |
| | | // skill = new DirectlyHealSkill(_skillConfig); |
New file |
| | |
| | | |
| | | // 攻击技能:本回合对敌人武将造成伤害 |
| | | // 治疗技能:本回合对已方武将回复生命值,回复生命值不可超过生命上限 |
| | | // 辅助技能:增加怒气、召唤、光环等 |
| | | // BUFF技能:提升已方属性的增益BUFF(加攻、加血、加状态等),降低敌方属性的减益BUFF(减攻、减血、控制等),持续多回合 |
| | | // 复活技能:复活已方已死武将并回复X生命值, |
| | | // 复活:继承死亡前的所有状态(各种状态、各种BUFF、怒气值等),复活后错过本回合攻击时机则下一回合才能出手 |
| | | |
| | | |
| | | public enum SkillType |
| | | { |
| | | Attack, |
| | | Heal, |
| | | Assist, |
| | | Buff, |
| | | Revive |
| | | } |
copy from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta
copy to Main/System/Battle/Skill/SkillType.cs.meta
File was copied from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 0c39e10c6d11822409ee2e39b684f89d |
| | | guid: caaeda374b158404196e766e25b9a3b3 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: dd67eeb1a237eb44cad753537ec81338 |
| | | folderAsset: yes |
| | | DefaultImporter: |
| | | externalObjects: {} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using Cysharp.Threading.Tasks; |
| | | using DG.Tweening; |
| | | using UnityEngine; |
| | | |
| | | public class BulletSkillEffect : SkillEffect |
| | | { |
| | | // protected SkillConfig skillConfig; |
| | | // protected BattleObject caster; |
| | | // protected List<BattleObject> targets; // 目标列表 |
| | | |
| | | public BulletSkillEffect(SkillConfig _skillConfig, BattleObject _caster, H0604_tagUseSkillAttack _tagUseSkillAttack) |
| | | : base(_skillConfig, _caster, _tagUseSkillAttack) |
| | | { |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | public override void Play(Action<int, List<H0604_tagUseSkillAttack.tagSkillHurtObj>> _onHit) |
| | | { |
| | | // Caster, //在施法者上 |
| | | // Target, //在目标上 |
| | | // AlliesCenter,// 在友方中心 |
| | | // EnemiesCenter,// 在敌方中心 |
| | | |
| | | Action<int, List<H0604_tagUseSkillAttack.tagSkillHurtObj>> onHitFormation = (_hitIndex, _hurtList) => |
| | | { |
| | | _onHit?.Invoke(_hitIndex, tagUseSkillAttack.HurtList.ToList()); |
| | | }; |
| | | |
| | | if (skillConfig.effectAnchor == SkillEffectAnchor.Caster) |
| | | { |
| | | // 不可能子弹射向自己吧 |
| | | Debug.LogError("子弹技能特效不能锚定在施法者上 skillConfig.effectAnchor"); |
| | | _onHit?.Invoke(0, default); |
| | | } |
| | | else if (skillConfig.effectAnchor == SkillEffectAnchor.Target) |
| | | { |
| | | if (tagUseSkillAttack == null || tagUseSkillAttack.HurtList.Length <= 0) |
| | | { |
| | | Debug.LogError("子弹技能特效没有目标 tagUseSkillAttack.HurtList.Length <= 0"); |
| | | _onHit?.Invoke(0, default); |
| | | return; |
| | | } |
| | | |
| | | foreach (var hurt in tagUseSkillAttack.HurtList) |
| | | { |
| | | BattleObject target = caster.battleField.battleObjMgr.GetBattleObject((int)hurt.ObjID); |
| | | if (target == null) |
| | | { |
| | | Debug.LogError("子弹技能特效目标为空 target == null ObjId : " + hurt.ObjID); |
| | | continue; |
| | | } |
| | | |
| | | ShotToTarget(target.heroGo.transform as RectTransform, (index, list) => _onHit(0, new List<H0604_tagUseSkillAttack.tagSkillHurtObj>() { hurt })); |
| | | } |
| | | } |
| | | else if (skillConfig.effectAnchor == SkillEffectAnchor.AlliesCenter) |
| | | { |
| | | ShotToTarget(caster.battleField.GetTeamNode(caster.Camp), onHitFormation); |
| | | } |
| | | else if (skillConfig.effectAnchor == SkillEffectAnchor.EnemiesCenter) |
| | | { |
| | | ShotToTarget(caster.battleField.GetTeamNode(caster.Camp == BattleCamp.Blue ? BattleCamp.Red : BattleCamp.Blue), onHitFormation); |
| | | } |
| | | else |
| | | { |
| | | Debug.LogError("未知的技能特效锚点类型: " + skillConfig.effectAnchor); |
| | | } |
| | | } |
| | | |
| | | protected void ShotToTarget(RectTransform target, Action<int, List<H0604_tagUseSkillAttack.tagSkillHurtObj>> _onHit) |
| | | { |
| | | EffectPlayer effectPlayer = caster.battleField.battleEffectMgr.PlayEffect(caster.ObjID, skillConfig.EffectId, caster.effectNode); |
| | | |
| | | effectPlayer.Play(); |
| | | |
| | | RectTransform effectTrans = effectPlayer.transform as RectTransform; |
| | | |
| | | var tween = BattleUtility.MoveToTarget(effectTrans, target, Vector2.zero, skillConfig.FlyTime, () => |
| | | { |
| | | // 表现子弹飞行到目标位置 |
| | | _onHit?.Invoke(0, null); |
| | | |
| | | // 击中就销毁子弹 |
| | | caster.battleField.battleEffectMgr.RemoveEffect(skillConfig.EffectId, effectPlayer); |
| | | // 播放子弹爆炸特效 |
| | | caster.battleField.battleEffectMgr.PlayEffect(caster.ObjID, skillConfig.ExplotionEffectId, target).Play(); |
| | | }); |
| | | |
| | | caster.battleField.battleTweenMgr.OnPlayTween(tween); |
| | | } |
| | | |
| | | public override void Run() |
| | | { |
| | | |
| | | } |
| | | } |
copy from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta
copy to Main/System/Battle/SkillEffect/BulletSkillEffect.cs.meta
File was copied from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 0c39e10c6d11822409ee2e39b684f89d |
| | | guid: 87730978d5481e24c9433f6cbe3bec78 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
New file |
| | |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using Cysharp.Threading.Tasks; |
| | | using DG.Tweening; |
| | | using UnityEngine; |
| | | |
| | | public class NormalSkillEffect : SkillEffect |
| | | { |
| | | // protected SkillConfig skillConfig; |
| | | // protected BattleObject caster; |
| | | // protected List<BattleObject> targets; // 目标列表 |
| | | |
| | | public NormalSkillEffect(SkillConfig _skillConfig, BattleObject _caster, H0604_tagUseSkillAttack _tagUseSkillAttack) |
| | | : base(_skillConfig, _caster, _tagUseSkillAttack) |
| | | { |
| | | |
| | | } |
| | | |
| | | |
| | | public override void Play(Action<int, List<H0604_tagUseSkillAttack.tagSkillHurtObj>> _onHit) |
| | | { |
| | | |
| | | Action<int, List<H0604_tagUseSkillAttack.tagSkillHurtObj>> onHitFormation = (_hitIndex, _hurtList) => |
| | | { |
| | | _onHit?.Invoke(_hitIndex, tagUseSkillAttack.HurtList.ToList()); |
| | | }; |
| | | |
| | | if (skillConfig.effectAnchor == SkillEffectAnchor.Caster) |
| | | { |
| | | CastInTarget(caster.heroGo.transform as RectTransform, onHitFormation); |
| | | } |
| | | else if (skillConfig.effectAnchor == SkillEffectAnchor.Target) |
| | | { |
| | | if (tagUseSkillAttack == null || tagUseSkillAttack.HurtList.Length <= 0) |
| | | { |
| | | Debug.LogError("没有目标 tagUseSkillAttack.HurtList.Length <= 0"); |
| | | _onHit?.Invoke(0, default); |
| | | return; |
| | | } |
| | | |
| | | foreach (var hurt in tagUseSkillAttack.HurtList) |
| | | { |
| | | BattleObject target = caster.battleField.battleObjMgr.GetBattleObject((int)hurt.ObjID); |
| | | if (target == null) |
| | | { |
| | | Debug.LogError("特效目标为空 target == null ObjId : " + hurt.ObjID); |
| | | continue; |
| | | } |
| | | |
| | | CastInTarget(target.heroGo.transform as RectTransform, (index, list) => _onHit(0, new List<H0604_tagUseSkillAttack.tagSkillHurtObj>() { hurt })); |
| | | } |
| | | } |
| | | else if (skillConfig.effectAnchor == SkillEffectAnchor.AlliesCenter) |
| | | { |
| | | CastInTarget(caster.battleField.GetTeamNode(caster.Camp), onHitFormation); |
| | | } |
| | | else if (skillConfig.effectAnchor == SkillEffectAnchor.EnemiesCenter) |
| | | { |
| | | CastInTarget(caster.battleField.GetTeamNode(caster.Camp == BattleCamp.Blue ? BattleCamp.Red : BattleCamp.Blue), onHitFormation); |
| | | } |
| | | else |
| | | { |
| | | Debug.LogError("未知的技能特效锚点类型: " + skillConfig.effectAnchor); |
| | | } |
| | | } |
| | | |
| | | protected void CastInTarget(RectTransform target, Action<int, List<H0604_tagUseSkillAttack.tagSkillHurtObj>> _onHit) |
| | | { |
| | | EffectPlayer effectPlayer = caster.battleField.battleEffectMgr.PlayEffect(caster.ObjID, skillConfig.EffectId, caster.effectNode); |
| | | |
| | | effectPlayer.Play(); |
| | | |
| | | RectTransform effectTrans = effectPlayer.transform as RectTransform; |
| | | |
| | | _onHit?.Invoke(0, null); |
| | | |
| | | // 销毁自身上的特效应该是等特效播放完毕之后 |
| | | // caster.battleField.battleEffectMgr.RemoveEffect(skillConfig.EffectId, effectPlayer); |
| | | // 播放受击特效 |
| | | caster.battleField.battleEffectMgr.PlayEffect(caster.ObjID, skillConfig.ExplotionEffectId, target).Play(); |
| | | |
| | | } |
| | | |
| | | public override void Run() |
| | | { |
| | | |
| | | } |
| | | } |
copy from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta
copy to Main/System/Battle/SkillEffect/NormalSkillEffect.cs.meta
File was copied from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 0c39e10c6d11822409ee2e39b684f89d |
| | | guid: 532aa7a2a76cb1646ba7b5e9e6b5114a |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
New file |
| | |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using UnityEngine; |
| | | |
| | | public class SkillEffect |
| | | { |
| | | protected SkillConfig skillConfig; |
| | | protected BattleObject caster; |
| | | protected H0604_tagUseSkillAttack tagUseSkillAttack;// 目标列表 |
| | | |
| | | public SkillEffect(SkillConfig _skillConfig, BattleObject _caster, H0604_tagUseSkillAttack _tagUseSkillAttack) |
| | | { |
| | | skillConfig = _skillConfig; |
| | | caster = _caster; |
| | | tagUseSkillAttack = _tagUseSkillAttack; |
| | | } |
| | | |
| | | public Action OnHit; // 表现到达目标时回调 |
| | | |
| | | // |
| | | public virtual void Play(Action<int, List<H0604_tagUseSkillAttack.tagSkillHurtObj>> _onHit) |
| | | { |
| | | // OnHit = _onHit; |
| | | // switch (skillConfig.effectType) |
| | | // { |
| | | // case SkillEffectType.StageEffect: |
| | | // Debug.LogError("播放场景特效"); |
| | | // break; |
| | | // case SkillEffectType.Bullet: |
| | | // // 伪代码:表现子弹飞行 |
| | | // Debug.Log("播放子弹特效"); |
| | | // // 到达目标时 |
| | | // OnHit?.Invoke(); |
| | | // break; |
| | | // case SkillEffectType.Direct: |
| | | // // 伪代码:直接在目标身上播放特效 |
| | | // Debug.Log("播放直接特效"); |
| | | // OnHit?.Invoke(); |
| | | // break; |
| | | // case SkillEffectType.BuffEffect: |
| | | // // 伪代码:播放持续特效 |
| | | // Debug.Log("播放Buff特效"); |
| | | // break; |
| | | // default: |
| | | // break; |
| | | // } |
| | | } |
| | | |
| | | public virtual void Run() |
| | | { |
| | | |
| | | } |
| | | } |
copy from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta
copy to Main/System/Battle/SkillEffect/SkillEffect.cs.meta
File was copied from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 0c39e10c6d11822409ee2e39b684f89d |
| | | guid: fac494539cf0a0b41b14681032f00cbf |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
New file |
| | |
| | | |
| | | |
| | | using System.Collections.Generic; |
| | | |
| | | public static class SkillEffectFactory |
| | | { |
| | | public static SkillEffect CreateSkillEffect(BattleObject caster, SkillConfig skillConfig, H0604_tagUseSkillAttack tagUseSkillAttack) |
| | | { |
| | | switch (skillConfig.effectType) |
| | | { |
| | | case SkillEffectType.Bullet: |
| | | return new BulletSkillEffect(skillConfig, caster, tagUseSkillAttack); |
| | | case SkillEffectType.Direct: |
| | | return new NormalSkillEffect(skillConfig, caster, tagUseSkillAttack); |
| | | // case SkillEffectType.BuffEffect: |
| | | // return new BuffSkillEffect(skillConfig, caster, targets); |
| | | // case SkillEffectType.StageEffect: |
| | | // return new StageSkillEffect(skillConfig, caster, targets); |
| | | default: |
| | | UnityEngine.Debug.LogError("Unknown Skill Effect Type"); |
| | | break; |
| | | } |
| | | return null; |
| | | } |
| | | } |
copy from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta
copy to Main/System/Battle/SkillEffect/SkillEffectFactory.cs.meta
File was copied from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 0c39e10c6d11822409ee2e39b684f89d |
| | | guid: 010772e03bcf658429d8aaf42b2483e4 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | |
| | | line.SetActive(false); |
| | | } |
| | | |
| | | public void SetDamage(List<int> damages, Action _onComplete) |
| | | public void SetDamage(List<long> damages, Action _onComplete) |
| | | { |
| | | for (int i = 0; i < damages.Count; i++) |
| | | { |
| | |
| | | |
| | | public TextEx damageValueLabel; |
| | | |
| | | public void SetDamage(DamageType damageType, int damage) |
| | | public void SetDamage(DamageType damageType, long damage) |
| | | { |
| | | damageTypeLabel.SetActive(true); |
| | | damageValueLabel.text = damage.ToString(); |
| | | } |
| | | |
| | | public void SetDamage(int damage) |
| | | public void SetDamage(long damage) |
| | | { |
| | | damageTypeLabel.SetActive(false); |
| | | damageValueLabel.text = damage.ToString(); |
| | |
| | | return inputString; |
| | | } |
| | | |
| | | |
| | | public static long GetFactValue(uint value, uint valueEx) |
| | | { |
| | | return (long)valueEx * HundredMillion +(long)value; |
| | | } |
| | | } |
| | |
| | | if (null == teamHero) |
| | | continue; |
| | | |
| | | if (Array.IndexOf(fetterConfig.HeroIDList, teamHero.heroInfo.heroId) >= 0) |
| | | if (Array.IndexOf(fetterConfig.HeroIDList, teamHero.heroId) >= 0) |
| | | { |
| | | count++; |
| | | } |
New file |
| | |
| | | |
| | | using System.Collections.Generic; |
| | | using UnityEngine; |
| | | |
| | | public partial class HeroInfo |
| | | { |
| | | public Dictionary<TeamType, KeyValuePair<int, int>> GetTeamTypeShapeTypePositionDict() |
| | | { |
| | | // 英雄当前所有在的队伍 |
| | | List<int> heroTeams = itemHero.GetUseData(81); |
| | | |
| | | Dictionary<TeamType, KeyValuePair<int, int>> teamTypeShapeTypePositionDict = new Dictionary<TeamType, KeyValuePair<int, int>>(); |
| | | foreach (var teamMsg in heroTeams) |
| | | { |
| | | // 所在阵容信息列表 [阵容类型*10000+阵型类型*100+位置编号, ...] |
| | | int teamType = teamMsg / 10000; |
| | | int shapeType = (teamMsg % 10000) / 100; |
| | | int positionIndex = teamMsg % 100; |
| | | |
| | | if (teamTypeShapeTypePositionDict.ContainsKey((TeamType)teamType)) |
| | | { |
| | | // 队伍类型相同,更新阵型和位置 |
| | | Debug.LogError("当前英雄拥有两个相同的队伍信息: " + teamType + " " + shapeType + " " + positionIndex + ", hero guid is " + itemHero.guid); |
| | | } |
| | | else |
| | | { |
| | | // 队伍类型不同,添加新的 |
| | | KeyValuePair<int, int> shapeTypePosition = new KeyValuePair<int, int>(shapeType, positionIndex); |
| | | teamTypeShapeTypePositionDict.Add((TeamType)teamType, shapeTypePosition); |
| | | } |
| | | } |
| | | |
| | | return teamTypeShapeTypePositionDict; |
| | | } |
| | | } |
copy from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta
copy to Main/System/Hero/HeroInfo.Lineup.cs.meta
File was copied from Main/Core/NetworkPackage/ServerPack/H06_PlayerVsNPC/H0602_tagObjBaseAttack.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 0c39e10c6d11822409ee2e39b684f89d |
| | | guid: fe5defee75fe9b24c81fd8cb22c7d952 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | |
| | | UpdateHero(_itemHero); |
| | | } |
| | | |
| | | public HeroInfo(HB424_tagSCTurnFightInit.tagSCTurnFightObj fightObj) |
| | | { |
| | | // 战斗表现需要这些基本就够 不够还需要服务器加 |
| | | |
| | | heroId = (int)fightObj.HeroID; |
| | | heroConfig = HeroConfig.Get(heroId); |
| | | SkinID = (int)fightObj.SkinID; |
| | | skinConfig = HeroSkinConfig.Get(SkinID); |
| | | } |
| | | |
| | | #if UNITY_EDITOR |
| | | public HeroInfo() |
| | | { |
| | |
| | | |
| | | public Action<HeroInfo> onHeroChangeEvent; |
| | | |
| | | public Action<HeroInfo> onHeroDeleteEvent; |
| | | |
| | | public override void Init() |
| | | { |
| | | base.Init(); |
| | |
| | | { |
| | | heroInfo.UpdateHero(PackManager.Instance.GetItemByGuid(guid)); |
| | | } |
| | | |
| | | onHeroChangeEvent?.Invoke(heroInfo); |
| | | } |
| | | } |
| | | |
| | |
| | | { |
| | | if (packType == PackType.Hero) |
| | | { |
| | | if (heroInfoDict.ContainsKey(guid)) |
| | | { |
| | | heroInfoDict.Remove(guid); |
| | | } |
| | | HeroInfo heroInfo = null; |
| | | heroInfoDict.TryGetValue(guid, out heroInfo); |
| | | |
| | | heroInfoDict.Remove(guid); |
| | | |
| | | if (null != heroInfo) |
| | | onHeroDeleteEvent?.Invoke(heroInfo); |
| | | } |
| | | } |
| | | |
| | |
| | | return heroInfoDict[guid]; |
| | | } |
| | | |
| | | public List<HeroInfo> GetHeroList() |
| | | { |
| | | return heroInfoDict.Values.ToList(); |
| | | } |
| | | |
| | | |
| | | void InitHerosInfo() |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: a02c6eff6ff37404ab5bdfb3357a7fa1 |
| | | folderAsset: yes |
| | | DefaultImporter: |
| | | externalObjects: {} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
| | |
| | | |
| | | protected void UpdateProperties() |
| | | { |
| | | // YYL TODO |
| | | // 羁绊 |
| | | for (int i = 0; i < teamHeros.Length; i++) |
| | | { |
| | | TeamHero hero = teamHeros[i]; |
| | | if (null != hero) |
| | | { |
| | | for (int j = 0; j < hero.heroInfo.fetterInfoList.Count; j++) |
| | | { |
| | | hero.heroInfo.fetterInfoList[j].SetIsActiveFetter(this); |
| | | } |
| | | } |
| | | } |
| | | // for (int i = 0; i < teamHeros.Length; i++) |
| | | // { |
| | | // TeamHero hero = teamHeros[i]; |
| | | // if (null != hero) |
| | | // { |
| | | // for (int j = 0; j < hero.heroInfo.fetterInfoList.Count; j++) |
| | | // { |
| | | // hero.heroInfo.fetterInfoList[j].SetIsActiveFetter(this); |
| | | // } |
| | | // } |
| | | // } |
| | | |
| | | // 阵型 |
| | | |
| | | |
| | | // 属性计算 |
| | | for (int i = 0; i < teamHeros.Length; i++) |
| | | { |
| | | TeamHero hero = teamHeros[i]; |
| | | if (null != hero) |
| | | hero.heroInfo.CalculateProperties(); |
| | | } |
| | | // for (int i = 0; i < teamHeros.Length; i++) |
| | | // { |
| | | // TeamHero hero = teamHeros[i]; |
| | | // if (null != hero) |
| | | // hero.heroInfo.CalculateProperties(); |
| | | // } |
| | | } |
| | | |
| | | public void CalculatePower() |
| | |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using UnityEngine; |
| | | |
| | | // 阵型基础 |
| | | |
| | | public partial class TeamBase |
| | | { |
| | | // 该阵容在本阵营的编号,不同阵营的阵容编号可能相同,都是从1开始,一般1V1时每个阵营为1个阵容,多V多时则每个阵营为多个阵容 |
| | | private int teamIndex = 0; |
| | | private uint playerId = 0; |
| | | |
| | | // 区分一下阵营跟阵容 阵营为一个TeamBase列表 可能是多个玩家组合而成 |
| | | // 阵容为一个TeamBase 是玩家的一个队伍 |
| | | private int teamIndex = 0;//该阵营的第几个队伍 |
| | | |
| | | private uint playerId = 0; //该阵容的玩家id |
| | | |
| | | private int ShapeType; //本阵容阵型,0为默认阵型,可扩展不同的阵型,如boss特殊战斗阵型,或者其他不同站位的阵型 |
| | | // 本地可变阵型 |
| | | |
| | | public bool IsPlayer |
| | | { |
| | | get |
| | | { |
| | | return playerId == 0; |
| | | } |
| | | get { return playerId == 0; } |
| | | } |
| | | |
| | | public TeamHero[] teamHeros = new TeamHero[TeamConst.MaxTeamSlotCount]; |
| | | |
| | | public TeamBase() |
| | | // 服务器下发的阵型和阵容,只能通过网络协议赋值,外部只读 |
| | | public TeamType teamType |
| | | { |
| | | |
| | | get; |
| | | private set; |
| | | } |
| | | |
| | | private int ShapeType; |
| | | public int ServerShapeType { get; private set; } |
| | | |
| | | public TeamHero[] teamHeros = new TeamHero[TeamConst.MaxTeamHeroCount]; |
| | | |
| | | public TeamHero[] serverData { get; private set; } = new TeamHero[TeamConst.MaxTeamHeroCount]; |
| | | |
| | | public TeamBase(TeamType _teamType) |
| | | { |
| | | teamType = _teamType; |
| | | teamIndex = 0; |
| | | playerId = PlayerDatas.Instance.baseData.PlayerID; |
| | | } |
| | | |
| | | // 这边来的可以没有队伍类型 |
| | | public TeamBase(HB424_tagSCTurnFightInit.tagSCTurnFightLineup lineUp) |
| | | { |
| | | teamIndex = lineUp.Num; |
| | | playerId = lineUp.OwnerID; |
| | | ShapeType = lineUp.ShapeType; |
| | | ServerShapeType = lineUp.ShapeType; |
| | | |
| | | for (int i = 0; i < lineUp.ObjCnt; i++) |
| | | { |
| | | if (i < teamHeros.Length) |
| | | { |
| | | TeamHero hero = new TeamHero(lineUp.ObjList[i], this); |
| | | AddTeamHero(hero); |
| | | var fightObj = lineUp.ObjList[i]; |
| | | TeamHero hero = new TeamHero(fightObj, this); |
| | | teamHeros[fightObj.PosNum] = hero; |
| | | serverData[fightObj.PosNum] = hero; |
| | | } |
| | | else |
| | | { |
| | | Debug.LogError("TeamBase: Too many heroes in lineup, exceeding MaxTeamHeroCount."); |
| | | } |
| | | } |
| | | |
| | | Update(); |
| | | |
| | | |
| | | // 刷新服务器数据 |
| | | UpdateProperties(); |
| | | } |
| | | |
| | | protected void Update() |
| | | { |
| | | // 检查国籍 |
| | | |
| | | // 检查羁绊 |
| | | |
| | | // 检查阵型 |
| | | |
| | | // 更新队伍英雄属性 |
| | | foreach (var teamHero in teamHeros) |
| | | { |
| | | teamHero.Update(); |
| | | } |
| | | |
| | | // 更新队伍属性 |
| | | // UpdateProperties(); |
| | | |
| | | // CalculatePower(); |
| | | } |
| | | |
| | | public void SetShapeType(int shapeType) |
| | | { |
| | | ShapeType = shapeType; |
| | | } |
| | | |
| | | public int GetTeamHeroCount() |
| | | { |
| | |
| | | count++; |
| | | } |
| | | } |
| | | |
| | | return count; |
| | | } |
| | | |
| | | public bool SwapTeamHero(int index1, int index2) |
| | | { |
| | | if (index1 < 0 || index1 >= teamHeros.Length || index2 < 0 || index2 >= teamHeros.Length) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | TeamHero temp = teamHeros[index1]; |
| | | teamHeros[index1] = teamHeros[index2]; |
| | | teamHeros[index2] = temp; |
| | | temp.heroIndex = index2; |
| | | teamHeros[index1].heroIndex = index1; |
| | | |
| | | return true; |
| | | } |
| | | |
| | | public void AddHeroInfos(List<HeroInfo> heroInfos) |
| | | { |
| | | for (int i = 0; i < heroInfos.Count; i++) |
| | | { |
| | | AddHeroInfo(heroInfos[i]); |
| | | } |
| | | |
| | | UpdateProperties(); |
| | | } |
| | | |
| | | |
| | | public bool AddHeroInfo(HeroInfo heroInfo) |
| | | { |
| | | if (heroInfo == null) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | for (int i = 0; i < teamHeros.Length; i++) |
| | | { |
| | | if (teamHeros[i] == null) |
| | | { |
| | | teamHeros[i] = new TeamHero(); |
| | | teamHeros[i].heroInfo = heroInfo; |
| | | teamHeros[i].heroIndex = i; |
| | | UpdateProperties(); |
| | | return true; |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | |
| | | public void AddTeamHero(TeamHero teamHero) |
| | | { |
| | | if (null == teamHero) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | teamHeros[teamHero.heroIndex] = teamHero; |
| | | } |
| | | |
| | | |
| | | public bool RemoveTeamHero(int index) |
| | | { |
| | | if (index < 0 || index >= teamHeros.Length) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | teamHeros[index] = null; |
| | | return true; |
| | | } |
| | | |
| | | public bool IsFull() |
| | | { |
| | |
| | | } |
| | | |
| | | |
| | | #if UNITY_EDITOR |
| | | public void FillWithFakeData() |
| | | /// <summary> |
| | | /// 保存阵容(预留接口) |
| | | /// </summary> |
| | | public void SaveTeam() |
| | | { |
| | | for (int i = 0; i < TeamConst.MaxTeamHeroCount; i++) |
| | | if (IsEmpty()) |
| | | { |
| | | TeamHero hero = new TeamHero(); |
| | | hero.curHp = 100; |
| | | hero.heroInfo = new HeroInfo(); |
| | | hero.teamBase = this; |
| | | hero.heroIndex = i; |
| | | teamHeros[i] = hero; |
| | | Debug.LogError("Cannot save an empty team. You should at least have one hero in the team."); |
| | | return; |
| | | } |
| | | |
| | | CB412_tagCSHeroLineupSave savePack = new CB412_tagCSHeroLineupSave(); |
| | | savePack.LineupID = (byte)teamType; |
| | | savePack.ShapeType = (byte)ShapeType; |
| | | savePack.PosCnt = (byte)GetTeamHeroCount(); |
| | | savePack.HeroPosList = new CB412_tagCSHeroLineupSave.tagCSHeroLineupPos[savePack.PosCnt]; |
| | | |
| | | foreach (var hero in teamHeros) |
| | | { |
| | | if (hero != null) |
| | | { |
| | | int posNum = hero.positionNum; |
| | | var heroInfo = HeroManager.Instance.GetHero(hero.guid); |
| | | |
| | | if (heroInfo == null) |
| | | { |
| | | Debug.LogError($"Hero with GUID {hero.guid} not found in HeroManager."); |
| | | continue; |
| | | } |
| | | |
| | | savePack.HeroPosList[posNum] = new CB412_tagCSHeroLineupSave.tagCSHeroLineupPos |
| | | { |
| | | ItemIndex = (ushort)heroInfo.itemHero.gridIndex, |
| | | PosNum = (byte)posNum |
| | | }; |
| | | } |
| | | } |
| | | |
| | | GameNetSystem.Instance.SendInfo(savePack); |
| | | } |
| | | |
| | | public void OnChangeShapeType(int newShapeType) |
| | | { |
| | | ShapeType = newShapeType; |
| | | } |
| | | |
| | | public void OnServerChangeShapeType(int newShapeType) |
| | | { |
| | | ServerShapeType = newShapeType; |
| | | ShapeType = newShapeType; |
| | | } |
| | | |
| | | // hero info could be null if the hero is removed from the team |
| | | public void RefreshServerData(int shapeType, int positionIndex, HeroInfo heroInfo) |
| | | { |
| | | TeamHero teamHero = heroInfo == null ? null : new TeamHero(heroInfo, positionIndex, this); |
| | | SetServerTeamHero(positionIndex, teamHero); |
| | | OnServerChangeShapeType(shapeType); |
| | | } |
| | | |
| | | public void CreateDefault(List<HeroInfo> heroInfos) |
| | | { |
| | | teamIndex = 0; |
| | | playerId = PlayerDatas.Instance.baseData.PlayerID; |
| | | OnServerChangeShapeType(0); |
| | | |
| | | for (int i = 0; i < heroInfos.Count; i++) |
| | | { |
| | | if (i < teamHeros.Length) |
| | | { |
| | | var heroInfo = heroInfos[i]; |
| | | TeamHero hero = new TeamHero(heroInfo, i, this); |
| | | SetServerTeamHero(i, hero); |
| | | } |
| | | else |
| | | { |
| | | Debug.LogError("TeamBase: Too many heroes in lineup"); |
| | | } |
| | | } |
| | | } |
| | | #endif |
| | | |
| | | public TeamHero GetHero(string guid) |
| | | { |
| | | foreach (var hero in teamHeros) |
| | | { |
| | | if (hero != null && hero.guid == guid) |
| | | { |
| | | return hero; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | public TeamHero GetServerHero(string guid) |
| | | { |
| | | foreach (var hero in serverData) |
| | | { |
| | | if (hero != null && hero.guid == guid) |
| | | { |
| | | return hero; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | // 布阵接口 |
| | | public bool HasHero(string guid) |
| | | { |
| | | foreach (var hero in teamHeros) |
| | | { |
| | | if (hero != null && hero.guid == guid) |
| | | { |
| | | return true; |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | public int GetEmptyPosition() |
| | | { |
| | | for (int i = 0; i < teamHeros.Length; i++) |
| | | { |
| | | if (teamHeros[i] == null) |
| | | { |
| | | return i; |
| | | } |
| | | } |
| | | return -1; // No empty position |
| | | } |
| | | |
| | | // 布阵接口 |
| | | public void SetTeamHero(int posNum, TeamHero hero) |
| | | { |
| | | teamHeros[posNum] = hero; |
| | | } |
| | | |
| | | // 布阵接口 |
| | | public void SetServerTeamHero(int posNum, TeamHero hero) |
| | | { |
| | | serverData[posNum] = hero; |
| | | teamHeros[posNum] = hero; |
| | | } |
| | | |
| | | public void AddHero(HeroInfo heroInfo, int targetPosition) |
| | | { |
| | | if (targetPosition < 0 || targetPosition >= teamHeros.Length) |
| | | { |
| | | Debug.LogError("Invalid target position for adding hero."); |
| | | return; |
| | | } |
| | | |
| | | TeamHero targetHero = teamHeros[targetPosition]; |
| | | |
| | | if (null == targetHero) |
| | | { |
| | | TeamHero newHero = new TeamHero(heroInfo, targetPosition, this); |
| | | SetTeamHero(targetPosition, newHero); |
| | | } |
| | | else |
| | | { |
| | | SetTeamHero(targetPosition, new TeamHero(heroInfo, targetPosition, this)); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | // add只可能是点下面卡牌 |
| | | public bool AddHero(HeroInfo heroInfo) |
| | | { |
| | | if (heroInfo == null || heroInfo.itemHero == null) return false; |
| | | |
| | | |
| | | // 如果当前英雄已经在队伍里了 就不处理了 |
| | | if (GetHero(heroInfo.itemHero.guid) != null) |
| | | { |
| | | return false; // Hero already in team |
| | | } |
| | | else |
| | | { |
| | | int emptyPosition = GetEmptyPosition(); |
| | | |
| | | if (emptyPosition < 0) |
| | | { |
| | | Debug.LogError("No empty position available in the team."); |
| | | return false; // No empty position available |
| | | } |
| | | |
| | | TeamHero teamHero = new TeamHero(heroInfo, GetEmptyPosition(), this); |
| | | SetTeamHero(teamHero.positionNum, teamHero); |
| | | return true; |
| | | } |
| | | } |
| | | |
| | | |
| | | public bool RemoveHero(HeroInfo heroInfo) |
| | | { |
| | | if (heroInfo == null || heroInfo.itemHero == null) return false; |
| | | |
| | | TeamHero teamHero = GetHero(heroInfo.itemHero.guid); |
| | | |
| | | if (teamHero != null) |
| | | { |
| | | // 从当前队伍里移除该英雄 |
| | | SetTeamHero(teamHero.positionNum, null); |
| | | return true; |
| | | } |
| | | else |
| | | { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | public bool RemoveHero(TeamHero teamHero) |
| | | { |
| | | if (teamHero == null) return false; |
| | | |
| | | for (int i = 0; i < teamHeros.Length; i++) |
| | | { |
| | | if (teamHeros[i] != null && teamHeros[i].guid == teamHero.guid) |
| | | { |
| | | SetTeamHero(i, null); |
| | | return true; // Hero removed successfully |
| | | } |
| | | } |
| | | return false; // Hero not found |
| | | } |
| | | |
| | | public void SwapPosition(int index1, int index2) |
| | | { |
| | | if (index1 < 0 || index1 >= teamHeros.Length || index2 < 0 || index2 >= teamHeros.Length) |
| | | { |
| | | Debug.LogError("Invalid indices for swapping positions."); |
| | | return; |
| | | } |
| | | |
| | | TeamHero temp = teamHeros[index1]; |
| | | teamHeros[index1] = teamHeros[index2]; |
| | | teamHeros[index2] = temp; |
| | | |
| | | // 更新位置编号 |
| | | if (teamHeros[index1] != null) teamHeros[index1].positionNum = index1; |
| | | if (teamHeros[index2] != null) teamHeros[index2].positionNum = index2; |
| | | } |
| | | |
| | | } |
| | |
| | | public class TeamConst |
| | | { |
| | | public const int MaxTeamHeroCount = 6;//最大布阵数量 |
| | | public const int MaxTeamSlotCount = 7;//最大槽位数量 |
| | | public const int MaxTeamSlotCount = 7;//最大槽位数量 包含boss的中间位置 布阵的时候不能用这个 |
| | | } |
| | |
| | | |
| | | public partial class TeamHero |
| | | { |
| | | public HeroInfo heroInfo; |
| | | public TeamBase teamBase; |
| | | public int heroIndex; |
| | | public int heroId; |
| | | public HeroConfig heroConfig; |
| | | public int SkinID; |
| | | public HeroSkinConfig skinConfig; |
| | | public string guid; |
| | | |
| | | |
| | | public TeamBase teamBase |
| | | { |
| | | get; private set; |
| | | } |
| | | public int positionNum; |
| | | |
| | | // 战场数据 |
| | | public uint ObjID = 0;// 战斗单位唯一ID |
| | | public int ObjID = 0;// 战斗单位唯一ID |
| | | |
| | | public uint NPCID = 0;// 战斗NPCID,不同的实例ID对应的NPCID可能一样 |
| | | public int NPCID = 0;// 战斗NPCID,不同的实例ID对应的NPCID可能一样 |
| | | |
| | | |
| | | public TeamHero() |
| | | { |
| | | |
| | | } |
| | | |
| | | // 服务器来的构造 |
| | | public TeamHero(HB424_tagSCTurnFightInit.tagSCTurnFightObj fightObj, TeamBase _teamBase) |
| | | { |
| | | heroInfo = new HeroInfo(fightObj); |
| | | teamBase = _teamBase; |
| | | if (fightObj.PosNum < 0 || fightObj.PosNum >= TeamConst.MaxTeamSlotCount) |
| | | { |
| | | Debug.LogError("Invalid PosNum: " + fightObj.PosNum); |
| | | } |
| | | else |
| | | { |
| | | teamBase.teamHeros[fightObj.PosNum] = this; // 将当前对象添加到对应位置 |
| | | } |
| | | heroId = (int)fightObj.HeroID; |
| | | heroConfig = HeroConfig.Get(heroId); |
| | | SkinID = (int)fightObj.SkinID; |
| | | skinConfig = HeroSkinConfig.Get(SkinID); |
| | | |
| | | ObjID = fightObj.ObjID; |
| | | NPCID = fightObj.NPCID; |
| | | teamBase = _teamBase; |
| | | |
| | | ObjID = (int)fightObj.ObjID; |
| | | NPCID = (int)fightObj.NPCID; |
| | | |
| | | // HPEx * 1亿 + HP |
| | | |
| | | curHp = (long)fightObj.HPEx * GeneralDefine.HundredMillion +(long)fightObj.HP; |
| | | maxHp = (long)fightObj.MaxHPEx * GeneralDefine.HundredMillion +(long)fightObj.MaxHP; |
| | | curHp = (long)fightObj.HPEx * GeneralDefine.HundredMillion + (long)fightObj.HP; |
| | | maxHp = (long)fightObj.MaxHPEx * GeneralDefine.HundredMillion + (long)fightObj.MaxHP; |
| | | rage = (int)fightObj.AngreXP; |
| | | |
| | | heroIndex = fightObj.PosNum; |
| | | positionNum = fightObj.PosNum; |
| | | |
| | | // 【重要】战斗构成里没有卡牌的guid |
| | | guid = string.Empty; |
| | | |
| | | Update(); |
| | | } |
| | | |
| | | // 布阵时的构造 |
| | | public TeamHero(HeroInfo heroInfo, int posNum, TeamBase _teamBase) |
| | | { |
| | | heroId = heroInfo.itemHero.config.ID; |
| | | heroConfig = HeroConfig.Get(heroId); |
| | | SkinID = heroInfo.SkinID; |
| | | skinConfig = heroInfo.skinConfig; |
| | | |
| | | teamBase = _teamBase; |
| | | |
| | | ObjID = 0; |
| | | NPCID = 0; |
| | | |
| | | curHp = heroInfo.hp; |
| | | maxHp = heroInfo.hp; |
| | | rage = 0; |
| | | |
| | | positionNum = posNum; |
| | | |
| | | // 【重要】布阵里的要guid |
| | | guid = heroInfo.itemHero.guid; |
| | | |
| | | Update(); |
| | | } |
| | | |
| | | public void OnSwapPosition(TeamHero teamHero) |
| | | { |
| | | int tempPosNum = positionNum; |
| | | positionNum = teamHero.positionNum; |
| | | teamHero.positionNum = tempPosNum; |
| | | |
| | | teamBase.teamHeros[positionNum] = this; |
| | | teamBase.teamHeros[teamHero.positionNum] = teamHero; |
| | | |
| | | Update(); |
| | | } |
| | | |
| | | public void Update() |
| | | { |
| | | |
| | | |
| | | } |
| | | |
| | | |
| | | // 最终属性 当前属性应该是要在这一层的 |
| | | |
| | | public int GetPower() |
| | | { |
| | | return heroInfo.CalculatePower(); |
| | | // 计算战斗力YYL TODO |
| | | return 0; |
| | | } |
| | | } |
| | |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using UnityEngine; |
| | | |
| | | |
| | |
| | | { |
| | | protected Dictionary<TeamType, TeamBase> teamDict = new Dictionary<TeamType, TeamBase>(); |
| | | |
| | | public override void Init() |
| | | { |
| | | base.Init(); |
| | | public override void Init() |
| | | { |
| | | base.Init(); |
| | | |
| | | HeroManager.Instance.onHeroChangeEvent += onHeroChangeEvent; |
| | | HeroManager.Instance.onHeroDeleteEvent += onHeroDeleteEvent; |
| | | DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent += OnBeforePlayerDataInitialize; |
| | | } |
| | | |
| | | public override void Release() |
| | | { |
| | | base.Release(); |
| | | public override void Release() |
| | | { |
| | | base.Release(); |
| | | HeroManager.Instance.onHeroChangeEvent += onHeroChangeEvent; |
| | | HeroManager.Instance.onHeroDeleteEvent += onHeroDeleteEvent; |
| | | DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent += OnBeforePlayerDataInitialize; |
| | | } |
| | | |
| | | protected void OnBeforePlayerDataInitialize() |
| | | { |
| | | teamDict.Clear(); |
| | | } |
| | | |
| | | protected void onHeroChangeEvent(HeroInfo heroInfo) |
| | | { |
| | | // 英雄当前所有在的队伍 |
| | | List<int> heroTeams = heroInfo.itemHero.GetUseData(81); |
| | | |
| | | Dictionary<TeamType, KeyValuePair<int, int>> teamTypeShapeTypePositionDict = new Dictionary<TeamType, KeyValuePair<int, int>>(); |
| | | foreach (var teamMsg in heroTeams) |
| | | { |
| | | // 所在阵容信息列表 [阵容类型*10000+阵型类型*100+位置编号, ...] |
| | | int teamType = teamMsg / 10000; |
| | | int shapeType = (teamMsg % 10000) / 100; |
| | | int positionIndex = teamMsg % 100; |
| | | |
| | | if (teamTypeShapeTypePositionDict.ContainsKey((TeamType)teamType)) |
| | | { |
| | | // 队伍类型相同,更新阵型和位置 |
| | | Debug.LogError("当前英雄拥有两个相同的队伍信息: " + teamType + " " + shapeType + " " + positionIndex + ", hero guid is " + heroInfo.itemHero.guid); |
| | | } |
| | | else |
| | | { |
| | | // 队伍类型不同,添加新的 |
| | | KeyValuePair<int, int> shapeTypePosition = new KeyValuePair<int, int>(shapeType, positionIndex); |
| | | teamTypeShapeTypePositionDict.Add((TeamType)teamType, shapeTypePosition); |
| | | } |
| | | } |
| | | |
| | | // 遍历当前所有队伍 判断当前队伍里是否有该英雄 |
| | | // 如果有的话 读取一下当前是否该英雄还在队伍里 位置是否发生变化 |
| | | // 或者是阵型发生变化 或者单纯的英雄发生变化 |
| | | // 如果没有的话 就说明该英雄被移出队伍了 |
| | | foreach (var team in teamDict.Values) |
| | | { |
| | | // 检查一下当前队伍是否有该英雄 |
| | | // 如果有的话 读取一下当前是否该英雄还在队伍里 位置是否发生变化 |
| | | TeamHero teamHero = team.GetHero(heroInfo.itemHero.guid); |
| | | if (teamHero != null) |
| | | { |
| | | if ((teamTypeShapeTypePositionDict.ContainsKey(team.teamType))) |
| | | { |
| | | KeyValuePair<int, int> shapeTypePosition = teamTypeShapeTypePositionDict[team.teamType]; |
| | | // 更新队伍信息 |
| | | // 可以判断teamHero的positionNum是否跟shapeTypePosition.Value一致 判断是否变位置了 |
| | | // 可以判断teamHero的ServerShapeType是否跟shapeTypePosition.Key一致 判断是否变阵型了 |
| | | team.RefreshServerData(shapeTypePosition.Key, shapeTypePosition.Value, heroInfo); |
| | | } |
| | | else |
| | | { |
| | | // 队伍里有这个英雄,但是在队伍信息里没有了 置空 (被移出队伍) |
| | | team.SetTeamHero(teamHero.positionNum, null); |
| | | } |
| | | } |
| | | // 原来队伍里没这个英雄 |
| | | else |
| | | { |
| | | // 如果当前队伍类型在英雄的所在阵容信息列表里有的话 |
| | | // 就说明队伍里新增了这个英雄 (新增进队伍) |
| | | if (teamTypeShapeTypePositionDict.ContainsKey(team.teamType)) |
| | | { |
| | | KeyValuePair<int, int> shapeTypePosition = teamTypeShapeTypePositionDict[team.teamType]; |
| | | team.RefreshServerData(shapeTypePosition.Key, shapeTypePosition.Value, null); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | // 遍历英雄所在的队伍信息列表 新增一下当前储存的队伍里没有的队伍 |
| | | foreach (var teamTypeShapeTypePosition in teamTypeShapeTypePositionDict) |
| | | { |
| | | // 如果当前队伍类型在队伍字典里没有的话 |
| | | if (!teamDict.ContainsKey(teamTypeShapeTypePosition.Key)) |
| | | { |
| | | // 新建一个队伍 |
| | | TeamBase team = new TeamBase(teamTypeShapeTypePosition.Key); |
| | | team.RefreshServerData(teamTypeShapeTypePosition.Value.Key, teamTypeShapeTypePosition.Value.Value, heroInfo); |
| | | teamDict.Add(teamTypeShapeTypePosition.Key, team); |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
| | | |
| | | protected void onHeroDeleteEvent(HeroInfo heroInfo) |
| | | { |
| | | List<int> heroTeams = heroInfo.itemHero.GetUseData(81); |
| | | |
| | | foreach (int teamMsg in heroTeams) |
| | | { |
| | | // 所在阵容信息列表 [阵容类型*10000+阵型类型*100+位置编号, ...] |
| | | int teamType = teamMsg / 10000; |
| | | int shapeType = (teamMsg % 10000) / 100; |
| | | int positionIndex = teamMsg % 100; |
| | | |
| | | TeamBase team = GetTeam((TeamType)teamType); |
| | | |
| | | if (team != null) |
| | | { |
| | | team.RefreshServerData(shapeType, positionIndex, null); |
| | | } |
| | | } |
| | | } |
| | | |
| | | public bool HasTeam(TeamType teamType) |
| | | { |
| | | return teamDict.ContainsKey(teamType); |
| | | } |
| | | |
| | | public TeamBase GetTeam(TeamType teamType) |
| | | { |
| | |
| | | |
| | | if (!teamDict.TryGetValue(teamType, out team)) |
| | | { |
| | | team = new TeamBase(); |
| | | team.AddHeroInfos(HeroManager.Instance.GetPowerfulHeroList()); |
| | | team = new TeamBase(teamType); |
| | | team.CreateDefault(HeroManager.Instance.GetPowerfulHeroList()); |
| | | teamDict.Add(teamType, team); |
| | | } |
| | | |
| | |
| | | |
| | | public static class UniTaskExtension |
| | | { |
| | | public static void DelayFrame(this GameObject go, Action action) |
| | | public static void DelayFrame(this GameObject go, Action action) |
| | | { |
| | | DelayFrameInternal(1, action); |
| | | } |
| | | |
| | | public static void DelayFrame(this Component cmp, Action action) |
| | | public static void DelayFrame(this Component cmp, Action action) |
| | | { |
| | | DelayFrameInternal(1, action); |
| | | } |
| | |
| | | { |
| | | DelayFrameInternal(frames, action); |
| | | } |
| | | |
| | | public static void DelayFrame(Action action) |
| | | { |
| | | DelayFrameInternal(1, action); |
| | | } |
| | | } |