ModernUO/Scripts/Mobiles/Monsters/ML/Humanoid/Magic/Satyr.cs
daedalus cd7c2becf7 - Hit Life Leech now works in PvP
(http://www.uodemise.com/discussion/showthread.php?t=121298)

- Summoned Daemon now has the proper bodyvalue (AoS+) and effect
(http://www.uodemise.com/discussion/showthread.php?t=127404)

- Two new house signs are added
(http://www.uodemise.com/discussion/showthread.php?t=125409)

- Changes to Satyrs and Dryads:
--> Dryads:
----> they do area peace
----> can partially undress males
----> have chance to drop peculiar or fragrant (not yet implemented) seeds
--> Satyrs:
----> their karma is neutral
----> can peace combatants
----> can provoke nearby creatures to the combatant
----> can undress females
----> can discord combatants
--> Both: can drop spellweaving scrolls
(http://www.uodemise.com/discussion/showthread.php?t=125444)

- Added Auto Arrow Recovery feature (SE+)
(http://www.uodemise.com/discussion/showthread.php?t=114807)
2009-12-14 19:01:59 +00:00

234 lines
6 KiB
C#

using System;
using System.Collections.Generic;
namespace Server.Mobiles
{
[CorpseName( "a satyr's corpse" )]
public class Satyr : BaseCreature
{
[Constructable]
public Satyr() : base( AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4 )
{
Name = "a satyr";
Body = 271;
BaseSoundID = 0x586;
SetStr( 177, 195 );
SetDex( 251, 269 );
SetInt( 153, 170 );
SetHits( 350, 400 );
SetDamage( 13, 24 );
SetDamageType( ResistanceType.Physical, 100 );
SetResistance( ResistanceType.Physical, 55, 60 );
SetResistance( ResistanceType.Fire, 25, 35 );
SetResistance( ResistanceType.Cold, 30, 40 );
SetResistance( ResistanceType.Poison, 30, 40 );
SetResistance( ResistanceType.Energy, 30, 40 );
SetSkill( SkillName.MagicResist, 55.0, 65.0 );
SetSkill( SkillName.Tactics, 80.0, 100.0 );
SetSkill( SkillName.Wrestling, 80.0, 100.0 );
Fame = 5000;
Karma = 0;
VirtualArmor = 28; // Don't know what it should be
PackArcanceScroll( 0.05 );
}
public override void GenerateLoot()
{
AddLoot( LootPack.MlRich );
}
public override void OnThink()
{
base.OnThink();
Peace( Combatant );
Undress( Combatant );
Suppress( Combatant );
Provoke( Combatant );
}
#region Peace
private DateTime m_NextPeace;
public void Peace( Mobile target )
{
if ( target == null || Deleted || !Alive || m_NextPeace > DateTime.Now || 0.1 < Utility.RandomDouble() )
return;
PlayerMobile p = target as PlayerMobile;
if ( p != null && p.PeacedUntil < DateTime.Now && !p.Hidden && CanBeHarmful( p ) )
{
p.PeacedUntil = DateTime.Now + TimeSpan.FromMinutes( 1 );
p.SendLocalizedMessage( 500616 ); // You hear lovely music, and forget to continue battling!
p.FixedParticles( 0x376A, 1, 32, 0x15BD, EffectLayer.Waist );
p.Combatant = null;
PlaySound( 0x58D );
}
m_NextPeace = DateTime.Now + TimeSpan.FromSeconds( 10 );
}
#endregion
#region Suppress
private static Dictionary<Mobile, Timer> m_Suppressed = new Dictionary<Mobile, Timer>();
private DateTime m_NextSuppress;
public void Suppress( Mobile target )
{
if ( target == null || m_Suppressed.ContainsKey( target ) || Deleted || !Alive || m_NextSuppress > DateTime.Now || 0.1 < Utility.RandomDouble() )
return;
TimeSpan delay = TimeSpan.FromSeconds( Utility.RandomMinMax( 20, 80 ) );
if ( !target.Hidden && CanBeHarmful( target ) )
{
target.SendLocalizedMessage( 1072061 ); // You hear jarring music, suppressing your strength.
for ( int i = 0; i < target.Skills.Length; i++ )
{
Skill s = target.Skills[ i ];
target.AddSkillMod( new TimedSkillMod( s.SkillName, true, s.Base * -0.28, delay ) );
}
int count = (int) Math.Round( delay.TotalSeconds / 1.25 );
Timer timer = new AnimateTimer( target, count );
m_Suppressed.Add( target, timer );
timer.Start();
PlaySound( 0x58C );
}
m_NextSuppress = DateTime.Now + TimeSpan.FromSeconds( 10 );
}
public static void SuppressRemove( Mobile target )
{
if ( target != null && m_Suppressed.ContainsKey( target ) )
{
Timer timer = m_Suppressed[ target ];
if ( timer != null || timer.Running )
timer.Stop();
m_Suppressed.Remove( target );
}
}
private class AnimateTimer : Timer
{
private Mobile m_Owner;
private int m_Count;
public AnimateTimer( Mobile owner, int count ) : base( TimeSpan.Zero, TimeSpan.FromSeconds( 1.25 ) )
{
m_Owner = owner;
m_Count = count;
}
protected override void OnTick()
{
if ( m_Owner.Deleted || !m_Owner.Alive || m_Count-- < 0 )
{
SuppressRemove( m_Owner );
}
else
m_Owner.FixedParticles( 0x376A, 1, 32, 0x15BD, EffectLayer.Waist );
}
}
#endregion
#region Undress
private DateTime m_NextUndress;
public void Undress( Mobile target )
{
if ( target == null || Deleted || !Alive || m_NextUndress > DateTime.Now || 0.005 < Utility.RandomDouble() )
return;
if ( target.Player && target.Female && !target.Hidden && CanBeHarmful( target ) )
{
UndressItem( target, Layer.OuterTorso );
UndressItem( target, Layer.InnerTorso );
UndressItem( target, Layer.MiddleTorso );
UndressItem( target, Layer.Pants );
UndressItem( target, Layer.Shirt );
target.SendLocalizedMessage( 1072196 ); // The satyr's music makes your blood race. Your clothing is too confining.
}
m_NextUndress = DateTime.Now + TimeSpan.FromMinutes( 1 );
}
public void UndressItem( Mobile m, Layer layer )
{
Item item = m.FindItemOnLayer( layer );
if ( item != null && item.Movable )
m.PlaceInBackpack( item );
}
#endregion
#region Provoke
private DateTime m_NextProvoke;
public void Provoke( Mobile target )
{
if ( target == null || Deleted || !Alive || m_NextProvoke > DateTime.Now || 0.05 < Utility.RandomDouble() )
return;
foreach ( Mobile m in GetMobilesInRange( RangePerception ) )
{
if ( m is BaseCreature )
{
BaseCreature c = (BaseCreature) m;
if ( c == this || c == target || c.Unprovokable || c.IsParagon || c.BardProvoked || c.AccessLevel != AccessLevel.Player || !c.CanBeHarmful( target ) )
continue;
c.Provoke( this, target, true );
if ( target.Player )
target.SendLocalizedMessage( 1072062 ); // You hear angry music, and start to fight.
PlaySound( 0x58A );
break;
}
}
m_NextProvoke = DateTime.Now + TimeSpan.FromSeconds( 10 );
}
#endregion
public override int Meat { get { return 1; } }
public Satyr( 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();
}
}
}