/// <summary> /// 这个函数目前没有作用, /// 准备将来用于Buff第一次释放时,需要调用的函数 /// </summary> public void FirstCast(RtBufData rtbf) { /// /// --- 设置NPC的状态 --- /// ServerNPC hang = BFSelector.getHangUp(rtbf); ServerLifeNpc life = hang as ServerLifeNpc; if (life != null) { NpcStatus status = (NpcStatus)Enum.ToObject(typeof(NpcStatus), rtbf.BuffCfg.Status); //去除不需要挂载的状态 status = status.rmDiscrete(); if (status != NpcStatus.None) { life.curStatus = life.curStatus.set(status); } //如果有嘲讽的话 if (status.AnySame(NpcStatus.Taunt)) { life.addHatred(rtbf.CastorNpcID, 1); } } /// /// ---- 释放技能 --- /// castBuff_Skill(rtbf, BuffPhase.Start); }
public static GameObject getStatusObj(NpcStatus status) { switch (status) { case NpcStatus.Taunt: if (Effect_ChaoFeng == null) { Effect_ChaoFeng = WarEffectLoader.Load("gongyong/ChaoFeng"); } return(Effect_ChaoFeng); case NpcStatus.Slient: if (Effect_Silence == null) { Effect_Silence = WarEffectLoader.Load("gongyong/Silence"); } return(Effect_Silence); case NpcStatus.Unconscious: if (Effect_Unconscious == null) { Effect_Unconscious = WarEffectLoader.Load("gongyong/Vertigo"); } return(Effect_Unconscious); } return(null); }
public void addItem(NpcStatus s, bool add) { if (items == null) { items = new List <StatusInfoItem>(); } items.Add(new StatusInfoItem(s, add)); }
/// <summary> /// 获取特定的KindOfNPC,敌友方,有效状态的, 是建筑物还是什么的 活着的NPC /// </summary> /// <returns>ServerNPC 列表</returns> /// <param name="caster">Caster.</param> /// <param name="NpcSource">Npc source.</param> /// <param name="kind">KindOfNPC</param> /// <param name="target">TargetClass</param> /// <param name="TarStatusInCfg">NpcStatus</param> /// <param name="type">LifeNPCType.</param> public static IEnumerable <ServerNPC> GetNPCValideStatus(ServerNPC caster, WarServerNpcMgr NpcSource, KindOfNPC kind, TargetClass target, NpcStatus TarStatusInCfg, LifeNPCType type = LifeNPCType.SkTarAll) { // 临时枚举器 IEnumerable <ServerNPC> Itor1 = null; CAMP camp = CAMP.None; if (target.AnySame(TargetClass.Friendly)) { camp = caster.Camp; } else if (target.AnySame(TargetClass.Hostile)) { camp = caster.Camp.Hostile(); } else { //全阵营 camp = CAMP.All; } Itor1 = NpcSource.getCampBnpc(camp); if (kind == KindOfNPC.Life) { Itor1 = Itor1.Where(n => (n.WhatKindOf() == kind) && (type.check(((ServerLifeNpc)n).WhatTypeOf))); } else if (kind == KindOfNPC.NonLife) { Itor1 = Itor1.Where(n => n.WhatKindOf() == kind); } /// /// --- 筛选出有效状态的NPC ---- /// Itor1 = Itor1.Where(n => { ServerLifeNpc lifeTar = n as ServerLifeNpc; if (lifeTar != null) { return(!lifeTar.curStatus.AnySame(TarStatusInCfg)); } else { return(true); } }); return(Itor1); }
public virtual void OnNpcStatus() { if (cachedNpc != null) { NpcStatus status = cachedNpc.curStatus; if (status != statusInLastFrame) { NpcStatusInfo info = new NpcStatusInfo(); if (status.AnySame(NpcStatus.Slient) && !statusInLastFrame.AnySame(NpcStatus.Slient)) { info.addItem(NpcStatus.Slient, true); } else if (!status.AnySame(NpcStatus.Slient) && statusInLastFrame.AnySame(NpcStatus.Slient)) { info.addItem(NpcStatus.Slient, false); } if (status.AnySame(NpcStatus.Unconscious) && !statusInLastFrame.AnySame(NpcStatus.Unconscious)) { info.addItem(NpcStatus.Unconscious, true); On_Suffer(true); } else if (!status.AnySame(NpcStatus.Unconscious) && statusInLastFrame.AnySame(NpcStatus.Unconscious)) { info.addItem(NpcStatus.Unconscious, false); On_Suffer(false); } if (status.AnySame(NpcStatus.Taunt) && !statusInLastFrame.AnySame(NpcStatus.Taunt)) { info.addItem(NpcStatus.Taunt, true); } else if (!status.AnySame(NpcStatus.Taunt) && statusInLastFrame.AnySame(NpcStatus.Taunt)) { info.addItem(NpcStatus.Taunt, false); } animMsg.nextAnim = WarMsg_Type.OnStatus.ToString(); animMsg.uniqueId = cachedNpc.UniqueID; animMsg.data = JSON.Instance.ToJSON(info); if (serMgr != null) { serMgr.realServer.proxyCli.NPCAnim(animMsg); } } statusInLastFrame = status; } }
/// <summary> /// Create a generic NpcCharacter. /// </summary> /// <param name="ParentObjectScript">The in-game object that represents this NPC.</param> /// <param name="MasterSubjectListRef">A reference to the main MasterSubjectList.</param> public NpcCore(AnimalObjectScript ParentObjectScript, MasterSubjectList MasterSubjectListRef) { db = MasterSubjectListRef; objectScript = ParentObjectScript; health = 100; food = 100; safety = 100; definition = new NpcDefinition(); status = new NpcStatus(); drivers = new NpcDriversList(); unexploredLocations = new List <LocationSubject>(); subjectID = -1; searchedObjects = new List <int>(); searchedLocations = new List <int>(); reExploreLocations = new List <LocationSubject>(); SetFoodPreference(); }
/// <summary> /// 挑选出, 某个NPC可以被删除的NpcStatus /// </summary> /// <returns><c>true</c>, if buff status was found, <c>false</c> otherwise.</returns> /// <param name="toTest">To test.</param> public NpcStatus SiftOutStatus(NpcStatus toBeRmed, int buffId, int npcId) { NpcStatus S1 = NpcStatus.None; /// /// 找出当前所有buff的(除了buffId) /// foreach (RtBufData buf in OnWork.Values) { if (buf != null && buf.ID != buffId && npcId == buf.HangUpNpcID) { S1 = S1.set(buf.BuffCfg.Status); } } NpcStatus S2 = S1.pickUp(toBeRmed); return(S2); }
/// <summary> /// Initialize a new NpcCharacter. /// </summary> /// <param name="ParentObject">The in-game object that represents this NPC.</param> /// <param name="MasterSubjectListRef">A reference to the main MasterSubjectList.</param> /// <param name="BasedOnSubject">Subject's NpcDefinition will define the character's initial resource pools, thresholds for fulfilling basic needs, and memories.</param> public NpcCore(AnimalObjectScript ParentObjectScript, MasterSubjectList MasterSubjectListRef, Subject BasedOnSubject) { db = MasterSubjectListRef; if (BasedOnSubject is AnimalSubject) { objectScript = ParentObjectScript; AnimalSubject animalSubject = BasedOnSubject as AnimalSubject; definition = animalSubject.Definition; subjectID = animalSubject.SubjectID; health = definition.HealthMax; food = definition.FoodMax; safety = definition.SafetyHigh; status = new NpcStatus(); drivers = new NpcDriversList(); unexploredLocations = new List <LocationSubject>(); searchedObjects = new List <int>(); searchedLocations = new List <int>(); reExploreLocations = new List <LocationSubject>(); SetFoodPreference(); } }
public void SetStatus(NpcStatus npcStatus) { switch (npcStatus) { case NpcStatus.AvailableQuest: StatusText.text = "<color=yellow>!</color>"; break; case NpcStatus.InProgressQuest: StatusText.text = "<color=silver>?</color>"; break; case NpcStatus.CompletableQuest: StatusText.text = "<color=yellow>?</color>"; break; case NpcStatus.None: StatusText.text = " "; break; default: throw new ArgumentOutOfRangeException("npcStatus"); } }
//挑选出flags和totest两者不相关的状态 public static NpcStatus pickUp(this NpcStatus flags, NpcStatus totest) { return((flags | totest) & ~flags); }
//是离散的状态吗? //就是说:一次伤害,一次治疗属于离散。但是昏迷属于持续 public static NpcStatus rmDiscrete(this NpcStatus flags) { return(flags & ~NpcStatus.Treat); }
public static bool AnySame(this NpcStatus flags, NpcStatus totest) { return((flags & totest) != 0); }
public static NpcStatus clear(this NpcStatus flags, NpcStatus totest) { return(flags & ~totest); }
public static NpcStatus set(this NpcStatus flags, NpcStatus totest) { return(flags | totest); }
//可以选择单个目标,也可以是多个目标 //提供给SkillSelecotr使用 public static IEnumerable <ServerNPC> GetNPCInRange(ServerNPC caster, float range, WarServerNpcMgr NpcSource, KindOfNPC kind, TargetClass target, NpcStatus TarStatusInCfg, LifeNPCType type = LifeNPCType.SkTarAll) { List <ServerNPC> found = new List <ServerNPC>(); /// /// 枚举器,其实不用返回特定类型,返回枚举器就可以了。(在不需要Copy容器里面的数据时,就是用枚举器) /// IEnumerable <ServerNPC> Itor = found.AsEnumerable(); // 临时枚举器 IEnumerable <ServerNPC> Itor1 = null; Vector3 anchor = caster.transform.position; Transform trans = caster.transform; ServerNPC nearest = null; CAMP camp = CAMP.None; if (target.AnySame(TargetClass.Friendly)) { camp = caster.Camp; } else if (target.AnySame(TargetClass.Hostile)) { camp = caster.Camp.Hostile(); } Itor1 = NpcSource.getCampBnpc(camp); if (kind == KindOfNPC.Life) { Itor1 = Itor1.Where(n => (n.WhatKindOf() == kind) && (type.check(((ServerLifeNpc)n).WhatTypeOf))); } else if (kind == KindOfNPC.NonLife) { Itor1 = Itor1.Where(n => n.WhatKindOf() == kind); } bool any = Itor1 != null?Itor1.Any() : false; if (any) { /// /// --- 筛选出有效状态的NPC ---- /// Itor1 = Itor1.Where(n => { ServerLifeNpc lifeTar = n as ServerLifeNpc; if (lifeTar != null) { return(!lifeTar.curStatus.AnySame(TarStatusInCfg)); } else { return(true); } }); /// /// --- 再次根据距离条件筛选出NPC ---- /// float radius = caster.data.configData.radius; Itor1 = Itor1.Where(n => IsInRange(anchor, n.data.configData.radius + radius + range, n.transform)); if (target.AnySame(TargetClass.FarAwary)) { nearest = Itor1.OrderByDescending(n => GetVirtualDistance(trans, n.transform)).FirstOrDefault(); if (nearest != null) { found.Add(nearest); } } else if (target.AnySame(TargetClass.Nearest)) { nearest = Itor1.OrderBy(n => GetVirtualDistance(trans, n.transform)).FirstOrDefault(); if (nearest != null) { found.Add(nearest); } } else { Itor = Itor1; } /// /// --- 判定最大,最小生命值的NPC ----- /// if (target.AnySame(TargetClass.HpLowest)) { ServerNPC lowest = Itor1.OrderBy(n => n.data.rtData.CurHpNested).FirstOrDefault(); if (lowest != null) { found.Add(lowest); } } else if (target.AnySame(TargetClass.HpHighest)) { ServerNPC highest = Itor1.OrderByDescending(n => n.data.rtData.CurHpNested).FirstOrDefault(); if (highest != null) { found.Add(highest); } } } return(Itor); }
//此方法仅仅对单体目标有效,多目标的选择不走优先级排序逻辑 //且不能对自己生效和无优先级 //排序完了之后,按照“血量或距离”筛选出合适的NPC public static ServerNPC GetPrioritiedNpc(ServerNPC caster, TargetClass target, WarServerNpcMgr NpcSource, float range, NpcStatus TarStatusInCfg, SkTargetPriority priority, SkPriorityMgr PriorityMgr, LifeNPCType type = LifeNPCType.SkTarAll) { /// /// 获取未排好序的 /// IEnumerable <ServerNPC> unPriority = GetNPCValideStatus(caster, NpcSource, KindOfNPC.Life, target, TarStatusInCfg, type); /// /// 过滤掉超出范围的数据 /// Vector3 anchor = caster.transform.position; Transform trans = caster.transform; float radius = caster.data.configData.radius; unPriority = unPriority.Where(n => IsInRange(anchor, n.data.configData.radius + radius + range, n.transform)); /// /// 排序 /// IPrioritySelect selector = PriorityMgr.getImplement(priority); selector.SortByPriority(unPriority, NpcSource, hasPriority); /// /// 依照排好序的顺序,依次查找出一个适合的目标 /// 查找的方式为:血量和距离 /// ServerNPC theOne = null; bool Highest = target.AnySame(TargetClass.HpHighest); bool Lowest = target.AnySame(TargetClass.HpLowest); bool Farest = target.AnySame(TargetClass.FarAwary); bool Nearest = target.AnySame(TargetClass.Nearest); bool ExceptionCheck = false; int Condition = 0; if (Highest) { Condition++; } if (Lowest) { Condition++; } if (Farest) { Condition++; } if (Nearest) { Condition++; } #if DEBUG Utils.Assert(Condition >= 2, "TargetPriority shall set only one Max Or Min condition."); #endif int count = hasPriority.Count; if (Highest || Lowest) { for (int i = 0; i < count; ++i) { List <ServerNPC> line = hasPriority[i]; if (line != null) { if (Highest) { theOne = line.OrderByDescending(n => n.data.rtData.CurHpNested).FirstOrDefault(); } if (Lowest) { theOne = line.OrderBy(n => n.data.rtData.CurHpNested).FirstOrDefault(); } if (theOne != null) { break; } } } } if (Farest || Nearest) { for (int i = 0; i < count; ++i) { List <ServerNPC> line = hasPriority[i]; if (line != null) { if (Farest) { theOne = line.OrderByDescending(n => GetVirtualDistance(trans, n.transform)).FirstOrDefault(); } if (Nearest) { theOne = line.OrderBy(n => GetVirtualDistance(trans, n.transform)).FirstOrDefault(); } if (theOne != null) { break; } } } } /// /// 这种情况是没有排序的情况,只要能选出来第一个就可以 /// if (Condition == 0) { for (int i = 0; i < count; ++i) { List <ServerNPC> line = hasPriority[i]; if (line != null && line.Count > 0) { theOne = line[0]; if (theOne != null) { break; } } } } return(theOne); }
/// <summary> /// Buff结束时,处理的逻辑 /// </summary> public void EndCast(RtBufData rtbf) { /// /// --- 解除NPC的状态 --- /// ServerNPC hang = BFSelector.getHangUp(rtbf); ServerLifeNpc life = hang as ServerLifeNpc; if (life != null) { NpcStatus status = (NpcStatus)Enum.ToObject(typeof(NpcStatus), rtbf.BuffCfg.Status); //去除不需要挂载的状态 status = status.rmDiscrete(); /// /// 如果还有同类型的,其他Buff则不应该清除Buff的状态 /// if (status != NpcStatus.None) { NpcStatus toCleared = WarServerManager.Instance.bufMgr.SiftOutStatus(status, rtbf.ID, rtbf.HangUpNpcID); life.curStatus = life.curStatus.clear(toCleared); } /// /// 删除嘲讽的目标 /// if (status.check(NpcStatus.Taunt)) { life.clearSpecHatred(rtbf.CastorNpcID); } } /// /// ---- 解除挂载的Trigger ---- /// int NpcId = hang.UniqueID; WarServerManager.Instance.triMgr.RemoveTrigger(rtbf.TriggerID, NpcId); /// /// ---- 是否删除NPC (目前不适用) ---- /// if (life != null) { SelfDescribed des = new SelfDescribed() { src = hang.UniqueID, target = hang.UniqueID, act = Verb.Punch, srcEnd = null, targetEnd = new EndResult( ) { param1 = life.data.rtData.totalHp * 10, param2 = 0, param3 = 2, }, }; WarSrcAnimParam warParam = new WarSrcAnimParam() { OP = EffectOp.Injury, described = des, }; } /// /// ---- 释放技能 --- /// castBuff_Skill(rtbf, BuffPhase.End); }
//更新 private void uploadStatus(GameNpc npc) { this.textOfStatusPanel.text = NpcStatus.getStatus(npc); }
public StatusInfoItem(NpcStatus s, bool add) { status = s; isAdd = add; }
//检测一个或多个,单必须全部满足 public static bool check(this NpcStatus flags, NpcStatus totest) { return((flags & totest) == totest); }