public void analyze(MsgParam msg, WarServerNpcMgr npcMgr) { WarAnimParam warParam = msg as WarAnimParam; if (warParam != null && warParam.described != null) { SelfDescribed des = warParam.described; int castor = des.srcEnd.param1; int sufferer = des.srcEnd.param2; ServerNPC bCast = npcMgr.GetNPCByUniqueID(castor); ServerNPC bSuf = npcMgr.GetNPCByUniqueID(sufferer); if (bCast != null && bSuf != null) { Pair pair = new Pair() { CastorNum = bCast.data.num, KilledNum = bCast.data.num, }; killingInfo.Add(pair); } } }
void HookNpcOnAttack(WarAnimParam warParam, WarServerNpcMgr npcMgr) { ServerNPC caster = npcMgr.GetNPCByUniqueID(warParam.Sender); ServerNPC suffer = npcMgr.GetNPCByUniqueID(warParam.Receiver); SufferHookEffect hookSuf = warMgr.sufMgr.getImplement <SufferHookEffect>(EffectOp.HookNpc); hookSuf.Suffer(caster, suffer, warParam.described, npcMgr); }
public void OnHappen(MsgParam msg, WarServerNpcMgr npcMgr) { if (msg != null) { ServerNPC castor = npcMgr.GetNPCByUniqueID(msg.Sender); ServerNPC target = npcMgr.GetNPCByUniqueID(msg.Receiver); List <ServerNPC> itor = new List <ServerNPC>(); itor.Add(target); warMgr.triMgr.trigCastor.cast(castor, itor, cfg); } }
//收到伤害 protected void BeInjured(WarTarAnimParam param) { if (param == null) { ConsoleEx.DebugWarning("BeInjured :: BeInjured :: param is null"); return; } if (param.described != null) { SufferInjureEffect sufInjury = warServerMgr.sufMgr.getImplement <SufferInjureEffect>(EffectOp.Injury); SelfDescribed des = param.described; //记录攻击自己的人的ID data.btData.atkerID = des.src; if (des.target == UniqueId && IsAlive) { ServerNPC caster = npcMgr.GetNPCByUniqueID(des.src); sufInjury.Suffer(caster, this, des, npcMgr); Dmg oneDmg = sufInjury.getHandled; hpMsg.uniqueId = UniqueID; hpMsg.deltaHp = (int)oneDmg.dmgValue; hpMsg.curHp = data.rtData.curHp; hpMsg.totalHp = data.rtData.totalHp; hpMsg.isDamage = true; hpMsg.srcID = des.src; warServerMgr.realServer.proxyCli.NPChp(hpMsg); // if (caster.UniqueID == npcMgr.ActiveHero.UniqueId) // { // if (OnHitByActiveHero != null) // { // Vector3 posIn2D = Vector3.zero; // Vector3 posIn3D = transform.position; // posIn3D.y += 3.5f; // wmMgr.GetUIPos_Ref3DPos (posIn3D, ref posIn2D); // OnHitByActiveHero ((int)oneDmg.dmgValue, true, oneDmg.isCritical, posIn2D); // } // } //检查自己是否被杀 if (data.rtData.curHp <= 0) { BeKillded(); } } } }
/// <summary> /// 触发条件满足,或者说感兴趣的事情发生了。 /// 但是是不是要真的处理什么逻辑,还不一定 /// </summary> /// <param name="msg">Message</param> /// <param name="npcMgr">Npc mgr.</param> public void OnHappen(MsgParam msg, WarServerNpcMgr npcMgr) { checkList.Clear(); WarAnimParam warParam = msg as WarAnimParam; if (warParam != null && warParam.described != null) { SelfDescribed des = warParam.described; Pair pair = new Pair(); pair.castor = npcMgr.GetNPCByUniqueID(des.src); pair.target = npcMgr.GetNPCByUniqueID(des.target); checkList.Add(pair); } }
void BulletNPCCreator(WarAnimParam warParam, WarServerNpcMgr npcMgr) { ServerNPC caster = npcMgr.GetNPCByUniqueID(warParam.Sender); ServerNPC suffer = npcMgr.GetNPCByUniqueID(warParam.Receiver); SelfDescribed des = new SelfDescribed() { src = warParam.arg1, target = warParam.arg2, }; SufferBulletEffect bulletSuf = warMgr.sufMgr.getImplement <SufferBulletEffect>(EffectOp.Bullet_NPC); bulletSuf.Suffer(caster, suffer, des, npcMgr); }
public void OnHappen(MsgParam msg, WarServerNpcMgr npcMgr) { WarAnimParam warParam = msg as WarAnimParam; if (warParam != null && warParam.described != null) { SelfDescribed described = warParam.described; if (described.srcEnd != null) { /// /// 每次被攻击几率对周围造成伤害 /// int casterId = described.srcEnd.param1; int sufferId = described.srcEnd.param2; //不能自己打自己也反弹 if (sufferId == casterId) { return; } if (sufferId == HangUpNpcId) { //选择自己和目标 //目标也是自己 ServerNPC castor = npcMgr.GetNPCByUniqueID(sufferId); List <ServerNPC> targets = new List <ServerNPC>(); targets.Add(castor); warMgr.triMgr.trigCastor.cast(castor, targets, cfg); } } } }
//清理逻辑 void clearDeadNpcStatus(MsgParam msg, WarServerNpcMgr npcMgr) { WarAnimParam warMsg = msg as WarAnimParam; if (warMsg != null && warMsg.described != null) { int deadNpcId = warMsg.described.srcEnd.param2; ServerNPC npc = npcMgr.GetNPCByUniqueID(deadNpcId); ServerLifeNpc life = npc as ServerLifeNpc; if (life != null) { life.curStatus = NpcStatus.None; /// /// ---- 解除挂载的Trigger ---- /// WarServerManager.Instance.triMgr.RemoveAllTrigger(deadNpcId); /// /// ---- 解除挂载的Buff ---- /// WarServerManager.Instance.bufMgr.rmAllBuff(deadNpcId); //--- 解除仇恨信息 ---- life.clearHatred(); } } }
ExistFlag NPCToFlag(ServerNPC npc, WarServerNpcMgr npcMgr, LifeNPCType type) { ExistFlag tar1 = ExistFlag.None; ExistFlag tar2 = ExistFlag.None; switch (type) { case LifeNPCType.Hero: tar1 = ExistFlag.Hostile_Hero; tar2 = ExistFlag.Hostile_Hero_ATK_Self_Hero; break; case LifeNPCType.Summon: tar1 = ExistFlag.Hostile_Summoner; tar2 = ExistFlag.Hostile_Summoner_ATK_Self_Hero; break; case LifeNPCType.Soldier: tar1 = ExistFlag.Hostile_Minion; tar2 = ExistFlag.Hostile_Minion_ATK_Self_Hero; break; } ExistFlag toTest = ExistFlag.None; //没有攻击过的目标 if (npc.TargetID == -1) { toTest = tar1; } else { ServerNPC targetNpc = npcMgr.GetNPCByUniqueID(npc.TargetID); if (targetNpc != null) { /// /// 发现目标是Hero,则会判定为攻击了英雄 /// NPCConfigData tarCfg = targetNpc.data.configData; if (tarCfg.type.check(LifeNPCType.Hero)) { toTest = tar2; } else { toTest = tar1; } } else { toTest = tar1; } } return(toTest); }
/// <summary> /// 获取挂载BUff的NPC /// </summary> /// <returns>The hang up.</returns> public ServerNPC getHangUp(RtBufData rtBf) { #if DEBUG Utils.Assert(rtBf == null, "RtBufData is null when get Hang Up."); #endif ServerNPC hangUp = npcMgr.GetNPCByUniqueID(rtBf.HangUpNpcID); return(hangUp); }
ExistFlag toExistType(ServerNPC npc, WarServerNpcMgr npcMgr) { NPCConfigData cfg = npc.data.configData; ExistFlag flag = LifeNpcType2ExistFlag(cfg.type, cfg.bldType); if (flag == ExistFlag.Hero) { if (npc.TargetID != -1) { ServerNPC npcTar = npcMgr.GetNPCByUniqueID(npc.TargetID); if (npcTar != null) { flag = ExistFlag.HeroTar; } } } return(flag); }
public void Update(float delTime) { foreach (RtBufData buf in OnWork.Values) { if (buf != null) { working.Add(buf); } } int workCnt = working.Count; if (workCnt > 0) { for (int i = 0; i < workCnt; ++i) { RtBufData buf = working[i]; bool alive = buf.Update(delTime); if (!alive) { rmBuff(buf.ID, buf.HangUpNpcID, true); } /// /// 判定当前的是否是引导技能 /// if (buf.canInterrupt) { //检测是否已被打断 ServerNPC npc = NpcMgr.GetNPCByUniqueID(buf.HangUpNpcID); ServerLifeNpc life = npc as ServerLifeNpc; bool interrupt = life.curStatus.AnySame(NpcStatus.Interrupt); if (interrupt) { rmBuff(buf.ID, buf.HangUpNpcID); } } } working.Clear(); } }
/// <summary> /// 选择的规则是: /// 多目标判定规则 /// 1. 判定施法者的状态 /// 2. 判定施法者的上次目标,如果目标在攻击范围内,则选择为最优先目标 /// 3. 判定施法的范围类型 /// 4. 目标的状态 /// 5. 根据施法的距离选择出目标 /// 6. 根据血量选择出目标 /// 7. 目标的优先级 /// 8. 单体攻击敌方,并且有最高优先级的目标 /// /// /// 单目标判定规则 /// /// /// /// </summary> /// <returns><c>true</c>, if cast was caned, <c>false</c> otherwise.</returns> public IEnumerable <ServerNPC> Select(ServerNPC caster, RtSkData rtOne, Sight sight) { //枚举器 IEnumerable <ServerNPC> itor = null, itor1 = null; #if DEBUG Utils.Assert(caster == null, "Can't find target unless caster isn't null"); Utils.Assert(rtOne == null, "Can't find target unless runtime skill isn't null"); #endif SkillConfigData skillCfg = rtOne.skillCfg; /// 视野范围 -- 决定索敌范围 float CheckDistance = 0F; if (sight == Sight.NearSight) { CheckDistance = skillCfg.Distance; } else { CheckDistance = caster.data.rtData.seekRange; } bool castcan = true; //只有LifeNPC才检查施法者的状态 //1. 判定施法者的状态 ServerLifeNpc castlife = caster as ServerLifeNpc; if (castlife != null) { if (castlife.curStatus.AnySame(skillCfg.CasterStatusReject)) { //不可施法 castcan = false; } } if (castcan == false) { return(new List <ServerNPC>().AsEnumerable <ServerNPC>()); } //能进入CD rtOne.EnterCD(); /// /// 3. 判定施法的范围类型 . /// 单体和AOE都需要在技能配置里选择出目标 , 再次到Effect里面选择目标。 -- 叫做前置判定 /// 方向性则不需要选择目标,该类型的技能可对空地释放,再次到EffectTarget的目标是skill的目标 -- 叫做后置判定 /// TargetClass rtTargetCls = skillCfg.SkillTarget; if (skillCfg.RangeType == RangeClass.Direction) { //后置判定 return(new List <ServerNPC>().AsEnumerable <ServerNPC>()); } bool isMultiTarget = skillCfg.RangeType != RangeClass.SingleTarget; bool isNoPriority = skillCfg.TargetPriority == SkTargetPriority.NonePriority; bool isTargetSelf = rtTargetCls.AnySame(TargetClass.Self); //单目标 ServerNPC singlePriority = null; LifeNPCType type = skillCfg.TargetType.toPositive(); /// /// 是否为多目标的战斗, 或者是没有优先级的单目标 /// if (isMultiTarget || isNoPriority || isTargetSelf) { /// /// 4. 目标的状态 /// if (rtTargetCls.AnySame(TargetClass.Friendly)) { //友方 itor1 = SelectorTools.GetNPCValideStatus(caster, npcMgr, KindOfNPC.Life, rtTargetCls, NpcStatus.None, type); } else if (rtTargetCls.AnySame(TargetClass.Hostile)) { //敌方 itor1 = SelectorTools.GetNPCValideStatus(caster, npcMgr, KindOfNPC.Life, rtTargetCls, skillCfg.TargetStatusReject, type); } else if (rtTargetCls.AnySame(TargetClass.Self)) { //自己 List <ServerNPC> targets = new List <ServerNPC>(); targets.Add(caster); itor = targets.AsEnumerable <ServerNPC>(); return(targets); } else { itor1 = SelectorTools.GetNPCValideStatus(caster, npcMgr, KindOfNPC.Life, rtTargetCls, skillCfg.TargetStatusReject, type); ConsoleEx.DebugLog("Warning : We should have a Camp. But sometimes, it's Ok.", ConsoleEx.RED); } /// /// 5. 根据施法的距离选择出目标 /// itor1 = SelectorTools.GetNPCInRadius(caster, CheckDistance, rtTargetCls, itor1); /// /// 6. 根据血量选择出目标 /// itor1 = SelectorTools.GetNPCByHp(caster, rtTargetCls, itor1); if (isNoPriority) { singlePriority = itor1.FirstOrDefault(); } } else { /// /// 获取单目标 /// singlePriority = SelectorTools.GetPrioritiedNpc(caster, rtTargetCls, npcMgr, CheckDistance, skillCfg.TargetStatusReject, skillCfg.TargetPriority, priorityMgr, type); //单目标的友方,有可能选择到自己(但并不属于 TargetClass 64.就针对自己) if (!rtTargetCls.AnySame(TargetClass.Hostile)) { List <ServerNPC> broker = new List <ServerNPC>(); if (singlePriority != null) { broker.Add(singlePriority); } itor1 = broker.AsEnumerable <ServerNPC>(); } } if (isMultiTarget == false) { /// /// 9. 单体攻击敌方,只有打敌方单体的时候,TargetID才会被重新设定 /// if (rtTargetCls.AnySame(TargetClass.Hostile)) { ServerLifeNpc HighestPriority = null; /// /// 检测嘲讽 /// int tarId = caster.getHighestHatred; if (tarId != -1) { //有被嘲讽的目标 HighestPriority = npcMgr.GetNPCByUniqueID(tarId) as ServerLifeNpc; } else { //没有被嘲讽的目标 /// /// 判定施法者的上次目标,则选择为最优先目标 /// 此逻辑,能保证追击残血逃跑的 /// if (caster.TargetID != -1) { HighestPriority = npcMgr.GetNPCByUniqueID(caster.TargetID) as ServerLifeNpc; if (HighestPriority != null) { /// /// 如果单一目标的是英雄, /// if (singlePriority != null && singlePriority.data.configData.type == LifeNPCType.Hero && HighestPriority.data.configData.type != LifeNPCType.Hero) { HighestPriority = null; caster.TargetID = -1; } else { bool validate1 = true, validate2 = true, validate3 = true; /// 生命判定 if (HighestPriority.data.rtData.curHp <= 0) { validate1 = false; } /// 距离判定 float distance = SelectorTools.GetDistance(HighestPriority.transform.position, caster.transform.position); distance = distance - HighestPriority.data.configData.radius - caster.data.configData.radius; /// 视野范围 if (distance > CheckDistance) { validate2 = false; } ///如果有相同的状态,则不让释放技能 validate3 = !HighestPriority.curStatus.AnySame(skillCfg.TargetStatusReject); /// 失败的判定 bool validate = validate1 & validate2 & validate3; if (!validate) { HighestPriority = null; caster.TargetID = -1; } else { caster.RstTimeout(); } } } else { caster.TargetID = -1; } } } //找到普通选择出的目标 if (HighestPriority == null) { ServerNPC target = singlePriority; caster.TargetID = target != null ? target.UniqueID : -1; HighestPriority = target as ServerLifeNpc; } List <ServerNPC> high = new List <ServerNPC>(); if (HighestPriority != null) { high.Add(HighestPriority); } itor1 = high.AsEnumerable <ServerNPC>(); } else { /// /// 10.单体友方 /// if (itor1.Any()) { itor1 = itor1.Take(1); } } } itor = itor1; return(itor); }
/// <summary> /// 处理主动打击其他NPC的时候,触发的事情 /// </summary> /// <param name="CasterId">施法者ID</param> /// <param name="SufferId">撞击者ID</param> /// <param name="idx">几个被撞击者</param> /// <param name="finalTar">是否最终目标</param> /// <param name="maxDis">是否最大距离</param> /// <param name="returnback">返回原处</param> /// <param name="EffectId">效果ID</param> /// <param name="npcMgr">Npc mgr.</param> void HandleOnAttack(int CasterId, int SufferId, int idx, bool finalTar, bool maxDis, bool returnback, int EffectId, WarServerNpcMgr npcMgr) { ServerNPC caster = npcMgr.GetNPCByUniqueID(CasterId); ServerNPC suffer = npcMgr.GetNPCByUniqueID(SufferId); /// /// -------- 获取Effect的配置 ------- /// EffectModel efModel = Core.Data.getIModelConfig <EffectModel>(); EffectConfigData efCfg = efModel.get(EffectId); Utils.Assert(efCfg == null, "Can't find Effect Configure. effect ID = " + EffectId); if (efSelector == null) { efSelector = EffectSufferShared.get(npcMgr); } /// /// 先做技能 /// IEnumerable <ServerNPC> filter = efSelector.Select(caster, new List <ServerNPC> { suffer }, efCfg); if (filter.Any()) { //消失的时候,触发可能的位移 HookNpcDisappearType disappearType = (HookNpcDisappearType)Enum.ToObject(typeof(HookNpcDisappearType), efCfg.Param2); //HookNpcDmgType hookDmgType = (HookNpcDmgType) Enum.ToObject(typeof(HookNpcDmgType), efCfg.Param8); HookNpcMoveType moveType = (HookNpcMoveType)Enum.ToObject(typeof(HookNpcMoveType), efCfg.Param5); /// /// 一定会有伤害,之后,先判定是否消失,如果消失,则再次判定是否移动 /// /// /// ------- 开始运算BulletOp -------- /// OperatorMgr OpMgr = OperatorMgr.instance; BulletNpcOp op = OpMgr.getImplement <BulletNpcOp>(EffectOp.Bullet_NPC); Dmg dmg = op.toTargetDmg(caster.data, suffer.data, efCfg); int moveDirection = 0; bool dis = Disappear(disappearType, idx, finalTar, maxDis, returnback); if (dis) { moveDirection = (int)moveType; } SelfDescribed des = record(CasterId, SufferId, dmg, dis, moveDirection); WarTarAnimParam param = new WarTarAnimParam() { OP = EffectOp.Injury, OringinOP = EffectOp.HookNpc, described = des, }; ///发送消息 npcMgr.SendMessageAsync(CasterId, SufferId, param); } }
/// <summary> /// 处理主动打击其他NPC的时候,触发的事情 /// </summary> void HandleOnAttack(MsgParam msg, WarServerNpcMgr npcMgr) { WarMsgParam warMsg = msg as WarMsgParam; if (warMsg != null) { if (efSelector == null) { efSelector = EffectSufferShared.get(npcMgr); } int CasterId = warMsg.Sender; int SufferId = warMsg.Receiver; int EffectId = warMsg.arg1; int FinalId = warMsg.arg2; //是否是最终目标 bool IsfinalTarget = SufferId == FinalId; /// /// -------- 获取Effect的配置 ------- /// EffectModel efModel = Core.Data.getIModelConfig <EffectModel>(); EffectConfigData efCfg = efModel.get(EffectId); Utils.Assert(efCfg == null, "Can't find Effect Configure. effect ID = " + EffectId); //半径 float radius = efCfg.Param9 * Consts.oneHundred; ServerNPC caster = npcMgr.GetNPCByUniqueID(CasterId); ServerNPC suffer = npcMgr.GetNPCByUniqueID(SufferId); /// /// ----------- 先坐第一步的选择和解析 ------------ /// IEnumerable <ServerNPC> filter = efSelector.Select(caster, new List <ServerNPC> { suffer }, efCfg); if (filter.Count() > 0) { BulletHurtType HurtType = (BulletHurtType)Enum.ToObject(typeof(BulletHurtType), efCfg.Param8); List <ServerNPC> targets = selectTarget(HurtType, suffer, IsfinalTarget, npcMgr, radius); int tarCnt = targets.Count; if (tarCnt > 0) { /// /// ------- 开始运算BulletOp -------- /// OperatorMgr OpMgr = OperatorMgr.instance; BulletNpcOp op = OpMgr.getImplement <BulletNpcOp>(EffectOp.Bullet_NPC); for (int i = 0; i < tarCnt; ++i) { ServerNPC target = targets[i]; //alive ? if (target.data.rtData.curHp > 0) { Dmg damage = op.toTargetDmg(caster.data, target.data, efCfg); SelfDescribed des = record(CasterId, SufferId, damage, i); WarTarAnimParam param = new WarTarAnimParam() { OP = EffectOp.Injury, OringinOP = EffectOp.Bullet_NPC, described = des, }; ///发送消息 npcMgr.SendMessageAsync(CasterId, SufferId, param); } } } } } }