void Start() { //获取被操控的角色 aiObject = GetComponent <AIObject>(); //获取最大速度 maxSpeed = aiObject.maxSpeed; }
public override void OnThink() { if (SummonMaster?.Deleted != false) { Delete(); } /* * On OSI, without combatant, they behave as if they have been * given "come" command, ie they wander towards their summoner, * but never actually "follow". */ else if (!Combat(this)) { AIObject?.MoveTo(SummonMaster, false, 5); } /* * On OSI, if the summon attacks a mobile, the summoner meer also * attacks them, regardless of karma, etc. as long as the combatant * is a player or controlled/summoned, and the summoner is not already * engaged in combat. */ else if (!Combat(SummonMaster)) { if (Combatant.Player || Combatant is BaseCreature bc && (bc.Controlled || bc.SummonMaster != null)) { SummonMaster.Combatant = Combatant; } } else { base.OnThink(); } }
private Vector3 Hide(AIAgent hunter, List <AIObject> obstacles) { float DistToClosest = float.MaxValue; Vector3 BestHidingSpot = Vector3.zero; AIObject closest; for (int i = 0; i < obstacles.Count; ++i) { AIObject curOb = obstacles[i]; Vector3 hidingSpot = GetHidingPosition(curOb.VPos(), curOb.BRadius(), hunter.VPos()); float dist = (m_entity.VPos() - hidingSpot).sqrMagnitude; DistToClosest = dist; BestHidingSpot = hidingSpot; if (dist < DistToClosest) { closest = curOb; } } //if no suitable obstacles found then Evade the hunter if (DistToClosest == float.MaxValue) { return(Evade(hunter)); } //else use Arrive on the hiding spot return(Arrive(BestHidingSpot, Deceleration.fast)); }
public void TagObstaclesWithinViewRange(AIAgent entity, float radius) { IEnumerator <AIObject> it = m_Obstacles.GetEnumerator(); while (it.MoveNext()) { AIObject curEntity = it.Current; //first clear any current tag curEntity.UnTagging(); Vector3 to = curEntity.VPos() - entity.VPos(); //the bounding radius of the other is taken into account by adding it //to the range float range = radius + curEntity.BRadius(); //if entity within range, tag for further consideration. (working in //distance-squared space to avoid sqrts) if ((curEntity.GetHashCode() != entity.GetHashCode()) && (to.sqrMagnitude < range * range)) { curEntity.Tagging(); } } }
public void Goto(int x, int y, int z) { if (!AIObject.MoveToDistant(new Point3D(x, y, z), false)) { this.DebugSay("Unable to reach location"); CurrentSpeed = 3; } }
public override void OnThink() { Mobile master = ControlMaster; if (Deleted) { return; } if (master == null || master.Deleted) { DropPackContents(); EndRelease(null); return; } RangeCheck(); if (m_LastHidden != master.Hidden) { Hidden = m_LastHidden = master.Hidden; } if (AIObject != null && AIObject.WalkMobileRange(master, 5, true, 1, 1)) { if ((master.Combatant != null) && (InRange(master.Combatant, 1))) { Warmode = master.Warmode; Combatant = master.Combatant; CurrentSpeed = 0.10; } if ((master.Combatant != null) && (!InRange(master.Combatant, 1))) { Warmode = false; FocusMob = null; Combatant = null; CurrentSpeed = 0.01; } if (master.Combatant == null) { Warmode = false; FocusMob = null; Combatant = null; CurrentSpeed = 0.01; } } else { Warmode = false; FocusMob = null; Combatant = null; CurrentSpeed = .01; } }
public List <Enemy> findEnemies(AIObject o, float radius) { List <Enemy> getEnemies = new List <Enemy> (); foreach (Enemy e in enemies) { if (Vector3.Distance(o.pos, e.pos) <= radius) { getEnemies.Add(e); } } return(getEnemies); }
public override void OnSpeech(SpeechEventArgs e) { //base.OnSpeech( e ); Mobile from = e.Mobile; if (from.InRange(this, 20)) { if (from != null) { if (e.Speech.ToLower().IndexOf("go") > -1) { string gostring = e.Speech.ToLower(); string[] goprops = gostring.Split(' '); int x, y, z; if (goprops.Length == 4) { x = GetIntArg(goprops[1]); y = GetIntArg(goprops[2]); z = GetIntArg(goprops[3]); } else if (goprops.Length == 3) { x = GetIntArg(goprops[1]); y = GetIntArg(goprops[2]); z = 0; } else { from.Target = new InternalTarget(this); return; } this.DebugSay("Going to location " + x + "," + y + "," + z); CurrentSpeed = 0.5; if (!AIObject.MoveToDistant(new Point3D(x, y, z), false)) { this.DebugSay("Unable to reach location"); CurrentSpeed = 3; } } if (e.Speech.ToLower().IndexOf("stop") > -1) { AIObject.StopMove(); CurrentSpeed = 3; } } } }
// Update is called once per frame void Update() { return; //{DataType : 10, ID : aiID, TeamID : -1, ...} float newAngle; Vector3 attack; string packet = "["; foreach (var AIObject in aiArray) { var AI = AIObject.GetComponent <AI>(); newAngle = faceClosest(AI); if (newAngle == -1) { AI.reload -= Time.fixedDeltaTime; continue; } if (AI.reload < 0) { string projectilePacket = getAttack(newAngle, AI); packet += projectilePacket + ","; AI.reload = 2; } else { AI.reload -= Time.fixedDeltaTime; } string localPacket = "{DataType : 9, ID : " + AI.aiID + ", x : " + AI.xCoord + ", y : " + AI.yCoord + ", facing : " + newAngle + "},"; packet += localPacket; } packet.Remove(packet.Length - 1); packet += "]"; Debug.Log("Sending packet: " + packet); NetworkingManager.instance.update_data(packet); /* if (!route) * { * curMove = getRoute(); * route = true; * } */ }
public List <Member> findNeighbours(AIObject o, float radius) { List <Member> neighbourFound = new List <Member>(); foreach (Member otherMember in members) { if (otherMember == o) { continue; } if (Vector3.Distance(o.transform.position, otherMember.transform.position) <= radius) { neighbourFound.Add(otherMember); } } return(neighbourFound); }
public bool Overlapped(AIObject ob, List <AIObject> conOb, float MinDistBetweenObstacles) { IEnumerator <AIObject> it = conOb.GetEnumerator(); while (it.MoveNext()) { AIObject tmp = it.Current; if (MathUtil.TwoCirclesOverlapped(ob.VPos(), ob.BRadius() + MinDistBetweenObstacles, tmp.VPos(), tmp.BRadius())) { return(true); } } return(false); }
public void Load() { AIBase AIObject; AIList.Clear(); //We do this for all the lists of characters foreach (CharacterData data in saveManager.SaveData.worldData.AIData.characters) { AIObject = Instantiate(characterPrefabs[data.id], data.position, Quaternion.identity).GetComponent <AIBase>(); AIObject.loaded = true; AIObject.Load(data); } foreach (BuilderData data in saveManager.SaveData.worldData.AIData.builders) { AIObject = Instantiate(builderPrefabs[data.id], data.position, Quaternion.identity).GetComponent <AIBase>(); AIObject.loaded = true; AIObject.Load(data); } }
public void SetCrosshair(Vector3 p, string id = "basic") { Vector3 ProposedPosition = p; //make sure it's not inside an obstacle for (int i = 0; i < m_Obstacles.Count; ++i) { AIObject curOb = m_Obstacles[i]; if (MathUtil.PointInCircle(curOb.VPos(), curOb.BRadius(), ProposedPosition)) { return; } } AIGroup aiGroup = GetAIGroup(id); if (aiGroup != null) { aiGroup.SetCrosshair(p); } }
public override void OnThink() { var master = ControlMaster; if (Deleted) { return; } if (master?.Deleted != false) { DropPackContents(); EndRelease(null); return; } RangeCheck(); if (m_LastHidden != master.Hidden) { Hidden = m_LastHidden = master.Hidden; } if (AIObject?.WalkMobileRange(master, 5, true, 1, 1) == true) { Warmode = master.Warmode; Combatant = master.Combatant; CurrentSpeed = 0.10; } else { Warmode = false; FocusMob = Combatant = null; CurrentSpeed = .01; } }
public void Load(string path) { using (FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read)) { BinaryReader reader = new BinaryReader(fileStream); uint Count = reader.ReadUInt32(); for (uint i = 0; i < Count; i++) { AIObject Object = new AIObject(); string tempName = new string(reader.ReadChars(0x10)); Object.Name = tempName.Trim('\0'); uint VectorCount = reader.ReadUInt32(); Object.Pos = new List <TWOC_Vector3>(); for (int v = 0; v < VectorCount; v++) { Object.Pos.Add(new TWOC_Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle())); } AI.Add(Object); } } }
public override void OnThink() { base.OnThink(); if (Deleted || !Alive || Aspect == null || !Aspect.InCombat() || Core.TickCount < _NextHeal) { return; } if (ControlMaster != Aspect) { ControlMaster = Aspect; } if (ControlTarget != Aspect) { ControlTarget = Aspect; } if (ControlOrder != OrderType.Follow) { ControlOrder = OrderType.Follow; } if (!InRange(Aspect, Aspect.RangePerception)) { AIObject.MoveTo(Aspect, true, Aspect.RangePerception); return; } _NextHeal = Core.TickCount + 5000; var q = new MovingEffectQueue(); q.Callback = q.Dispose; for (var i = 0; i < 5; i++) { var fx = new MovingEffectInfo( this, Aspect, Map, 0x36F4, 1150, 10, EffectRender.LightenMore, TimeSpan.FromMilliseconds(200)); fx.ImpactCallback += HealAspect; q.Add(fx); } if (this.PlayAttackAnimation()) { this.PlayAttackSound(); this.TryParalyze( TimeSpan.FromSeconds(1.5), m => { SpellHelper.Turn(m, Aspect); q.Process(); }); } else { SpellHelper.Turn(this, Aspect); q.Process(); } }
public override void OnThink() { if (ControlMaster != null && QuestOverride) { if (X == 1076 && Y == 450) { AIObject.MoveTo(ControlMaster, false, 1); PlayerMobile pm = ControlMaster as PlayerMobile; if (pm != null) { QuestSystem qs = pm.Quest; if (qs is DarkTidesQuest) { QuestObjective obj = qs.FindObjective(typeof(FetchAbraxusScrollObjective)); if (obj != null && !obj.Completed) { AddToBackpack(new ScrollOfAbraxus()); obj.Complete(); CurrentSpeed = 0.1; QuestOverride = false; } } } } return; } base.OnThink(); if (DateTime.UtcNow < m_NextPickup) { return; } m_NextPickup = DateTime.UtcNow + TimeSpan.FromSeconds(Utility.RandomMinMax(5, 10)); Container pack = Backpack; if (pack == null) { return; } ArrayList list = new ArrayList(); foreach (Item item in GetItemsInRange(2)) { if (item.Movable && item.Stackable) { list.Add(item); } } int pickedUp = 0; for (int i = 0; i < list.Count; ++i) { Item item = (Item)list[i]; if (!pack.CheckHold(this, item, false, true)) { return; } bool rejected; LRReason reject; NextActionTime = Core.TickCount; Lift(item, item.Amount, out rejected, out reject); if (rejected) { continue; } Drop(this, Point3D.Zero); if (++pickedUp == 3) { break; } } }
/** * Given a vector of obstacles, this method returns a steering force * that will prevent the agent colliding with the closest obstacle */ private Vector3 ObstacleAvoidance(List <AIObject> obstacles) { //* //the detection box length is proportional to the agent's velocity m_fDBoxLength = minDetectionBoxLength + (m_entity.Speed() / m_entity.MaxSpeed()) * minDetectionBoxLength; //tag all obstacles within range of the box for processing m_entity.World().TagObstaclesWithinViewRange(m_entity, m_fDBoxLength); //this will keep track of the closest intersecting obstacle (CIB) AIObject ClosestIntersectingObstacle = null; //this will be used to track the distance to the CIB float DistToClosestIP = float.MaxValue; //this will record the transformed local coordinates of the CIB Vector3 LocalPosOfClosestObstacle = Vector3.zero; IEnumerator <AIObject> it = obstacles.GetEnumerator(); for (int i = 0; i < obstacles.Count; ++i) { //if the obstacle has been tagged within range proceed AIObject curOb = obstacles[i]; if (curOb.Tag) { //calculate this obstacle's position in local space Vector3 LocalPos = MathUtil.PointToLocalSpace(curOb.VPos(), m_entity.Heading(), m_entity.Side(), m_entity.VPos()); // entity Heading and LocalPos is if (Vector3.Dot(LocalPos, Vector3.forward) > 0) { //than its radius + half the width of the detection box then there //is a potential intersection. float ExpandedRadius = curOb.BRadius() + m_entity.BRadius(); if (Mathf.Abs(LocalPos.x) < ExpandedRadius) { //test to see if this is the closest so far. If it is keep a //record of the obstacle and its local coordinates if (LocalPos.magnitude < DistToClosestIP) { DistToClosestIP = LocalPos.magnitude; ClosestIntersectingObstacle = curOb; LocalPosOfClosestObstacle = LocalPos; } } } } } //if we have found an intersecting obstacle, calculate a steering //force away from it Vector3 steeringForce = Vector3.zero; if (ClosestIntersectingObstacle != null) { //should be //the closer the agent is to an object, the stronger the //steering force should be float multiplier = 1.0f + (m_fDBoxLength - LocalPosOfClosestObstacle.z) / m_fDBoxLength; //calculate the lateral force steeringForce.x = (ClosestIntersectingObstacle.BRadius() - LocalPosOfClosestObstacle.x) * multiplier; //apply a braking force proportional to the obstacles distance from //the vehicle. float BrakingWeight = 0.2f; steeringForce.z = (ClosestIntersectingObstacle.BRadius() - LocalPosOfClosestObstacle.z) * BrakingWeight; } //finally, convert the steering vector from local to world space return(MathUtil.VectorToWorldSpace(steeringForce, m_entity.Heading(), m_entity.Side())); }
public override void OnThink() { if (Deleted || Map == null) { return; } Mobile master = ControlMaster; if (master == null || master.Deleted) { DropPackContents(); EndRelease(null); return; } if (m_LastHidden != master.Hidden) { Hidden = m_LastHidden = master.Hidden; } if (RangeCheck()) { if (AIObject != null && AIObject.WalkMobileRange(master, 5, true, 1, 1)) { if (master.Combatant != null && master.InRange(master.Combatant, 1) && Core.TickCount > m_NextMove) { IDamageable combatant = master.Combatant; if (!InRange(combatant.Location, 1)) { for (int x = combatant.X - 1; x <= combatant.X + 1; x++) { for (int y = combatant.Y - 1; y <= combatant.Y + 1; y++) { if (x == combatant.X && y == combatant.Y) { continue; } Point2D p = new Point2D(x, y); if (InRange(p, 1) && master.InRange(p, 1) && Map != null) { CurrentSpeed = .01; AIObject.MoveTo(new Point3D(x, y, Map.GetAverageZ(x, y)), false, 0); m_NextMove = Core.TickCount + 500; } } } } else { CurrentSpeed = .1; } } else if (master.Combatant == null) { CurrentSpeed = .1; } } else { CurrentSpeed = .1; } } }
public override void OnSpeech(SpeechEventArgs e) { Mobile from = e.Mobile; string mobileSpeechLowered = string.Empty; //Holds weather or not the vendor has been requested by a player bool hasRequestedVendor = false; //Only look for keywords if the speech still isn't handled if (!e.Handled) { mobileSpeechLowered = e.Speech.ToLower(); hasRequestedVendor = (!AIObject.NamedInRange(from, e.Speech) && (e.HasKeyword(0x171) || e.HasKeyword(0x171))) || AIObject.WasNamed(e.Speech); //Look for custom speech triggers if the vendor hasn't been named and if the keywords haven't been specified. if (!hasRequestedVendor) { for (int i = 0; i < m_BuyKeywords.Length; i++) { if (mobileSpeechLowered.Contains(m_BuyKeywords[i])) { hasRequestedVendor = true; break; } } } } else { return; } //Jump out if the vendor hasn't been requeted if (!hasRequestedVendor) { return; } //The barber will always react in some manner when we are passed this point e.Handled = true; //The barber is cutting someone if (m_CutTime != TimeSpan.Zero && m_CutTimer != null) { Speak(m_BusyResponse); return; } else if (InRange(from, m_MaxDistanceForCut)) { if (Combatant != null && Combatant != e.Mobile) { Speak(m_InCombatResponse); return; } else if (Combatant != null && Combatant == e.Mobile) { Speak(m_InCombatWithYouResponse); return; } if (FocusMob != from) { FocusMob = from; } //Buy if the mobile was named or if the player provided the buy keyword and another mobile wasnt named if (AIObject.WasNamed(e.Speech) || !AIObject.NamedInRange(from, e.Speech)) { //Checks if the stylist can cut hair and barbers through speech [string] buying. if (AllowSpeechBuying) { List <Item> styles = new List <Item>(); bool onlyBuyOne = (!mobileSpeechLowered.Contains("&") && !mobileSpeechLowered.Contains("and")); foreach (string s in m_HairAndBeardNames) { if (mobileSpeechLowered.Contains(s)) { Item styleItem = StyleItemFromString(s); if (styleItem != null) { if (styles.Count == 1 && onlyBuyOne) { Speak(m_BadBuyString); OnSpeechBuy(from, styles); return; } else { styles.Add(styleItem); } } } } // Try to buy the items if any styles have been selected if (styles.Count != 0) { OnSpeechBuy(from, styles); return; } else if (VendorBuyMethod == BuyStyle.SpeechOnly) { // Stop the buying if we haven't named a style and if the vendor doesnt accept any other buy method // otherwise just continiue to the other buy menus. Speak(m_NoStyleFound); return; } } if (e.HasKeyword(0x171)) // *buy* { if (VendorBuyMethod == BuyStyle.BuyMenuAndSpeech || VendorBuyMethod == BuyStyle.BuyMenu) { VendorBuy(from); } else if (VendorBuyMethod == BuyStyle.GumpMenuAndSpeech || VendorBuyMethod == BuyStyle.GumpMenu) { Speak("A BUY GUMP"); } } //Check if we can buy a hair style through the buy/sell menu or gump. else if (e.HasKeyword(0x177)) // *sell* { if (VendorBuyMethod == BuyStyle.BuyMenuAndSpeech || VendorBuyMethod == BuyStyle.BuyMenu) { VendorSell(from); } else if (VendorBuyMethod == BuyStyle.GumpMenuAndSpeech || VendorBuyMethod == BuyStyle.GumpMenu) { Speak("A SELL GUMP"); } } } } else { if (FocusMob != from) { FocusMob = from; } Speak(m_ToFarAway); } }