299 lines
6.4 KiB
C#
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();
|
|
}
|
|
}
|
|
}
|
|
}
|