ServUO Version
Publish 57
Ultima Expansion
Endless Journey
I made this with ChatGPT and it's supposed to create an NPC that randomly casts the Bless spell on players. But it doesn't.

Bless casting NPC:
// File: FancyBlessingNPC.cs
using System;
using System.Linq;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.Spells;
using Server.Spells.Third; // Required for the Bless spell
using Server.Network;
using Server.Targeting;

namespace Server.Custom
{
    public class FancyBlessingNPC : BaseCreature
    {
        private static string[] FemaleNames = new string[]
        {
            "Althea", "Bianca", "Celeste", "Diana", "Elise", "Fiona", "Gwendolyn", "Helena", "Isolde", "Jasmine",
            "Katarina", "Liana", "Melisande", "Nadia", "Olivia", "Penelope", "Quinn", "Rosalind", "Seraphina", "Talia",
            "Ursula", "Valeria", "Willa", "Xanthe", "Yvonne", "Zara"
        };

        [Constructable]
        public FancyBlessingNPC() : base(AIType.AI_Mage, FightMode.None, 10, 1, 0.1, 0.2)
        {
            Name = FemaleNames[Utility.Random(FemaleNames.Length)];
            Body = 0x191; // Female human
            Hue = Utility.RandomSkinHue();
            HairItemID = 0x203C; // Long hair
            HairHue = Utility.RandomHairHue();

            FancyDress dress = new FancyDress();
            dress.Hue = Utility.RandomNeutralHue();
            AddItem(dress);

            Sandals sandals = new Sandals();
            sandals.Hue = Utility.RandomNeutralHue();
            AddItem(sandals);

            Blessed = true;

            Timer.DelayCall(TimeSpan.FromSeconds(1.0), TimeSpan.FromSeconds(10.0), MoveAndBless);
        }

        public void MoveAndBless()
        {
            if (Deleted || !Alive) return;

            // Move randomly
            if (Utility.RandomDouble() < 0.5)
            {
                Map map = this.Map;

                if (map != null)
                {
                    int x = X + Utility.RandomMinMax(-5, 5);
                    int y = Y + Utility.RandomMinMax(-5, 5);
                    int z = map.GetAverageZ(x, y);

                    if (map.CanSpawnMobile(new Point3D(x, y, z)))
                    {
                        SetLocation(new Point3D(x, y, z), true);
                    }
                }
            }

            // Find nearby players and bless them
            IPooledEnumerable eable = this.GetMobilesInRange(3);

            foreach (Mobile m in eable)
            {
                
                    Spell spell = new BlessSpell(this, null);
                    spell.Cast();

                    m.SendMessage("Blessed Be!");
                    break; // Cast only on one player per iteration
                
            }

            eable.Free();
        }

        public FancyBlessingNPC(Serial serial) : base(serial) { }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);
            writer.Write((int)0); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);
            int version = reader.ReadInt();
        }
    }
}
 
C#:
using System;
using System.Linq;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.Spells;
using Server.Spells.Third; // Required for the Bless spell
using Server.Network;
using Server.Targeting;

namespace Server.Custom
{
    public class FancyBlessingNPC : BaseCreature
    {
        private static string[] FemaleNames = new string[]
        {
            "Althea", "Bianca", "Celeste", "Diana", "Elise", "Fiona", "Gwendolyn", "Helena", "Isolde", "Jasmine",
            "Katarina", "Liana", "Melisande", "Nadia", "Olivia", "Penelope", "Quinn", "Rosalind", "Seraphina", "Talia",
            "Ursula", "Valeria", "Willa", "Xanthe", "Yvonne", "Zara"
        };

        [Constructable]
        public FancyBlessingNPC() : base(AIType.AI_Mage, FightMode.None, 10, 1, 0.1, 0.2)
        {
            Name = FemaleNames[Utility.Random(FemaleNames.Length)];
            Body = 0x191; // Female human
            Hue = Utility.RandomSkinHue();
            HairItemID = 0x203C; // Long hair
            HairHue = Utility.RandomHairHue();

            FancyDress dress = new FancyDress();
            dress.Hue = Utility.RandomNeutralHue();
            AddItem(dress);

            Sandals sandals = new Sandals();
            sandals.Hue = Utility.RandomNeutralHue();
            AddItem(sandals);

            Blessed = true;

            Timer.DelayCall(TimeSpan.FromSeconds(1.0), TimeSpan.FromSeconds(10.0), MoveAndBless);
        }

        public void MoveAndBless()
        {
            if (Deleted || !Alive) return;

            // Move randomly
            if (Utility.RandomDouble() < 0.5)
            {
                Map map = this.Map;

                if (map != null)
                {
                    int x = X + Utility.RandomMinMax(-5, 5);
                    int y = Y + Utility.RandomMinMax(-5, 5);
                    int z = map.GetAverageZ(x, y);

                    if (map.CanSpawnMobile(new Point3D(x, y, z)))
                    {
                        SetLocation(new Point3D(x, y, z), true);
                    }
                }
            }

            // Find nearby players and bless them
            IPooledEnumerable eable = this.GetMobilesInRange(3);

            foreach (Mobile m in eable)
            {
                
                    BlessSpell spell = new BlessSpell(this, null); //Explicit call
                    spell.Target(m); //Use Target, not Cast!

                    m.SendMessage("Blessed Be!");
                    break; // Cast only on one player per iteration
                
            }

            eable.Free();
        }

        public FancyBlessingNPC(Serial serial) : base(serial) { }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);
            writer.Write((int)0); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);
            int version = reader.ReadInt();
        }
    }
}
 
Well its normal, the "Bless" function has to be triggered by something, now its only triggered by the creation of the NPC which is weird and not very optimal. Try the "OnThink

This is whats currently doing the bless spell
"
C#:
Timer.DelayCall(TimeSpan.FromSeconds(1.0), TimeSpan.FromSeconds(10.0), MoveAndBless);
function
 
I'd stay away from using OnThink(), but agree, having a timer start up on creation isn't good either! The range of 3 on the check for players is very limiting, I envision it teleporting to a new location, checks within 3 tiles finds nothing then teleports again on next delay call, which will only work until the shard restarts as the timer isn't restarted on load!
 
I'd stay away from using OnThink(), but agree, having a timer start up on creation isn't good either! The range of 3 on the check for players is very limiting, I envision it teleporting to a new location, checks within 3 tiles finds nothing then teleports again on next delay call, which will only work until the shard restarts as the timer isn't restarted on load!
All Chinese to me fellas.
 
I made this with ChatGPT and it's supposed to create an NPC that randomly casts the Bless spell on players. But it doesn't.

Bless casting NPC:
// File: FancyBlessingNPC.cs
using System;
using System.Linq;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.Spells;
using Server.Spells.Third; // Required for the Bless spell
using Server.Network;
using Server.Targeting;

namespace Server.Custom
{
    public class FancyBlessingNPC : BaseCreature
    {
        private static string[] FemaleNames = new string[]
        {
            "Althea", "Bianca", "Celeste", "Diana", "Elise", "Fiona", "Gwendolyn", "Helena", "Isolde", "Jasmine",
            "Katarina", "Liana", "Melisande", "Nadia", "Olivia", "Penelope", "Quinn", "Rosalind", "Seraphina", "Talia",
            "Ursula", "Valeria", "Willa", "Xanthe", "Yvonne", "Zara"
        };

        [Constructable]
        public FancyBlessingNPC() : base(AIType.AI_Mage, FightMode.None, 10, 1, 0.1, 0.2)
        {
            Name = FemaleNames[Utility.Random(FemaleNames.Length)];
            Body = 0x191; // Female human
            Hue = Utility.RandomSkinHue();
            HairItemID = 0x203C; // Long hair
            HairHue = Utility.RandomHairHue();

            FancyDress dress = new FancyDress();
            dress.Hue = Utility.RandomNeutralHue();
            AddItem(dress);

            Sandals sandals = new Sandals();
            sandals.Hue = Utility.RandomNeutralHue();
            AddItem(sandals);

            Blessed = true;

            Timer.DelayCall(TimeSpan.FromSeconds(1.0), TimeSpan.FromSeconds(10.0), MoveAndBless);
        }

        public void MoveAndBless()
        {
            if (Deleted || !Alive) return;

            // Move randomly
            if (Utility.RandomDouble() < 0.5)
            {
                Map map = this.Map;

                if (map != null)
                {
                    int x = X + Utility.RandomMinMax(-5, 5);
                    int y = Y + Utility.RandomMinMax(-5, 5);
                    int z = map.GetAverageZ(x, y);

                    if (map.CanSpawnMobile(new Point3D(x, y, z)))
                    {
                        SetLocation(new Point3D(x, y, z), true);
                    }
                }
            }

            // Find nearby players and bless them
            IPooledEnumerable eable = this.GetMobilesInRange(3);

            foreach (Mobile m in eable)
            {
               
                    Spell spell = new BlessSpell(this, null);
                    spell.Cast();

                    m.SendMessage("Blessed Be!");
                    break; // Cast only on one player per iteration
               
            }

            eable.Free();
        }

        public FancyBlessingNPC(Serial serial) : base(serial) { }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);
            writer.Write((int)0); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);
            int version = reader.ReadInt();
        }
    }
}
Hey, try this:
Code:
using System;
using Server.Items;
using Server.Mobiles;
using System.Collections;
using System.Collections.Generic;

namespace Server.Custom
{
    public class FancyBlessingNPC : BaseCreature
    {
        private static Dictionary<Mobile, InternalTimer> _Table;

        private static string[] FemaleNames = new string[]
        {
            "Althea", "Bianca", "Celeste", "Diana", "Elise", "Fiona", "Gwendolyn", "Helena", "Isolde", "Jasmine",
            "Katarina", "Liana", "Melisande", "Nadia", "Olivia", "Penelope", "Quinn", "Rosalind", "Seraphina", "Talia",
            "Ursula", "Valeria", "Willa", "Xanthe", "Yvonne", "Zara"
        };

        [Constructable]
        public FancyBlessingNPC()
            : base(AIType.AI_Mage, FightMode.Aggressor, 10, 1, 0.1, 0.2)
        {
            Name = FemaleNames[Utility.Random(FemaleNames.Length)];
            Body = 0x191; // Female human
            Hue = Utility.RandomSkinHue();
            HairItemID = 0x203C; // Long hair
            HairHue = Utility.RandomHairHue();

            FancyDress dress = new FancyDress();
            dress.Hue = Utility.RandomNeutralHue();
            AddItem(dress);

            Sandals sandals = new Sandals();
            sandals.Hue = Utility.RandomNeutralHue();
            AddItem(sandals);

            Blessed = true;

            SetStr(100);
            SetInt(125);
            SetDex(75);

            //Timer.DelayCall(TimeSpan.FromSeconds(1.0), TimeSpan.FromSeconds(10.0), MoveAndBless);
        }

        public override void OnMovement(Mobile m, Point3D oldLocation)
        {
            if (m is PlayerMobile && InRange(m, 10) && InLOS(m))
            {
                MoveAndBless();
            }
                
        }

        private int m_Range = 10;

        public static bool IsBlessed(Mobile m)
        {
            return _Table != null && _Table.ContainsKey(m);
        }

        public static void AddBless(Mobile m, TimeSpan duration)
        {
            if (_Table == null)
                _Table = new Dictionary<Mobile, InternalTimer>();

            if (_Table.ContainsKey(m))
            {
                _Table[m].Stop();
            }

            _Table[m] = new InternalTimer(m, duration);
        }

        public static void RemoveBless(Mobile m, bool early = false)
        {
            if (_Table != null && _Table.ContainsKey(m))
            {
                _Table[m].Stop();
                m.Delta(MobileDelta.Stat);

                _Table.Remove(m);
            }
        }

        //private DateTime BlessTime;
        public void MoveAndBless()
        {

            //BlessTime = DateTime.UtcNow + TimeSpan.FromSeconds(5);
            ArrayList list = new ArrayList();
            IPooledEnumerable eable = GetMobilesInRange(m_Range);
            
            int amount = 20;
            
            foreach (Mobile m in eable)
            {
                if (m is PlayerMobile && !IsBlessed(m))
                {
                    list.Add(m);
                    m.AddStatMod(new StatMod(StatType.Str, "Blessed_Str", amount, TimeSpan.FromSeconds(60)));
                    m.AddStatMod(new StatMod(StatType.Dex, "Blessed_Dex", amount, TimeSpan.FromSeconds(60)));
                    m.AddStatMod(new StatMod(StatType.Int, "Blessed_Int", amount, TimeSpan.FromSeconds(60)));

                    m.FixedParticles(0x373A, 10, 15, 5018, EffectLayer.Waist);
                    m.PlaySound(0x1EA);
                    AddBless(m, TimeSpan.FromSeconds(60));
                }
            }
            eable.Free();

            if (list.Count > 0)
                Animate(AnimationType.Spell, 0);
        }


        public FancyBlessingNPC(Serial serial) : base(serial) { }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);
            writer.Write((int)0); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);
            int version = reader.ReadInt();
        }

        private class InternalTimer : Timer
        {
            public Mobile Mobile { get; set; }

            public InternalTimer(Mobile m, TimeSpan duration)
                : base(duration)
            {
                Mobile = m;
                Start();
            }

            protected override void OnTick()
            {
                RemoveBless(Mobile);
            }
        }
    }
}

Hope this helps
 
Back