Full Version : Follow The Leader?
xmlspawner >>XMLSpawner Mods and Tips >>Follow The Leader?


<< Prev | Next >>

morganm- 12-27-2006
Hail once again =^.^=

Is there a way to make a boss MOB spawn and his minions that spawn after him then follow everywhere he goes? That way if someone tries to lead off the boss the minions will follow the leader everywhere he goes.

I have a boss that spawns. Would like to spawn some minions after him to spice up the whole encounter somewhat. However peopel will just lead the boss off and then the minions will spawn in the other room rendering them useless in protecting the leader.

Anotehr idea would be to have the minions spawn at the boss' current location. That way if the lead him off the next minion spawn will pop up near the boss. Thus protecting him and making it more of a challenge for the player.

Thank you.

ArteGordon- 12-27-2006
there is an example of that sort of thing in xmlextras called masterhelper.xml

When the master is attacked, it sets the combatant of the helpers to the attacker.

ArteGordon- 12-28-2006
You can also make a simple little mod to BaseAI.cs to allow any creature to follow a master. In the DoActionWander method

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);
            }


and then when you spawn it, just set the SummonMaster property and add the XmlValue attachment named "Follower" with the desired following range and the creature will follow the master wherever it goes.

For example:

subgroup 1: orcishlord
subgroup 1: orc/summonmaster/GETONSPAWN,1,SERIAL/ATTACH/xmlvalue,Follower,2


I tested it out and it is pretty cool.

You could also use the mod to spawn a creature that followed around a player for some period of time with something like

dog/summonmaster/GETONTRIGMOB,SERIAL/ATTACH/xmlvalue,Follower,2,10

which would spawn an dog that tried to stay within 2 tiles of the player for 10 minutes.

ArteGordon- 12-28-2006
here is another relevant post on controlling pulling
http://runuo.com/forums/showthread.php?p=3...ange#post320963

ArteGordon- 12-28-2006
Here is a slightly more efficient version that doesnt require accessing the attachment on every AI wandering check.
It uses a custom attachment called XmlFollow.cs and mods to basecreature.cs and baseai.cs

baseai.cs
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;
        }


basecreature.cs

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;



XmlFollow.cs
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);
           }
       }
   }
}



and to use it spawn the creatures like

subgroup 1: orcishlord
subgroup 1: orc/summonmaster/GETONSPAWN,1,SERIAL/ATTACH/xmlfollow,2


or

dog/summonmaster/GETONTRIGMOB,SERIAL/ATTACH/xmlfollow,2,10