I have set it so he does his ability he will not poison his owner, but he WILL poison any other good people around him not just combatants.
Help on this would be appreciated, this is the area causing the issue:
Code:
public override void OnActionCombat()
{
Mobile combatant = Combatant;

if ( DateTime.UtcNow < m_NextAbilityTime || combatant == null || combatant.Deleted || combatant.Map != Map || !InRange( combatant, 3 ) || !CanBeHarmful( combatant ) || !InLOS( combatant ) )
return;

m_NextAbilityTime = DateTime.UtcNow + TimeSpan.FromSeconds( Utility.RandomMinMax( 5, 30 ) );

if ( Utility.RandomBool() )
{
this.FixedParticles( 0x376A, 9, 32, 0x2539, EffectLayer.LeftHand );
this.PlaySound( 0x1DE );

foreach ( Mobile m in this.GetMobilesInRange( 2 ) )
{
if ( m != this.ControlMaster && m != this && IsEnemy( m ) )
{
m.ApplyPoison( this, Poison.Deadly );
}
}
}
}
I know there is a better way to take care of the owner, the mare itself and others to NOT get hit with the poison...but getting stuck on a new call. I think there has to be a
if(BLAH BLAH is BLah)
return;
or something like that.
I attached the script also, thanks for any assistance!

Shazzy
 

Attachments

  • DreadWarhorse.cs
    3.3 KB · Views: 8
Best way to approach something like this is to think if the game already has a similar mechanic. In this case, I immediately thought of the wither spell.

Looking at the wither spell, we see:

Code:
 foreach (Mobile m in this.Caster.GetMobilesInRange(Core.ML ? 4 : 5))
  {
       if (this.Caster != m && this.Caster.InLOS(m) && (isMonster || SpellHelper.ValidIndirectTarget(this.Caster, m)) &&     this.Caster.CanBeHarmful(m, false))

Notice that we have a call to a method SpellHelper.ValidIndirectTarget. If you look at that method, you see that it already does the party, pet, notoriety, player, and guild checks that you probably want.

I would suggest using that call instead of writing a whole new set of if statements. Always try to re-use code when possible.
 
I've never seen this problem but my script looks the same. Interested to see what you come up with.

Here is the Black Cloud Ability, it had some purpose in the original story arc, but mostly is used by players to prove it is a Dread Warhorse rather then a Nightmare, especially for people selling tames

When a player says the word 'Trick' the creature will emit a cloud of black smoke all around itself.
public static void Initialize()

{

EventSink.Speech += new SpeechEventHandler(EventSink_Speech);

}

#region [ BlackCloud Ability ]

private static void BlackCloud(Mobile from)

{

Effects.SendLocationEffect(new Point3D(from.X + 1, from.Y, from.Z + 4), from.Map, 0x3728, 13);

Effects.SendLocationEffect(new Point3D(from.X + 1, from.Y, from.Z), from.Map, 0x3728, 13);

Effects.SendLocationEffect(new Point3D(from.X + 1, from.Y, from.Z - 4), from.Map, 0x3728, 13);

Effects.SendLocationEffect(new Point3D(from.X, from.Y + 1, from.Z + 4), from.Map, 0x3728, 13);

Effects.SendLocationEffect(new Point3D(from.X, from.Y + 1, from.Z), from.Map, 0x3728, 13);

Effects.SendLocationEffect(new Point3D(from.X, from.Y + 1, from.Z - 4), from.Map, 0x3728, 13);

Effects.SendLocationEffect(new Point3D(from.X + 1, from.Y + 1, from.Z + 11), from.Map, 0x3728, 13);

Effects.SendLocationEffect(new Point3D(from.X + 1, from.Y + 1, from.Z + 7), from.Map, 0x3728, 13);

Effects.SendLocationEffect(new Point3D(from.X + 1, from.Y + 1, from.Z + 3), from.Map, 0x3728, 13);

Effects.SendLocationEffect(new Point3D(from.X + 1, from.Y + 1, from.Z - 1), from.Map, 0x3728, 13);

from.PlaySound(0x228);

from.Hidden = true; //this applies to staff members only; will not hide players

}

#endregion

#region [OnSpeech]

private static void EventSink_Speech(SpeechEventArgs e)

{

if (e.Handled)

{

return;

}

if (e.Mobile is PlayerMobile && e.Mobile.Mounted && e.Mobile.Mount is DreadWarHorse)

{

if (Insensitive.Equals(e.Speech, "Trick") )

{

BlackCloud(e.Mobile);

e.Handled = true;

}

}

}

#endregion
 
Last edited:
The biggest issue is the Dread in this script is doing an Ability, not casting.
The code was taken - I dug up- directly from the Betrayer script. For the Betrayer this works because he is always a bad guy.
Where as the Dread it tamed and now does not want to hurt its owner or other players in the area.
Nothing works to keep players from getting poisoned and I looked at holy light and other things.
Code:
private DateTime m_NextAbilityTime;

 public override void OnActionCombat()
 {
 Mobile combatant = Combatant;

 if ( DateTime.UtcNow < m_NextAbilityTime || combatant == null || combatant.Deleted || combatant.Map != Map || !InRange( combatant, 3 ) || !CanBeHarmful( combatant ) || !InLOS( combatant ) )
 return;

 m_NextAbilityTime = DateTime.UtcNow + TimeSpan.FromSeconds( Utility.RandomMinMax( 5, 30 ) );

 if ( Utility.RandomBool() )
 {
 this.FixedParticles( 0x376A, 9, 32, 0x2539, EffectLayer.LeftHand );
 this.PlaySound( 0x1DE );

 foreach ( Mobile m in this.GetMobilesInRange( 2 ) )
 {
 if (this != m && this.ControlMaster != m && this.CanBeHarmful(m, false) && IsEnemy( m ) )
 {
 m.ApplyPoison( this, Poison.Deadly );
 }
 }
 
 }
 }

This does not work. Tried to add a player mobile call in there and can;t do that.
The issue is that as a player I CanBeHarmful to THIS>

Thoughts anyone?
 
It doesn't really matter that its not a spell, we are just reusing that code. We are using it to reduce the targets (m) that he will ApplyPoison to, so it doesn't matter if its a spell, ability, or even direct damage.

I dont have players to test with, can you try it like this?

Code:
    public override void OnActionCombat()
     {
       Mobile combatant = Combatant;

       if ( DateTime.UtcNow < m_NextAbilityTime || combatant == null || combatant.Deleted || combatant.Map != Map || !InRange( combatant, 3 ) || !CanBeHarmful( combatant ) || !InLOS( combatant ) )
         return;

       m_NextAbilityTime = DateTime.UtcNow + TimeSpan.FromSeconds( Utility.RandomMinMax( 5, 30 ) );

       if ( Utility.RandomBool() )
       {
         this.FixedParticles( 0x376A, 9, 32, 0x2539, EffectLayer.LeftHand );
         this.PlaySound( 0x1DE );

         foreach ( Mobile m in this.GetMobilesInRange( 2 ) )
         {
           if (m != this && m is BaseCreature && SpellHelper.ValidIndirectTarget(this, m) && CanBeHarmful(m, false))
           {
             m.ApplyPoison( this, Poison.Deadly );
           }
         }
       }
     }
 
Code:
Errors:
 + CUSTOMS/QUESTS/Strangers Bearing Gifts Quests 4-2012/DreadWarhorse.cs:
  CS0103: Line 93: The name 'SpellHelper' does not exist in the current contex
t
Scripts: One or more scripts failed to compile or no script files were found.
 - Press return to exit, or R to try again.
I could not get the spell helper insert to work before, same error :(
[doublepost=1473352051][/doublepost]
Oh, you will need to add a directive at the top...

using Server.Spells;
And NOW I am gong to call myself a FRIGGIN IDIOT cause I forgot to put the
using Server.Spells;
*sobs uncontrollably*.......ok all better!

I believe it works!
Thanks Ravenwolfe!
 
Haha, don't feel bad, I had to add that post cause I forgot it as well. I use Virtual Studio and it added the directive for me, so I totally forgot to mention it.

By the way, I wasnt sure if you wanted it to ignore ALL players or just innocent ones. If you want the ability to hit players who are aggressive, then you can just remove the basecreature check:

Change:
Code:
if (m != this && m is BaseCreature && SpellHelper.ValidIndirectTarget(this, m) && CanBeHarmful(m, false))

To:
Code:
if (m != this && SpellHelper.ValidIndirectTarget(this, m) && CanBeHarmful(m, false))

That should then hit players who are aggressive to the dread as well.
 
Back