ModernUO/Scripts/Mobiles/Monsters/ML/Twisted Weald/Changeling.cs
eos a0e13d5007 - Future ML craftables added to the special repair list until the craft system is updated.
- Items can now be repaired while wearing them.
- Items can now be fortified while wearing them.
- Fixed repair deed messages not sending.
- Sound effect added to powder of fortifying.
- Map issue for fishing and SOSs fixed, where it would not allow fishing in empty resource banks when not on the target SOS map.
- Added proximity spawner.
- Improved spawner mouseover menu, now also shows types set on the spawner which are not yet spawned.
- Fixed spawners only deleting half of their spawned objects when deleted.
- Added the ability to set TextDefinition objects in the props gump.
- WaitTeleporters now round delays to nearest in the remaining time messages.
- Updated TextDefinition to be more usable; made it parsable from string and added safe serialization/deserialization methods.
- Improved checking whether a mobile can flee.
- Monsters that give ML minor artifacts will no longer flee when low on hits (like paragons).
- Monsters that give ML minor artifacts will no longer spawn as paragon.
- Fixed issue with pets not eating certain foods.
- AI and targeting fixes for Red Death, Pyre and Swoop.
- Fame and karma added to Rend.
- Swoop corrected to have 0 karma.
- Stat and skill tweaks for Putrefier.
- Changelings will no longer show their fame title when morphed.
- Added travel restrictions for ML dungeons.
- Fixed issue of travel restriction message displaying twice.
- Monster teleporting is no longer affected by region travel restrictions.
2012-03-07 18:59:52 +00:00

299 lines
6.3 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.Misc;
using Server.Spells;
using Server.Spells.Third;
using Server.Spells.Sixth;
using Server.Items;
using Server.Targeting;
namespace Server.Mobiles
{
[CorpseName( "a changeling corpse" )]
public class Changeling : BaseCreature
{
public virtual string DefaultName{ get{ return "a changeling"; } }
public virtual int DefaultHue{ get{ return 0; } }
[Constructable]
public Changeling()
: base( AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4 )
{
Name = DefaultName;
Body = 264;
Hue = DefaultHue;
BaseSoundID = 0x470;
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{ get{ return false; } }
public override void GenerateLoot()
{
AddLoot( LootPack.AosRich, 3 );
}
private Mobile m_MorphedInto;
private DateTime m_LastMorph;
private DateTime m_NextFireRing;
[CommandProperty( AccessLevel.GameMaster )]
public Mobile MorphedInto
{
get { return m_MorphedInto; }
set
{
if ( m_MorphedInto != value )
{
Revert();
if ( value == this )
value = null;
if ( value != null )
{
Morph( value );
m_LastMorph = DateTime.Now;
}
m_MorphedInto = value;
}
}
}
public override void OnThink()
{
base.OnThink();
if ( Combatant != null )
{
if ( m_NextFireRing <= DateTime.Now && Utility.RandomDouble() < 0.02 )
{
FireRing();
m_NextFireRing = DateTime.Now + 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.Now - 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 = new int[]
{
-1, -1,
1, -1,
-1, 2,
1, 2
};
private static readonly int[] m_FireEast = new int[]
{
-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 ? Paragon.Hue : DefaultHue;
Female = false;
Name = DefaultName;
NameHue = -1;
Title = null;
Kills = 0;
HairItemID = 0;
HairHue = 0;
FacialHairItemID = 0;
FacialHairHue = 0;
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();
}
}
PlaySound( 0x511 );
FixedParticles( 0x376A, 1, 14, 5045, EffectLayer.Waist );
}
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() )
m_ToRevert.Add( this );
}
private static List<Changeling> m_ToRevert;
public static void Configure()
{
m_ToRevert = new List<Changeling>();
}
public static void Initialize()
{
foreach ( Changeling c in m_ToRevert )
c.Revert();
m_ToRevert.Clear();
m_ToRevert = null;
}
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();
}
}
}
}