Here is what I have so far :
Error is in BlackCloud section
Errors:
+ Custom Systems/DreadWarHorseTemp.cs:
CS0246: Line 115: The type or namespace name 'mobile' could not be found (ar
e you missing a using directive or an assembly reference?)
Scripts: One or more scripts failed to compile or no script files were found.
Code:
using System;
using Server;
using Server.Items;
using Server.Mobiles;
using System.Collections;
using System.Collections.Generic;
using Server.Network;
using Server.Spells;
namespace Server.Mobiles
{
[CorpseName( "a dread warhorse corpse" )]
public class DreadWarHorseTemp : BaseMount
{
  [Constructable]
  public DreadWarHorseTemp() : this( "a dread warhorse" )
  {
  }
  [Constructable]
  public DreadWarHorseTemp( string name ) : base( name, 0x74, 0x3EA7, AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4 )
  {
  BodyValue = 177;
  BaseSoundID = 0xA8;
  Hue = 1175;
  SetStr( 502, 551 );
  SetDex( 89, 123 );
  SetInt( 100, 159 );
  SetHits( 555, 648 );
  SetDamage( 20, 26 );
  SetDamageType( ResistanceType.Physical, 40 );
  SetDamageType( ResistanceType.Poison, 20 );
  SetDamageType( ResistanceType.Energy, 40 );
  SetResistance( ResistanceType.Physical, 65, 75 );
  SetResistance( ResistanceType.Fire, 20, 40 );
  SetResistance( ResistanceType.Cold, 20, 40 );
  SetResistance( ResistanceType.Poison, 50, 60 );
  SetResistance( ResistanceType.Energy, 40, 50 );
  SetSkill( SkillName.EvalInt, 30.5, 50.0 );
  SetSkill( SkillName.Magery, 42.4, 50.0 );
  SetSkill( SkillName.MagicResist, 92.6, 96.4 );
  SetSkill( SkillName.Tactics, 97.6, 109.1 );
  SetSkill( SkillName.Wrestling, 80.5, 95.8 );
  Fame = 14000;
  Karma = -14000;
  VirtualArmor = 60;
  Tamable = true;
  ControlSlots = 3;
  MinTameSkill = 105.0;
  m_NextAbilityTime = DateTime.Now + TimeSpan.FromSeconds( Utility.RandomMinMax( 5, 30 ) );
  }
  public override void GenerateLoot()
  {
  AddLoot( LootPack.Rich );
  AddLoot( LootPack.Average );
  AddLoot( LootPack.LowScrolls );
  AddLoot( LootPack.Potions );
  }
  public override int GetAngerSound()
  {
  if ( !Controlled )
    return 0x16A;
  return base.GetAngerSound();
  }
  private DateTime m_NextAbilityTime;
  public override void OnActionCombat()
  {
  Mobile combatant = Combatant;
  if ( DateTime.Now < m_NextAbilityTime || combatant == null || combatant.Deleted || combatant.Map != Map || !InRange( combatant, 3 ) || !CanBeHarmful( combatant ) || !InLOS( combatant ) )
    return;
  m_NextAbilityTime = DateTime.Now + 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 && IsEnemy( m ) )
    {
      m.ApplyPoison( this, Poison.Deadly );
    }
    }
  }
  }
  public override bool HasBreath{ get{ return true; } } // fire breath enabled
  public override int Meat{ get{ return 5; } }
  public override int Hides{ get{ return 10; } }
  public override HideType HideType{ get{ return HideType.Barbed; } }
  public override FoodType FavoriteFood{ get{ return FoodType.Meat; } }
  public override bool CanAngerOnTame { get { return true; } }
 
        #region [ BlackCloud Ability ]
        public virtual bool BlackCloud (mobile from)  //(Basecreature m)
        {
                    from.Effects.SendLocationEffect(new Point3D(from.X + 1, from.Y, from.Z + 4), from.Map, 0x3728, 13);
                    from.Effects.SendLocationEffect(new Point3D(from.X + 1, from.Y, from.Z), from.Map, 0x3728, 13);
                    from.Effects.SendLocationEffect(new Point3D(from.X + 1, from.Y, from.Z - 4), from.Map, 0x3728, 13);
                    from.Effects.SendLocationEffect(new Point3D(from.X, from.Y + 1, from.Z + 4), from.Map, 0x3728, 13);
                    from.Effects.SendLocationEffect(new Point3D(from.X, from.Y + 1, from.Z), from.Map, 0x3728, 13);
                    from.Effects.SendLocationEffect(new Point3D(from.X, from.Y + 1, from.Z - 4), from.Map, 0x3728, 13);
                    from.Effects.SendLocationEffect(new Point3D(from.X + 1, from.Y + 1, from.Z + 11), from.Map, 0x3728, 13);
                    from.Effects.SendLocationEffect(new Point3D(from.X + 1, from.Y + 1, from.Z + 7), from.Map, 0x3728, 13);
                    from.Effects.SendLocationEffect(new Point3D(from.X + 1, from.Y + 1, from.Z + 3), from.Map, 0x3728, 13);
                    from.Effects.SendLocationEffect(new Point3D(from.X + 1, from.Y + 1, from.Z - 1), from.Map, 0x3728, 13);
                    from.PlaySound(0x228);
                    from.Hidden = true;
                    break;
        }
        #endregion
        #region [OnSpeech]
        public override void OnSpeech(SpeechEventArgs e)
        {
        if (this.Rider == null || attacker == null) //sanity
                return false;
            if (!e.Handled && e.Mobile.InRange(this, 6))
            {
                int[] keywords = e.Keywords;
                string speech = e.Speech;
                if ((e.HasKeyword("Trick") == true))
                {
                    if (this.Controlled == false)
                    {
                        e.Handled = this.BlackCloud(this);
                    }
                    else
                    {
                        this.Say("You must be mounted to perform this ability.");
                    }
                }
            }
            base.OnSpeech(e);
        }
        #endregion
  public DreadWarHorseTemp( Serial serial ) : base( serial )
  {
  }
  public override void GetProperties( ObjectPropertyList list )
  {
  base.GetProperties( list );
  }
  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();
  }
}
}
 
Last edited:
[fieldset=Line 90:]
Code:
public virtual bool BlackCloud (mobile from)
'Mobile' should be capitalized.
[/fieldset][fieldset=Line 92-101:]
Code:
from.Effects.SendLocationEffect(new Point3D(from.X+1, from.Y, from.Z+4), from.Map, 0x3728, 13);
All these 'from.Effects.SendLocationEffect' should just be 'Effects.SendLocationEffect'
[/fieldset][fieldset=Line 104:]Method is a bool but has no return type, instead you used 'break;'
[/fieldset][fieldset=Line 110-112:]
Code:
public override void OnSpeech(SpeechEventArgs e)
{
    if (this.Rider == null || attacker == null) //sanity
        return false;
Pretty sure you want to check if Rider is not null if you are going to return. Sorry didn't read the thread title, if you are doing this for mounted this ignore this comment.
There is no attacker variable, should be removed?
'return false;' can't return a bool when the method is a void. If you just want to exit the method just use 'return;'
[/fieldset][fieldset=Line 116:]
Code:
if ((e.HasKeyword("Trick") == true))
'e.HasKeyword' only accept int parameters
[/fieldset]
 
How to I fix this

Line 116:
Code (csharp):
  1. if ((e.HasKeyword("Trick") == true))
'e.HasKeyword' only accept int parameters
 
Use the 'e.Speech' instead to compare to a string. Try something like this:
Code:
if (Insensitive.Equals(e.Speech, "Trick"))
 
Ok compiled but the ability doesn't work

Code:
#region [ BlackCloud Ability ]
publicvirtualbool 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;
returntrue;
}
#endregion
#region [OnSpeech]
publicoverridevoid OnSpeech(SpeechEventArgs e)
{
if (this.Rider == null)  //sanity
return;
if (!e.Handled && e.Mobile.InRange(this, 6))
{
string speech = e.Speech;
if (Insensitive.Equals(e.Speech, "Trick"))
{
if (this.Controlled == false)
{
e.Handled = this.BlackCloud(this);
}
else
{
this.Say("You must be mounted to perform this ability.");
}
}
}
base.OnSpeech(e);
}
#endregion
 
Last edited:
*FacePalm* Didn't even think about this when I was looking over your code. You can't use OnSpeech for mobiles while they are mounted. The server sends the mount to the internal map when you mount them. While mounted they aren't really there, what you see is just graphics added to your character so the OnSpeech will never trigger for the mount.

Since the base Mobile class won't fire off the OnSpeech for the mount what you can do is bypass it and use the Speech Event.

Initialize the event like this:
Code:
public static void Initialize()
{
    EventSink.Speech += new SpeechEventHandler(EventSink_Speech);
}
Then add this method and put your code you have inside OnSpeech inside this method instead.
Code:
private static void EventSink_Speech(SpeechEventArgs e)
{
    // Put code here
}

Edit: Still nothing thinking straight, it's way too late. This is still going to cause problems with your range check so you'll have to get creative. When the event fires instead of checking the range you can check the Mobile doing the speech is the same as the Rider.

Edit 2: You'll also need to change the Effects to appear around the mobile instead of the mount. 'e.Handled = this.BlackCloud(e.Mobile);'
 
Last edited:
I decided to rewrite your methods some for you as what I stated above needed a bit more work than I explained ;). Use these methods and let me know how it works as it needs testing.
Code:
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;
}
#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 DreadWarHorseTemp)
    {
        if (Insensitive.Equals(e.Speech, "Trick"))
        {
            BlackCloud(e.Mobile);
            e.Handled = true;
        }
    }
}
#endregion
 
Neither but intended for players. For owner it works great effects plus it hide you. As player you get effect but doesn't hide a player makes me think there is a restriction somewhere to override.
 
I understand what you are saying now. Yeah that's another wall I didn't think of. The problem is the character is getting revealed because of the speech. The event fires before the speech checks, character gets hidden, speech checks kick in and then character gets revealed so it looks like the character was never hidden. Was trying to use the event to avoid distro edits but didn't think about the revealing action that gets called after.

Could try kicking off a short delay timer to do the hiding part and allow the speech code time to finish but I don't think this will be reliable since you have no control over how long all the other speech events will take and your timer might fire off first still.

Starting to think the easiest solution for you is a distro edit to achieve what you are looking for. The easiest solution would be to add your checks to PlayerMobile OnSpeech. There's more solutions to get around a distro edit but they will require some creativity and quite a bit more work and knowledge of what you are doing. One idea I can think of is to create a custom hidden item that gets placed on the player when mounting the DreadWarHorse and remove it on unmount. Give the item HandlesOnSpeech and then use the item's OnSpeech to do all your checks.
 
I found another issue In the ability to do Area poison attack. If in Felucca it poisons the pet owner also. LOL never thought bout Felucca

Code:
privateDateTime m_NextAbilityTime;
publicoverridevoid OnActionCombat()
{
Mobile combatant = Combatant;
if ( DateTime.Now < m_NextAbilityTime || combatant == null || combatant.Deleted || combatant.Map != Map || !InRange( combatant, 3 ) || !CanBeHarmful( combatant ) || !InLOS( combatant ) )
return;
m_NextAbilityTime = DateTime.Now + TimeSpan.FromSeconds( Utility.RandomMinMax( 5, 30 ) );
if ( Utility.RandomBool() )
{
this.FixedParticles( 0x376A, 9, 32, 0x2539, EffectLayer.LeftHand );
this.PlaySound( 0x1DE );
foreach ( Mobile m inthis.GetMobilesInRange( 2 ) )
{
if ( m != this && IsEnemy( m ) )
{
m.ApplyPoison( this, Poison.Greater );
}
}
}
}
 
Try adding 'm != this.ControlMaster' to your mobile checks.
Code:
foreach (Mobile m in this.GetMobilesInRange(2))
{
    if (m != this && m != this.ControlMaster && IsEnemy(m))
    {
        m.ApplyPoison(this, Poison.Deadly);
    }
}
 
Back