New file |
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年8月6日 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | | using System; |
| | | using UnityEngine; |
| | | using LitJson; |
| | | |
| | | public partial class DamageNumConfig : ConfigBase<string, DamageNumConfig> |
| | | { |
| | | static DamageNumConfig() |
| | | { |
| | | // 访问过静态构造函数 |
| | | visit = true; |
| | | } |
| | | |
| | | public string id; |
| | | public int prefix; |
| | | public int plus; |
| | | public int minus; |
| | | public int[] nums; |
| | | |
| | | public override string LoadKey(string _key) |
| | | { |
| | | string key = GetKey(_key); |
| | | return key; |
| | | } |
| | | |
| | | public override void LoadConfig(string input) |
| | | { |
| | | try { |
| | | string[] tables = input.Split('\t'); |
| | | id = tables[0]; |
| | | |
| | | int.TryParse(tables[1],out prefix); |
| | | |
| | | int.TryParse(tables[2],out plus); |
| | | |
| | | int.TryParse(tables[3],out minus); |
| | | |
| | | if (tables[4].Contains("[")) |
| | | { |
| | | nums = JsonMapper.ToObject<int[]>(tables[4]); |
| | | } |
| | | else |
| | | { |
| | | string[] numsStringArray = tables[4].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries); |
| | | nums = new int[numsStringArray.Length]; |
| | | for (int i=0;i<numsStringArray.Length;i++) |
| | | { |
| | | int.TryParse(numsStringArray[i],out nums[i]); |
| | | } |
| | | } |
| | | } |
| | | catch (Exception exception) |
| | | { |
| | | Debug.LogError(exception); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 8189c5d3b27328346a2b8b3eb50d45cf |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年8月5日 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | | using System; |
| | | using UnityEngine; |
| | | using LitJson; |
| | | |
| | | public partial class PlayerAttrConfig : ConfigBase<int, PlayerAttrConfig> |
| | | { |
| | | static PlayerAttrConfig() |
| | | { |
| | | // 访问过静态构造函数 |
| | | visit = true; |
| | | } |
| | | |
| | | public int ID; |
| | | public string Name; |
| | | public string ShowName; |
| | | public int ISPercentage; |
| | | public int type; |
| | | public int decimalCount; |
| | | public int showType; |
| | | public int showSequence; |
| | | public string desc; |
| | | public string Parameter; |
| | | |
| | | public override int LoadKey(string _key) |
| | | { |
| | | int key = GetKey(_key); |
| | | return key; |
| | | } |
| | | |
| | | public override void LoadConfig(string input) |
| | | { |
| | | try { |
| | | string[] tables = input.Split('\t'); |
| | | int.TryParse(tables[0],out ID); |
| | | |
| | | Name = tables[1]; |
| | | |
| | | ShowName = tables[2]; |
| | | |
| | | int.TryParse(tables[3],out ISPercentage); |
| | | |
| | | int.TryParse(tables[4],out type); |
| | | |
| | | int.TryParse(tables[5],out decimalCount); |
| | | |
| | | int.TryParse(tables[6],out showType); |
| | | |
| | | int.TryParse(tables[7],out showSequence); |
| | | |
| | | desc = tables[8]; |
| | | |
| | | Parameter = tables[9]; |
| | | } |
| | | catch (Exception exception) |
| | | { |
| | | Debug.LogError(exception); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: f1fc6e60e5eeba644bf77f0c7b22879e |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年8月5日 |
| | | // [ Date ]: 2025年8月7日 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | |
| | | } |
| | | |
| | | public int SkillID; |
| | | public int SkillTypeID; |
| | | public int SkillMaxLV; |
| | | public string SkillName; |
| | | public string Description; |
| | | public string IconName; |
| | | public int FuncType; |
| | | public int SkillType; |
| | | public int HurtType; |
| | | public int AtkType; |
| | | public int TagAim; |
| | | public int TagFriendly; |
| | | public int TagAffect; |
| | | public int TagCount; |
| | | public int HappenRate; |
| | | public int LastTime; |
| | | public int CoolDownTime; |
| | | public int Priority; |
| | | public int EffectID1; |
| | | public int[] EffectValues1; |
| | | public int EffectID2; |
| | |
| | | public int EffectId; |
| | | public int EffectPos; |
| | | public int EffectType; |
| | | public string IconName; |
| | | |
| | | public override int LoadKey(string _key) |
| | | { |
| | |
| | | string[] tables = input.Split('\t'); |
| | | int.TryParse(tables[0],out SkillID); |
| | | |
| | | SkillName = tables[1]; |
| | | int.TryParse(tables[1],out SkillTypeID); |
| | | |
| | | Description = tables[2]; |
| | | int.TryParse(tables[2],out SkillMaxLV); |
| | | |
| | | IconName = tables[3]; |
| | | SkillName = tables[3]; |
| | | |
| | | int.TryParse(tables[4],out FuncType); |
| | | Description = tables[4]; |
| | | |
| | | int.TryParse(tables[5],out SkillType); |
| | | int.TryParse(tables[5],out FuncType); |
| | | |
| | | int.TryParse(tables[6],out HurtType); |
| | | int.TryParse(tables[6],out SkillType); |
| | | |
| | | int.TryParse(tables[7],out AtkType); |
| | | int.TryParse(tables[7],out HurtType); |
| | | |
| | | int.TryParse(tables[8],out TagAim); |
| | | int.TryParse(tables[8],out AtkType); |
| | | |
| | | int.TryParse(tables[9],out LastTime); |
| | | int.TryParse(tables[9],out TagAim); |
| | | |
| | | int.TryParse(tables[10],out CoolDownTime); |
| | | int.TryParse(tables[10],out TagFriendly); |
| | | |
| | | int.TryParse(tables[11],out EffectID1); |
| | | int.TryParse(tables[11],out TagAffect); |
| | | |
| | | if (tables[12].Contains("[")) |
| | | int.TryParse(tables[12],out TagCount); |
| | | |
| | | int.TryParse(tables[13],out HappenRate); |
| | | |
| | | int.TryParse(tables[14],out LastTime); |
| | | |
| | | int.TryParse(tables[15],out CoolDownTime); |
| | | |
| | | int.TryParse(tables[16],out Priority); |
| | | |
| | | int.TryParse(tables[17],out EffectID1); |
| | | |
| | | if (tables[18].Contains("[")) |
| | | { |
| | | EffectValues1 = JsonMapper.ToObject<int[]>(tables[12]); |
| | | EffectValues1 = JsonMapper.ToObject<int[]>(tables[18]); |
| | | } |
| | | else |
| | | { |
| | | string[] EffectValues1StringArray = tables[12].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries); |
| | | string[] EffectValues1StringArray = tables[18].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries); |
| | | EffectValues1 = new int[EffectValues1StringArray.Length]; |
| | | for (int i=0;i<EffectValues1StringArray.Length;i++) |
| | | { |
| | |
| | | } |
| | | } |
| | | |
| | | int.TryParse(tables[13],out EffectID2); |
| | | int.TryParse(tables[19],out EffectID2); |
| | | |
| | | if (tables[14].Contains("[")) |
| | | if (tables[20].Contains("[")) |
| | | { |
| | | EffectValues2 = JsonMapper.ToObject<int[]>(tables[14]); |
| | | EffectValues2 = JsonMapper.ToObject<int[]>(tables[20]); |
| | | } |
| | | else |
| | | { |
| | | string[] EffectValues2StringArray = tables[14].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries); |
| | | string[] EffectValues2StringArray = tables[20].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries); |
| | | EffectValues2 = new int[EffectValues2StringArray.Length]; |
| | | for (int i=0;i<EffectValues2StringArray.Length;i++) |
| | | { |
| | |
| | | } |
| | | } |
| | | |
| | | int.TryParse(tables[15],out EffectID3); |
| | | int.TryParse(tables[21],out EffectID3); |
| | | |
| | | if (tables[16].Contains("[")) |
| | | if (tables[22].Contains("[")) |
| | | { |
| | | EffectValues3 = JsonMapper.ToObject<int[]>(tables[16]); |
| | | EffectValues3 = JsonMapper.ToObject<int[]>(tables[22]); |
| | | } |
| | | else |
| | | { |
| | | string[] EffectValues3StringArray = tables[16].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries); |
| | | string[] EffectValues3StringArray = tables[22].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries); |
| | | EffectValues3 = new int[EffectValues3StringArray.Length]; |
| | | for (int i=0;i<EffectValues3StringArray.Length;i++) |
| | | { |
| | |
| | | } |
| | | } |
| | | |
| | | int.TryParse(tables[17],out ConnSkill); |
| | | int.TryParse(tables[23],out ConnSkill); |
| | | |
| | | if (tables[18].Contains("[")) |
| | | if (tables[24].Contains("[")) |
| | | { |
| | | EnhanceSkillList = JsonMapper.ToObject<int[]>(tables[18]); |
| | | EnhanceSkillList = JsonMapper.ToObject<int[]>(tables[24]); |
| | | } |
| | | else |
| | | { |
| | | string[] EnhanceSkillListStringArray = tables[18].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries); |
| | | string[] EnhanceSkillListStringArray = tables[24].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries); |
| | | EnhanceSkillList = new int[EnhanceSkillListStringArray.Length]; |
| | | for (int i=0;i<EnhanceSkillListStringArray.Length;i++) |
| | | { |
| | |
| | | } |
| | | } |
| | | |
| | | int.TryParse(tables[19],out FightPower); |
| | | int.TryParse(tables[25],out FightPower); |
| | | |
| | | int.TryParse(tables[20],out StartupFrames); |
| | | int.TryParse(tables[26],out StartupFrames); |
| | | |
| | | int.TryParse(tables[21],out ActiveFrames); |
| | | int.TryParse(tables[27],out ActiveFrames); |
| | | |
| | | int.TryParse(tables[22],out RecoveryFrames); |
| | | int.TryParse(tables[28],out RecoveryFrames); |
| | | |
| | | int.TryParse(tables[23],out LoopCount); |
| | | int.TryParse(tables[29],out LoopCount); |
| | | |
| | | int.TryParse(tables[24],out CastPosition); |
| | | int.TryParse(tables[30],out CastPosition); |
| | | |
| | | int.TryParse(tables[25],out CastIndexNum); |
| | | int.TryParse(tables[31],out CastIndexNum); |
| | | |
| | | float.TryParse(tables[26],out CastDistance); |
| | | float.TryParse(tables[32],out CastDistance); |
| | | |
| | | DamageDivide = JsonMapper.ToObject<int[][]>(tables[27].Replace("(", "[").Replace(")", "]")); |
| | | DamageDivide = JsonMapper.ToObject<int[][]>(tables[33].Replace("(", "[").Replace(")", "]")); |
| | | |
| | | int.TryParse(tables[28],out BulletEffectId); |
| | | int.TryParse(tables[34],out BulletEffectId); |
| | | |
| | | int.TryParse(tables[29],out BulletPos); |
| | | int.TryParse(tables[35],out BulletPos); |
| | | |
| | | int.TryParse(tables[30],out BulletPath); |
| | | int.TryParse(tables[36],out BulletPath); |
| | | |
| | | int.TryParse(tables[31],out BulletFlyTime); |
| | | int.TryParse(tables[37],out BulletFlyTime); |
| | | |
| | | int.TryParse(tables[32],out ExplosionEffectId); |
| | | int.TryParse(tables[38],out ExplosionEffectId); |
| | | |
| | | int.TryParse(tables[33],out ExplosionPos); |
| | | int.TryParse(tables[39],out ExplosionPos); |
| | | |
| | | SkillMotionName = tables[34]; |
| | | SkillMotionName = tables[40]; |
| | | |
| | | int.TryParse(tables[35],out EffectId); |
| | | int.TryParse(tables[41],out EffectId); |
| | | |
| | | int.TryParse(tables[36],out EffectPos); |
| | | int.TryParse(tables[42],out EffectPos); |
| | | |
| | | int.TryParse(tables[37],out EffectType); |
| | | int.TryParse(tables[43],out EffectType); |
| | | |
| | | IconName = tables[44]; |
| | | } |
| | | catch (Exception exception) |
| | | { |
New file |
| | |
| | | using UnityEngine; |
| | | using System.Collections; |
| | | |
| | | // B4 15 主线掉落物品操作 #tagCSMainDropItemOP |
| | | |
| | | public class CB415_tagCSMainDropItemOP : GameNetPackBasic { |
| | | public byte Count; |
| | | public ushort[] IndexList; // 掉落背包中的物品格子索引列表 |
| | | public byte OPType; // 0 - 拾取非装备物品;1 - 分解;2 - 穿戴/替换; |
| | | public byte OPValue; // 操作额外指令值,由操作类型决定,如穿戴时可发送穿戴后是否自动分解 |
| | | |
| | | public CB415_tagCSMainDropItemOP () { |
| | | combineCmd = (ushort)0x03FE; |
| | | _cmd = (ushort)0xB415; |
| | | } |
| | | |
| | | public override void WriteToBytes () { |
| | | WriteBytes (Count, NetDataType.BYTE); |
| | | WriteBytes (IndexList, NetDataType.WORD, Count); |
| | | WriteBytes (OPType, NetDataType.BYTE); |
| | | WriteBytes (OPValue, NetDataType.BYTE); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 869e528814e57b34cb674f8b554a911f |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
| | |
| | | public class CustomHB426CombinePack : GameNetPackBasic |
| | | { |
| | | |
| | | protected HB426_tagSCTurnFightTag startTag; |
| | | public HB426_tagSCTurnFightTag startTag; |
| | | |
| | | protected HB426_tagSCTurnFightTag endTag; |
| | | public HB426_tagSCTurnFightTag endTag; |
| | | |
| | | public int fromIndex; |
| | | |
| | |
| | | return; |
| | | } |
| | | |
| | | // 技能包 |
| | | if (startTag.Tag.StartsWith("Skill_")) |
| | | { |
| | | H0604_tagUseSkillAttack skill = packList[0] as H0604_tagUseSkillAttack; |
| | | BattleObject caster = battleField.battleObjMgr.GetBattleObject((int)skill.ObjID); |
| | | // 注意处理packList |
| | | SkillRecordAction skillRecordAction = new SkillRecordAction(battleField, caster, skill, packList); |
| | | battleField.PlayRecord(skillRecordAction); |
| | | } |
| | |
| | | //玩家主动点击休息时,后端会回收创建的战斗主阵容武将实例,前端收到//04 07 NPC消失#tagNPCDisappear时进行解绑 |
| | | |
| | | BattleField battleField = BattleManager.Instance.GetBattleField(vNetPack.packUID); |
| | | |
| | | //04 07 NPC消失#tagNPCDisappear 中的字段NPCID实际上同步的是ObjID,只是命名问题 |
| | | // 提前结束战斗 删除NPCID()实际上是对象的ObjID |
| | | battleField.FinishBattleInAdvance(vNetData.NPCID); |
| | | battleField.NPCDisappear(vNetData.NPCID); |
| | | |
| | | } |
| | | } |
| | |
| | | public class DTC0604_tagUseSkillAttack : DtcBasic { |
| | | public override void Done(GameNetPackBasic vNetPack) { |
| | | base.Done(vNetPack); |
| | | H0604_tagUseSkillAttack vNetData = vNetPack as H0604_tagUseSkillAttack; |
| | | // H0604_tagUseSkillAttack vNetData = vNetPack as H0604_tagUseSkillAttack; |
| | | |
| | | |
| | | // public uint ObjID; |
| | |
| | | |
| | | // ObjType类型的ObjID使用BattleType类技能SkillID攻击了AttackObjType类型的AttackID 伤害数字是HurtList |
| | | |
| | | BattleField battleField = BattleManager.Instance.GetBattleField(vNetPack.packUID); |
| | | // BattleField battleField = BattleManager.Instance.GetBattleField(vNetPack.packUID); |
| | | |
| | | battleField.ProcessUseSkillAttack(vNetData); |
| | | // battleField.ProcessUseSkillAttack(vNetData); |
| | | |
| | | |
| | | } |
New file |
| | |
| | | using UnityEngine; |
| | | using System.Collections; |
| | | |
| | | //B4 05 获得经验 #tagMCAddExp |
| | | |
| | | public class DTCB405_tagMCAddExp : DtcBasic { |
| | | public override void Done(GameNetPackBasic vNetPack) { |
| | | base.Done(vNetPack); |
| | | HB405_tagMCAddExp vNetData = vNetPack as HB405_tagMCAddExp; |
| | | } |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 70b2b77edce0c7346a9df59f1266cb83 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
| | |
| | | } |
| | | } |
| | | |
| | | |
| | | // 主线 |
| | | // 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]); |
| | | // } |
| | | JsonData extendData = JsonMapper.ToObject(vNetData.Msg); |
| | | |
| | | string guid = BattleManager.Instance.GetGUID(vNetPack.packUID); |
| | | |
| | | BattleManager.Instance.CreateBattleField(guid, (int)vNetData.MapID, (int)vNetData.FuncLineID, extendData, redTeamList, blueTeamList); |
| | | BattleField battleField = BattleManager.Instance.CreateBattleField(guid, (int)vNetData.MapID, (int)vNetData.FuncLineID, extendData, redTeamList, blueTeamList); |
| | | BattleStartAction battleStartAction = new BattleStartAction(battleField); |
| | | battleField.recordPlayer.PlayRecord(battleStartAction); |
| | | } |
| | | } |
| | |
| | | using System.Collections; |
| | | |
| | | // B4 25 回合战斗战报片段标记 #tagSCTurnFightReportSign |
| | | // 战斗相关封包说明 |
| | | // // B4 25 回合战斗战报片段标记 #tagSCTurnFightReportSign 后端同步战斗片段时会用该封包标记开始跟结束,中间的所有封包即为本次战斗片段的所有封包(主线小怪战斗可能包含其他非战斗类的封包,如战锤数量同步、经验同步、升级同步等) |
| | | // // B4 24 回合战斗初始化 #tagSCTurnFightInit 标记一场战斗的初始化,主线关卡分波、每波可支持多个小队,一个小队的战斗就是一场战斗 |
| | | // 主线战斗中,Msg初始化信息包含 {"teamNum":当前小队编号, "teamMax":最大小队数} , 前端如果有需要展示小队相关信息的话可以解析该值 |
| | | // // B4 20 回合制战斗状态 #tagMCTurnFightState 一般同步该场战斗相关的信息,如回合变化、战斗状态等,目前State只同步 2-战斗中及 4-结算,其他有需要的话再扩展 |
| | | // // B4 21 回合战斗对象开始行动 #tagMCTurnFightObjAction |
| | | // 标记某个战斗实例开始行动,后续的封包都是该次行动产生的一些列行为,直到下一个B421封包(另一个战斗实例行动) |
| | | // // B4 22 回合战斗对象死亡 #tagMCTurnFightObjDead |
| | | // 通知某个战斗实例死亡了(后端战斗实例还在),注意和0407区分,0407代表的是NPC消失了(后端战斗实例也已经销毁回收) |
| | | // // B4 23 回合战斗对象复活 #tagMCTurnFightObjReborn |
| | | // //04 07 NPC消失#tagNPCDisappear |
| | | // 注意与B422区分,0407仅代表该战斗实例被后端回收了 |
| | | // 后端战斗实例会重复利用,比如切换小队时,原小队的实例会先被回收,然后再创建新的小队战斗实例,可能复用相同的实例ID,即ObjID |
| | | // //04 18 周围对象刷新#tagObjInfoRefresh |
| | | // 通知某个对象(战斗实例或者玩家自身)相关的属性刷新,如通知战斗NPC怒气值刷新,通知玩家战锤数量刷新等 |
| | | // 技能通知,详见 【技能】 说明 |
| | | //06 04 技能攻击使用成功#tagUseSkillAttack |
| | | //04 23 对象状态刷新通知(只显示)#tagObjPropertyRefreshView |
| | | |
| | | public class DTCB425_tagSCTurnFightReportSign : DtcBasic { |
| | | public override void Done(GameNetPackBasic vNetPack) { |
| | | |
| | | public class DTCB425_tagSCTurnFightReportSign : DtcBasic |
| | | { |
| | | public override void Done(GameNetPackBasic vNetPack) |
| | | { |
| | | base.Done(vNetPack); |
| | | HB425_tagSCTurnFightReportSign vNetData = vNetPack as HB425_tagSCTurnFightReportSign; |
| | | |
| | |
| | | |
| | | public static bool IsCorrectType(GameNetPackBasic vNetPack) |
| | | { |
| | | return vNetPack is HB425_tagSCTurnFightReportSign; |
| | | return vNetPack is HB425_tagSCTurnFightReportSign; |
| | | } |
| | | } |
New file |
| | |
| | | using UnityEngine; |
| | | using System.Collections; |
| | | |
| | | //B4 05 获得经验 #tagMCAddExp |
| | | |
| | | public class HB405_tagMCAddExp : GameNetPackBasic { |
| | | public uint ExpPoint; // 单位亿点 |
| | | public uint Exp; // 单位点 |
| | | public byte Source; //经验获取来源 |
| | | |
| | | public HB405_tagMCAddExp () { |
| | | _cmd = (ushort)0xB405; |
| | | } |
| | | |
| | | public override void ReadFromBytes (byte[] vBytes) { |
| | | TransBytes (out ExpPoint, vBytes, NetDataType.DWORD); |
| | | TransBytes (out Exp, vBytes, NetDataType.DWORD); |
| | | TransBytes (out Source, vBytes, NetDataType.BYTE); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 657dd96a4b0eca64386a70ac86ec48a9 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
| | |
| | | public const int BattleStartEffectID = 1001; // Example effect ID for battle start |
| | | |
| | | public const int skillMotionFps = 30; |
| | | |
| | | public const int BattlePointItemID = 3;//战锤ID |
| | | } |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | public void HaveRest() |
| | | { |
| | | foreach (KeyValuePair<int, List<EffectPlayer>> kvPair in effectDict) |
| | | { |
| | | foreach (EffectPlayer effectPlayer in kvPair.Value) |
| | | { |
| | | if (effectPlayer != null) |
| | | { |
| | | GameObject.DestroyImmediate(effectPlayer.gameObject); |
| | | } |
| | | } |
| | | } |
| | | effectDict.Clear(); |
| | | } |
| | | } |
| | |
| | | |
| | | public JsonData extendData; |
| | | |
| | | public bool IsActive |
| | | { |
| | | get; |
| | | protected set; |
| | | } |
| | | |
| | | public bool IsBattleFinish |
| | | { |
| | | get; |
| | | protected set; |
| | | } |
| | | |
| | | public virtual bool IsPvp |
| | | { |
| | | get |
| | | { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | private bool m_IsPause = false; |
| | |
| | | public BattleField(string _guid) |
| | | { |
| | | guid = _guid; |
| | | |
| | | 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(); |
| | | battleEffectMgr = new BattleEffectMgr(); |
| | | battleTweenMgr = new BattleTweenMgr(); |
| | | recordPlayer = new RecordPlayer(); |
| | | |
| | | battleEffectMgr.Init(this); |
| | | battleTweenMgr.Init(this); |
| | | recordPlayer.Init(this); |
| | | } |
| | | |
| | | public virtual void Init(int _MapID, int _FuncLineID, JsonData _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(); |
| | | if (blueTeamList == null) |
| | | { |
| | | battleObjMgr.Init(this, redTeamList[redTeamIndex], null); |
| | | battleObjMgr.HaveRest(BattleCamp.Red); |
| | | HaveRest(); |
| | | } |
| | | else |
| | | { |
| | | 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); |
| | | } |
| | | |
| | | // 在Run之前要设置完毕 要创建Agent |
| | |
| | | |
| | | } |
| | | |
| | | public virtual void OnTurnFightState(int turnNum, int State, int FuncLineID, JsonData extendData) |
| | | public virtual void OnTurnFightState(int turnNum, int State, int FuncLineID, JsonData turnFightStateData) |
| | | { |
| | | // 切换回合 |
| | | // 是每个战斗开始/每个回合的第一个战斗包 |
| | |
| | | // TurnNum; // 当前轮次 |
| | | // Len; |
| | | // Msg; //size = Len + |
| | | |
| | | if (State == 4) |
| | | { |
| | | //已经结束并结算 |
| | | OnBattleEnd(turnFightStateData); |
| | | return; |
| | | } |
| | | |
| | | // 做表现 |
| | | if (turnNum == 1) |
| | |
| | | // 销毁全部内容 |
| | | } |
| | | |
| | | public void FinishBattleInAdvance(uint[] ObjIDArr) |
| | | public void NPCDisappear(uint[] ObjIDArr) |
| | | { |
| | | // 让npc隐藏后 左边播放睡觉动作 |
| | | |
| | | |
| | | // 让npc消失 |
| | | battleObjMgr.DestroyObjIds(ObjIDArr); |
| | | } |
| | | |
| | | 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) |
| | | { |
| | |
| | | } |
| | | } |
| | | |
| | | public RectTransform GetTeamNode(BattleCamp battleCamp, int index) |
| | | public RectTransform GetTeamNode(BattleCamp battleCamp, BattleObject target) |
| | | { |
| | | int index = target.teamHero.positionNum; |
| | | return GetTeamNode(battleCamp, index); |
| | | } |
| | | |
| | | public RectTransform GetTeamNode(BattleCamp battleCamp, SkillConfig skillConfig) |
| | | { |
| | | int index = skillConfig.CastIndexNum - 1; // 技能配置的index是从1开始的,所以要减1 |
| | | return GetTeamNode(battleCamp, index); |
| | | } |
| | | |
| | | private RectTransform GetTeamNode(BattleCamp battleCamp, int index) |
| | | { |
| | | if (index < 0 || index >= battleRootNode.redTeamNodeList.Count) |
| | | { |
| | | Debug.LogError($"GetTeamNode: Index {index} is out of range for {battleCamp} camp."); |
| | | return null; |
| | | } |
| | | |
| | | if (battleCamp == BattleCamp.Red) |
| | | { |
| | | return battleRootNode.redTeamNodeList[index].transform as RectTransform; |
| | |
| | | foreach (var obj in redTeam) |
| | | { |
| | | obj.motionBase.PlayAnimation(MotionName.run, true); |
| | | RectTransform trans = obj.heroGo.transform as RectTransform; |
| | | RectTransform trans = obj.heroRectTrans; |
| | | tween = trans.DOMove(obj.GetAliasTeamNode().position, 0.5f).SetEase(Ease.Linear); |
| | | battleTweenMgr.OnPlayTween(tween); |
| | | } |
| | |
| | | efplayer.onDestroy += a => onMoveComplete(); |
| | | }; |
| | | } |
| | | |
| | | public void OnObjDropItem(int positionNum, ItemModel item) |
| | | { |
| | | // 处理掉落物品 |
| | | //无论如何图层应该在人物上面 所以这里应该有个挂点 |
| | | // YYL TODO |
| | | |
| | | |
| | | } |
| | | |
| | | public void OnObjReborn(HB423_tagMCTurnFightObjReborn vNetData) |
| | | { |
| | | // 处理复活逻辑 |
| | | BattleObject battleObj = battleObjMgr.GetBattleObject((int)vNetData.ObjID); |
| | | if (battleObj != null) |
| | | { |
| | | battleObj.OnReborn(vNetData); |
| | | } |
| | | else |
| | | { |
| | | Debug.LogError($"BattleObject with ID {vNetData.ObjID} not found for reborn."); |
| | | } |
| | | } |
| | | |
| | | public void OnObjDropExp(BattleObject battleObject) |
| | | { |
| | | // 处理掉落经验 |
| | | // YYL TODO |
| | | battleObject.DropExp(); |
| | | } |
| | | |
| | | public virtual void OnBattleEnd(JsonData turnFightStateData) |
| | | { |
| | | // 处理战斗结束逻辑 |
| | | IsBattleFinish = true; |
| | | // 结算逻辑 |
| | | |
| | | // {"winFaction":获胜阵营, "statInfo":统计信息, “itemInfo“:[奖励物品信息列表]} |
| | | } |
| | | |
| | | public virtual void HaveRest() |
| | | { |
| | | // 休息状态 |
| | | battleObjMgr.HaveRest(BattleCamp.Red); |
| | | battleObjMgr.DestroyTeam(BattleCamp.Blue); |
| | | |
| | | battleEffectMgr.HaveRest(); |
| | | battleTweenMgr.HaveRest(); |
| | | } |
| | | |
| | | public bool IsBattleEnd() |
| | | { |
| | | return IsBattleFinish; |
| | | } |
| | | } |
| | |
| | | public class BattleRootNode : MonoBehaviour |
| | | { |
| | | public RectTransform redTeamNode; |
| | | public List<GameObject> redTeamNodeList = new List<GameObject>(); |
| | | public List<GameObject> redTeamNodeList |
| | | { |
| | | get |
| | | { |
| | | return _redTeamNodeList; |
| | | } |
| | | } |
| | | |
| | | private List<GameObject> _redTeamNodeList = new List<GameObject>(); |
| | | |
| | | public RectTransform blueTeamNode; |
| | | public List<GameObject> blueTeamNodeList = new List<GameObject>(); |
| | | public List<GameObject> blueTeamNodeList |
| | | { |
| | | get |
| | | { |
| | | return _blueTeamNodeList; |
| | | } |
| | | } |
| | | |
| | | private List<GameObject> _blueTeamNodeList = new List<GameObject>(); |
| | | |
| | | public RawImage imgBackground; |
| | | |
| | | void Awake() |
| | | { |
| | | if (redTeamNodeList.Count != TeamConst.MaxTeamSlotCount) |
| | | for (int i = 1; i <= TeamConst.MaxTeamSlotCount; i++) |
| | | { |
| | | Debug.LogError("redTeamNodeList count is not equal to MaxTeamSlotCount: " + redTeamNodeList.Count); |
| | | } |
| | | Transform redTrans = redTeamNode.Find("Pos" + i); |
| | | _redTeamNodeList.Add(redTrans.gameObject); |
| | | |
| | | if (blueTeamNodeList.Count != TeamConst.MaxTeamSlotCount) |
| | | { |
| | | Debug.LogError("blueTeamNodeList count is not equal to MaxTeamSlotCount: " + blueTeamNodeList.Count); |
| | | Transform blueTrans = blueTeamNode.Find("Pos" + i); |
| | | _blueTeamNodeList.Add(blueTrans.gameObject); |
| | | } |
| | | DontDestroyOnLoad(gameObject); |
| | | } |
| | | |
| | | public void SetBackground(Texture texture) |
| | | { |
| | | if (imgBackground != null) |
| | | { |
| | | imgBackground.texture = texture; |
| | | imgBackground.SetNativeSize(); |
| | | } |
| | | } |
| | | } |
| | |
| | | using UnityEngine; |
| | | |
| | | // 只有主线战斗用到 所以这里可能会放一些主线的特殊处理 |
| | | |
| | | public class HandModeOperationAgent : IOperationAgent |
| | | { |
| | | protected StoryBattleField storyBattleField; |
| | | |
| | | public HandModeOperationAgent(BattleField battleField) : base(battleField) |
| | | { |
| | | |
| | | storyBattleField = battleField as StoryBattleField; |
| | | } |
| | | |
| | | public override void Run() |
| | |
| | | { |
| | | base.DoNext(); |
| | | |
| | | // 当前没有在播放战斗录像 |
| | | if (!battleField.recordPlayer.IsPlaying()) |
| | | { |
| | | // ask for next action |
| | | // 没有下一个包可以发了 |
| | | if (!BattleManager.Instance.DistributeNextPackage()) |
| | | { |
| | | // 请求下一个战斗包 或者检查战斗是否结束 |
| | | // ReqType; // 0-停止战斗回城;1-设置消耗倍值;2-挑战关卡小怪;3-挑战关卡boss;4-继续战斗; |
| | | |
| | | // 如果在休息 点一下之后应该是挑战小怪或者挑战关卡 |
| | | // 如果在战斗 战斗是否结束/战斗持续中 结束应该是挑战下一关 持续应该是继续战斗 |
| | | |
| | | |
| | | // 检查一下锤子的消耗 |
| | | //FightPoint 用于记录消耗战锤倍数,小于等于1时默认1倍,大于1时为对应消耗倍值,0418刷新类型22 |
| | | ulong costRate = PlayerDatas.Instance.GetPlayerDataByType(PlayerDataType.FightPoint); |
| | | |
| | | int cost = (int)(costRate > 1 ? costRate : 1) * 1; // 1是默认消耗 |
| | | |
| | | |
| | | // 检查一下锤子的消耗 |
| | | if (!ItemLogicUtility.CheckItemCount(PackType.Item, BattleConst.BattlePointItemID, cost, true)) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | byte reqType; |
| | | |
| | | if (storyBattleField.battleState == StoryBattleState.Break) |
| | | { |
| | | reqType = 2; |
| | | } |
| | | else if (storyBattleField.battleState == StoryBattleState.Battle) |
| | | { |
| | | if (battleField.IsBattleEnd()) |
| | | { |
| | | reqType = 2; // 继续挑战小怪 |
| | | } |
| | | else |
| | | { |
| | | reqType = 4; // 继续战斗 |
| | | } |
| | | } |
| | | else |
| | | { |
| | | Debug.LogError("unknown battle state"); |
| | | return; |
| | | } |
| | | |
| | | BattleManager.Instance.MainFightRequest(reqType); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | Debug.LogError("action doesnt finish, wait a moment please"); |
| | | } |
| | | } |
| | | |
| | | |
| | | } |
| | |
| | | { |
| | | private bool isRun = false; |
| | | |
| | | public BattleStartAction(BattleField _battleField, BattleObject _caster, H0604_tagUseSkillAttack vNetData) |
| | | : base(RecordActionType.BattleStart, _battleField, _caster) |
| | | public BattleStartAction(BattleField _battleField) |
| | | : base(RecordActionType.BattleStart, _battleField, null) |
| | | { |
| | | |
| | | } |
| | |
| | | |
| | | private void OnDeathAnimationEnd() |
| | | { |
| | | // 掉落物品 增加经验 |
| | | |
| | | isFinish = true; |
| | | } |
| | | } |
| | |
| | | using UnityEngine; |
| | | using System.Collections.Generic; |
| | | |
| | | // 【主线战斗流程】 |
| | | // 发送 B413 (ReqType 为 2 或 3) |
| | | // 后端回复 B425标记0开始 (中间N个战斗片段封包) B425标记1结束 |
| | | // 前端解析 N个战斗片段封包 ,拆解成前端支持的action指令,然后进行战斗表现 |
| | | // 表现完毕后继续发送 B413 (ReqType 为 4) |
| | | // 后端回复 B425标记0开始 (中间N个战斗片段封包) B425标记1结束 |
| | | // 前端解析表现,然后一直循环即可 |
| | | |
| | | public enum StoryBattleState |
| | | { |
| | | Break, |
| | | Battle, |
| | | } |
| | | |
| | | public class StoryBattleField : BattleField |
| | | { |
| | | protected int chapter;// 章节 |
| | |
| | | |
| | | protected MainLevelConfig levelConfig; |
| | | |
| | | public StoryBattleState battleState; |
| | | |
| | | public StoryBattleField() : base(string.Empty) |
| | | { |
| | | |
| | | } |
| | | |
| | | public override void Init(int MapID, int FuncLineID, JsonData _extendData, |
| | | |
| | | public override void Init(int MapID, int FuncLineID, JsonData _extendData, |
| | | List<TeamBase> _redTeamList, List<TeamBase> _blueTeamList) |
| | | { |
| | | base.Init(MapID, FuncLineID, extendData, _redTeamList, _blueTeamList); |
| | | |
| | | if (null == _blueTeamList || _blueTeamList.Count == 0) |
| | | { |
| | | battleState = StoryBattleState.Break; |
| | | } |
| | | else |
| | | { |
| | | battleState = StoryBattleState.Battle; |
| | | } |
| | | |
| | | LoadBattleMode(); |
| | | |
| | |
| | | chapterConfig = MainChapterConfig.Get(chapter); |
| | | levelConfig = MainLevelConfig.Get(level); |
| | | |
| | | TeamManager.Instance.OnTeamChange += OnTeamChange; |
| | | } |
| | | |
| | | public override void Release() |
| | | { |
| | | base.Release(); |
| | | TeamManager.Instance.OnTeamChange -= OnTeamChange; |
| | | } |
| | | |
| | | protected void LoadBattleMode() |
| | |
| | | SetBattleMode((BattleMode)Enum.Parse(typeof(BattleMode), savedStr)); |
| | | } |
| | | |
| | | public override void TurnFightState(int TurnNum, int State, |
| | | public override void TurnFightState(int TurnNum, int State, |
| | | uint FuncLineID, JsonData extendData) |
| | | { |
| | | base.TurnFightState(TurnNum, State, FuncLineID, extendData); |
| | |
| | | public override void OnTurnFightState(int turnNum, int State, int FuncLineID, JsonData extendData) |
| | | { |
| | | base.OnTurnFightState(turnNum, State, FuncLineID, extendData); |
| | | |
| | | |
| | | } |
| | | |
| | | protected void OnTeamChange(TeamType teamType) |
| | | { |
| | | if (teamType == TeamType.Story) |
| | | { |
| | | if (battleState == StoryBattleState.Break) |
| | | { |
| | | ReloadTeam(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | public override void HaveRest() |
| | | { |
| | | base.HaveRest(); |
| | | battleState = StoryBattleState.Break; |
| | | } |
| | | |
| | | protected void ReloadTeam() |
| | | { |
| | | battleObjMgr.ReloadTeam(TeamManager.Instance.GetTeam(TeamType.Story), BattleCamp.Red); |
| | | } |
| | | |
| | | public override void OnBattleEnd(JsonData turnFightStateData) |
| | | { |
| | | base.OnBattleEnd(turnFightStateData); |
| | | } |
| | | |
| | | // public override void Run() |
| | |
| | | damageContentList.Add(content); |
| | | |
| | | // heroGo 的 parent 作为参考节点 |
| | | var heroGo = bo.heroGo; |
| | | if (heroGo == null) |
| | | return; |
| | | |
| | | var heroRect = heroGo.GetComponent<RectTransform>(); |
| | | var heroRect = bo.heroRectTrans; |
| | | if (heroRect == null) |
| | | return; |
| | | |
| | |
| | | using LitJson; |
| | | |
| | | |
| | | |
| | | |
| | | public class BattleManager : GameSystemManager<BattleManager> |
| | | { |
| | | public StoryBattleField storyBattleField = null; |
| | |
| | | ulong exAttr1 = PlayerDatas.Instance.GetPlayerDataByType(PlayerDataType.ExAttr1); |
| | | ulong exAttr2 = PlayerDatas.Instance.GetPlayerDataByType(PlayerDataType.ExAttr2); |
| | | |
| | | int MapID = 0; |
| | | int MapID = 1; |
| | | int FuncLineID = (int)exAttr2; |
| | | |
| | | CreateStoryBattle(MapID, FuncLineID, null, null); |
| | |
| | | { |
| | | if (null == storyBattleField) |
| | | { |
| | | storyBattleField = new StoryBattleField(); |
| | | |
| | | storyBattleField.guid = string.Empty; // 主线副本的guid为空 |
| | | var redTeamList = new List<TeamBase>(); |
| | | redTeamList.Add(TeamManager.Instance.GetTeam(TeamType.Story)); |
| | | storyBattleField.Init(MapID, FuncLineID, extendData, redTeamList, blueTeamList); |
| | | |
| | | TeamBase storyTeam = TeamManager.Instance.GetTeam(TeamType.Story); |
| | | |
| | | redTeamList.Add(storyTeam); |
| | | |
| | | CreateBattleField(string.Empty, MapID, FuncLineID, extendData, redTeamList, blueTeamList); |
| | | } |
| | | else |
| | | { |
| | | // storyBattleField |
| | | } |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | |
| | | #region 截断网络派发包 只收入当前包的后续 b425是主线的 非主线的包并不会走b425 |
| | | #region 截断网络派发包 只收入当前包的后续 b425是主线的 非主线的包并不会走b425 |
| | | private bool allow = true; |
| | | |
| | | private Queue<GameNetPackBasic> packQueue = new Queue<GameNetPackBasic>(); |
| | |
| | | |
| | | // 发送战报片段结束包 |
| | | AnalysisPackQueueAndDistribute(); |
| | | |
| | | |
| | | } |
| | | } |
| | | else |
| | |
| | | return allow; |
| | | } |
| | | |
| | | protected int continousEmptyCount = 0; // 连续空包计数 |
| | | |
| | | protected void AnalysisPackQueueAndDistribute() |
| | | { |
| | | // 建议前端做一个防范机制:当连续多次请求得到空的战斗片段封包时(不包含B425标记的开始跟结束封包,即开始跟中间没有任何封包),强制自动帮玩家回城休息, |
| | | // 原因可能前后端数据不一致bug(比如战锤可能后端没有了,前端认为还有)或者 后端有bug导致没有处理战斗 |
| | | // 为防止死循环,可强制回城休息,让玩家重新点击关卡战斗或挑战boss, |
| | | // 正常情况下在战锤足够时理论上都可以一直循环刷怪,如果连续多次没有战斗片段封包,比如限制个连续10次以内,就可以理解为异常了 |
| | | |
| | | const int MaxContinousEmptyCount = 10; // 连续空包最大次数 |
| | | |
| | | List<GameNetPackBasic> packQueueSnapshot = new List<GameNetPackBasic>(packQueue); |
| | | |
| | | List<GameNetPackBasic> newPackList = new List<GameNetPackBasic>(); |
| | | |
| | | // 这里已经是按照Dequeue的顺序了 |
| | | // 这里已经是按照Dequeue的顺序了 |
| | | for (int i = 0; i < packQueueSnapshot.Count; i++) |
| | | { |
| | | GameNetPackBasic pack = packQueueSnapshot[i]; |
| | | |
| | | // 碰到B421 截断 往下收集b421里的全部内容 |
| | | // 碰到B421 截断 往下收集b421里的全部内容 |
| | | if (pack is HB421_tagMCTurnFightObjAction) |
| | | { |
| | | HB421_tagMCTurnFightObjAction b421Pack = pack as HB421_tagMCTurnFightObjAction; |
| | | |
| | | List<GameNetPackBasic> b421PackList = new List<GameNetPackBasic>(); |
| | | |
| | | i++; // 跳过当前的B421包 |
| | | i++; // 跳过当前的B421包 |
| | | |
| | | for (; i < packQueueSnapshot.Count; i++) |
| | | { |
| | |
| | | } |
| | | } |
| | | |
| | | // 可能没用了 主要就是利用一下skill的combine 暂留 看之后还有没有别的需求 |
| | | // 可能没用了 主要就是利用一下skill的combine 暂留 看之后还有没有别的需求 |
| | | CustomB421ActionPack actionPack = CustomB421ActionPack.CreateB421ActionPack(GetGUID(b421Pack.packUID), b421PackList); |
| | | |
| | | while (actionPack.actionPacks.Count > 0) |
| | |
| | | } |
| | | } |
| | | |
| | | // 防范机制:连续多次没有战斗片段封包时自动回城 |
| | | if (newPackList.Count == 0) |
| | | { |
| | | continousEmptyCount++; |
| | | Debug.LogWarning($"连续空战斗片段封包次数:{continousEmptyCount}"); |
| | | if (continousEmptyCount >= MaxContinousEmptyCount) |
| | | { |
| | | Debug.LogError("连续多次没有战斗片段封包,自动回城休息!"); |
| | | MainFightRequest(0); // 0-停止战斗回城 |
| | | continousEmptyCount = 0; |
| | | packQueue.Clear(); |
| | | return; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | continousEmptyCount = 0; // 有包就重置 |
| | | } |
| | | |
| | | // b421跟b426的包已经处理完了 |
| | | // b421跟b426的包已经处理完了 |
| | | packQueue = new Queue<GameNetPackBasic>(newPackList); |
| | | |
| | | DistributeNextPackage(); |
| | |
| | | } |
| | | } |
| | | |
| | | #endregion |
| | | #endregion |
| | | |
| | | #region 战报部分 |
| | | #region 战报部分 |
| | | |
| | | protected Dictionary<string, Queue<GameNetPackBasic>> battleReportDict = new Dictionary<string, Queue<GameNetPackBasic>>(); |
| | | |
| | |
| | | { |
| | | BattleField battleField = null; |
| | | battleFields.TryGetValue(guid, out battleField); |
| | | if (battleField == null) |
| | | { |
| | | battleField = storyBattleField; |
| | | } |
| | | return battleField; |
| | | } |
| | | |
| | |
| | | if (kv.Value.Contains(packUID)) |
| | | { |
| | | return kv.Key; |
| | | } |
| | | } |
| | | } |
| | | return string.Empty; |
| | | } |
| | |
| | | battlePackRelationList.Remove(guid); |
| | | } |
| | | } |
| | | #endregion |
| | | #endregion |
| | | |
| | | public BattleField CreateBattleField(string guid, int MapID, int FuncLineID, JsonData extendData, List<TeamBase> redTeamList, List<TeamBase> blueTeamList) |
| | | { |
| | |
| | | battleField.Destroy(); |
| | | } |
| | | |
| | | battleField = BattleFieldFactory.CreateBattleField(guid, MapID, FuncLineID, extendData, redTeamList, blueTeamList); |
| | | |
| | | if (string.IsNullOrEmpty(guid)) |
| | | { |
| | | battleField = storyBattleField; |
| | | } |
| | | else |
| | | { |
| | | battleField = BattleFieldFactory.CreateBattleField(guid, MapID, FuncLineID, extendData, redTeamList, blueTeamList); |
| | | storyBattleField = (StoryBattleField)battleField; |
| | | } |
| | | |
| | | battleFields.Add(guid, battleField); |
| | |
| | | } |
| | | |
| | | |
| | | // public void OnTurnFightObjAction(battleType, vNetData.TurnNum, (int)vNetData.ObjID) |
| | | // 目前支持 BYTE ReqType; // 0-停止战斗回城;1-设置消耗倍值;2-挑战关卡小怪;3-挑战关卡boss;4-继续战斗; |
| | | // 0-停止战斗回城 - 玩家主动点击回城时发送 |
| | | // 1-设置消耗倍值 - 玩家设置消耗倍值,对应到玩家FightPoint的值 |
| | | // 2-挑战关卡小怪 - 玩家点击开始战斗时发送,仅从休息状态到开始战斗时发送即可 |
| | | // 3-挑战关卡boss - 玩家请求挑战该关卡boss时发送 |
| | | // 4-继续战斗 - 玩家主线战斗中(包含主线小怪、主线boss),前端表现完后端同步的战斗片段后,可再回复该值,后端会根据战斗逻辑及流程自动回复下一段的战斗片段封包,一直循环 |
| | | public void MainFightRequest(byte reqType, uint reqValue = 0) |
| | | { |
| | | CB413_tagCSMainFightReq req = new CB413_tagCSMainFightReq(); |
| | | req.ReqType = reqType; |
| | | req.ReqValue = reqValue; |
| | | |
| | | GameNetSystem.Instance.SendInfo(req); |
| | | } |
| | | |
| | | |
| | | public void Run() |
| | | { |
| | | if (null != storyBattleField) |
| | | { |
| | | storyBattleField.Run(); |
| | | } |
| | | // if (null != storyBattleField) |
| | | // { |
| | | // storyBattleField.Run(); |
| | | // } |
| | | |
| | | foreach (var battleField in battleFields) |
| | | { |
| | |
| | | public void Init(BattleField _battleField, TeamBase _redTeam, TeamBase _blueTeam) |
| | | { |
| | | battleField = _battleField; |
| | | CreateTeam(battleField.battleRootNode.redTeamNodeList, redCampDict, _redTeam, BattleCamp.Red); |
| | | CreateTeam(battleField.battleRootNode.blueTeamNodeList, blueCampDict, _blueTeam, BattleCamp.Blue); |
| | | ReloadTeam(_redTeam, BattleCamp.Red); |
| | | ReloadTeam(_blueTeam, BattleCamp.Blue); |
| | | } |
| | | |
| | | public void ReloadTeam(TeamBase teamBase, BattleCamp _camp) |
| | | { |
| | | var posNodeList = _camp == BattleCamp.Red ? battleField.battleRootNode.redTeamNodeList : battleField.battleRootNode.blueTeamNodeList; |
| | | var campDict = _camp == BattleCamp.Red ? redCampDict : blueCampDict; |
| | | CreateTeam(posNodeList, campDict, teamBase, _camp); |
| | | } |
| | | |
| | | protected void CreateTeam(List<GameObject> posNodeList, Dictionary<int, BattleObject> campDict, TeamBase teamBase, BattleCamp _Camp) |
| | | { |
| | |
| | | return; |
| | | } |
| | | |
| | | |
| | | for (int i = 0; i < teamBase.serverHeroes.Length; i++) |
| | | { |
| | | TeamHero teamHero = teamBase.serverHeroes[i]; |
| | | if (teamHero != null) |
| | | { |
| | | |
| | | BattleObject battleObj = BattleObjectFactory.CreateBattleObject(battleField, posNodeList, teamHero, _Camp); |
| | | if (battleObj.ObjID == 0) |
| | | continue; |
| | | allBattleObjDict.Add(battleObj.ObjID, battleObj); |
| | | campDict.Add(teamHero.positionNum, battleObj); |
| | | } |
| | |
| | | return retList; |
| | | } |
| | | |
| | | public void DestroyTeam(BattleCamp battleCamp) |
| | | { |
| | | Dictionary<int, BattleObject> campDict = battleCamp == BattleCamp.Red ? redCampDict : blueCampDict; |
| | | if (campDict == null) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | DestroyTeam(campDict); |
| | | } |
| | | |
| | | public void DestroyObjIds(uint[] objIDs) |
| | | { |
| | | if (objIDs == null || objIDs.Length == 0) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | foreach (var objID in objIDs) |
| | | { |
| | | if (allBattleObjDict.TryGetValue((int)objID, out BattleObject battleObj)) |
| | | { |
| | | allBattleObjDict.Remove((int)objID); |
| | | redCampDict.Remove((int)objID); |
| | | blueCampDict.Remove((int)objID); |
| | | BattleObjectFactory.DestroyBattleObject((int)objID, battleObj); |
| | | } |
| | | } |
| | | } |
| | | |
| | | protected void DestroyTeam(Dictionary<int, BattleObject> campDict) |
| | | { |
| | | foreach (var item in campDict) |
| | |
| | | } |
| | | } |
| | | campDict.Clear(); |
| | | |
| | | } |
| | | |
| | | // 空闲状态 |
| | | public void HaveRest(BattleCamp _Camp) |
| | | public virtual void HaveRest(BattleCamp _Camp) |
| | | { |
| | | // 休息状态 |
| | | if (_Camp == BattleCamp.Red) |
| | |
| | | } |
| | | } |
| | | |
| | | public void Release() |
| | | public virtual void Release() |
| | | { |
| | | DestroyTeam(redCampDict); |
| | | DestroyTeam(blueCampDict); |
| | |
| | | private set; |
| | | } |
| | | |
| | | private RectTransform m_heroRectTrans; |
| | | |
| | | public RectTransform heroRectTrans |
| | | { |
| | | get |
| | | { |
| | | if (m_heroRectTrans == null) |
| | | { |
| | | m_heroRectTrans = heroGo.GetComponent<RectTransform>(); |
| | | } |
| | | return m_heroRectTrans; |
| | | } |
| | | } |
| | | |
| | | protected Action onDeathAnimationComplete; |
| | | |
| | | protected Renderer[] renderers; |
| | | |
| | | public Transform effectNode; |
| | | |
| | | private List<HB405_tagMCAddExp> hB405_tagMCAddExps = new List<HB405_tagMCAddExp>(); |
| | | |
| | | public BattleObject(BattleField _battleField) |
| | | { |
| | |
| | | |
| | | public virtual void Destroy() |
| | | { |
| | | if (heroGo != null) |
| | | { |
| | | GameObject.DestroyImmediate(heroGo); |
| | | heroGo = null; |
| | | } |
| | | |
| | | motionBase.onAnimationComplete -= OnAnimationComplete; |
| | | |
| | | motionBase.Release(); |
| | | motionBase = null; |
| | | teamHero = null; |
| | | ObjID = 0; |
| | | motionBase.onAnimationComplete -= OnAnimationComplete; |
| | | |
| | | if (heroGo != null) |
| | | { |
| | | GameObject.DestroyImmediate(heroGo); |
| | | heroGo = null; |
| | | } |
| | | } |
| | | |
| | | public void OnObjInfoRefresh(H0418_tagObjInfoRefresh _refreshInfo) |
| | |
| | | return true; |
| | | } |
| | | |
| | | public virtual void Hurt(List<long> damageValues, int attackType) |
| | | public virtual void Hurt(List<long> damageValues, long _totalDamage, int attackType) |
| | | { |
| | | PopDamage(teamHero.curHp, damageValues, attackType); |
| | | |
| | | motionBase.PlayAnimation(MotionName.hit, false); |
| | | |
| | | // 计算伤害 |
| | | long totalDamage = 0; |
| | | foreach (var damage in damageValues) |
| | | { |
| | | totalDamage += damage; |
| | | } |
| | | |
| | | // 扣血 |
| | | teamHero.curHp -= totalDamage; |
| | | teamHero.curHp -= _totalDamage; |
| | | } |
| | | |
| | | // 闪避开始 |
| | | public virtual void OnDodgeBegin() |
| | | { |
| | | float pingpongTime = 0.2f; |
| | | RectTransform rectTrans = heroGo.GetComponent<RectTransform>(); |
| | | RectTransform rectTrans = heroRectTrans; |
| | | var tween = rectTrans.DOAnchorPos(new Vector3(-50, 50, 0), pingpongTime) |
| | | .SetEase(Ease.OutCubic); |
| | | |
| | |
| | | public virtual void OnDodgeEnd() |
| | | { |
| | | float pingpongTime = 0.2f; |
| | | RectTransform rectTrans = heroGo.GetComponent<RectTransform>(); |
| | | RectTransform rectTrans = heroRectTrans; |
| | | |
| | | var tween = rectTrans.DOAnchorPos(Vector3.zero, pingpongTime) |
| | | .SetEase(Ease.OutCubic); |
| | |
| | | heroGo.SetActive(false); |
| | | } |
| | | |
| | | public void OnReborn(HB423_tagMCTurnFightObjReborn vNetData) |
| | | { |
| | | // 处理复活逻辑 |
| | | teamHero.curHp = GeneralDefine.GetFactValue(vNetData.HP, vNetData.HPEx); |
| | | heroGo.SetActive(true); |
| | | motionBase.PlayAnimation(MotionName.idle, true); |
| | | } |
| | | |
| | | // 伤害还要看 是否闪避 暴击 and so on 需要有一个DamageType 服务器应该会给 |
| | | protected virtual void PopDamage(long curHp, List<long> damageValues, int attackType) |
| | | { |
| | |
| | | Debug.Log($"Damage: {damage}"); |
| | | } |
| | | |
| | | // YYL TODO 是否需要挂在在自身的follow点上 |
| | | EventBroadcast.Instance.Broadcast(EventName.BATTLE_DAMAGE_TAKEN, battleField.guid, this, damageValues); |
| | | } |
| | | |
| | |
| | | // YYL TODO |
| | | // 休息状态 |
| | | // 多一个zzz的一个特效 |
| | | |
| | | motionBase.PlayAnimation(MotionName.idle, true); |
| | | } |
| | | |
| | | public void PushExpPackList(List<HB405_tagMCAddExp> _hB405_tagMCAddExps) |
| | | { |
| | | // YYL TODO 死亡后弹出经验掉落提醒 |
| | | hB405_tagMCAddExps = _hB405_tagMCAddExps; |
| | | } |
| | | |
| | | public void DropExp() |
| | | { |
| | | // YYL TODO |
| | | // hB405_tagMCAddExps |
| | | } |
| | | |
| | | |
| | | |
| | | #if UNITY_EDITOR_STOP_USING |
| | | public void EditorRevive() |
| | | { |
| | |
| | | |
| | | tween.Play(); |
| | | } |
| | | |
| | | public void HaveRest() |
| | | { |
| | | foreach (var tween in tweenList) |
| | | { |
| | | if (tween != null && !tween.IsComplete()) |
| | | { |
| | | tween.Kill(); |
| | | } |
| | | } |
| | | tweenList.Clear(); |
| | | } |
| | | } |
| | |
| | | .OnComplete(() => onComplete?.Invoke()); |
| | | } |
| | | |
| | | public static string DisplayDamageNum(long num, int attackType) |
| | | { |
| | | var basePowerStr = UIHelper.ReplaceLargeArtNum(num); |
| | | var result = string.Empty; |
| | | for (int i = 0; i < basePowerStr.Length; i++) |
| | | { |
| | | var numChar = (char)GetDamageNumKey((DamageType)attackType, basePowerStr[i]); |
| | | if (numChar > 0) |
| | | { |
| | | result += numChar; |
| | | } |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | public static int GetDamageNumKey(DamageType damageType, int _num) |
| | | { |
| | | var config = DamageNumConfig.Get(damageType.ToString()); |
| | | //.的ASCII码是46 |
| | | if (_num == 46) |
| | | { |
| | | return config.nums[10]; |
| | | } |
| | | //k的ASCII码是107 |
| | | else if (_num == 107) |
| | | { |
| | | return config.nums[11]; |
| | | } |
| | | //m的ASCII码是109 |
| | | else if (_num == 109) |
| | | { |
| | | return config.nums[12]; |
| | | } |
| | | //b的ASCII码是98 |
| | | else if (_num == 98) |
| | | { |
| | | return config.nums[13]; |
| | | } |
| | | //t的ASCII码是116 |
| | | else if (_num == 116) |
| | | { |
| | | return config.nums[14]; |
| | | } |
| | | return config.nums[_num - 48]; |
| | | } |
| | | |
| | | } |
| | |
| | | |
| | | private void PauseGame() |
| | | { |
| | | Debug.LogError("PauseeGame"); |
| | | if (null == battleField) |
| | | return; |
| | | // Debug.LogError("PauseeGame"); |
| | | // if (null == battleField) |
| | | // return; |
| | | |
| | | battleField.IsPause = !battleField.IsPause; |
| | | // battleField.IsPause = !battleField.IsPause; |
| | | |
| | | Debug.LogError(" is pause " + battleField.IsPause.ToString()); |
| | | // Debug.LogError(" is pause " + battleField.IsPause.ToString()); |
| | | |
| | | if (battleField != null) |
| | | { |
| | | battleField.operationAgent.DoNext(); |
| | | } |
| | | } |
| | | |
| | | protected override void OnPreOpen() |
| | |
| | | |
| | | public enum DamageType |
| | | { |
| | | Normal, //普通伤害 |
| | | Dodge, //闪避 |
| | | Heal, //治疗 |
| | | Continuous,//持续伤害 |
| | | Block, //格挡 |
| | | ReverseInjury,//反伤 |
| | | Recovery, //吸血 |
| | | Crit, //暴击 |
| | | Combo, //连击 |
| | | Stuned, //击晕 |
| | | Damage, //普通伤害 |
| | | Recovery, //治疗 |
| | | Reflect, //反弹伤害 |
| | | Bloody, //流血伤害 |
| | | Block, //格挡 |
| | | Critical, //暴击 |
| | | Dodge, //闪避 |
| | | Combo, //连击 |
| | | CounterAttack, //反击 |
| | | RageUp, //怒气提升 |
| | | |
| | | |
| | | } |
| | |
| | | { |
| | | |
| | | } |
| | | |
| | | public void HaveRest() |
| | | { |
| | | currentRecordAction = null; |
| | | recordActionQueue.Clear(); |
| | | } |
| | | } |
| | |
| | | base.OnHitTargets(_hitIndex, hitList); |
| | | } |
| | | |
| | | protected override void OnHitEachTarget(BattleObject target, List<long> damageList, ref H0604_tagUseSkillAttack.tagSkillHurtObj hurt) |
| | | protected override void OnHitEachTarget(BattleObject target, long totalDamage, List<long> damageList, ref H0604_tagUseSkillAttack.tagSkillHurtObj hurt) |
| | | { |
| | | base.OnHitEachTarget(target, damageList, ref hurt); |
| | | base.OnHitEachTarget(target, totalDamage, damageList, ref hurt); |
| | | } |
| | | |
| | | |
New file |
| | |
| | | |
| | | using System.Collections.Generic; |
| | | using UnityEngine; |
| | | using System; |
| | | using System.Linq; |
| | | |
| | | public class DirectlyHealSkill : SkillBase |
| | | { |
| | | protected SkillEffect skillEffect; |
| | | |
| | | public DirectlyHealSkill(BattleObject _caster, SkillConfig _skillCfg, |
| | | H0604_tagUseSkillAttack _vNetData, List<GameNetPackBasic> _packList, BattleField _battleField) |
| | | : base(_caster, _skillCfg, _vNetData, _packList, _battleField) |
| | | { |
| | | foreach (var pack in packList) |
| | | { |
| | | Debug.LogError("directly heal skill pack type is " + pack.GetType()); |
| | | } |
| | | } |
| | | |
| | | public override void Run() |
| | | { |
| | | if (null != skillEffect) |
| | | { |
| | | skillEffect.Run(); |
| | | } |
| | | |
| | | base.Run(); |
| | | } |
| | | |
| | | |
| | | // 技能动画播放完毕 |
| | | protected override void DoSkillLogic(Action _onComplete = null) |
| | | { |
| | | // if (skillConfig.EffectId > 0) |
| | | // { |
| | | // // 播放技能特效 |
| | | // caster.battleField.battleEffectMgr.PlayEffect( |
| | | // caster.ObjID, |
| | | // skillConfig.EffectId, |
| | | // caster.heroGo.transform |
| | | // ); |
| | | // } |
| | | |
| | | _onComplete?.Invoke(); |
| | | } |
| | | |
| | | // 前摇结束 |
| | | protected override void OnStartSkillFrame() |
| | | { |
| | | skillEffect = SkillEffectFactory.CreateSkillEffect( |
| | | caster, |
| | | skillConfig, |
| | | tagUseSkillAttack |
| | | ); |
| | | if (skillEffect != null) |
| | | { |
| | | skillEffect.Play(OnHitTargets); |
| | | } |
| | | } |
| | | |
| | | protected override void OnHitTargets(int _healIndex, List<H0604_tagUseSkillAttack.tagSkillHurtObj> healList) |
| | | { |
| | | base.OnHitTargets(_healIndex, healList); |
| | | } |
| | | |
| | | protected override void OnHitEachTarget(BattleObject target, long totalDamage, List<long> damageList, ref H0604_tagUseSkillAttack.tagSkillHurtObj hurt) |
| | | { |
| | | base.OnHitEachTarget(target, totalDamage, damageList, ref hurt); |
| | | } |
| | | |
| | | |
| | | // 中摇结束 |
| | | protected override void OnActiveSkillFrame() |
| | | { |
| | | |
| | | } |
| | | |
| | | // 后摇结束 |
| | | protected override void OnEndSkillFrame() |
| | | { |
| | | |
| | | } |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 38e775dae78a7c9418366ae4f0f6514e |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | |
| | | using System.Collections.Generic; |
| | | using UnityEngine; |
| | | using System; |
| | | using System.Linq; |
| | | |
| | | public class RebornSkill : SkillBase |
| | | { |
| | | protected SkillEffect skillEffect; |
| | | |
| | | public RebornSkill(BattleObject _caster, SkillConfig _skillCfg, |
| | | H0604_tagUseSkillAttack _vNetData, List<GameNetPackBasic> _packList, BattleField _battleField) |
| | | : base(_caster, _skillCfg, _vNetData, _packList, _battleField) |
| | | { |
| | | |
| | | } |
| | | |
| | | public override void Run() |
| | | { |
| | | if (null != skillEffect) |
| | | { |
| | | skillEffect.Run(); |
| | | } |
| | | |
| | | base.Run(); |
| | | } |
| | | |
| | | |
| | | // 技能动画播放完毕 |
| | | protected override void DoSkillLogic(Action _onComplete = null) |
| | | { |
| | | // if (skillConfig.EffectId > 0) |
| | | // { |
| | | // // 播放技能特效 |
| | | // caster.battleField.battleEffectMgr.PlayEffect( |
| | | // caster.ObjID, |
| | | // skillConfig.EffectId, |
| | | // caster.heroGo.transform |
| | | // ); |
| | | // } |
| | | |
| | | _onComplete?.Invoke(); |
| | | } |
| | | |
| | | // 前摇结束 |
| | | protected override void OnStartSkillFrame() |
| | | { |
| | | skillEffect = SkillEffectFactory.CreateSkillEffect( |
| | | caster, |
| | | skillConfig, |
| | | tagUseSkillAttack |
| | | ); |
| | | if (skillEffect != null) |
| | | { |
| | | skillEffect.Play(OnHitTargets); |
| | | } |
| | | } |
| | | |
| | | protected override void OnHitTargets(int _hitIndex, List<H0604_tagUseSkillAttack.tagSkillHurtObj> hitList) |
| | | { |
| | | base.OnHitTargets(_hitIndex, hitList); |
| | | } |
| | | |
| | | protected override void OnHitEachTarget(BattleObject target, long totalDamage, List<long> damageList, ref H0604_tagUseSkillAttack.tagSkillHurtObj hurt) |
| | | { |
| | | base.OnHitEachTarget(target, totalDamage, damageList, ref hurt); |
| | | } |
| | | |
| | | |
| | | // 中摇结束 |
| | | protected override void OnActiveSkillFrame() |
| | | { |
| | | |
| | | } |
| | | |
| | | // 后摇结束 |
| | | protected override void OnEndSkillFrame() |
| | | { |
| | | |
| | | } |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 88762e1ee728ecd45808b8759a3431ca |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
| | |
| | | |
| | | protected SkillBase otherSkill; |
| | | |
| | | protected List<H0704_tagRolePackRefresh> dropPackList = new List<H0704_tagRolePackRefresh>(); |
| | | |
| | | protected List<HB405_tagMCAddExp> expPackList = new List<HB405_tagMCAddExp>(); |
| | | |
| | | public SkillBase(BattleObject _caster, SkillConfig _skillCfg, H0604_tagUseSkillAttack vNetData, List<GameNetPackBasic> _packList, BattleField _battleField = null) |
| | | { |
| | | caster = _caster; |
| | |
| | | PlayCastAnimation(() => DoSkillLogic(OnSkillFinished)); |
| | | break; |
| | | case SkillCastMode.Enemy: |
| | | MoveToTarget(caster.GetEnemyCamp(), skillConfig.CastIndexNum, _onComplete: () => TurnBack(() => PlayCastAnimation(() => DoSkillLogic(() => { BackToOrigin(OnSkillFinished); })))); |
| | | MoveToTarget(caster.GetEnemyCamp(), skillConfig, _onComplete: () => TurnBack(() => PlayCastAnimation(() => DoSkillLogic(() => { BackToOrigin(OnSkillFinished); })))); |
| | | break; |
| | | case SkillCastMode.Target: |
| | | // 目标是敌方主目标 |
| | |
| | | OnSkillFinished(); |
| | | return; |
| | | } |
| | | MoveToTarget(mainTarget.Camp, mainTarget.teamHero.positionNum, _onComplete: () => TurnBack(() => PlayCastAnimation(() => DoSkillLogic(() => { BackToOrigin(OnSkillFinished); })))); |
| | | MoveToTarget(mainTarget.Camp, mainTarget, _onComplete: () => TurnBack(() => PlayCastAnimation(() => DoSkillLogic(() => { BackToOrigin(OnSkillFinished); })))); |
| | | break; |
| | | case SkillCastMode.Allies: |
| | | MoveToTarget(caster.Camp, skillConfig.CastIndexNum, _onComplete: () => TurnBack(() => PlayCastAnimation(() => DoSkillLogic(() => { BackToOrigin(OnSkillFinished); })))); |
| | | MoveToTarget(caster.Camp, skillConfig, _onComplete: () => TurnBack(() => PlayCastAnimation(() => DoSkillLogic(() => { BackToOrigin(OnSkillFinished); })))); |
| | | break; |
| | | // case SkillCastMode.DashCast: |
| | | // DashToTarget(() => BackToOrigin(OnSkillFinished)); |
| | |
| | | OnActiveSkillFrame);//攻击中摇结束 |
| | | } |
| | | |
| | | public void MoveToTarget(BattleCamp camp, int index, float duration = 0.2f, Action _onComplete = null) |
| | | public void MoveToTarget(BattleCamp camp, BattleObject target, float duration = 0.2f, Action _onComplete = null) |
| | | { |
| | | // GetTargetNode(); |
| | | targetNode = battleField.GetTeamNode(camp, index); |
| | | targetNode = battleField.GetTeamNode(camp, target); |
| | | |
| | | Vector2 offset = new Vector2(skillConfig.CastDistance, 0); |
| | | RectTransform selfRect = caster.heroGo.transform as RectTransform; |
| | | RectTransform selfRect = caster.heroRectTrans; |
| | | RectTransform targetRect = targetNode; |
| | | |
| | | var tweener = BattleUtility.MoveToTarget(selfRect, targetRect, offset, duration, _onComplete); |
| | | battleField.battleTweenMgr.OnPlayTween(tweener); |
| | | } |
| | | |
| | | public void MoveToTarget(BattleCamp camp, SkillConfig skillCfg, float duration = 0.2f, Action _onComplete = null) |
| | | { |
| | | targetNode = battleField.GetTeamNode(camp, skillCfg); |
| | | |
| | | Vector2 offset = new Vector2(skillConfig.CastDistance, 0); |
| | | RectTransform selfRect = caster.heroRectTrans; |
| | | RectTransform targetRect = targetNode; |
| | | |
| | | var tweener = BattleUtility.MoveToTarget(selfRect, targetRect, offset, duration, _onComplete); |
| | |
| | | |
| | | public void BackToOrigin(Action _onComplete = null) |
| | | { |
| | | RectTransform selfRect = caster.heroGo.transform as RectTransform; |
| | | RectTransform selfRect = caster.heroRectTrans; |
| | | Vector2 targetAnchoredPos = Vector2.zero; |
| | | var tween = selfRect.DOAnchorPos(targetAnchoredPos, 0.2f) |
| | | .SetEase(Ease.Linear) |
| | |
| | | // 高亮所有目标 |
| | | HashSet<BattleObject> highlightList = new HashSet<BattleObject>(battleField.battleObjMgr.GetBattleObjList(tagUseSkillAttack)); |
| | | highlightList.Add(caster); |
| | | |
| | | |
| | | |
| | | // 把这些BO全高亮 或者说把除了这些的都放在遮罩后面 |
| | |
| | | continue; |
| | | } |
| | | |
| | | // 伤害结算 |
| | | // 伤害分布 (万分比) |
| | | int[] damageDivide = skillConfig.DamageDivide[_hitIndex]; |
| | | |
| | | List<long> damageList = new List<long>(); |
| | | |
| | | long totalDamage = GeneralDefine.GetFactValue(hurt.HurtHP, hurt.HurtHPEx); |
| | | |
| | | for (int j = 0; j < damageDivide.Length; j++) |
| | | { |
| | | long damage = totalDamage * damageDivide[j] / 10000; |
| | | damageList.Add(damage); |
| | | } |
| | | // 保证所有分配项加起来等于totalDamage,避免因整除导致的误差 |
| | | List<long> damageList = DivideDamageToList(damageDivide, totalDamage); |
| | | |
| | | OnHitEachTarget(target, damageList, ref hurt); |
| | | OnHitEachTarget(target, totalDamage, damageList, ref hurt); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 保证所有分配项加起来等于totalDamage,避免因整除导致的误差 |
| | | /// </summary> |
| | | protected List<long> DivideDamageToList(int[] damageDivide, long totalDamage) |
| | | { |
| | | List<long> fixedDamageList = new List<long>(); |
| | | long assigned = 0; |
| | | int count = damageDivide.Length; |
| | | |
| | | for (int i = 0; i < count; i++) |
| | | { |
| | | long damage; |
| | | if (i == count - 1) |
| | | { |
| | | // 最后一个分配项修正为剩余 |
| | | damage = totalDamage - assigned; |
| | | } |
| | | else |
| | | { |
| | | damage = (totalDamage * damageDivide[i] + 5000) / 10000; // 四舍五入 |
| | | assigned += damage; |
| | | } |
| | | fixedDamageList.Add(damage); |
| | | } |
| | | return fixedDamageList; |
| | | } |
| | | |
| | | protected virtual void OnHitEachTarget(BattleObject target, List<long> damageList, ref H0604_tagUseSkillAttack.tagSkillHurtObj hurt) |
| | | protected virtual void OnHitEachTarget(BattleObject target, long totalDamage, List<long> damageList, ref H0604_tagUseSkillAttack.tagSkillHurtObj hurt) |
| | | { |
| | | target.Hurt(damageList, hurt.AttackType); |
| | | target.Hurt(damageList, totalDamage, hurt.AttackType); |
| | | |
| | | // 击中目标的时候,不管近战远程 都确认一下是否有爆炸特效 然后播放 |
| | | // 击中目标的时候,不管近战远程 都确认一下是否有爆炸特效 然后播放 |
| | | if (skillConfig.ExplosionEffectId > 0) |
| | | { |
| | | // 播放爆炸特效 |
| | |
| | | target.heroGo.transform |
| | | ); |
| | | } |
| | | |
| | | // 受伤之后辨别死亡状态 死亡包其实前后帧会多次触发 应该要即时remove其他的包来保证不重复 |
| | | if (target.IsDead()) |
| | | { |
| | | // SkillRecordAction里的drop事件前移到dead之后 |
| | | HB422_tagMCTurnFightObjDead deadPack = FindDeadPack(target); |
| | | CheckAfterDeadhPack(target, deadPack); |
| | | if (deadPack != null) |
| | | { |
| | | // 处理掉落包 |
| | | for (int i = 0; i < dropPackList.Count; i++) |
| | | { |
| | | PackageRegedit.Distribute(dropPackList[i]); |
| | | } |
| | | |
| | | dropPackList.Clear(); |
| | | |
| | | target.PushExpPackList(new List<HB405_tagMCAddExp>(expPackList)); |
| | | |
| | | expPackList.Clear(); |
| | | |
| | | // 处理死亡包 |
| | | PackageRegedit.Distribute(deadPack); |
| | | packList.Remove(deadPack); |
| | | } |
| | | |
| | | // 复活包暂时不管 可能是技能的包 |
| | | // HB423_tagMCTurnFightObjReborn rebornPack = FindRebornPack(target); |
| | | // if (rebornPack != null) |
| | | // { |
| | | // // 处理复活包 |
| | | // PackageRegedit.Distribute(rebornPack); |
| | | // packList.Remove(rebornPack); |
| | | // } |
| | | } |
| | | } |
| | | |
| | | protected HB423_tagMCTurnFightObjReborn FindRebornPack(BattleObject target) |
| | | { |
| | | HB423_tagMCTurnFightObjReborn rebornPack = null; |
| | | for (int i = 0; i < packList.Count; i++) |
| | | { |
| | | var pack = packList[i]; |
| | | if (pack is HB423_tagMCTurnFightObjReborn) |
| | | { |
| | | rebornPack = pack as HB423_tagMCTurnFightObjReborn; |
| | | if (rebornPack.ObjID == target.ObjID) |
| | | { |
| | | return rebornPack; |
| | | } |
| | | } |
| | | else if (pack is CustomHB426CombinePack) |
| | | { |
| | | var combinePack = pack as CustomHB426CombinePack; |
| | | if (combinePack.startTag.Tag.StartsWith("Skill_")) |
| | | { |
| | | break; // 找到技能包就不需要再处理了 |
| | | } |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | protected HB422_tagMCTurnFightObjDead FindDeadPack(BattleObject target) |
| | | { |
| | | HB422_tagMCTurnFightObjDead deadPack = null; |
| | | for (int i = 0; i < packList.Count; i++) |
| | | { |
| | | var pack = packList[i]; |
| | | // 寻找死亡包 找到死亡包之后要找掉落包 不能超过技能包 |
| | | if (pack is HB422_tagMCTurnFightObjDead) |
| | | { |
| | | deadPack = pack as HB422_tagMCTurnFightObjDead; |
| | | if (deadPack.ObjID == target.ObjID) |
| | | { |
| | | return deadPack; |
| | | } |
| | | } |
| | | else if (pack is CustomHB426CombinePack) |
| | | { |
| | | // 找死亡包不要越过技能包 |
| | | var combinePack = pack as CustomHB426CombinePack; |
| | | if (combinePack.startTag.Tag.StartsWith("Skill_")) |
| | | { |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | protected void CheckAfterDeadhPack(BattleObject target, HB422_tagMCTurnFightObjDead deadPack) |
| | | { |
| | | if (null == deadPack) |
| | | { |
| | | return; |
| | | } |
| | | var deadPackIndex = packList.IndexOf(deadPack); |
| | | if (deadPackIndex < 0) |
| | | { |
| | | return; |
| | | } |
| | | List<int> removeIndexList = new List<int>(); |
| | | for (int i = deadPackIndex + 1; i < packList.Count; i++) |
| | | { |
| | | var pack = packList[i]; |
| | | |
| | | // 复活基本都靠技能包 |
| | | if (pack is CustomHB426CombinePack) |
| | | { |
| | | var combinePack = pack as CustomHB426CombinePack; |
| | | if (combinePack.startTag.Tag.StartsWith("Skill_")) |
| | | { |
| | | break; // 找到技能包就不需要再处理了 |
| | | } |
| | | } |
| | | else if (pack is H0704_tagRolePackRefresh) |
| | | { |
| | | var h0704Pack = pack as H0704_tagRolePackRefresh; |
| | | if (h0704Pack.PackType == (byte)PackType.DropItem) |
| | | { |
| | | // 掉落的 |
| | | if (h0704Pack.IsBind == 1) |
| | | { |
| | | // 掉落的物品 |
| | | dropPackList.Add(h0704Pack); |
| | | removeIndexList.Add(i); |
| | | } |
| | | else if (h0704Pack.IsBind == 0) |
| | | { |
| | | // 替换的 |
| | | } |
| | | } |
| | | } |
| | | else if (pack is HB405_tagMCAddExp) |
| | | { |
| | | var h405Pack = pack as HB405_tagMCAddExp; |
| | | |
| | | //B4 05 获得经验 #tagMCAddExp 通知获得的经验, |
| | | //可用于做经验获得表现 Source = 2 时为主线击杀怪物获得经验 |
| | | if (h405Pack.Source == 2) |
| | | { |
| | | expPackList.Add(h405Pack); |
| | | removeIndexList.Add(i); |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
| | | for (int i = removeIndexList.Count - 1; i >= 0; i--) |
| | | { |
| | | packList.RemoveAt(removeIndexList[i]); |
| | | } |
| | | } |
| | | public virtual bool IsFinished() |
| | | { |
| | | return isFinished; |
| | |
| | | Debug.LogError("子弹的目标是自己,暂时不支持 协商程序完成"); |
| | | break; |
| | | case SkillCastMode.Enemy: |
| | | var targetNode = caster.battleField.GetTeamNode(caster.GetEnemyCamp(), skillConfig.CastIndexNum); |
| | | var targetNode = caster.battleField.GetTeamNode(caster.GetEnemyCamp(), skillConfig); |
| | | ShotToFormation(targetNode, onHitFormation); |
| | | break; |
| | | case SkillCastMode.Target: |
| | |
| | | } |
| | | break; |
| | | case SkillCastMode.Allies: |
| | | var healNode = caster.battleField.GetTeamNode(caster.Camp, skillConfig.CastIndexNum); |
| | | var healNode = caster.battleField.GetTeamNode(caster.Camp, skillConfig); |
| | | ShotToFormation(healNode, onHitFormation); |
| | | break; |
| | | default: |
| | |
| | | EffectPlayer effectPlayer = caster.battleField.battleEffectMgr.PlayEffect(caster.ObjID, skillConfig.BulletEffectId, caster.effectNode); |
| | | RectTransform effectTrans = effectPlayer.transform as RectTransform; |
| | | |
| | | var bulletCurve = BulletCurveFactory.CreateBulletCurve(caster, skillConfig, effectPlayer, target.heroGo.transform as RectTransform, tagUseSkillAttack, (index, hitList) => |
| | | var bulletCurve = BulletCurveFactory.CreateBulletCurve(caster, skillConfig, effectPlayer, target.heroRectTrans, tagUseSkillAttack, (index, hitList) => |
| | | { |
| | | // 击中就销毁子弹 子弹不需要自动销毁 配置表里autoDestroy为false |
| | | caster.battleField.battleEffectMgr.RemoveEffect(skillConfig.BulletEffectId, effectPlayer); |
| | |
| | | }
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | | /// <param name="packType 背包类型"></param>
|
| | | /// <param name="itemId 物品ID"></param>
|
| | | /// <param name="needCount 需要数量"></param>
|
| | | /// <param name="needTips 是否需要提示"></param>
|
| | | /// <returns></returns>
|
| | | public static bool CheckItemCount(PackType packType, int itemId, int needCount, bool needTips)
|
| | | {
|
| | | if (needCount <= 0)
|
| | | {
|
| | | return true;
|
| | | }
|
| | |
|
| | | int haveCount = PackManager.Instance.GetItemCountByID(packType, itemId);
|
| | |
|
| | | bool isEnough = haveCount >= needCount;
|
| | |
|
| | | if (!isEnough && needTips)
|
| | | {
|
| | | var itemConfig = ItemConfig.Get(itemId);
|
| | |
|
| | | if (null != itemConfig)
|
| | | {
|
| | | // SysNotifyMgr.Instance.ShowTip();
|
| | | }
|
| | | }
|
| | |
|
| | | return isEnough;
|
| | | }
|
| | |
|
| | | public static bool CheckCurrencyCount()
|
| | | {
|
| | | return true;
|
| | | }
|
| | |
|
| | | public event Action<string> GetBetterEquipEvent; //得到更好的装备 value 物品的实例ID
|
| | |
|
| | | // public void OnGetEquip(ItemModel item)
|
| | |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using UnityEngine; |
| | | |
| | | using System; |
| | | |
| | | |
| | | public class TeamManager : GameSystemManager<TeamManager> |
| | | { |
| | | protected Dictionary<TeamType, TeamBase> teamDict = new Dictionary<TeamType, TeamBase>(); |
| | | |
| | | public Action<TeamType> OnTeamChange = null; |
| | | |
| | | public override void Init() |
| | | { |
| | |
| | | public void OnHeroChangeEvent(HB124_tagSCLineupInfo vNetData) |
| | | { |
| | | var heroPack = PackManager.Instance.GetSinglePack(PackType.Hero); |
| | | HashSet<TeamType> teamTypeSet = new HashSet<TeamType>(); |
| | | for (int i = 0; i < vNetData.LineupCnt; i++) |
| | | { |
| | | var team = GetTeam((TeamType)vNetData.LineupList[i].LineupID); |
| | | TeamType teamType = (TeamType)vNetData.LineupList[i].LineupID; |
| | | teamTypeSet.Add(teamType); |
| | | var team = GetTeam(teamType); |
| | | for (int j = 0; j < vNetData.LineupList[i].HeroCnt; j++) |
| | | { |
| | | int index = vNetData.LineupList[i].HeroItemIndexList[j]; |
| | |
| | | team.RefreshServerData(vNetData.LineupList[i].ShapeType, j, hero); |
| | | } |
| | | } |
| | | } |
| | | |
| | | foreach (var tt in teamTypeSet) |
| | | { |
| | | OnTeamChange?.Invoke(tt); |
| | | } |
| | | } |
| | | |
| | | |
| | | public bool HasTeam(TeamType teamType) |
| | |
| | | GoldPaper = 19, //金票 19, |
| | | Silver = 20, //银子 20, |
| | | SilverPaper = 21, //银票 21, |
| | | //FightPoint = 22, //战斗值 22, |
| | | FightPoint = 22, //战斗值(锤子) 22, |
| | | HappyPoint = 23, //娱乐值 23, |
| | | MapID = 24, //角色所在地图 24, |
| | | PosX = 25, //角色坐标 25, |