public void EnterIncite(RtSkData sk, EffectConfigData efCfg, ServerNPC caster, IEnumerable <ServerNPC> targets) { bool canEnter = CheckIncite(sk, efCfg); if (canEnter) { bool injured = CheckBeHead(sk); if (injured) { float Delay = 0.6F; /// /// 检测伤害类的还需要至少延迟了两个FixedUpdate,因为承受伤害的逻辑,还没开始执行 /// 所以,目标血量的判定还不能开始 /// DelayedSkData data = new DelayedSkData() { caster = caster, chosen = targets, rtsk = sk, }; SkAsyncRunner.AysncRun(EnterIncite, Delay, data); } else { EnterIncite(sk, caster, targets); } } }
/// <summary> /// 获取特定的Effect实例 /// </summary> /// <returns>The implement.</returns> /// <param name="op">Op.</param> public ICastEffect getImplement(EffectConfigData cfg, SkillConfigData sk) { Queue <ICastEffect> impQueue = null; ICastEffect imp = null; EffectOp op = cfg.EffectType; Type type = null; if (ISkEff.TryGetValue(op, out type)) { if (ImpleEff.TryGetValue(op, out impQueue)) { if (impQueue.Count == 0) { imp = (ICastEffect)Activator.CreateInstance(type); } else { imp = impQueue.Dequeue(); } } else { imp = (ICastEffect)Activator.CreateInstance(type); } if (imp != null) { imp.Init(cfg, sk); } } return(imp); }
/// <summary> /// 这个Targets不能为空 /// </summary> /// <param name="caster">Caster.</param> /// <param name="targets">Targets.</param> /// <param name="efCfg">Ef cfg.</param> /// <param name="npcMgr">Npc mgr.</param> public List <ServerNPC> Select(ServerNPC caster, List <ServerNPC> targets, EffectConfigData efCfg, WarServerNpcMgr npcMgr) { #if DEBUG Utils.Assert(efCfg == null, "Can't find target unless EffectConfigData isn't null."); Utils.Assert(npcMgr == null, "Can't find target unless WarServerNpcMgr isn't null."); Utils.Assert(targets == null, "Can't find target unless targets isn't null."); #endif List <ServerNPC> reTarget = new List <ServerNPC>(); //转换为Camp类型,还有一部分的检查不在这里 //剔除自己的是在Factory里面(即EffectAreaSector) CAMP camp = efCfg.Flags.switchTo(caster.Camp); int count = targets.Count; if (count > 0) { for (int i = 0; i < count; ++i) { UVec3 anchor = targets[i].transform.position; reTarget.AddRange(SelectorTools.GetNPCRadius(anchor, caster.data.configData.radius + efCfg.eParam1, camp, npcMgr)); } } return(reTarget); }
bool CheckIncite(RtSkData sk, EffectConfigData efCfg) { #if DEBUG Utils.Assert(sk == null, "RtSkData is null in CheckIncite."); Utils.Assert(efCfg == null, "EffectConfigData is null in CheckIncite."); #endif return(sk.skillCfg.InciteEffectID == efCfg.ID); }
private Polygon Select(ServerNPC caster, EffectConfigData efCfg) { #if DEBUG Utils.Assert(caster == null, "Can't find target unless caster isn't null."); Utils.Assert(efCfg == null, "Can't find target unless EffectConfigData isn't null."); #endif UTran trans = caster.transform; float Y = trans.localPosition.y; float halfWidth = efCfg.eParam2 * 0.5F; float Height = efCfg.eParam1; UVec3[] localVecs = new UVec3[4]; localVecs[0] = new UVec3(-halfWidth, Y, 0f); localVecs[1] = new UVec3(-halfWidth, Y, Height); localVecs[2] = new UVec3(halfWidth, Y, Height); localVecs[3] = new UVec3(halfWidth, Y, 0f); UVec3[] WorldVecs = new UVec3[4]; WorldVecs[0] = trans.TransformPoint(localVecs[0]); WorldVecs[1] = trans.TransformPoint(localVecs[1]); WorldVecs[2] = trans.TransformPoint(localVecs[2]); WorldVecs[3] = trans.TransformPoint(localVecs[3]); PointF[] vecs = new PointF[4]; vecs[0] = new PointF() { X = WorldVecs[0].x, Y = WorldVecs[0].z, }; vecs[1] = new PointF() { X = WorldVecs[1].x, Y = WorldVecs[1].z, }; vecs[2] = new PointF() { X = WorldVecs[2].x, Y = WorldVecs[2].z, }; vecs[3] = new PointF() { X = WorldVecs[3].x, Y = WorldVecs[3].z, }; Polygon rectangle = new Polygon(vecs); return(rectangle); }
void Awake() { efcfg = new EffectConfigData() { eParam1 = 2.0F, eParam2 = 3.0F, }; npc = GetComponent <ServerNPC>(); }
public Dmg toTargetDmg(NPCData self, NPCData target, EffectConfigData cfg) { ///-------- 物理伤害强度------ ///先计算自己的物理伤害, float bphyselfhit = Physical_Hit(self, cfg); ///-------- 魔法伤害强度 ------- /// 先计算自己的魔法伤害, float bMagselfhit = Magical_Hit(self, cfg); ///-------- NPC的总攻击强度,是cfg.EffectClass 类型------- float hit = bphyselfhit + bMagselfhit; //---------- 开始计算伤害 --------- float dmg = 0f; switch (cfg.EffectClass) { case SkillTypeClass.Holly: //神圣伤害不减少伤害 dmg = hit; break; case SkillTypeClass.Magical: float magenemyavoid = Magical_Avoid(target, self); dmg = hit * (1.0f - magenemyavoid); break; case SkillTypeClass.Physical: float avdenemyratio = Physical_Avoid(target, self); dmg = hit * (1.0f - avdenemyratio); break; } /// --------- 暴击伤害 ---------- /// float critialRatio = CriticalRatio(self, target, cfg); bool isCri = PseudoRandom.getInstance().happen(critialRatio); if (isCri) { float addtion = AdditionRatio(self, cfg); dmg = dmg * addtion; } Dmg final = new Dmg() { dmgValue = dmg, dmgType = cfg.EffectClass, isCritical = isCri, hitCls = HurtHitClass.None, }; return(final); }
/// <summary> /// 这个是给技能使用的,可能不会立即有结果 /// </summary> /// <param name="caster">Caster.</param> /// <param name="chosen">Chosen.</param> /// <param name="rtSk">技能</param> /// <param name="pos">技能的索引</param> /// <param name="Report">Report.</param> public void Cast(ServerNPC Caster, IEnumerable <ServerNPC> Chosen, RtSkData RtSk, Action <MsgParam> ReportFunc) { #if DEBUG Utils.Assert(Caster == null, "Effect Castor"); Utils.Assert(RtSk == null, "Effect Castor"); #endif List <EffectConfigData> effCfg = new List <EffectConfigData>(); foreach (EffectConfigData cfg in RtSk.effectCfgDic.Values) { effCfg.Add(cfg); } //虚假的Buff桩对象 EffectConfigData stub = ctorStubEffCfg(RtSk); if (stub != null) { effCfg.Add(stub); } ICastEffect[] castor = effMgr.getImplements(effCfg.ToArray(), RtSk.skillCfg); if (castor != null) { int len = castor.Length; for (int i = 0; i < len; ++i) { if (castor[i] == null) { ConsoleEx.DebugLog("ICastEffect Not Implement. ID = " + effCfg[i].ID, ConsoleEx.YELLOW); } else { float Delay = RtSk.skillCfg.EffectDelayTime[i]; if (Delay > 0) { DelayedSkData data = new DelayedSkData() { caster = Caster, chosen = Chosen, castor = castor[i], cfg = effCfg[i], Report = ReportFunc, rtsk = RtSk, }; SkAsyncRunner.AysncRun(DelayCast, Delay, data); } else { DelayCast(Caster, Chosen, castor[i], effCfg[i], RtSk, ReportFunc); } } } } castor = null; }
public float Physical_Hit(NPCData self, EffectConfigData cfg) { #if DEBUG Utils.Assert(self == null, "npc is null."); Utils.Assert(cfg == null, "EffectConfigData is null."); #endif float bPhyHit = self.rtData.attackpower * cfg.Param6 * Consts.OneThousand; return(bPhyHit); }
public float Magical_Hit(NPCData self, EffectConfigData cfg) { #if DEBUG Utils.Assert(self == null, "npc is null."); Utils.Assert(cfg == null, "EffectConfigData is null."); #endif float bMagicalHit = self.rtData.spellpower * cfg.Param7 * Consts.OneThousand; return(bMagicalHit); }
/// 治疗值 = (p(1)*物理攻击系数+p(2)*法术攻击系数) /1000 + p(3) +p(4) * TargetAttr(MaxHP) / 1000 /// /// 疗效 = TargetAttr(BeHeal) /// 治疗值 = 治疗值 * (1+疗效) * (1+p(5) / 1000) /// /// 是否可暴击按照p(6)处理 /// 技能暴击率 = 暴击率 + p(7) / 1000 /// 技能治疗暴击提升比=治疗暴击提升比+P(8) / 1000 /// /// if 暴击 then /// 真实治疗值 = 治疗值 * 技能治疗暴击提升比 /// end if public Treat toTargetTreat(NPCData self, NPCData target, EffectConfigData cfg) { ///-------- 物理伤害强度------ ///先计算自己的物理伤害, float bphyselfhit = Physical_Hit(self, cfg); ///-------- 魔法伤害强度 ------- /// 先计算自己的魔法伤害, float bMagselfhit = Magical_Hit(self, cfg); ///-------- NPC的总攻击强度,是cfg.EffectClass 类型------- float hit = bphyselfhit + bMagselfhit + cfg.Param3 + cfg.Param4 * self.rtData.totalHp * Consts.OneThousand; /// /// ------------ 分为不可暴击 和 不计算疗效 ------------ /// TreatClass treatCls = (TreatClass)Enum.ToObject(typeof(TreatClass), cfg.Param6); bool forbid_critical = treatCls == TreatClass.Forbid_Critical; bool forbid_beheal = treatCls == TreatClass.Forbid_BeHeal; /// 治疗值 float treat = hit * (1 + cfg.Param7 * Consts.OneThousand); if (!forbid_beheal) { treat = treat * (1 + self.rtData.BeHeal); } /// --------- 暴击伤害 ---------- /// bool isCri = false; if (!forbid_critical) { float critialRatio = CriticalRatio(self, target, cfg); isCri = PseudoRandom.getInstance().happen(critialRatio); if (isCri) { float addtion = AdditionRatio(self, cfg); treat = treat * addtion; } } Treat val = new Treat() { treatValue = (int)treat, treatType = cfg.EffectClass, isCritical = isCri, }; return(val); }
/// 暴击伤害加成 = 150% +人物暴击伤害加成 + 技能暴击加成 public float AdditionRatio(NPCData self, EffectConfigData cfg) { //TODO: 断言 #if DEBUG Utils.Assert(self == null, "Src npc is null when doing Critial Addition Ratio."); Utils.Assert(cfg == null, "EffectConfigData is null when doing Critial Addition Ratio."); #endif float ratio = CRITICAL_RATIO + self.rtData.additionalcrit; if (cfg != null && cfg.EffectType == EffectOp.Injury) { ratio += cfg.Param6 * Consts.OneThousand; } return(ratio); }
public float CriticalRatio(NPCData self, NPCData enemy, EffectConfigData cfg) { //TODO: 断言 #if DEBUG Utils.Assert(self == null, "Src npc is null when doing Critical Ratio."); Utils.Assert(enemy == null, "Enemy npc is null when doing Critical Ratio."); Utils.Assert(cfg == null, "EffectConfigData is null when doing Critial Ratio."); #endif float ratio = self.rtData.crit - enemy.rtData.critresistance; ratio = ratio <= 0f ? 0f : ratio; if (cfg != null && cfg.EffectType == EffectOp.Injury) { ratio = ratio + cfg.Param5 * Consts.OneThousand; } return(ratio); }
/// <summary> /// 回收Effect实例 /// </summary> /// <param name="cfg">Cfg.</param> /// <param name="casteff">Casteff.</param> public void Recycle(EffectConfigData cfg, ICastEffect casteff) { if (casteff != null && cfg != null) { EffectOp op = cfg.EffectType; Queue <ICastEffect> impQueue = null; if (ImpleEff.TryGetValue(op, out impQueue)) { impQueue.Enqueue(casteff); } else { impQueue = new Queue <ICastEffect>(); impQueue.Enqueue(casteff); ImpleEff[op] = impQueue; } } }
/// /// 引导Buff是可以被打断的 /// 创建假的Effect的配置(桩对象) /// EffectConfigData ctorStubEffCfg(RtSkData RtSk) { EffectConfigData stub = null; if (RtSk.ChannelBuff != null) { stub = new EffectConfigData() { ID = -1, Flags = EffectFlag.None, EffectClass = SkillTypeClass.Magical, EffectTarget = EffectTargetClass.SkillTarget, EffectTargetType = TargetSubClass.AllTarget, EffectTargetStatusReject = NpcStatus.None, EffectType = EffectOp.DotHot, Param1 = RtSk.ChannelBuff.ID, Prob = 1000, EffectLimit = -1, }; } return(stub); }
/// <summary> /// Init the specified owner and param. /// </summary> /// <param name="owner">Owner.</param> /// <param name="param">Parameter.</param> public override void Init(ServerNPC owner, WarMsgParam param) { parent = owner; tran = transform; wmMgr = WarServerManager.Instance; Camp = Camp.set(parent.Camp); WarSrcAnimParam srcParam = param as WarSrcAnimParam; if (srcParam != null) { SelfDescribed sd = srcParam.described; if (sd != null) { EndResult result = sd.targetEnd; int effectIndex = result.param2; targetIndex = result.param5; if (targetIndex > 0) { if (wmMgr != null) { target = wmMgr.npcMgr.GetNPCByUniqueID(targetIndex); } } EffectConfigData effect = Core.Data.getIModelConfig <EffectModel>().get(effectIndex); if (effect != null) { effectID = effectIndex; speed = effect.Param3 / 1000f; maxDis = effect.Param4 / 1000; damageType = effect.Param8; disappearType = effect.Param5; } // string msg = string.Format("[effect:{0} speed:{1} maxDis:{2} disappearType:{3} damageType:{4}]", effectID, speed, maxDis, disappearType, damageType); // Debug.Log(msg); } inited = true; } }
/// <param name="targets">没用的</param> public List <ServerNPC> Select(ServerNPC caster, List <ServerNPC> targets, EffectConfigData efCfg, WarServerNpcMgr npcMgr) { #if DEBUG Utils.Assert(caster == null, "Can't find target unless caster isn't null."); Utils.Assert(efCfg == null, "Can't find target unless EffectConfigData isn't null."); Utils.Assert(npcMgr == null, "Can't find target unless WarServerNpcMgr isn't null."); #endif //转换为Camp类型,还有一部分的检查不在这里 //剔除自己的是在Factory里面(即EffectAreaSector) CAMP camp = efCfg.Flags.switchTo(caster.Camp); UTran trans = caster.transform; float Y = trans.localPosition.y; float halfWidth = efCfg.eParam2 * 0.5F + caster.data.configData.radius; float Height = efCfg.eParam1 + caster.data.configData.radius; UVec3[] localVecs = new UVec3[4]; localVecs[0] = new UVec3(-halfWidth, Y, 0f); localVecs[1] = new UVec3(-halfWidth, Y, Height); localVecs[2] = new UVec3(halfWidth, Y, Height); localVecs[3] = new UVec3(halfWidth, Y, 0f); UVec3[] WorldVecs = new UVec3[4]; WorldVecs[0] = trans.TransformPoint(localVecs[0]); WorldVecs[1] = trans.TransformPoint(localVecs[1]); WorldVecs[2] = trans.TransformPoint(localVecs[2]); WorldVecs[3] = trans.TransformPoint(localVecs[3]); //caster.transform.forward; PointF[] vecs = new PointF[4]; vecs[0] = new PointF() { X = WorldVecs[0].x, Y = WorldVecs[0].z, }; vecs[1] = new PointF() { X = WorldVecs[1].x, Y = WorldVecs[1].z, }; vecs[2] = new PointF() { X = WorldVecs[2].x, Y = WorldVecs[2].z, }; vecs[3] = new PointF() { X = WorldVecs[3].x, Y = WorldVecs[3].z, }; Polygon rectangle = new Polygon(vecs); List <ServerNPC> TargetList = SelectorTools.GetNPCPolygon(rectangle, camp, npcMgr).ToList(); return(TargetList); }
/// <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); } } } } } }
public void Init(EffectConfigData config, SkillConfigData skillcfg) { base.cfg = config; base.skCfg = skillcfg; }
/// /// 带AI的伤害技能的实现 /// 但是要不要减伤 /// /// 〖物理伤害〗_敌=〖物理攻击力〗_敌×(1-〖物理免伤〗_自 ) /// 〖法术伤害〗_敌=〖法术攻击力〗_敌×(1-〖法术免伤〗_自 ) /// 〖伤害〗_敌=〖物理伤害〗_敌+〖法术伤害〗_敌 /// /// Self 对 target的技能伤害 /// 只考虑了输出值,并不考虑后续的反弹,护盾等情况 /// public Dmg toTargetDmg(NPCData self, NPCData target, EffectConfigData cfg) { ///-------- 物理伤害强度------ ///先计算自己的物理伤害, float bphyselfhit = Physical_Hit(self, cfg); ///-------- 魔法伤害强度 ------- /// 先计算自己的魔法伤害, float bMagselfhit = Magical_Hit(self, cfg); ///-------- NPC的总攻击强度,是cfg.EffectClass 类型------- float hit = bphyselfhit + bMagselfhit + cfg.Param3; HurtHitClass hitType = (HurtHitClass)Enum.ToObject(typeof(HurtHitClass), cfg.Param7); /// /// --------- 检测 不计算减伤 ----------- /// bool forbidArmer = hitType.check(HurtHitClass.Forbid_Armer); float dmg = 0f; if (forbidArmer) { dmg = hit; } else { switch (cfg.EffectClass) { case SkillTypeClass.Holly: //神圣伤害不减少伤害 dmg = hit; break; case SkillTypeClass.Magical: float magenemyavoid = Magical_Avoid(target, self); dmg = hit * (1.0f - magenemyavoid); break; case SkillTypeClass.Physical: float avdenemyratio = Physical_Avoid(target, self); dmg = hit * (1.0f - avdenemyratio); break; } } dmg = dmg * (1 + cfg.Param4 * Consts.OneThousand); /// --------- 暴击伤害 ---------- /// float critialRatio = CriticalRatio(self, target, cfg); bool isCri = PseudoRandom.getInstance().happen(critialRatio); if (isCri) { float addtion = AdditionRatio(self, cfg); dmg = dmg * addtion; } Dmg final = new Dmg() { dmgValue = dmg, dmgType = cfg.EffectClass, isCritical = isCri, hitCls = hitType, }; return(final); }
public void Init(EffectConfigData config, SkillConfigData skillcfg) { cfg = config; skCfg = skillcfg; }
private Polygon Select(ServerNPC caster, EffectConfigData efCfg) { Transform trans = caster.transform; float Y = trans.localPosition.y; //角度转化为弧度 float angel = Mathf.Deg2Rad * efCfg.eParam2 * 0.5f; float radius = efCfg.eParam1; float X = Mathf.Sin(angel) * radius; float Z = Mathf.Cos(angel) * radius; //本地坐标 UVec3[] localVecs = new UVec3[4]; localVecs[0] = new UVec3() { x = 0F, y = Y, z = 0F, }; localVecs[1] = new UVec3() { x = -X, y = Y, z = Z, }; localVecs[2] = new UVec3() { x = 0, y = Y, z = radius, }; localVecs[3] = new UVec3() { x = X, y = Y, z = Z, }; //世界坐标 UVec3[] worldVecs = new UVec3[4]; worldVecs[0] = trans.TransformPoint(localVecs[0]); worldVecs[1] = trans.TransformPoint(localVecs[1]); worldVecs[2] = trans.TransformPoint(localVecs[2]); worldVecs[3] = trans.TransformPoint(localVecs[3]); //转换为2D坐标 PointF[] Vecs = new PointF[4]; Vecs[0] = new PointF() { X = worldVecs[0].x, Y = worldVecs[0].z }; Vecs[1] = new PointF() { X = worldVecs[1].x, Y = worldVecs[1].z }; Vecs[2] = new PointF() { X = worldVecs[2].x, Y = worldVecs[2].z }; Vecs[3] = new PointF() { X = worldVecs[3].x, Y = worldVecs[3].z }; Polygon polygon = new Polygon(Vecs); return(polygon); }
//挑出阵营,但是不应该把施法者过滤掉 //后续如果有要求,才会过滤施法者 IEnumerable <ServerNPC> SelectCamp(ServerNPC caster, IEnumerable <ServerNPC> targets, EffectConfigData efCfg) { CAMP camp = efCfg.Flags.switchTo(caster.Camp); IEnumerable <ServerNPC> itor = targets.Where(n => camp.check(n.Camp) || caster.UniqueID == n.UniqueID); return(itor); }
public List <ServerNPC> SelectArea(ServerNPC caster, IEnumerable <ServerNPC> targets, EffectConfigData efCfg) { ///1. 判定EffectTarget(范围), 不区分敌友 IEffectAreaSelector areaSelector = null; List <ServerNPC> list = null; switch (efCfg.EffectTarget) { case EffectTargetClass.Self_Front_Fan: areaSelector = fan ?? (fan = new SelfFrontFanSelector()); break; case EffectTargetClass.Self_Front_Rectangle: areaSelector = rectangle ?? (rectangle = new SelfFrontRectangleSelector()); break; case EffectTargetClass.SkillTarget_Radius: areaSelector = radius ?? (radius = new TargetRadiusSelector()); list = targets.ToList(); break; case EffectTargetClass.SkillTarget: IEnumerable <ServerNPC> itor = SelectCamp(caster, targets, efCfg); list = itor.ToList(); break; case EffectTargetClass.Self_And_Target: areaSelector = both ?? (both = new SelfAndTargetSelector()); break; } /// ///安装Camp和区域选择目标 List <ServerNPC> reTarget = areaSelector != null?areaSelector.Select(caster, list, efCfg, npcMgr) : list; //是否要过滤掉自己 bool ck = efCfg.Flags.check(EffectFlag.Forbid_Self); if (ck) { int fCount = reTarget.Count; if (fCount > 0) { int found = -1; for (int i = 0; i < fCount; ++i) { if (reTarget[i].UniqueID == caster.UniqueID) { found = i; break; } } if (found >= 0) { reTarget.RemoveAt(found); } } } return(reTarget); }
void DelayCast(ServerNPC caster, IEnumerable <ServerNPC> chosen, ICastEffect castor, EffectConfigData cfg, RtSkData RtSk, Action <MsgParam> Report) { bool skDirecHurt = true; List <MsgParam> MsgContainer = new List <MsgParam>(); IEnumerable <ServerNPC> reTarget = selector.Select(caster, chosen, cfg); castor.Cast(caster, chosen, reTarget, skDirecHurt, MsgContainer); effMgr.Recycle(cfg, castor); /// /// ---- 进入激活判定器 ---- /// conDicder.EnterIncite(RtSk, cfg, caster, chosen); short pos = RtSk.pos; /// /// 回报数据,区分一条数据和多条数据 /// HowToReport(MsgContainer, pos, Report); }
/// <summary> /// 扇形选择区域 /// </summary> /// <param name="caster">Caster.</param> /// <param name="targets">Targets 不适用,,可以为Null</param> /// <param name="efCfg">Effect的配置</param> /// <param name="npcMgr">WarNpcManager</param> public List <ServerNPC> Select(ServerNPC caster, List <ServerNPC> targets, EffectConfigData efCfg, WarServerNpcMgr npcMgr) { #if DEBUG Utils.Assert(caster == null, "Can't find targets unless caster isn't null."); Utils.Assert(efCfg == null, "Can't find targets unless EffectConfigData isn't null."); Utils.Assert(npcMgr == null, "Can't find targets unless WarServerNpcMgr isn't null."); #endif //转换为Camp类型,还有一部分的检查不在这里 //剔除自己的是在Factory里面(即EffectAreaSector) CAMP camp = efCfg.Flags.switchTo(caster.Camp); Transform trans = caster.transform; float Y = trans.localPosition.y; //角度转化为弧度 float angel = Mathf.Deg2Rad * efCfg.eParam2 * 0.5f; float radius = efCfg.eParam1 + caster.data.configData.radius; float X = Mathf.Sin(angel) * radius; float Z = Mathf.Cos(angel) * radius; //本地坐标 UVec3[] localVecs = new UVec3[4]; localVecs[0] = new UVec3() { x = 0F, y = Y, z = 0F, }; localVecs[1] = new UVec3() { x = -X, y = Y, z = Z, }; localVecs[2] = new UVec3() { x = 0, y = Y, z = radius, }; localVecs[3] = new UVec3() { x = X, y = Y, z = Z, }; //世界坐标 UVec3[] worldVecs = new UVec3[4]; worldVecs[0] = trans.TransformPoint(localVecs[0]); worldVecs[1] = trans.TransformPoint(localVecs[1]); worldVecs[2] = trans.TransformPoint(localVecs[2]); worldVecs[3] = trans.TransformPoint(localVecs[3]); //转换为2D坐标 PointF[] Vecs = new PointF[4]; Vecs[0] = new PointF() { X = worldVecs[0].x, Y = worldVecs[0].z }; Vecs[1] = new PointF() { X = worldVecs[1].x, Y = worldVecs[1].z }; Vecs[2] = new PointF() { X = worldVecs[2].x, Y = worldVecs[2].z }; Vecs[3] = new PointF() { X = worldVecs[3].x, Y = worldVecs[3].z }; Polygon polygon = new Polygon(Vecs); List <ServerNPC> TargetList = SelectorTools.GetNPCPolygon(polygon, camp, npcMgr).ToList(); return(TargetList); }
/// <summary> /// 选择的规则是: /// 1. 判定EffectTarget(范围) /// 2. 判定flag-剔除友军,敌军等概念, 进入战斗状态的则再最后判定(状态可能目前并不会去设定) /// 3. 判定EffectTargetType-剔除 /// 4. 每个NPC的概率 /// 5. 判定EffectTargetStatusReject-剔除 /// 6. 选择目标的数量不能超过上限 /// /// </summary> /// <param name="caster">Caster.</param> /// <param name="targets">Targets.</param> /// <param name="efCfg">Ef cfg.</param> public IEnumerable <ServerNPC> Select(ServerNPC caster, IEnumerable <ServerNPC> targets, EffectConfigData efCfg) { #if DEBUG Utils.Assert(efCfg == null, "Effect Selector can't find target unless EffectConfigData isn't null"); #endif List <ServerNPC> reTarget = null; IEnumerable <ServerNPC> itor = null; /// 1. 判定EffectTarget(范围)2. 判定flag-剔除友军,敌军等概念 reTarget = areaSelector.SelectArea(caster, targets, efCfg); /// 3. 判定EffectTargetType-剔除 建筑物 LifeNPCType lifeType = efCfg.EffectTargetType.toPositive(); itor = reTarget.Where(n => lifeType.check(n.data.configData.type)); /// 4. 每个NPC的概率 5.判定EffectTargetStatusReject itor = itor.Where(n => { ServerLifeNpc lifeTar = n as ServerLifeNpc; bool ok = random.happen(efCfg.Prob); if (lifeTar != null) { if (ok) { return(!lifeTar.curStatus.AnySame(efCfg.EffectTargetStatusReject)); } else { return(ok); } } else { return(ok); } } ); ///6. 选择的目标数量不能超过上限 if (efCfg.EffectLimit > 0) { itor = itor.Take(efCfg.EffectLimit); } else if (efCfg.EffectLimit == 0) { itor = new List <ServerNPC>().AsEnumerable <ServerNPC>(); } return(itor); }