ServUO Version
Publish 57
Ultima Expansion
Time Of Legends
hello folks, i created new custom fire field spell for ACC systems and its working like charm except one thing:
spell should not damage caster or players who are in "Imperial Order" faction, but everyone in area takes damage from the field including caster. here is the code part .. dont know what im doing wrong. im using latest servuo Publish 57.3.

C#:
public override bool OnMoveOver(Mobile m)
{
    if (Visible && m_Caster != null && m != m_Caster && SpellHelper.ValidIndirectTarget(m_Caster, m) && m_Caster.CanBeHarmful(m, false))
    {
        m_Caster.DoHarmful(m);

        int damage = Utility.Random(35, 75);

        if (!Core.AOS && m.CheckSkill(SkillName.MagicResist, 0.0, 30.0))
        {
            damage = Utility.Random(25, 65);
            m.SendLocalizedMessage(501783); // You feel yourself resisting magical energy.
        }

        if (m is PlayerMobile player)
        {
            Faction faction = Faction.Find(player);

            if (faction != null && faction.Definition != null && faction.Definition.ToString() == "Imperial Order")
            {
                // Player belongs to Imperial Order faction, do not apply damage
                return true;
            }
        }

        if (m != m_Caster)
        {
            AOS.Damage(m, m_Caster, damage, 0, 100, 0, 0, 0);
        }

        m.PlaySound(0x207);
    }

    return true;
}
 
Not seeing how your current implementation would cause damage to the caster nor the specified faction.
But I do see another issue.

You first do DoHarmful, then check the faction.
Therefor the ordering is / was off.

Additionally, if your faction class name is ImperialOrder, you can just use the static Instance property.

Also since you check for m != m_Caster in the main condition, you wouldnt need to do the same again inside.

And lastly, depending on your ServUO version, dont forget to recompile

C#:
public override bool OnMoveOver(Mobile m)
{
    if (Visible && m_Caster != null && m != m_Caster && Faction.Find(m) != ImperialOrder.Instance && SpellHelper.ValidIndirectTarget(m_Caster, m) && m_Caster.CanBeHarmful(m, false))
    {
        m_Caster.DoHarmful(m);

        int damage = Utility.Random(35, 75);

        if (!Core.AOS && m.CheckSkill(SkillName.MagicResist, 0.0, 30.0))
        {
            damage = Utility.Random(25, 65);
            m.SendLocalizedMessage(501783); // You feel yourself resisting magical energy.
        }

        AOS.Damage(m, m_Caster, damage, 0, 100, 0, 0, 0);

        m.PlaySound(0x207);
    }

    return true;
}
 
Not seeing how your current implementation would cause damage to the caster nor the specified faction.
But I do see another issue.

You first do DoHarmful, then check the faction.
Therefor the ordering is / was off.

Additionally, if your faction class name is ImperialOrder, you can just use the static Instance property.

Also since you check for m != m_Caster in the main condition, you wouldnt need to do the same again inside.

And lastly, depending on your ServUO version, dont forget to recompile

C#:
public override bool OnMoveOver(Mobile m)
{
    if (Visible && m_Caster != null && m != m_Caster && Faction.Find(m) != ImperialOrder.Instance && SpellHelper.ValidIndirectTarget(m_Caster, m) && m_Caster.CanBeHarmful(m, false))
    {
        m_Caster.DoHarmful(m);

        int damage = Utility.Random(35, 75);

        if (!Core.AOS && m.CheckSkill(SkillName.MagicResist, 0.0, 30.0))
        {
            damage = Utility.Random(25, 65);
            m.SendLocalizedMessage(501783); // You feel yourself resisting magical energy.
        }

        AOS.Damage(m, m_Caster, damage, 0, 100, 0, 0, 0);

        m.PlaySound(0x207);
    }

    return true;
}
well, i only renamed True Britanians faction name inside TrueBritanians.cs so in this case i need to
if (Visible && m_Caster != null && m != m_Caster && Faction.Find(m) != TrueBritanians.Instance && SpellHelper.ValidIndirectTarget(m_Caster, m) && m_Caster.CanBeHarmful(m, false))
?
p.s update: I did as you mentioned and players from imperial order are not taking damage from that spell, but caster still gets damaged.
 
Last edited:
In that case, check if m and m_Caster are not null.

For that simply make a World.Broadcast or if you do not have much data running in the console, you can use
Console.WriteLine.
 
sadly after all my effords, spell still damages caster... here is entire spell
Rain Of Fire:
using System;
using System.Collections;
using Server.Targeting;
using Server.Network;
using Server.Misc;
using Server.Items;
using Server.Mobiles;
using Server.Spells;
using Server.Factions;

namespace Server.ACC.CSS.Systems.FireWizard
{
    public class RainOfFireSpell : FireWizardSpell
    {
        private static SpellInfo m_Info = new SpellInfo("Rain Of Fire", "Flam Dominus",233,9012,false);
                                                      

        public override SpellCircle Circle
        {
            get { return SpellCircle.Sixth; }
        }
        
        public override double CastDelay { get { return 2.0; } }
        public override int RequiredMana { get { return 250; } }
        public override double RequiredSkill { get { return 90; } }
        
        public RainOfFireSpell(Mobile caster, Item scroll)
            : base(caster, scroll, m_Info)
        {
        }

        public override void OnCast()
        {
            Caster.Target = new InternalTarget(this);
        }

//castsequence
public void Target(IPoint3D p)
{
    if (!Caster.CanSee(p))
    {
        Caster.SendLocalizedMessage(500237); // Target can not be seen.
    }
    else if (CheckSequence())
    {
        if (this.Scroll != null)
            Scroll.Consume();
        SpellHelper.Turn(Caster, p);

        SpellHelper.GetSurfaceTop(ref p);
        int val = (int)(Caster.Skills[CastSkill].Value / 20.0 + 5);

        Effects.PlaySound(p, Caster.Map, 0x207);

        Point3D loc = new Point3D(p.X, p.Y, p.Z);
        int mushx;
        int mushy;
        int mushz;

        InternalItem firstFlamea = new InternalItem(Caster.Location, Caster.Map, Caster);
        mushx = loc.X - 2 + Utility.RandomMinMax(-2, 2);
        mushy = loc.Y - 2 + Utility.RandomMinMax(-2, 2);
        mushz = loc.Z;
        Point3D mushxyz = new Point3D(mushx, mushy, mushz);
        firstFlamea.MoveToWorld(mushxyz, Caster.Map);

        InternalItem firstFlamec = new InternalItem(Caster.Location, Caster.Map, Caster);
        mushx = loc.X + Utility.RandomMinMax(-2, 2);
        mushy = loc.Y - 3 + Utility.RandomMinMax(-2, 2);
        mushz = loc.Z;
        Point3D mushxyzb = new Point3D(mushx, mushy, mushz);
        firstFlamec.MoveToWorld(mushxyzb, Caster.Map);

        InternalItem firstFlamed = new InternalItem(Caster.Location, Caster.Map, Caster);
firstFlamed.ItemID = 0x1A75;
firstFlamed.Name = "Rain Of Fire";
mushx = loc.X + 2 + Utility.RandomMinMax(-2, 2);
mushy = loc.Y - 2 + Utility.RandomMinMax(-2, 2);
mushz = loc.Z;
Point3D mushxyzc = new Point3D(mushx, mushy, mushz);
firstFlamed.MoveToWorld(mushxyzc, Caster.Map);

InternalItem firstFlamee = new InternalItem(Caster.Location, Caster.Map, Caster);
mushx = loc.X + 3 + Utility.RandomMinMax(-2, 2);
firstFlamee.ItemID = 0x1A75;
firstFlamee.Name = "Rain Of Fire";
mushy = loc.Y + Utility.RandomMinMax(-2, 2);
mushz = loc.Z;
Point3D mushxyzd = new Point3D(mushx, mushy, mushz);
firstFlamee.MoveToWorld(mushxyzd, Caster.Map);

InternalItem firstFlamef = new InternalItem(Caster.Location, Caster.Map, Caster);
firstFlamef.ItemID = 0x1A75;
firstFlamef.Name = "Rain Of Fire";
mushx = loc.X + 2 + Utility.RandomMinMax(-2, 2);
mushy = loc.Y + 2 + Utility.RandomMinMax(-2, 2);
mushz = loc.Z;
Point3D mushxyze = new Point3D(mushx, mushy, mushz);
firstFlamef.MoveToWorld(mushxyze, Caster.Map);

InternalItem firstFlameg = new InternalItem(Caster.Location, Caster.Map, Caster);
mushx = loc.X + Utility.RandomMinMax(-2, 2);
firstFlameg.ItemID = 0x1A75;
firstFlameg.Name = "Rain Of Fire";
mushy = loc.Y + 3 + Utility.RandomMinMax(-2, 2);
mushz = loc.Z;
Point3D mushxyzf = new Point3D(mushx, mushy, mushz);
firstFlameg.MoveToWorld(mushxyzf, Caster.Map);

InternalItem firstFlameh = new InternalItem(Caster.Location, Caster.Map, Caster);
mushx = loc.X - 2 + Utility.RandomMinMax(-2, 2);
firstFlameh.ItemID = 0x1A75;
firstFlameh.Name = "Rain Of Fire";
mushy = loc.Y + 2 + Utility.RandomMinMax(-2, 2);
mushz = loc.Z;
Point3D mushxyzg = new Point3D(mushx, mushy, mushz);
firstFlameh.MoveToWorld(mushxyzg, Caster.Map);

InternalItem firstFlamei = new InternalItem(Caster.Location, Caster.Map, Caster);
mushx = loc.X - 3 + Utility.RandomMinMax(-2, 2);
firstFlamei.ItemID = 0x1A75;
firstFlamei.Name = "Rain Of Fire";
mushy = loc.Y + Utility.RandomMinMax(-2, 2);
mushz = loc.Z;
Point3D mushxyzh = new Point3D(mushx, mushy, mushz);
firstFlamei.MoveToWorld(mushxyzh, Caster.Map);

InternalItem firstFlamej = new InternalItem(Caster.Location, Caster.Map, Caster);
mushx = loc.X - 1 + Utility.RandomMinMax(-2, 2);
firstFlamej.ItemID = 0x1A75;
firstFlamej.Name = "Rain Of Fire";
mushy = loc.Y + Utility.RandomMinMax(-2, 2);
mushz = loc.Z;
Point3D mushxyzj = new Point3D(mushx, mushy, mushz);
firstFlamej.MoveToWorld(mushxyzj, Caster.Map);

InternalItem firstFlamek = new InternalItem(Caster.Location, Caster.Map, Caster);
mushx = loc.X - 3 + Utility.RandomMinMax(-2, 2);
firstFlamek.ItemID = 0x1A75;
firstFlamek.Name = "Rain Of Fire";
mushy = loc.Y - 2 + Utility.RandomMinMax(-2, 2);
mushz = loc.Z;
Point3D mushxyzk = new Point3D(mushx, mushy, mushz);
firstFlamek.MoveToWorld(mushxyzk, Caster.Map);

InternalItem firstFlamel = new InternalItem(Caster.Location, Caster.Map, Caster);
mushx = loc.X + Utility.RandomMinMax(-2, 2);
firstFlamel.ItemID = 0x1A75;
firstFlamel.Name = "Rain Of Fire";
mushy = loc.Y - 2 + Utility.RandomMinMax(-2, 2);
mushz = loc.Z;
Point3D mushxyzl = new Point3D(mushx, mushy, mushz);
firstFlamel.MoveToWorld(mushxyzl, Caster.Map);

InternalItem firstFlamem = new InternalItem(Caster.Location, Caster.Map, Caster);
mushx = loc.X + Utility.RandomMinMax(-2, 2);
firstFlamem.ItemID = 0x1A75;
firstFlamem.Name = "Rain Of Fire";
mushy = loc.Y + 1 + Utility.RandomMinMax(-2, 2);
mushz = loc.Z;
Point3D mushxyzm = new Point3D(mushx, mushy, mushz);
firstFlamem.MoveToWorld(mushxyzm, Caster.Map);

InternalItem firstFlamep = new InternalItem(Caster.Location, Caster.Map, Caster);
mushx = loc.X + Utility.RandomMinMax(-2, 2);
firstFlamep.ItemID = 0x1A75;
firstFlamep.Name = "Rain Of Fire";
mushy = loc.Y + 3 + Utility.RandomMinMax(-2, 2);
mushz = loc.Z;
Point3D mushxyzp = new Point3D(mushx, mushy, mushz);
firstFlamep.MoveToWorld(mushxyzp, Caster.Map);

InternalItem firstFlameq = new InternalItem(Caster.Location, Caster.Map, Caster);
mushx = loc.X - 2 + Utility.RandomMinMax(-2, 2);
firstFlameq.ItemID = 0x1A75;
firstFlameq.Name = "Rain Of Fire";
mushy = loc.Y + 2 + Utility.RandomMinMax(-2, 2);
mushz = loc.Z;
Point3D mushxyzq = new Point3D(mushx, mushy, mushz);
firstFlameq.MoveToWorld(mushxyzq, Caster.Map);

InternalItem firstFlamer = new InternalItem(Caster.Location, Caster.Map, Caster);
mushx = loc.X - 3 + Utility.RandomMinMax(-2, 2);
firstFlamer.ItemID = 0x1A75;
firstFlamer.Name = "Rain Of Fire";
mushy = loc.Y + Utility.RandomMinMax(-2, 2);
mushz = loc.Z;
Point3D mushxyzr = new Point3D(mushx, mushy, mushz);
firstFlamer.MoveToWorld(mushxyzr, Caster.Map);

InternalItem firstFlamet = new InternalItem(Caster.Location, Caster.Map, Caster);
mushx = loc.X + 2 + Utility.RandomMinMax(-2, 2);
firstFlamet.ItemID = 0x1A75;
firstFlamet.Name = "Rain Of Fire";
mushy = loc.Y + Utility.RandomMinMax(-2, 2);
mushz = loc.Z;
Point3D mushxyzt = new Point3D(mushx, mushy, mushz);
firstFlamet.MoveToWorld(mushxyzt, Caster.Map);

InternalItem firstFlameu = new InternalItem(Caster.Location, Caster.Map, Caster);
mushx = loc.X - 3 + Utility.RandomMinMax(-2, 2);
firstFlameu.ItemID = 0x1A75;
firstFlameu.Name = "Rain Of Fire";
mushy = loc.Y - 1 + Utility.RandomMinMax(-2, 2);
mushz = loc.Z;
Point3D mushxyzu = new Point3D(mushx, mushy, mushz);
firstFlameu.MoveToWorld(mushxyzu, Caster.Map);


    }

    FinishSequence();
}
//castsequence end


        [DispellableField]
        private class InternalItem : Item
        {
            private Timer m_Timer;
            private Timer m_Burn;
            private DateTime m_End;
            private Mobile m_Caster;

            public override bool BlocksFit { get { return true; } }

            public InternalItem(Point3D loc, Map map, Mobile caster)
                : base(0x1A75)
            {
                Visible = false;
                Movable = false;
                Light = LightType.Circle150;
                MoveToWorld(loc, map);
                m_Caster = caster;

                if (caster.InLOS(this))
                    Visible = true;
                else
                    Delete();

                if (Deleted)
                    return;

                m_Timer = new InternalTimer(this, TimeSpan.FromSeconds(10.0));
                m_Timer.Start();
                m_Burn = new BurnTimer(this, m_Caster);
                m_Burn.Start();

                m_End = DateTime.Now + TimeSpan.FromSeconds(10.0);
            }

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

            public override bool OnMoveOver(Mobile m)
{
    if (Visible && m_Caster != null && m != m_Caster && Faction.Find(m) != TrueBritannians.Instance && SpellHelper.ValidIndirectTarget(m_Caster, m) && m_Caster.CanBeHarmful(m, false))
    {
        m_Caster.DoHarmful(m);

        int damage = Utility.Random(35, 75);

        if (!Core.AOS && m.CheckSkill(SkillName.MagicResist, 0.0, 30.0))
        {
            damage = Utility.Random(25, 65);
            m.SendLocalizedMessage(501783); // You feel yourself resisting magical energy.
        }

        AOS.Damage(m, m_Caster, damage, 0, 100, 0, 0, 0);

        m.PlaySound(0x207);
    }

    return true;
}









            public override void Serialize(GenericWriter writer)
            {
                base.Serialize(writer);

                writer.Write((int)1); // version

                writer.Write(m_End - DateTime.Now);
            }

            public override void Deserialize(GenericReader reader)
            {
                base.Deserialize(reader);

                int version = reader.ReadInt();

                switch (version)
                {
                    case 1:
                        {
                            TimeSpan duration = reader.ReadTimeSpan();

                            m_Timer = new InternalTimer(this, duration);
                            m_Timer.Start();

                            m_End = DateTime.Now + duration;

                            break;
                        }
                    case 0:
                        {
                            TimeSpan duration = TimeSpan.FromSeconds(10.0);

                            m_Timer = new InternalTimer(this, duration);
                            m_Timer.Start();

                            m_End = DateTime.Now + duration;

                            break;
                        }
                }
            }

            public override void OnAfterDelete()
            {
                base.OnAfterDelete();

                if (m_Timer != null)
                    m_Timer.Stop();
            }

            private class InternalTimer : Timer
            {
                private InternalItem m_Item;

                public InternalTimer(InternalItem item, TimeSpan duration)
                    : base(duration)
                {
                    m_Item = item;
                }

                protected override void OnTick()
                {
                    m_Item.Delete();
                }
            }
        }

        private class InternalTarget : Target
        {
            private RainOfFireSpell m_Owner;

            public InternalTarget(RainOfFireSpell owner)
                : base(12, true, TargetFlags.None)
            {
                m_Owner = owner;
            }

            protected override void OnTarget(Mobile from, object o)
            {
                if (o is IPoint3D)
                    m_Owner.Target((IPoint3D)o);
            }

            protected override void OnTargetFinish(Mobile from)
            {
                m_Owner.FinishSequence();
            }
        }

        private class BurnTimer : Timer
        {
            private Item m_RainOfFire;
            private Mobile m_Caster;
            private DateTime m_Duration;

            private static Queue m_Queue = new Queue();

            public BurnTimer(Item ap, Mobile ca)
    : base(TimeSpan.FromSeconds(0.5), TimeSpan.FromSeconds(0.5))
{
    Priority = TimerPriority.FiftyMS;

    m_RainOfFire = ap;
    m_Caster = ca;
    m_Duration = DateTime.Now + TimeSpan.FromSeconds(10.0);
}

            protected override void OnTick()
            {
                if (m_RainOfFire.Deleted)
                    return;

                if (DateTime.Now > m_Duration)
                {
                    Stop();
                }
                else
                {
                    Map map = m_RainOfFire.Map;

                    if (map != null)
                    {
                        foreach (Mobile m in m_RainOfFire.GetMobilesInRange(1))
                        {
                            if ((m.Z + 16) > m_RainOfFire.Z && (m_RainOfFire.Z + 12) > m.Z)
                                m_Queue.Enqueue(m);
                        }

                        while (m_Queue.Count > 0)
                        {
                            Mobile m = (Mobile)m_Queue.Dequeue();

                            if (m_RainOfFire.Visible && m_Caster != null && SpellHelper.ValidIndirectTarget(m_Caster, m) && m_Caster.CanBeHarmful(m, false))
                            {
                                m_Caster.DoHarmful(m);

                                int damage = Utility.Random(35, 75);

                                if (!Core.AOS && m.CheckSkill(SkillName.MagicResist, 0.0, 30.0))
                                {
                                    damage = Utility.Random(25, 65);
                                    m.SendLocalizedMessage(501783); // You feel yourself resisting magical energy.
                                }

                                AOS.Damage(m, m_Caster, damage, 0, 100, 0, 0, 0);
                                m.PlaySound(0x207);
                                m.SendLocalizedMessage(503000);
                            }
                        }
                    }
                }
            }
        }
    }
}

also dont want to create separated thread so ill ask it here, unmodified cleric spell "trial by fire" refuses to deal reflect damage to attackers. i was told that i need some changes in baseweapon.cs and kinda did as one topic said but without resoults. codes compile without errors, spell is cast and buff is applied (cant cast again because player is under the effect) but nothing happens when player is damaged)

here is the modified part
baseweapon:
if (attacker is BaseCreature)
            {
                ((BaseCreature)attacker).OnGaveMeleeAttack(defender);
            }

            if (defender is BaseCreature)
            {
                ((BaseCreature)defender).OnGotMeleeAttack(attacker);
            }

            if (a != null)
            {
                a.OnHit( attacker, defender, damage );
                PlayerEvent.InvokeHitByWeapon(attacker, defender, damage, a); // Invoke clerric event
            }

            if (move != null)
            {
                move.OnHit(attacker, defender, damage);
            }

used this https://www.servuo.com/threads/cleric-spells-whats-wrong.12115/ as guide...
 

Attachments

  • PlayerEvent.cs
    505 bytes · Views: 1
  • TrialByFireSpell.cs
    3.3 KB · Views: 1
Is it your custom spell? In the only copy I found of ACC on here there is no flamewizrd nor the spell. Sticking to that "problem" first
 
Is it your custom spell? In the only copy I found of ACC on here there is no flamewizrd nor the spell. Sticking to that "problem" first
yes it is custom spell using same mechanic as Fire Ring from ancient spellbook. and original fire ring spell from ancient spellbook also damages caster...
 
For your fire spell, the issue is simple, you have a on tick function at the bottom. That is causing you to get damage, not the OnMoveOver.

For your second question. Looking at it, I assume you put the PlayerEvents line inside the if ( a != null )

That would mean you need to hit with a weapon ability to be able to get the reflect damage on you.
 
For your fire spell, the issue is simple, you have a on tick function at the bottom. That is causing you to get damage, not the OnMoveOver.

For your second question. Looking at it, I assume you put the PlayerEvents line inside the if ( a != null )

That would mean you need to hit with a weapon ability to be able to get the reflect damage on you.
i assume i must put
C#:
if (Visible && m_Caster != null && m != m_Caster && Faction.Find(m) != TrueBritannians.Instance && SpellHelper.ValidIndirectTarget(m_Caster, m) && m_Caster.CanBeHarmful(m, false))
instead of
C#:
 if (m_RainOfFire.Visible && m_Caster != null && SpellHelper.ValidIndirectTarget(m_Caster, m) && m_Caster.CanBeHarmful(m, false))
in ontick method?

about cleric... i tried putting it inside if ( a != null) it is not working, not even triggering console test message.
 
For the ontick, you just want to add the check for caster and the faction to the if

for cleric, I added it inside the baseweapon.cs, and it trigger. The instructions from the other thread kinda read as "put it inside" the mentioned if, thats why I was making sure.

Where did you put it inside baseweapon?
 
on line 3003... sadly instructions there was not so clear and this is what it is...
 

Attachments

  • BaseWeapon.cs
    189.6 KB · Views: 1
The way you have it added, should work since it is the same spot in mine (relative speaking).

So have the cerlic spell running, and attack that char with the spell active with a weapon ability. In that case it should have like a 50/50 chance to trigger
 
The way you have it added, should work since it is the same spot in mine (relative speaking).

So have the cerlic spell running, and attack that char with the spell active with a weapon ability. In that case it should have like a 50/50 chance to trigger
i tried every single way to do trigger it, spells, specials, barehands, mele/ranged weapons. nothing triggers it. all i need is to trigger it when caster is hit with melee weapon...
 
Like I said the way it is set up, it would trigger when the caster is hit by a weapon ability.

If you want it on all melee hits (so excluding ranged) then you would need to add the line to the if at 3019 in your script
 
like this?

C#:
if (!ranged)
            {
                PlayerEvent.InvokeHitByWeapon(attacker, defender, damage, a); // Invoke the event
                if (AnimalForm.UnderTransformation(attacker, typeof(GiantSerpent)))
                {
                    defender.ApplyPoison(attacker, Poison.Lesser);
                }

                if (AnimalForm.UnderTransformation(defender, typeof(BullFrog)))
                {
                    attacker.ApplyPoison(defender, Poison.Regular);
                }
            }
 
yes, then it would only trigger on melee attacks, not ranged weapon attacks
tried that method too and still not triggering...
updated scripts. im sure i have a mistake somewhere... thats why its not triggering...
P.S just noticed. trialbyfire spell triggers it but flame shield which is exact copy of TBF, doesnot.
P.S.2. im really ashamed now... all i had to do is to remove "//" from using Server.ACC.CSS.Systems.FireWizard; and rename PlayerEvent.cs to soemthing else to avoid dualscripting... now everything works fine! thank you very much!
 

Attachments

  • FlameShieldSpell.cs
    3.3 KB · Views: 4
  • BaseWeapon.cs
    189.7 KB · Views: 0
  • PlayerEvent.cs
    719 bytes · Views: 0
Last edited:
Back