I would like provocation to work on players (similar to taunt in mmorpgs)

Whenever i try provocation on someone server crash on second target

Im using runuo 2.2


Crashlog

Exception:
System.NullReferenceException: Object reference not set to an instance of an object.
at Server.SkillHandlers.Provocation.InternalSecondTarget.OnTarget(Mobile from, Object targeted) in c:\Users\mypc\Desktop\\Skills\Provocation.cs:line 104
at Server.Targeting.Target.Invoke(Mobile from, Object targeted)
at Server.Network.PacketHandlers.TargetResponse(NetState state, PacketReader pvSrc)
at Server.Network.MessagePump.HandleReceive(NetState ns)
at Server.Network.MessagePump.Slice()
at Server.Core.Main(String[] args)


Provocation.cs

Code:
using System;
using Server.Targeting;
using Server.Network;
using Server.Mobiles;
using Server.Items;

namespace Server.SkillHandlers
{
    public class Provocation
    {
        public static void Initialize()
        {
            SkillInfo.Table[(int)SkillName.Provocation].Callback = new SkillUseCallback( OnUse );
        }

        public static TimeSpan OnUse( Mobile m )
        {
            m.RevealingAction();

            BaseInstrument.PickInstrument( m, new InstrumentPickedCallback( OnPickedInstrument ) );

            return TimeSpan.FromSeconds( 1.0 ); // Cannot use another skill for 1 second
        }

        public static void OnPickedInstrument( Mobile from, BaseInstrument instrument )
        {
            from.RevealingAction();
            from.SendLocalizedMessage( 501587 ); // Whom do you wish to incite?
            from.Target = new InternalFirstTarget( from, instrument );
        }

        private class InternalFirstTarget : Target
        {
            private BaseInstrument m_Instrument;

            public InternalFirstTarget( Mobile from, BaseInstrument instrument ) : base( BaseInstrument.GetBardRange( from, SkillName.Provocation ), false, TargetFlags.None )
            {
                m_Instrument = instrument;
            }

            protected override void OnTarget( Mobile from, object targeted )
            {
                from.RevealingAction();
        if( targeted is PlayerMobile )
                {
                    PlayerMobile b = (PlayerMobile)targeted;

                    if (!m_Instrument.IsChildOf(from.Backpack))
                    {
                        from.SendLocalizedMessage(1062488); // The instrument you are trying to play is no longer in your backpack!
                    }
                    else if (b.Map != b.Map || !b.InRange(b, BaseInstrument.GetBardRange(from, SkillName.Provocation)))
                    {
                        from.SendLocalizedMessage(1049450); // The creatures you are trying to provoke are too far away from each other for your music to have an effect.
                    }
                    else
                    {
           
                   
                        from.RevealingAction();
                        m_Instrument.PlayInstrumentWell( from );
                        from.SendLocalizedMessage( 1008085 ); // You play your music and your target becomes angered.  Whom do you wish them to attack?
                         from.Target = new InternalSecondTarget(from, m_Instrument, b);
                    }
                }
               
        }
        }

        private class InternalSecondTarget : Target
        {
            private BaseCreature m_Creature;
            private BaseInstrument m_Instrument;

            public InternalSecondTarget( Mobile from, BaseInstrument instrument, PlayerMobile b ) : base( BaseInstrument.GetBardRange( from, SkillName.Provocation ), false, TargetFlags.None )
            {
                m_Instrument = instrument;
                //m_Creature = creature;
            }

            protected override void OnTarget( Mobile from, object targeted )
            {

        from.RevealingAction();
       
        if( targeted is PlayerMobile )
                {
                    PlayerMobile b = (PlayerMobile)targeted;

                    if (!m_Instrument.IsChildOf(from.Backpack))
                    {
                        from.SendLocalizedMessage(1062488); // The instrument you are trying to play is no longer in your backpack!
                    }
                    else if (b.Map != b.Map || !b.InRange(b, BaseInstrument.GetBardRange(from, SkillName.Provocation)))
                    {
                        from.SendLocalizedMessage(1049450); // The creatures you are trying to provoke are too far away from each other for your music to have an effect.
                    }

                                else
                                {
                                    from.SendLocalizedMessage( 501602 ); // Your music succeeds, as you start a fight.
                                    m_Instrument.PlayInstrumentWell( from );
                                    m_Instrument.ConsumeUse( from );
                                    m_Creature.Provoke( true, from, b );    ////<- Line 104 crash
                                }
                            }
                                 else
                {
                    from.SendLocalizedMessage(501589); // You can't incite that!
                }
                        }
        }
            }
        }

Basecreature.cs Provoke method:

Code:
public void Provoke(Mobile master, Mobile target, bool bSuccess)
        {
            BardProvoked = true;

            PublicOverheadMessage(MessageType.Emote, EmoteHue, false, "*Seems furious*");

            if (bSuccess)
            {
                PlaySound(GetIdleSound());

                BardMaster = master;
                BardTarget = target;
                Combatant = target;
                BardEndTime = DateTime.Now + TimeSpan.FromSeconds(30.0);

                if (target is BaseCreature)
                {
                    BaseCreature t = (BaseCreature)target;

                    if (t.Unprovokable || (t.IsParagon && BaseInstrument.GetBaseDifficulty(t) >= 160.0))
                        return;

                    t.BardProvoked = true;

                    t.BardMaster = master;
                    t.BardTarget = this;
                    t.Combatant = this;
                    t.BardEndTime = DateTime.Now + TimeSpan.FromSeconds(30.0);
                }
               
            }
            else
            {
                PlaySound(GetAngerSound());

                BardMaster = master;
                BardTarget = target;
            }
        }


Thanks!
 
You never set m_Creature so it stays null. Thats why you crash. I think you wanted to use b there. Also it is helpful to give the variable meaningful names
 
I already did that and it throw errors


Errors:
+ Skills/Provocation.cs:
CS1061: Line 107: 'Server.Mobiles.PlayerMobile' does not contain a definitio
n for 'Provoke' and no extension method 'Provoke' accepting a first argument of
type 'Server.Mobiles.PlayerMobile' could be found (are you missing a using direc
tive or an assembly reference?)

i changed it to

Code:
b.DoHarmful( from );

and it almost work like a taunt xD at least it dont crash anymore
 
You shouldn't be allowing PlayerMobiles to be provoked onto things, rather allow BaseCreatures to be provoked onto PlayerMobiles.

On OSI, back when you could provoke interaction between creature and player (may still be possible in felucca - not sure), it only worked when the creature was targeted first.

Allowing a player to be provoked opens up a lot of problems with notoriety. For instance, what if you provoke a player onto a blue pet for example, or another player? The player could be guard whacked, or worse, eligible for murder if the other player dies.

Instead, allowing a BaseCreature to be provoked onto a player is a lot more simple.

I'm hesitant to give code advice since it's been a long time since I've played with this myself, but on my own server, I did set up BaseCreature -> PlayerMobile provoking a long time ago. But yes, in your script the problem occurs from the fact that m_Creature has never been set (which denotes the first BaseCreature to be provoked).

The problem is deeper than that though as you have changed method signatures in ways that will be difficult to get the code running properly at all. Your code is no longer capable of provoking BaseCreatures OR players.

It'd be interesting to check if official UO servers still allow BaseCreature to PlayerMobile provoking in Felucca.
 
Last edited:
Allowing a player to be provoked opens up a lot of problems with notoriety. For instance, what if you provoke a player onto a blue pet for example, or another player? The player could be guard whacked, or worse, eligible for murder if the other player dies.

on my server players can only use provocation in a pvp event, so it shouldnt be an issue :)

Thanks
 
Back