ModernUO/Scripts/Mobiles/Monsters/ML/Twisted Weald/Changeling.cs
2018-09-14 08:46:14 -07:00

299 lines
6.4 KiB
C#

using System;
using Server.Spells;
using Server.Items;
namespace Server.Mobiles
{
public class Changeling : BaseCreature
{
public override string CorpseName => "a changeling corpse";
public override string DefaultName => "a changeling";
public virtual int DefaultHue => 0;
[Constructible]
public Changeling()
: base( AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4 )
{
Body = 264;
Hue = DefaultHue;
SetStr( 36, 105 );
SetDex( 212, 262 );
SetInt( 317, 399 );
SetHits( 201, 211 );
SetStam( 212, 262 );
SetMana( 317, 399 );
SetDamage( 9, 15 );
SetDamageType( ResistanceType.Physical, 100 );
SetResistance( ResistanceType.Physical, 81, 90 );
SetResistance( ResistanceType.Fire, 40, 50 );
SetResistance( ResistanceType.Cold, 40, 49 );
SetResistance( ResistanceType.Poison, 40, 50 );
SetResistance( ResistanceType.Energy, 43, 50 );
SetSkill( SkillName.Wrestling, 10.4, 12.5 );
SetSkill( SkillName.Tactics, 101.1, 108.3 );
SetSkill( SkillName.MagicResist, 121.6, 132.2 );
SetSkill( SkillName.Magery, 91.6, 99.5 );
SetSkill( SkillName.EvalInt, 91.5, 98.8 );
SetSkill( SkillName.Meditation, 91.7, 98.5 );
Fame = 15000;
Karma = -15000;
PackScroll( 1, 7 );
PackItem( new Arrow( 35 ) );
PackItem( new Bolt( 25 ) );
PackGem( 2 );
PackArcaneScroll( 0, 1 );
}
public override bool ShowFameTitle => false;
public override bool InitialInnocent => m_MorphedInto != null;
public override void GenerateLoot()
{
AddLoot( LootPack.AosRich, 3 );
}
public override int GetAngerSound() { return 0x46E; }
public override int GetIdleSound() { return 0x470; }
public override int GetAttackSound() { return 0x46D; }
public override int GetHurtSound() { return 0x471; }
public override int GetDeathSound() { return 0x46F; }
private Mobile m_MorphedInto;
private DateTime m_LastMorph;
private DateTime m_NextFireRing;
[CommandProperty( AccessLevel.GameMaster )]
public Mobile MorphedInto
{
get => m_MorphedInto;
set
{
if ( value == this )
value = null;
if ( m_MorphedInto != value )
{
Revert();
if ( value != null )
{
Morph( value );
m_LastMorph = DateTime.UtcNow;
}
m_MorphedInto = value;
Delta( MobileDelta.Noto );
}
}
}
public override void OnThink()
{
base.OnThink();
if ( Combatant != null )
{
if ( m_NextFireRing <= DateTime.UtcNow && Utility.RandomDouble() < 0.02 )
{
FireRing();
m_NextFireRing = DateTime.UtcNow + TimeSpan.FromMinutes( 2 );
}
if ( Combatant.Player && m_MorphedInto != Combatant && Utility.RandomDouble() < 0.05 )
MorphedInto = Combatant;
}
}
public override bool CheckIdle()
{
bool idle = base.CheckIdle();
if ( idle && m_MorphedInto != null && DateTime.UtcNow - m_LastMorph > TimeSpan.FromSeconds( 30 ) )
MorphedInto = null;
return idle;
}
private void FireEffects( int itemID, int[] offsets )
{
for ( int i = 0; i < offsets.Length; i += 2 )
{
Point3D p = Location;
p.X += offsets[i];
p.Y += offsets[i + 1];
if ( SpellHelper.AdjustField( ref p, Map, 12, false ) )
Effects.SendLocationEffect( p, Map, itemID, 50 );
}
}
private static readonly int[] m_FireNorth =
{
-1, -1,
1, -1,
-1, 2,
1, 2
};
private static readonly int[] m_FireEast =
{
-1, 0,
2, 0
};
protected virtual void FireRing()
{
FireEffects( 0x3E27, m_FireNorth );
FireEffects( 0x3E31, m_FireEast );
}
protected virtual void Morph( Mobile m )
{
Body = m.Body;
Hue = m.Hue;
Female = m.Female;
Name = m.Name;
NameHue = m.NameHue;
Title = m.Title;
Kills = m.Kills;
HairItemID = m.HairItemID;
HairHue = m.HairHue;
FacialHairItemID = m.FacialHairItemID;
FacialHairHue = m.FacialHairHue;
// TODO: Skills?
foreach ( Item item in m.Items )
{
if ( item.Layer != Layer.Backpack && item.Layer != Layer.Mount && item.Layer != Layer.Bank )
AddItem( new ClonedItem( item ) ); // TODO: Clone weapon/armor attributes
}
PlaySound( 0x511 );
FixedParticles( 0x376A, 1, 14, 5045, EffectLayer.Waist );
}
protected virtual void Revert()
{
Body = 264;
Hue = ( IsParagon && DefaultHue == 0 ) ? Paragon.Hue : DefaultHue;
Female = false;
Name = null;
NameHue = -1;
Title = null;
Kills = 0;
HairItemID = 0;
HairHue = 0;
FacialHairItemID = 0;
FacialHairHue = 0;
DeleteClonedItems();
PlaySound( 0x511 );
FixedParticles( 0x376A, 1, 14, 5045, EffectLayer.Waist );
}
public void DeleteClonedItems()
{
for ( int i = Items.Count - 1; i >= 0; --i )
{
Item item = Items[i];
if ( item is ClonedItem )
item.Delete();
}
if ( Backpack != null )
{
for ( int i = Backpack.Items.Count - 1; i >= 0; --i )
{
Item item = Backpack.Items[i];
if ( item is ClonedItem )
item.Delete();
}
}
}
public override void OnAfterDelete()
{
DeleteClonedItems();
base.OnAfterDelete();
}
public override void ClearHands()
{
}
public Changeling( Serial serial )
: base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
writer.Write( ( m_MorphedInto != null ) );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
if ( reader.ReadBool() )
ValidationQueue<Changeling>.Add( this );
}
public void Validate()
{
Revert();
}
private class ClonedItem : Item
{
public ClonedItem( Item item )
: base( item.ItemID )
{
Name = item.Name;
Weight = item.Weight;
Hue = item.Hue;
Layer = item.Layer;
Movable = false;
}
public ClonedItem( 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();
}
}
}
}