QUOTE |
public virtual bool DoActionWander() { // ARTEGORDONMOD // allow followers with variable following ranges XmlValue follower = (XmlValue)XmlAttach.FindAttachment(m_Mobile, typeof(XmlValue), "Follower"); int followrange = 1; if (follower != null) followrange = follower.Value; if (CheckHerding()) { m_Mobile.DebugSay("Praise the shepherd!"); } else if (m_Mobile.CurrentWayPoint != null) { WayPoint point = m_Mobile.CurrentWayPoint; if ((point.X != m_Mobile.Location.X || point.Y != m_Mobile.Location.Y) && point.Map == m_Mobile.Map && point.Parent == null && !point.Deleted) { m_Mobile.DebugSay("I will move towards my waypoint."); DoMove(m_Mobile.GetDirectionTo(m_Mobile.CurrentWayPoint)); } else if (OnAtWayPoint()) { m_Mobile.DebugSay("I will go to the next waypoint"); m_Mobile.CurrentWayPoint = point.NextPoint; if (point.NextPoint != null && point.NextPoint.Deleted) m_Mobile.CurrentWayPoint = point.NextPoint = point.NextPoint.NextPoint; } } // ARTEGORDONMOD // allow any creatures to follow a summonmaster else if (m_Mobile.IsAnimatedDead || follower != null) { // animated dead follow their master Mobile master = m_Mobile.SummonMaster; // ARTEGORDONMOD // support variable following range if (master != null && master.Map == m_Mobile.Map && master.InRange(m_Mobile, m_Mobile.RangePerception + followrange)) MoveTo(master, false, followrange); else WalkRandomInHome(2, 2, 1); } |
QUOTE |
public virtual bool DoActionWander() { // ARTEGORDONMOD // allow the creature to follow a summonmaster at the specified distance int followrange = 1; if (m_Mobile.FollowRange > 0) followrange = m_Mobile.FollowRange; if (CheckHerding()) { m_Mobile.DebugSay("Praise the shepherd!"); } else if (m_Mobile.CurrentWayPoint != null) { WayPoint point = m_Mobile.CurrentWayPoint; if ((point.X != m_Mobile.Location.X || point.Y != m_Mobile.Location.Y) && point.Map == m_Mobile.Map && point.Parent == null && !point.Deleted) { m_Mobile.DebugSay("I will move towards my waypoint."); DoMove(m_Mobile.GetDirectionTo(m_Mobile.CurrentWayPoint)); } else if (OnAtWayPoint()) { m_Mobile.DebugSay("I will go to the next waypoint"); m_Mobile.CurrentWayPoint = point.NextPoint; if (point.NextPoint != null && point.NextPoint.Deleted) m_Mobile.CurrentWayPoint = point.NextPoint = point.NextPoint.NextPoint; } } // ARTEGORDONMOD // allow any creatures to follow a summonmaster else if (m_Mobile.IsAnimatedDead || m_Mobile.FollowRange > 0) { // animated dead follow their master Mobile master = m_Mobile.SummonMaster; // ARTEGORDONMOD // support variable following range if (master != null && master.Map == m_Mobile.Map && master.InRange(m_Mobile, m_Mobile.RangePerception + followrange)) MoveTo(master, false, followrange); else WalkRandomInHome(2, 2, 1); } else if (CheckMove()) { if (!m_Mobile.CheckIdle()) WalkRandomInHome(2, 2, 1); } if (m_Mobile.Combatant != null && !m_Mobile.Combatant.Deleted && m_Mobile.Combatant.Alive && !m_Mobile.Combatant.IsDeadBondedPet) { m_Mobile.Direction = m_Mobile.GetDirectionTo(m_Mobile.Combatant); } return true; } |
QUOTE |
public class BaseCreature : Mobile, IHonorTarget { public const int MaxLoyalty = 100; // ARTEGORDONMOD // allow any creature to follow a summonmaster if FollowRange > 0 public int FollowRange = -1; |
CODE |
using System; using Server; using Server.Items; using Server.Network; using Server.Mobiles; namespace Server.Engines.XmlSpawner2 { public class XmlFollow : XmlAttachment { private int m_DataValue; [CommandProperty(AccessLevel.GameMaster)] public int Distance { get { return m_DataValue; } set { m_DataValue = value; if (AttachedTo is BaseCreature) { ((BaseCreature)AttachedTo).FollowRange = m_DataValue; } } } // These are the various ways in which the message attachment can be constructed. // These can be called via the [addatt interface, via scripts, via the spawner ATTACH keyword. // Other overloads could be defined to handle other types of arguments // a serial constructor is REQUIRED public XmlFollow(ASerial serial) : base(serial) { } [Attachable] public XmlFollow(int distance) { Distance = distance; } [Attachable] public XmlFollow(int distance, double expiresin) { Distance = distance; Expiration = TimeSpan.FromMinutes(expiresin); } public override void Serialize(GenericWriter writer) { base.Serialize(writer); writer.Write((int)0); // version 0 writer.Write(m_DataValue); } public override void Deserialize(GenericReader reader) { base.Deserialize(reader); int version = reader.ReadInt(); // version 0 m_DataValue = reader.ReadInt(); } public override void OnDelete() { base.OnDelete(); // remove the mod if (AttachedTo is BaseCreature) { ((BaseCreature)AttachedTo).FollowRange = -1; } } public override void OnAttach() { base.OnAttach(); // apply the mod immediately if attached to a mob if (AttachedTo is BaseCreature) { ((BaseCreature)AttachedTo).FollowRange = Distance; } } public override void OnReattach() { base.OnReattach(); // reapply the mod if attached to a mob if (AttachedTo is BaseCreature) { ((BaseCreature)AttachedTo).FollowRange = Distance; } } public override string OnIdentify(Mobile from) { if (from == null || from.AccessLevel == AccessLevel.Player || !(AttachedTo is BaseCreature)) return null; BaseCreature b = AttachedTo as BaseCreature; if (Expiration > TimeSpan.Zero) { return String.Format("Following {0} at Distance {1} expires in {2} mins", b.SummonMaster, Distance, Expiration.TotalMinutes); } else { return String.Format("Following {0} at Distance {1}", b.SummonMaster, Distance); } } } } |