RunUO Community

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

Waypoint Anomoly.

Enroq

Sorceror
So I've waypoints setup for guards to walk, and the guards have a few different AI Types. The problem I'm having is that my medic guards, will not execute waypoints. The first guess is the AI, but different mobiles with the same Healer AI preform the path as it is supposed to. I can't get the medics to follow the waypoints even when I set them to them to a known working ai such as mage or melee. So then you're like it's the mobile, but the mobile is the same base as all the other guards.

I was just wondering what you guys thought about it.
 

Panthar

Sorceror
I have actually have a similar anomoly that seems similar to yours, that I just can't figure out! I even created my own WayPoint class to try to diagnose.

Essentially what I have is a spawner, where I set the waypoint of the spawner, so that when the spanwer spawns, the monster is instructed to go to the way point, when the monster gets to it's waypoint, I want it to commit suicide. This works great when the server boots up, or when there are players near by.

The problem is,

IF NO PLAYERS are around the area of the spawner, after its "first run through on server start" the monster that spawns will not move at all.

IF PLAYERS ARE NEAR BY and the monster from the spawner is killed, the spawner will spawn a monster that correctly goes to it's waypoint.

The monster I am using is a MAGE_AI Monster, I have looked through the AI, as well as trying other AI's. I have looked through the onTick() and the Spawner.cs, with no avail.

I have a feeling something on the server is controlling this, meaning it's not sending the onTick() until players are near by?

Somehow the waypoints just don't work. The monsters stop going to the way points, and it's loosly related to players being around the spawner or not. I don't know what specifically the problem here is, but there is a file somewhere called like "PersistenceSpawner.cs" that is my next guess for why the waypoints inexplicably stop working.

If you find a solution, please post!

Thx
 

Enroq

Sorceror
That's actually a the product of a mobile variable that keeps them from moving when there's no players nearby, it's just a boolean in either basecreature or mobile.cs if I remember correctly. I'll try and find it, its' name escapes me =/

++ Check out this block in BaseCreature.cs
Code:
public virtual bool PlayerRangeSensitive { get { return (this.CurrentWayPoint == null); } }    //If they are following a waypoint, they'll continue to follow it even if players aren't around
 

Panthar

Sorceror
Wow! you are awesome. I thought my problem might of been related to yours, but this fixed the problem!
 

Enroq

Sorceror
Unfortunately my screen capture software is being a pain in the ass, so I can't really record anything right now. I'm probably going to have to get Tech Smith's - we'll see. As for the code:

Code:
using System;
using Server;
using Server.Items;
using Server.Mobiles;
using System.Collections.Generic;
using Server.Spells;
 
namespace Server.Mobiles
{
    public enum GuardType
    {
        Pikeman,
        Swordsman,
        Archer,
        Cavalry,
        Wizard,
        Medic
    }
 
    [CorpseName("a fallen Imperial guard")]
    public class Guard : BaseCreature
    {
        private GuardType m_Type;
 
        [CommandProperty(AccessLevel.GameMaster)]
        public GuardType Type { get { return m_Type; } }
 
        [Constructable]
        public Guard(GuardType type)
            : this(type, AIType.AI_Melee)
        {
        }
 
        [Constructable]
        public Guard(GuardType type, AIType ai)
            : base(ai, FightMode.Closest, 20, 1, 0.2, 0.4)
        {
            m_Type = type;
 
            Title = GetTitle(type);
            Hue = Utility.RandomSkinHue();
 
            if(m_Type == GuardType.Wizard)
                ChangeAIType(AIType.AI_Mage);
 
            if (m_Type == GuardType.Archer)
                ChangeAIType(AIType.AI_Archer);
 
            if (m_Type == GuardType.Medic)
                ChangeAIType(AIType.AI_Healer);
 
            if (0.35 >= Utility.RandomDouble())
            {
                Name = NameList.RandomName("female") + ",";
                Female = true;
                Body = 0x191;
            }
            else
            {
                Name = NameList.RandomName("male") + ",";
                Body = 0x190;
                FacialHairItemID = Utility.RandomList(0x203E, 0x203F, 0x2040, 0x2041, 0x204B, 0x204C, 0x204D);
            }
 
            SetStatsAndSkills(type);
 
            SetDamage(7, 13);
            SetDamageType(ResistanceType.Physical, 100);
 
            SetResistance(ResistanceType.Physical, 55, 65);
            SetResistance(ResistanceType.Fire, 40, 50);
            SetResistance(ResistanceType.Cold, 30, 45);
            SetResistance(ResistanceType.Poison, 40, 50);
            SetResistance(ResistanceType.Energy, 50, 60);
 
            HairItemID = Utility.RandomList(0x203B, 0x203C, 0x203D, 0x2048);
            HairHue = FacialHairHue = Utility.RandomHairHue();
 
            Backpack pack = new Backpack();
            pack.AddItem(new Bandage(Utility.RandomMinMax(100, 200)));
 
            this.AddItem(pack);
 
            AddEquipment(type);
 
            if (type == GuardType.Cavalry)
            {
                Horse horse = new Horse();
                horse.Body = 0xE4;
                horse.Controlled = true;
                horse.ControlMaster = this;
                horse.ControlOrder = OrderType.Come;
                horse.RawName = "an Imperial War Horse";
                horse.Hue = 1410;
                horse.ItemID = 16033;
                horse.Rider = this;
 
                horse.RawStr += Utility.RandomMinMax(45, 60);
                horse.RawDex += Utility.RandomMinMax(25, 30);
                horse.RawInt += Utility.RandomMinMax(15, 20);
 
                horse.SetSkill(SkillName.Wrestling, horse.Skills.Wrestling.Value + Utility.RandomMinMax(15, 20));
                horse.SetSkill(SkillName.Tactics, horse.Skills.Tactics.Value + Utility.RandomMinMax(20, 25));
                horse.SetSkill(SkillName.MagicResist, horse.Skills.MagicResist.Value + Utility.RandomMinMax(30, 40));
 
            }
        }
 
        public Guard(Serial serial)
            : base(serial)
        {
        }
 
        public override bool BardImmune { get { return true; } }
 
        #region Stats
        private string GetTitle(GuardType type)
        {
            string title;
 
            switch (type)
            {
                default:
                case GuardType.Archer: title = "the Imperial Archer"; break;
                case GuardType.Cavalry: title = "Imperial Cavalry"; break;
                case GuardType.Pikeman: title = "the Imperial Hoplite"; break;
                case GuardType.Swordsman: title = "the Imperial Knight"; break;
                case GuardType.Wizard: title = "the Imperial Wizard"; break;
                case GuardType.Medic: title = "the Imperial Medic"; break;
            }
 
            return title;
        }
 
        private void SetStatsAndSkills(GuardType type)
        {
            switch (type)
            {
                default:
                case GuardType.Cavalry:
                case GuardType.Pikeman:
                case GuardType.Swordsman:
                    {
                        SetStr(150, 175);
                        SetDex(80, 100);
                        SetInt(65, 80);
 
                        SetHits(475, 700);
 
                        SetSkill(SkillName.Tactics, 85, 100);
                        SetSkill(SkillName.Healing, 65, 85);
                        SetSkill(SkillName.Anatomy, 100, 110);
                        SetSkill(SkillName.Wrestling, 95, 110);
                        SetSkill(SkillName.Swords, 95, 105);
                        SetSkill(SkillName.Fencing, 95, 105);
                        SetSkill(SkillName.MagicResist, 95, 105);
 
                    } break;
                case GuardType.Archer:
                    {
                        SetStr(100, 130);
                        SetDex(125, 140);
                        SetInt(75, 90);
 
                        SetHits(300, 400);
 
                        SetSkill(SkillName.Tactics, 85, 100);
                        SetSkill(SkillName.Healing, 65, 85);
                        SetSkill(SkillName.Anatomy, 100, 105);
                        SetSkill(SkillName.Wrestling, 75, 80);
                        SetSkill(SkillName.Archery, 95, 105);
                        SetSkill(SkillName.MagicResist, 95, 105);
 
                        this.RangeFight = 6;
                    } break;
                case GuardType.Wizard:
                    {
                        SetStr(75, 80);
                        SetDex(100, 125);
                        SetInt(175, 200);
 
                        SetHits(200, 250);
                        SetMana(200, 300);
 
                        SetSkill(SkillName.Tactics, 70, 85);
                        SetSkill(SkillName.Wrestling, 70, 85);
                        SetSkill(SkillName.Magery, 90, 1000);
                        SetSkill(SkillName.EvalInt, 95, 105);
                        SetSkill(SkillName.Focus, 60, 70);
                        SetSkill(SkillName.Macing, 90, 100);
                        SetSkill(SkillName.MagicResist, 95, 105);
                        SetSkill(SkillName.Meditation, 90, 100);
 
                    } break;
 
                case GuardType.Medic:
                    {
                        SetStr(75, 80);
                        SetDex(100, 125);
                        SetInt(175, 200);
 
                        SetHits(200, 250);
                        SetMana(200, 300);
 
                        SetSkill(SkillName.Tactics, 40, 55);
                        SetSkill(SkillName.Wrestling, 90, 105);
                        SetSkill(SkillName.Magery, 100, 105);
                        SetSkill(SkillName.EvalInt, 55, 65);
                        SetSkill(SkillName.Focus, 60, 70);
                        SetSkill(SkillName.Meditation, 90, 100);
                        SetSkill(SkillName.MagicResist, 95, 105);
 
                    } break;
            }
        }
 
        private void AddEquipment(GuardType type)
        {
            AddItem(new Boots());
            AddItem(new Cloak(1155));
            AddItem(new BodySash(1155));
 
            switch (type)
            {
                default:
                case GuardType.Archer:
                    {
                        AddItem(new LeatherLegs());
                        AddItem(new StuddedChest());
                        AddItem(new LeatherGloves());
                        AddItem(new LeatherArms());
 
                        Bow bow = new Bow();
                        bow.Quality = WeaponQuality.Exceptional;
 
                        AddItem(bow);
                        AddToBackpack(new Arrow(200));
                    } break;
                case GuardType.Cavalry:
                    {
                        AddItem(new PlateLegs());
                        AddItem(new RingmailChest());
                        AddItem(new FancyShirt());
                        AddItem(new PlateGorget());
                        AddItem(new RingmailGloves());
 
                        BaseWeapon weapon;
 
                        if (Utility.RandomBool())
                            weapon = new Halberd();
                        else
                            weapon = new Bardiche();
 
                        weapon.Quality = WeaponQuality.Exceptional;
                        weapon.Resource = CraftResource.Gold;
                        weapon.Speed += 5;
 
                        AddItem(weapon);
                    } break;
 
                case GuardType.Pikeman:
                    {
                        AddItem(new RingmailLegs());
                        AddItem(new RingmailChest());
                        AddItem(new RingmailArms());
                        AddItem(new RingmailGloves());
                        AddItem(new PlateGorget());
 
                        if (Utility.RandomBool())
                            AddItem(new CloseHelm());
                        else
                            AddItem(new NorseHelm());
 
                        AddItem(new Pike());
                    }
                    break;
 
                case GuardType.Swordsman:
                    {
                        AddItem(new ChainLegs());
                        AddItem(new ChainChest());
                        AddItem(new RingmailArms());
                        AddItem(new RingmailGloves());
                        AddItem(new PlateGorget());
 
                        switch (Utility.Random(3))
                        {
                            case 0: AddItem(new CloseHelm()); break;
                            case 1: AddItem(new NorseHelm()); break;
                            case 2: AddItem(new PlateHelm()); break;
                        }
 
                        BaseWeapon weapon;
 
                        switch (Utility.Random(4))
                        {
                            default:
                            case 0: weapon = new Broadsword(); break;
                            case 1: weapon = new Longsword(); break;
                            case 2: weapon = new Katana(); break;
                            case 3: weapon = new Axe(); break;
                        }
 
                        weapon.Quality = WeaponQuality.Exceptional;
                        weapon.Resource = CraftResource.Gold;
                        weapon.Layer = Layer.OneHanded;
 
                        AddItem(weapon);
 
                        if (Utility.RandomBool())
                            AddItem(new HeaterShield());
                        else
                            AddItem(new MetalKiteShield());
                    }
                    break;
 
                case GuardType.Wizard:
                    {
                        AddItem(new WizardsHat(Utility.RandomGreenHue()));
                        AddItem(new Robe(Utility.RandomGreenHue()));     
 
                        GnarledStaff staff = new GnarledStaff();
                        staff.Attributes.SpellChanneling = 1;
                        staff.Attributes.SpellDamage = Utility.RandomMinMax(4, 8);
                        AddItem(staff);
                    }
                    break;
 
                case GuardType.Medic:
                    {
                        AddItem(new Bandana(Utility.RandomGreenHue()));
                        AddItem(new Robe(Utility.RandomGreenHue()));
                    }
                    break;
            }
        }
        #endregion
 
        public override bool OnMoveOver(Mobile m)
        {
            return true;
        }
 
        public override bool IsEnemy(Mobile m)
        {
            int noto = Server.Misc.NotorietyHandlers.MobileNotoriety(this, m);
 
            if (noto == Notoriety.Criminal || noto == Notoriety.Murderer || noto == Notoriety.Enemy)
                return true;
 
            return false;
        }
 
        public override void OnThink()
        {
            //Adjust to control speed of recognition
            if (Utility.RandomDouble() > 0.75)
            {
                if (!SpellHelper.CheckCombat(this))
                {
                    //Safeguard due to how often OnThink() is called.
                    //Can be removed for preformance gains, though minor.
                    try
                    {
                        foreach (Mobile mobile in this.GetMobilesInRange(10))
                        {
                            int noto = Server.Misc.NotorietyHandlers.MobileNotoriety(this, mobile);
                            bool isEnemy = (noto == Notoriety.Criminal || noto == Notoriety.Murderer || noto == Notoriety.Enemy);   
               
                            if (this.Combatant == null && isEnemy && this.CanSee(mobile))
                            {
                              this.DoHarmful(mobile);
                            }                   
                        }
                    }
 
                    catch { }
                }
            } 
        }
 
        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);
 
            writer.Write((int)0);
 
            writer.Write((int)m_Type);
        }
 
        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);
 
            int version = reader.ReadInt();
 
            m_Type = (GuardType)reader.ReadInt();
        }
    }
}
 
Top