- Terrible Hatchlings quest fixed to only reward SE weapons and armor.
- Slayer and opposition systems now account for inheritance. - Added Satyrs to the fey opposition group. - Added fey slayer vulnerability to cu sidhes. - Added reptilian and dragon slayer vulnerabilities to reptalons. - Various mage AI additions for necromancers. (Spirit speak for healing, pain spike and strangle for damage, automatic mage/necro bias by skill value.) - Fixed a targeting issue not accounting for FightMode.Evil versus low karma targeting. - Added melee damage bonus for Talisman killer properties. - Added general ML loot for ML areas. - Added ML minor artifact drops for named ML mobs. - Added named ML mobs for Bedlam.
This commit is contained in:
parent
a0bc5e2349
commit
43e5982fbb
22 changed files with 1207 additions and 231 deletions
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Server.Spells;
|
||||
using Server.Spells.Fifth;
|
||||
|
|
@ -37,24 +36,28 @@ namespace Server.Mobiles
|
|||
|
||||
public virtual bool SmartAI
|
||||
{
|
||||
get { return ( m_Mobile is BaseVendor || m_Mobile is BaseEscortable ); }
|
||||
get { return ( m_Mobile is BaseVendor || m_Mobile is BaseEscortable/* || m_Mobile is Changeling*/ ); } // TODO: Uncomment once added
|
||||
}
|
||||
|
||||
public virtual bool IsNecromancer
|
||||
{
|
||||
get { return ( m_Mobile.Skills[ SkillName.Necromancy ].Value > 50 ); }
|
||||
}
|
||||
|
||||
private const double HealChance = 0.10; // 10% chance to heal at gm magery
|
||||
private const double TeleportChance = 0.05; // 5% chance to teleport at gm magery
|
||||
private const double DispelChance = 0.75; // 75% chance to dispel at gm magery
|
||||
|
||||
public virtual double ScaleByMagery( double v )
|
||||
public virtual double ScaleBySkill( double v, SkillName skill )
|
||||
{
|
||||
return m_Mobile.Skills[ SkillName.Magery ].Value * v * 0.01;
|
||||
return v * m_Mobile.Skills[ skill ].Value / 100;
|
||||
}
|
||||
|
||||
public override bool DoActionWander()
|
||||
{
|
||||
if( AcquireFocusMob( m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true ) )
|
||||
{
|
||||
if( m_Mobile.Debug )
|
||||
m_Mobile.DebugSay( "I am going to attack {0}", m_Mobile.FocusMob.Name );
|
||||
m_Mobile.DebugSay( "I am going to attack {0}", m_Mobile.FocusMob.Name );
|
||||
|
||||
m_Mobile.Combatant = m_Mobile.FocusMob;
|
||||
Action = ActionType.Combat;
|
||||
|
|
@ -74,7 +77,7 @@ namespace Server.Mobiles
|
|||
|
||||
base.DoActionWander();
|
||||
|
||||
if( ( Utility.RandomDouble() < .05 ) )
|
||||
if( Utility.RandomDouble() < 0.05 )
|
||||
{
|
||||
Spell spell = CheckCastHealingSpell();
|
||||
|
||||
|
|
@ -104,7 +107,7 @@ namespace Server.Mobiles
|
|||
|
||||
if( !SmartAI )
|
||||
{
|
||||
if( ScaleByMagery( HealChance ) < Utility.RandomDouble() )
|
||||
if( ScaleBySkill( HealChance, SkillName.Magery ) < Utility.RandomDouble() )
|
||||
return null;
|
||||
}
|
||||
else
|
||||
|
|
@ -117,13 +120,22 @@ namespace Server.Mobiles
|
|||
|
||||
if( m_Mobile.Hits < ( m_Mobile.HitsMax - 50 ) )
|
||||
{
|
||||
spell = new GreaterHealSpell( m_Mobile, null );
|
||||
if ( UseNecromancy() )
|
||||
{
|
||||
m_Mobile.UseSkill( SkillName.SpiritSpeak );
|
||||
}
|
||||
else
|
||||
{
|
||||
spell = new GreaterHealSpell( m_Mobile, null );
|
||||
|
||||
if( spell == null )
|
||||
spell = new HealSpell( m_Mobile, null );
|
||||
if( spell == null )
|
||||
spell = new HealSpell( m_Mobile, null );
|
||||
}
|
||||
}
|
||||
else if( m_Mobile.Hits < ( m_Mobile.HitsMax - 10 ) )
|
||||
{
|
||||
spell = new HealSpell( m_Mobile, null );
|
||||
}
|
||||
|
||||
double delay;
|
||||
|
||||
|
|
@ -175,7 +187,7 @@ namespace Server.Mobiles
|
|||
|
||||
public void OnFailedMove()
|
||||
{
|
||||
if( !m_Mobile.DisallowAllMoves && ( SmartAI ? Utility.Random( 4 ) == 0 : ScaleByMagery( TeleportChance ) > Utility.RandomDouble() ) )
|
||||
if( !m_Mobile.DisallowAllMoves && ( SmartAI ? Utility.Random( 4 ) == 0 : ScaleBySkill( TeleportChance, SkillName.Magery ) > Utility.RandomDouble() ) )
|
||||
{
|
||||
if( m_Mobile.Target != null )
|
||||
m_Mobile.Target.Cancel( m_Mobile, TargetCancelType.Canceled );
|
||||
|
|
@ -186,8 +198,7 @@ namespace Server.Mobiles
|
|||
}
|
||||
else if( AcquireFocusMob( m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true ) )
|
||||
{
|
||||
if( m_Mobile.Debug )
|
||||
m_Mobile.DebugSay( "My move is blocked, so I am going to attack {0}", m_Mobile.FocusMob.Name );
|
||||
m_Mobile.DebugSay( "My move is blocked, so I am going to attack {0}", m_Mobile.FocusMob.Name );
|
||||
|
||||
m_Mobile.Combatant = m_Mobile.FocusMob;
|
||||
Action = ActionType.Combat;
|
||||
|
|
@ -209,46 +220,41 @@ namespace Server.Mobiles
|
|||
OnFailedMove();
|
||||
}
|
||||
|
||||
public virtual bool CanCastNecro()
|
||||
public virtual bool UseNecromancy()
|
||||
{
|
||||
return ( Utility.RandomBool() && ( m_Mobile is BaseCreature ) && ( (BaseCreature)m_Mobile ).IsNecromancer );
|
||||
}
|
||||
if ( IsNecromancer )
|
||||
return ( Utility.Random( m_Mobile.Skills[ SkillName.Necromancy ].BaseFixedPoint ) > Utility.Random( m_Mobile.Skills[ SkillName.Magery ].BaseFixedPoint ) );
|
||||
|
||||
public virtual bool CanCastNecroBias( int bias )
|
||||
{
|
||||
return ( CanCastNecro() && Utility.Random( bias ) == 0 );
|
||||
}
|
||||
|
||||
public virtual Spell GetRandomDamage()
|
||||
{
|
||||
return ( CanCastNecroBias( 2 ) ) ? GetRandomDamageNecroSpell() : GetRandomDamageSpell();
|
||||
}
|
||||
|
||||
public virtual Spell GetRandomDamageNecroSpell()
|
||||
{
|
||||
int possibles = 3;
|
||||
|
||||
if( myNecro >= 100 )
|
||||
{
|
||||
possibles = 5;
|
||||
}
|
||||
switch( Utility.Random( possibles ) )
|
||||
{
|
||||
default: m_Mobile.DebugSay( "Vengeful Spirit" ); return new VengefulSpiritSpell( m_Mobile, null );
|
||||
|
||||
case 0: m_Mobile.DebugSay( "Pain Spike" ); return new PainSpikeSpell( m_Mobile, null );
|
||||
case 1: m_Mobile.DebugSay( "Poison Strike" ); return new PoisonStrikeSpell( m_Mobile, null );
|
||||
case 2: m_Mobile.DebugSay( "Strangle" ); return new StrangleSpell( m_Mobile, null );
|
||||
case 3: m_Mobile.DebugSay( "Wither" ); return new WitherSpell( m_Mobile, null );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual Spell GetRandomDamageSpell()
|
||||
{
|
||||
int maxCircle = (int)( ( myMagery + 20.0 ) / ( 100.0 / 7.0 ) );
|
||||
return UseNecromancy() ? GetRandomDamageSpellNecro() : GetRandomDamageSpellMage();
|
||||
}
|
||||
|
||||
public virtual Spell GetRandomDamageSpellNecro()
|
||||
{
|
||||
int bound = ( m_Mobile.Skills[ SkillName.Necromancy ].Value >= 100 ) ? 5 : 3;
|
||||
|
||||
switch( Utility.Random( bound ) )
|
||||
{
|
||||
case 0: m_Mobile.DebugSay( "Pain Spike" ); return new PainSpikeSpell( m_Mobile, null );
|
||||
case 1: m_Mobile.DebugSay( "Poison Strike" ); return new PoisonStrikeSpell( m_Mobile, null );
|
||||
case 2: m_Mobile.DebugSay( "Strangle" ); return new StrangleSpell( m_Mobile, null );
|
||||
case 3: m_Mobile.DebugSay( "Wither" ); return new WitherSpell( m_Mobile, null );
|
||||
default: m_Mobile.DebugSay( "Vengeful Spirit" ); return new VengefulSpiritSpell( m_Mobile, null );
|
||||
}
|
||||
}
|
||||
|
||||
public virtual Spell GetRandomDamageSpellMage()
|
||||
{
|
||||
int maxCircle = (int)( ( m_Mobile.Skills[ SkillName.Magery ].Value + 20.0 ) / ( 100.0 / 7.0 ) );
|
||||
|
||||
if( maxCircle < 1 )
|
||||
maxCircle = 1;
|
||||
else if( maxCircle > 8 )
|
||||
maxCircle = 8;
|
||||
|
||||
switch( Utility.Random( maxCircle * 2 ) )
|
||||
{
|
||||
|
|
@ -268,49 +274,39 @@ namespace Server.Mobiles
|
|||
}
|
||||
}
|
||||
|
||||
public virtual Spell GetRandomCurse()
|
||||
public virtual Spell GetRandomCurseSpell()
|
||||
{
|
||||
return ( CanCastNecro() ) ? GetRandomNecroCurseSpell() : GetRandomCurseSpell();
|
||||
return UseNecromancy() ? GetRandomCurseSpellNecro() : GetRandomCurseSpellMage();
|
||||
}
|
||||
|
||||
public virtual Spell GetRandomNecroCurseSpell()
|
||||
public virtual Spell GetRandomCurseSpellNecro()
|
||||
{
|
||||
switch( Utility.Random( 4 ) )
|
||||
{
|
||||
default:
|
||||
case 0: m_Mobile.DebugSay( "Blood Oath" ); return new BloodOathSpell( m_Mobile, null );
|
||||
case 1: m_Mobile.DebugSay( "Corpse Skin" ); return new CorpseSkinSpell( m_Mobile, null );
|
||||
case 2: m_Mobile.DebugSay( "Evil Omen" ); return new EvilOmenSpell( m_Mobile, null );
|
||||
case 3: m_Mobile.DebugSay( "Mind Rot" ); return new MindRotSpell( m_Mobile, null );
|
||||
default: m_Mobile.DebugSay( "Mind Rot" ); return new MindRotSpell( m_Mobile, null );
|
||||
}
|
||||
}
|
||||
|
||||
public virtual Spell GetRandomCurseSpell()
|
||||
public virtual Spell GetRandomCurseSpellMage()
|
||||
{
|
||||
if( Utility.Random( 4 ) == 3 )
|
||||
{
|
||||
if( myMagery >= 40.0 )
|
||||
{
|
||||
return new CurseSpell( m_Mobile, null );
|
||||
}
|
||||
}
|
||||
if( m_Mobile.Skills[ SkillName.Magery ].Value >= 40.0 && Utility.Random( 4 ) == 0 )
|
||||
return new CurseSpell( m_Mobile, null );
|
||||
|
||||
switch( Utility.Random( 3 ) )
|
||||
{
|
||||
default:
|
||||
case 0: return new WeakenSpell( m_Mobile, null );
|
||||
case 1: return new ClumsySpell( m_Mobile, null );
|
||||
case 2: return new FeeblemindSpell( m_Mobile, null );
|
||||
default: return new FeeblemindSpell( m_Mobile, null );
|
||||
}
|
||||
}
|
||||
|
||||
public virtual Spell GetRandomManaDrainSpell()
|
||||
{
|
||||
if( Utility.RandomBool() )
|
||||
{
|
||||
if( myMagery >= 80.0 )
|
||||
return new ManaVampireSpell( m_Mobile, null );
|
||||
}
|
||||
if( m_Mobile.Skills[ SkillName.Magery ].Value >= 80.0 && Utility.RandomBool() )
|
||||
return new ManaVampireSpell( m_Mobile, null );
|
||||
|
||||
return new ManaDrainSpell( m_Mobile, null );
|
||||
}
|
||||
|
|
@ -319,7 +315,7 @@ namespace Server.Mobiles
|
|||
{
|
||||
if( !SmartAI )
|
||||
{
|
||||
if( ScaleByMagery( DispelChance ) > Utility.RandomDouble() )
|
||||
if( ScaleBySkill( DispelChance, SkillName.Magery ) > Utility.RandomDouble() )
|
||||
return new DispelSpell( m_Mobile, null );
|
||||
|
||||
return ChooseSpell( toDispel );
|
||||
|
|
@ -340,12 +336,6 @@ namespace Server.Mobiles
|
|||
return spell;
|
||||
}
|
||||
|
||||
public virtual double myNecro { get { return m_Mobile.Skills[ SkillName.Magery ].Value; } }
|
||||
|
||||
public virtual double myMagery { get { return m_Mobile.Skills[ SkillName.Magery ].Value; } }
|
||||
|
||||
public virtual double mySpiritSpeak { get { return m_Mobile.Skills[ SkillName.SpiritSpeak ].Value; } }
|
||||
|
||||
public virtual Spell ChooseSpell( Mobile c )
|
||||
{
|
||||
Spell spell = null;
|
||||
|
|
@ -357,64 +347,74 @@ namespace Server.Mobiles
|
|||
if( spell != null )
|
||||
return spell;
|
||||
|
||||
if( IsNecromancer )
|
||||
{
|
||||
double psDamage = ( ( m_Mobile.Skills[ SkillName.SpiritSpeak ].Value - c.Skills[ SkillName.MagicResist ].Value ) / 10 ) + ( c.Player ? 18 : 30 );
|
||||
|
||||
if( psDamage > c.Hits )
|
||||
return new PainSpikeSpell( m_Mobile, null );
|
||||
}
|
||||
|
||||
switch (Utility.Random(16))
|
||||
{
|
||||
case 0:
|
||||
case 1: // Poison them
|
||||
{
|
||||
//m_Mobile.DebugSay( "Attempting to poison" );
|
||||
if (c.Poisoned)
|
||||
goto default;
|
||||
|
||||
if (!c.Poisoned)
|
||||
spell = new PoisonSpell(m_Mobile, null);
|
||||
m_Mobile.DebugSay( "Attempting to poison" );
|
||||
|
||||
spell = new PoisonSpell(m_Mobile, null);
|
||||
break;
|
||||
}
|
||||
case 2: // Bless ourselves.
|
||||
case 2: // Bless ourselves
|
||||
{
|
||||
//m_Mobile.DebugSay( "Blessing myself" );
|
||||
m_Mobile.DebugSay( "Blessing myself" );
|
||||
|
||||
spell = new BlessSpell(m_Mobile, null);
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
case 4: // Curse them.
|
||||
case 4: // Curse them
|
||||
{
|
||||
//m_Mobile.DebugSay( "Attempting to curse" );
|
||||
m_Mobile.DebugSay( "Attempting to curse" );
|
||||
|
||||
spell = GetRandomCurse();
|
||||
spell = GetRandomCurseSpell();
|
||||
break;
|
||||
}
|
||||
case 5: // Paralyze them.
|
||||
case 5: // Paralyze them
|
||||
{
|
||||
//m_Mobile.DebugSay( "Attempting to paralyze" );
|
||||
if (m_Mobile.Skills[ SkillName.Magery ].Value <= 50.0)
|
||||
goto default;
|
||||
|
||||
if (m_Mobile.Skills[SkillName.Magery].Value > 50.0)
|
||||
spell = new ParalyzeSpell(m_Mobile, null);
|
||||
m_Mobile.DebugSay( "Attempting to paralyze" );
|
||||
|
||||
spell = new ParalyzeSpell(m_Mobile, null);
|
||||
break;
|
||||
}
|
||||
case 6: // Drain mana
|
||||
{
|
||||
//m_Mobile.DebugSay( "Attempting to drain mana" );
|
||||
m_Mobile.DebugSay( "Attempting to drain mana" );
|
||||
|
||||
spell = GetRandomManaDrainSpell();
|
||||
break;
|
||||
}
|
||||
case 7:
|
||||
case 7: // Invis ourselves
|
||||
{
|
||||
//m_Mobile.DebugSay( "Attempting to Invis" );
|
||||
|
||||
if (Utility.RandomBool())
|
||||
spell = new InvisibilitySpell(m_Mobile, null);
|
||||
goto default;
|
||||
|
||||
m_Mobile.DebugSay( "Attempting to invis myself" );
|
||||
|
||||
spell = new InvisibilitySpell(m_Mobile, null);
|
||||
break;
|
||||
}
|
||||
|
||||
default: // Damage them.
|
||||
default: // Damage them
|
||||
{
|
||||
//m_Mobile.DebugSay( "Just doing damage" );
|
||||
m_Mobile.DebugSay( "Just doing damage" );
|
||||
|
||||
spell = GetRandomDamage();
|
||||
spell = GetRandomDamageSpell();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -429,12 +429,12 @@ namespace Server.Mobiles
|
|||
|
||||
switch( Utility.Random( 3 ) )
|
||||
{
|
||||
default:
|
||||
case 0: // Poison them
|
||||
{
|
||||
if( !c.Poisoned )
|
||||
spell = new PoisonSpell( m_Mobile, null );
|
||||
if( c.Poisoned )
|
||||
goto case 1;
|
||||
|
||||
spell = new PoisonSpell( m_Mobile, null );
|
||||
break;
|
||||
}
|
||||
case 1: // Deal some damage
|
||||
|
|
@ -443,9 +443,9 @@ namespace Server.Mobiles
|
|||
|
||||
break;
|
||||
}
|
||||
case 2: // Set up a combo
|
||||
default: // Set up a combo
|
||||
{
|
||||
if( m_Mobile.Mana < 40 && m_Mobile.Mana > 15 )
|
||||
if( m_Mobile.Mana > 15 && m_Mobile.Mana < 40 )
|
||||
{
|
||||
if( c.Paralyzed && !c.Poisoned )
|
||||
{
|
||||
|
|
@ -460,7 +460,7 @@ namespace Server.Mobiles
|
|||
}
|
||||
else if( m_Mobile.Mana > 60 )
|
||||
{
|
||||
if( Utility.Random( 2 ) == 0 && !c.Paralyzed && !c.Frozen && !c.Poisoned )
|
||||
if( Utility.RandomBool() && !c.Paralyzed && !c.Frozen && !c.Poisoned )
|
||||
{
|
||||
m_Combo = 0;
|
||||
spell = new ParalyzeSpell( m_Mobile, null );
|
||||
|
|
@ -499,15 +499,16 @@ namespace Server.Mobiles
|
|||
{
|
||||
if( !c.Poisoned )
|
||||
spell = new PoisonSpell( m_Mobile, null );
|
||||
else if ( IsNecromancer )
|
||||
spell = new StrangleSpell( m_Mobile, null );
|
||||
|
||||
++m_Combo; // Move to next spell
|
||||
}
|
||||
|
||||
if( m_Combo == 3 && spell == null )
|
||||
{
|
||||
switch( Utility.Random( 3 ) )
|
||||
switch( Utility.Random( IsNecromancer ? 4 : 3 ) )
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
{
|
||||
if( c.Int < c.Dex )
|
||||
|
|
@ -531,6 +532,12 @@ namespace Server.Mobiles
|
|||
m_Combo = -1; // Reset combo state
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
spell = new PainSpikeSpell( m_Mobile, null );
|
||||
m_Combo = -1; // Reset combo state
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( m_Combo == 4 && spell == null )
|
||||
|
|
@ -550,7 +557,7 @@ namespace Server.Mobiles
|
|||
}
|
||||
else
|
||||
{
|
||||
double del = ScaleByMagery( 3.0 );
|
||||
double del = ScaleBySkill( 3.0, SkillName.Magery );
|
||||
double min = 6.0 - ( del * 0.75 );
|
||||
double max = 6.0 - ( del * 1.25 );
|
||||
|
||||
|
|
@ -573,8 +580,7 @@ namespace Server.Mobiles
|
|||
|
||||
if( AcquireFocusMob( m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true ) )
|
||||
{
|
||||
if( m_Mobile.Debug )
|
||||
m_Mobile.DebugSay( "Something happened to my combatant, so I am going to fight {0}", m_Mobile.FocusMob.Name );
|
||||
m_Mobile.DebugSay( "Something happened to my combatant, so I am going to fight {0}", m_Mobile.FocusMob.Name );
|
||||
|
||||
m_Mobile.Combatant = c = m_Mobile.FocusMob;
|
||||
m_Mobile.FocusMob = null;
|
||||
|
|
@ -650,8 +656,7 @@ namespace Server.Mobiles
|
|||
|
||||
if( flee )
|
||||
{
|
||||
if( m_Mobile.Debug )
|
||||
m_Mobile.DebugSay( "I am going to flee from {0}", c.Name );
|
||||
m_Mobile.DebugSay( "I am going to flee from {0}", c.Name );
|
||||
|
||||
Action = ActionType.Flee;
|
||||
return true;
|
||||
|
|
@ -784,8 +789,7 @@ namespace Server.Mobiles
|
|||
}
|
||||
else if( AcquireFocusMob( m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true ) )
|
||||
{
|
||||
if( m_Mobile.Debug )
|
||||
m_Mobile.DebugSay( "I am scared of {0}", m_Mobile.FocusMob.Name );
|
||||
m_Mobile.DebugSay( "I am scared of {0}", m_Mobile.FocusMob.Name );
|
||||
|
||||
RunFrom( m_Mobile.FocusMob );
|
||||
m_Mobile.FocusMob = null;
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ namespace Server
|
|||
bool contains = false;
|
||||
|
||||
for ( int j = 0; !contains && j < group.Length; ++j )
|
||||
contains = ( type == group[j] );
|
||||
contains = group[j].IsAssignableFrom( type );
|
||||
|
||||
if ( contains )
|
||||
return i;
|
||||
|
|
@ -107,7 +107,8 @@ namespace Server
|
|||
typeof( Unicorn ),
|
||||
typeof( Wisp ),
|
||||
typeof( Treefellow ),
|
||||
typeof( MLDryad )
|
||||
typeof( MLDryad ),
|
||||
typeof( Satyr )
|
||||
},
|
||||
new Type[]
|
||||
{
|
||||
|
|
|
|||
|
|
@ -286,8 +286,6 @@ namespace Server.Mobiles
|
|||
#region Bonding
|
||||
public const bool BondingEnabled = true;
|
||||
|
||||
public virtual bool IsNecromancer { get { return ( Skills[ SkillName.Necromancy ].Value > 50 ); } }
|
||||
|
||||
public virtual bool IsBondable{ get{ return ( BondingEnabled && !Summoned ); } }
|
||||
public virtual TimeSpan BondingDelay{ get{ return TimeSpan.FromDays( 7.0 ); } }
|
||||
public virtual TimeSpan BondingAbandonDelay{ get{ return TimeSpan.FromDays( 1.0 ); } }
|
||||
|
|
@ -525,7 +523,7 @@ namespace Server.Mobiles
|
|||
public virtual int BreathRange{ get{ return RangePerception; } }
|
||||
|
||||
// Damage types
|
||||
public virtual int BreathChaosDamage { get { return 0; } }
|
||||
public virtual int BreathChaosDamage{ get { return 0; } }
|
||||
public virtual int BreathPhysicalDamage{ get{ return 0; } }
|
||||
public virtual int BreathFireDamage{ get{ return 100; } }
|
||||
public virtual int BreathColdDamage{ get{ return 0; } }
|
||||
|
|
@ -648,7 +646,7 @@ namespace Server.Mobiles
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public virtual int BreathComputeDamage()
|
||||
{
|
||||
int damage = (int)(Hits * BreathDamageScalar);
|
||||
|
|
@ -683,7 +681,7 @@ namespace Server.Mobiles
|
|||
{
|
||||
loc = target.Location;
|
||||
map = target.Map;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bool validLocation = false;
|
||||
|
|
@ -869,6 +867,9 @@ namespace Server.Mobiles
|
|||
|
||||
BaseCreature c = (BaseCreature)m;
|
||||
|
||||
if ( ( FightMode == FightMode.Evil && m.Karma < 0 ) || ( c.FightMode == FightMode.Evil && Karma < 0 ) )
|
||||
return true;
|
||||
|
||||
return ( m_iTeam != c.m_iTeam || ( (m_bSummoned || m_bControlled) != (c.m_bSummoned || c.m_bControlled) )/* || c.Combatant == this*/ );
|
||||
}
|
||||
|
||||
|
|
@ -1351,6 +1352,20 @@ namespace Server.Mobiles
|
|||
|
||||
public virtual void AlterMeleeDamageFrom( Mobile from, ref int damage )
|
||||
{
|
||||
#region Mondain's Legacy
|
||||
if ( from != null && from.Talisman is BaseTalisman )
|
||||
{
|
||||
BaseTalisman talisman = (BaseTalisman)from.Talisman;
|
||||
|
||||
if ( talisman.Killer != null && talisman.Killer.Type != null )
|
||||
{
|
||||
Type type = talisman.Killer.Type;
|
||||
|
||||
if ( type.IsAssignableFrom( GetType() ) )
|
||||
damage = (int)( damage * ( 1 + (double)talisman.Killer.Amount / 100 ) );
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
public virtual void AlterMeleeDamageTo( Mobile to, ref int damage )
|
||||
|
|
@ -1371,19 +1386,17 @@ namespace Server.Mobiles
|
|||
int hides = Hides;
|
||||
int scales = Scales;
|
||||
|
||||
if ( (feathers == 0 && wool == 0 && meat == 0 && hides == 0 && scales == 0) || Summoned || IsBonded || corpse.Animated )
|
||||
if ( ( feathers == 0 && wool == 0 && meat == 0 && hides == 0 && scales == 0 ) || Summoned || IsBonded || corpse.Animated )
|
||||
{
|
||||
if ( corpse.Animated )
|
||||
corpse.SendLocalizedMessageTo( from, 500464 ); // Use this on corpses to carve away meat and hide
|
||||
if ( corpse.Animated )
|
||||
corpse.SendLocalizedMessageTo( from, 500464 ); // Use this on corpses to carve away meat and hide
|
||||
else
|
||||
from.SendLocalizedMessage( 500485 ); // You see nothing useful to carve from the corpse.
|
||||
from.SendLocalizedMessage( 500485 ); // You see nothing useful to carve from the corpse.
|
||||
}
|
||||
else
|
||||
{
|
||||
if( Core.ML && from.Race == Race.Human )
|
||||
{
|
||||
hides = (int)Math.Ceiling( hides * 1.1 ); //10% Bonus Only applies to Hides, Ore & Logs
|
||||
}
|
||||
if ( Core.ML && from.Race == Race.Human )
|
||||
hides = (int)Math.Ceiling( hides * 1.1 ); // 10% bonus only applies to hides, ore & logs
|
||||
|
||||
if ( corpse.Map == Map.Felucca )
|
||||
{
|
||||
|
|
@ -1427,6 +1440,7 @@ namespace Server.Mobiles
|
|||
if ( hides != 0 )
|
||||
{
|
||||
Item holding = from.Weapon as Item;
|
||||
|
||||
if ( Core.AOS && ( holding is SkinningKnife /* TODO: || holding is ButcherWarCleaver || with is ButcherWarCleaver */ ) )
|
||||
{
|
||||
Item leather = null;
|
||||
|
|
@ -1447,7 +1461,9 @@ namespace Server.Mobiles
|
|||
from.SendLocalizedMessage( 500471 ); // You skin it, and the hides are now in the corpse.
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage( 1073555 ); // You skin it and place the cut-up hides in your backpack.
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -3684,6 +3700,27 @@ namespace Server.Mobiles
|
|||
|
||||
#region Pack & Loot
|
||||
|
||||
#region Mondain's Legacy
|
||||
public void PackArcaneScroll( int min, int max )
|
||||
{
|
||||
PackArcaneScroll( Utility.RandomMinMax( min, max ) );
|
||||
}
|
||||
|
||||
public void PackArcaneScroll( int amount )
|
||||
{
|
||||
for ( int i = 0; i < amount; ++i )
|
||||
PackArcaneScroll();
|
||||
}
|
||||
|
||||
public void PackArcaneScroll()
|
||||
{
|
||||
if ( !Core.ML )
|
||||
return;
|
||||
|
||||
PackItem( Loot.Construct( Loot.ArcanistScrollTypes ) );
|
||||
}
|
||||
#endregion
|
||||
|
||||
public void PackPotion()
|
||||
{
|
||||
PackItem( Loot.RandomPotion() );
|
||||
|
|
@ -3694,7 +3731,7 @@ namespace Server.Mobiles
|
|||
if ( !Core.ML || chance <= Utility.RandomDouble() )
|
||||
return;
|
||||
|
||||
PackItem( Loot.Construct( Loot.ArcaneScrollTypes ) );
|
||||
PackItem( Loot.Construct( Loot.ArcanistScrollTypes ) );
|
||||
}
|
||||
|
||||
public void PackNecroScroll( int index )
|
||||
|
|
@ -4445,10 +4482,19 @@ namespace Server.Mobiles
|
|||
return rights;
|
||||
}
|
||||
|
||||
#region Mondain's Legacy
|
||||
public virtual bool GivesMLMinorArtifact{ get{ return false; } }
|
||||
#endregion
|
||||
|
||||
public virtual void OnKilledBy( Mobile mob )
|
||||
{
|
||||
if ( m_Paragon && Paragon.CheckArtifactChance( mob, this ) )
|
||||
Paragon.GiveArtifactTo( mob );
|
||||
|
||||
#region Mondain's Legacy
|
||||
if ( GivesMLMinorArtifact && MondainsLegacy.CheckArtifactChance( mob, this ) )
|
||||
MondainsLegacy.GiveArtifactTo( mob );
|
||||
#endregion
|
||||
}
|
||||
|
||||
public override void OnDeath( Container c )
|
||||
|
|
@ -4814,22 +4860,6 @@ namespace Server.Mobiles
|
|||
return true;
|
||||
}
|
||||
|
||||
private static Type[] m_MinorArtifactsMl = new Type[]
|
||||
{
|
||||
typeof( AegisOfGrace ), typeof( BladeDance ), typeof( Bonesmasher ),
|
||||
typeof( Boomstick ), typeof( FeyLeggings ), typeof( FleshRipper ),
|
||||
typeof( HelmOfSwiftness ), typeof( PadsOfTheCuSidhe ), typeof( QuiverOfRage ),
|
||||
typeof( QuiverOfElements ), typeof( RaedsGlory ), typeof( RighteousAnger ),
|
||||
typeof( RobeOfTheEclipse ), typeof( RobeOfTheEquinox ), typeof( SoulSeeker ),
|
||||
typeof( TalonBite ), typeof( WildfireBow ), typeof( Windsong ),
|
||||
// TODO: Brightsight lenses, Bloodwood spirit, Totem of the void
|
||||
};
|
||||
|
||||
public static Type[] MinorArtifactsMl
|
||||
{
|
||||
get { return m_MinorArtifactsMl; }
|
||||
}
|
||||
|
||||
private static bool EnableRummaging = true;
|
||||
|
||||
private const double ChanceToRummage = 0.5; // 50%
|
||||
|
|
@ -5004,10 +5034,10 @@ namespace Server.Mobiles
|
|||
if ( CanBreath && DateTime.Now >= m_NextBreathTime ) // tested: controlled dragons do breath fire, what about summoned skeletal dragons?
|
||||
{
|
||||
Mobile target = this.Combatant;
|
||||
|
||||
|
||||
if( target != null && target.Alive && !target.IsDeadBondedPet && CanBeHarmful( target ) && target.Map == this.Map && !IsDeadBondedPet && target.InRange( this, BreathRange ) && InLOS( target ) && !BardPacified )
|
||||
{
|
||||
if( ( DateTime.Now - m_NextBreathTime ) < TimeSpan.FromSeconds( 30 ) )
|
||||
if( ( DateTime.Now - m_NextBreathTime ) < TimeSpan.FromSeconds( 30 ) )
|
||||
{
|
||||
BreathStart( target );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ namespace Server.Mobiles
|
|||
Karma = -3000;
|
||||
|
||||
VirtualArmor = 40;
|
||||
|
||||
|
||||
switch ( Utility.Random( 6 ) )
|
||||
{
|
||||
case 0: PackItem( new PlateArms() ); break;
|
||||
|
|
|
|||
136
Scripts/Mobiles/Monsters/ML/Bedlam/LadyJennifyr.cs
Normal file
136
Scripts/Mobiles/Monsters/ML/Bedlam/LadyJennifyr.cs
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
[CorpseName( "a Lady Jennifyr corpse" )]
|
||||
public class LadyJennifyr : SkeletalKnight
|
||||
{
|
||||
[Constructable]
|
||||
public LadyJennifyr()
|
||||
{
|
||||
Name = "Lady Jennifyr";
|
||||
Hue = 0x76D;
|
||||
|
||||
SetStr( 208, 309 );
|
||||
SetDex( 91, 118 );
|
||||
SetInt( 44, 101 );
|
||||
|
||||
SetHits( 1113, 1285 );
|
||||
|
||||
SetDamage( 15, 25 );
|
||||
|
||||
SetDamageType( ResistanceType.Physical, 40 );
|
||||
SetDamageType( ResistanceType.Cold, 60 );
|
||||
|
||||
SetResistance( ResistanceType.Physical, 56, 65 );
|
||||
SetResistance( ResistanceType.Fire, 41, 49 );
|
||||
SetResistance( ResistanceType.Cold, 71, 80 );
|
||||
SetResistance( ResistanceType.Poison, 41, 50 );
|
||||
SetResistance( ResistanceType.Energy, 50, 58 );
|
||||
|
||||
SetSkill( SkillName.Wrestling, 127.9, 137.1 );
|
||||
SetSkill( SkillName.Tactics, 128.4, 141.9 );
|
||||
SetSkill( SkillName.MagicResist, 102.1, 119.5 );
|
||||
SetSkill( SkillName.Anatomy, 129.0, 137.5 );
|
||||
|
||||
Fame = 18000;
|
||||
Karma = -18000;
|
||||
}
|
||||
|
||||
public override void GenerateLoot()
|
||||
{
|
||||
AddLoot( LootPack.AosUltraRich, 4 );
|
||||
}
|
||||
|
||||
public override void OnGaveMeleeAttack( Mobile defender )
|
||||
{
|
||||
base.OnGaveMeleeAttack( defender );
|
||||
|
||||
if ( Utility.RandomDouble() < 0.1 )
|
||||
{
|
||||
ExpireTimer timer;
|
||||
|
||||
if ( m_Table.TryGetValue( defender, out timer ) )
|
||||
timer.DoExpire();
|
||||
|
||||
defender.FixedParticles( 0x3709, 10, 30, 5052, EffectLayer.LeftFoot );
|
||||
defender.PlaySound( 0x208 );
|
||||
defender.SendLocalizedMessage( 1070833 ); // The creature fans you with fire, reducing your resistance to fire attacks.
|
||||
|
||||
ResistanceMod mod = new ResistanceMod( ResistanceType.Fire, -10 );
|
||||
defender.AddResistanceMod( mod );
|
||||
|
||||
m_Table[defender] = timer = new ExpireTimer( defender, mod );
|
||||
timer.Start();
|
||||
}
|
||||
}
|
||||
|
||||
private static Dictionary<Mobile, ExpireTimer> m_Table = new Dictionary<Mobile, ExpireTimer>();
|
||||
|
||||
private class ExpireTimer : Timer
|
||||
{
|
||||
private Mobile m_Mobile;
|
||||
private ResistanceMod m_Mod;
|
||||
|
||||
public ExpireTimer( Mobile m, ResistanceMod mod )
|
||||
: base( TimeSpan.FromSeconds( 10 ) )
|
||||
{
|
||||
m_Mobile = m;
|
||||
m_Mod = mod;
|
||||
Priority = TimerPriority.TwoFiftyMS;
|
||||
}
|
||||
|
||||
public void DoExpire()
|
||||
{
|
||||
m_Mobile.RemoveResistanceMod( m_Mod );
|
||||
|
||||
Stop();
|
||||
m_Table.Remove( m_Mobile );
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
m_Mobile.SendLocalizedMessage( 1070834 ); // Your resistance to fire attacks has returned.
|
||||
DoExpire();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// TODO: Uncomment once added
|
||||
public override void OnDeath( Container c )
|
||||
{
|
||||
base.OnDeath( c );
|
||||
|
||||
if ( Utility.RandomDouble() < 0.15 )
|
||||
c.DropItem( new DisintegratingThesisNotes() );
|
||||
|
||||
if ( Utility.RandomDouble() < 0.1 )
|
||||
c.DropItem( new ParrotItem() );
|
||||
}
|
||||
*/
|
||||
|
||||
public override bool GivesMLMinorArtifact{ get{ return true; } }
|
||||
|
||||
public LadyJennifyr( 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
88
Scripts/Mobiles/Monsters/ML/Bedlam/LadyMarai.cs
Normal file
88
Scripts/Mobiles/Monsters/ML/Bedlam/LadyMarai.cs
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
[CorpseName( "a Lady Marai corpse" )]
|
||||
public class LadyMarai : SkeletalKnight
|
||||
{
|
||||
[Constructable]
|
||||
public LadyMarai()
|
||||
{
|
||||
Name = "Lady Marai";
|
||||
Hue = 0x21;
|
||||
|
||||
SetStr( 221, 304 );
|
||||
SetDex( 98, 138 );
|
||||
SetInt( 54, 99 );
|
||||
|
||||
SetHits( 694, 846 );
|
||||
|
||||
SetDamage( 15, 25 );
|
||||
|
||||
SetDamageType( ResistanceType.Physical, 40 );
|
||||
SetDamageType( ResistanceType.Cold, 60 );
|
||||
|
||||
SetResistance( ResistanceType.Physical, 55, 65 );
|
||||
SetResistance( ResistanceType.Fire, 40, 50 );
|
||||
SetResistance( ResistanceType.Cold, 70, 80 );
|
||||
SetResistance( ResistanceType.Poison, 40, 50 );
|
||||
SetResistance( ResistanceType.Energy, 50, 60 );
|
||||
|
||||
SetSkill( SkillName.Wrestling, 126.6, 137.2 );
|
||||
SetSkill( SkillName.Tactics, 128.7, 134.5 );
|
||||
SetSkill( SkillName.MagicResist, 102.1, 119.1 );
|
||||
SetSkill( SkillName.Anatomy, 126.2, 136.5 );
|
||||
|
||||
Fame = 18000;
|
||||
Karma = -18000;
|
||||
}
|
||||
|
||||
public override void GenerateLoot()
|
||||
{
|
||||
AddLoot( LootPack.AosUltraRich, 4 );
|
||||
}
|
||||
|
||||
public override WeaponAbility GetWeaponAbility()
|
||||
{
|
||||
return WeaponAbility.CrushingBlow;
|
||||
}
|
||||
|
||||
/*
|
||||
// TODO: Uncomment once added
|
||||
public override void OnDeath( Container c )
|
||||
{
|
||||
base.OnDeath( c );
|
||||
|
||||
if ( Utility.RandomDouble() < 0.15 )
|
||||
c.DropItem( new DisintegratingThesisNotes() );
|
||||
|
||||
if ( Utility.RandomDouble() < 0.1 )
|
||||
c.DropItem( new ParrotItem() );
|
||||
}
|
||||
*/
|
||||
|
||||
public override bool GivesMLMinorArtifact{ get{ return true; } }
|
||||
|
||||
public LadyMarai( 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
96
Scripts/Mobiles/Monsters/ML/Bedlam/MasterJonath.cs
Normal file
96
Scripts/Mobiles/Monsters/ML/Bedlam/MasterJonath.cs
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
[CorpseName( "a Master Jonath corpse" )]
|
||||
public class MasterJonath : BoneMagi
|
||||
{
|
||||
[Constructable]
|
||||
public MasterJonath()
|
||||
{
|
||||
Name = "Master Jonath";
|
||||
Hue = 0x455;
|
||||
|
||||
SetStr( 109, 131 );
|
||||
SetDex( 98, 110 );
|
||||
SetInt( 232, 259 );
|
||||
|
||||
SetHits( 766, 920 );
|
||||
|
||||
SetDamage( 10, 15 );
|
||||
|
||||
SetDamageType( ResistanceType.Physical, 100 );
|
||||
|
||||
SetResistance( ResistanceType.Physical, 55, 60 );
|
||||
SetResistance( ResistanceType.Fire, 43, 49 );
|
||||
SetResistance( ResistanceType.Cold, 45, 80 );
|
||||
SetResistance( ResistanceType.Poison, 41, 45 );
|
||||
SetResistance( ResistanceType.Energy, 54, 55 );
|
||||
|
||||
SetSkill( SkillName.Wrestling, 80.5, 88.6 );
|
||||
SetSkill( SkillName.Tactics, 88.5, 95.1 );
|
||||
SetSkill( SkillName.MagicResist, 102.7, 102.9 );
|
||||
SetSkill( SkillName.Magery, 100.0, 106.6 );
|
||||
SetSkill( SkillName.EvalInt, 99.6, 106.9 );
|
||||
SetSkill( SkillName.Necromancy, 100.0, 106.6 );
|
||||
SetSkill( SkillName.SpiritSpeak, 99.6, 106.9 );
|
||||
|
||||
Fame = 18000;
|
||||
Karma = -18000;
|
||||
|
||||
if ( Utility.RandomBool() )
|
||||
PackNecroScroll( Utility.RandomMinMax( 5, 9 ) );
|
||||
else
|
||||
PackScroll( 4, 7 );
|
||||
|
||||
PackReg( 7 );
|
||||
PackReg( 7 );
|
||||
PackReg( 8 );
|
||||
}
|
||||
|
||||
public override void GenerateLoot()
|
||||
{
|
||||
AddLoot( LootPack.AosUltraRich, 4 );
|
||||
}
|
||||
|
||||
// TODO: Special move?
|
||||
|
||||
/*
|
||||
// TODO: uncomment once added
|
||||
public override void OnDeath( Container c )
|
||||
{
|
||||
base.OnDeath( c );
|
||||
|
||||
if ( Utility.RandomDouble() < 0.05 )
|
||||
c.DropItem( new ParrotItem() );
|
||||
|
||||
if ( Utility.RandomDouble() < 0.15 )
|
||||
c.DropItem( new DisintegratingThesisNotes() );
|
||||
}
|
||||
*/
|
||||
|
||||
public override bool GivesMLMinorArtifact{ get{ return true; } }
|
||||
public override int TreasureMapLevel{ get{ return 5; } }
|
||||
|
||||
public MasterJonath( 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
94
Scripts/Mobiles/Monsters/ML/Bedlam/MasterMikael.cs
Normal file
94
Scripts/Mobiles/Monsters/ML/Bedlam/MasterMikael.cs
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
[CorpseName( "a Master Mikael corpse" )]
|
||||
public class MasterMikael : BoneMagi
|
||||
{
|
||||
[Constructable]
|
||||
public MasterMikael()
|
||||
{
|
||||
Name = "Master Mikael";
|
||||
Hue = 0x8FD;
|
||||
|
||||
SetStr( 93, 122 );
|
||||
SetDex( 91, 100 );
|
||||
SetInt( 252, 271 );
|
||||
|
||||
SetHits( 789, 1014 );
|
||||
|
||||
SetDamage( 11, 19 );
|
||||
|
||||
SetDamageType( ResistanceType.Physical, 100 );
|
||||
|
||||
SetResistance( ResistanceType.Physical, 55, 59 );
|
||||
SetResistance( ResistanceType.Fire, 40, 46 );
|
||||
SetResistance( ResistanceType.Cold, 72, 80 );
|
||||
SetResistance( ResistanceType.Poison, 44, 49 );
|
||||
SetResistance( ResistanceType.Energy, 50, 57 );
|
||||
|
||||
SetSkill( SkillName.Wrestling, 80.1, 87.2 );
|
||||
SetSkill( SkillName.Tactics, 79.0, 90.9 );
|
||||
SetSkill( SkillName.MagicResist, 90.3, 106.9 );
|
||||
SetSkill( SkillName.Magery, 103.8, 108.0 );
|
||||
SetSkill( SkillName.EvalInt, 96.1, 105.3 );
|
||||
SetSkill( SkillName.Necromancy, 103.8, 108.0 );
|
||||
SetSkill( SkillName.SpiritSpeak, 96.1, 105.3 );
|
||||
|
||||
Fame = 18000;
|
||||
Karma = -18000;
|
||||
|
||||
if ( Utility.RandomBool() )
|
||||
PackNecroScroll( Utility.RandomMinMax( 5, 9 ) );
|
||||
else
|
||||
PackScroll( 4, 7 );
|
||||
|
||||
PackReg( 3 );
|
||||
PackNecroReg( 1, 10 );
|
||||
}
|
||||
|
||||
public override void GenerateLoot()
|
||||
{
|
||||
AddLoot( LootPack.AosUltraRich, 3 );
|
||||
}
|
||||
|
||||
// TODO: Special move?
|
||||
|
||||
/*
|
||||
// TODO: uncomment once added
|
||||
public override void OnDeath( Container c )
|
||||
{
|
||||
base.OnDeath( c );
|
||||
|
||||
if ( Utility.RandomDouble() < 0.15 )
|
||||
c.DropItem( new DisintegratingThesisNotes() );
|
||||
|
||||
if ( Utility.RandomDouble() < 0.1 )
|
||||
c.DropItem( new ParrotItem() );
|
||||
}
|
||||
*/
|
||||
|
||||
public override bool GivesMLMinorArtifact{ get{ return true; } }
|
||||
|
||||
public MasterMikael( 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
104
Scripts/Mobiles/Monsters/ML/Bedlam/MasterTheophilus.cs
Normal file
104
Scripts/Mobiles/Monsters/ML/Bedlam/MasterTheophilus.cs
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
[CorpseName( "a Master Theophilus corpse" )]
|
||||
public class MasterTheophilus : EvilMageLord
|
||||
{
|
||||
[Constructable]
|
||||
public MasterTheophilus()
|
||||
{
|
||||
Name = "Master Theophilus";
|
||||
Title = "the necromancer";
|
||||
|
||||
SetStr( 137, 187 );
|
||||
SetDex( 253, 301 );
|
||||
SetInt( 393, 444 );
|
||||
|
||||
SetHits( 663, 876 );
|
||||
|
||||
SetDamage( 15, 20 );
|
||||
|
||||
SetDamageType( ResistanceType.Physical, 100 );
|
||||
|
||||
SetResistance( ResistanceType.Physical, 55, 60 );
|
||||
SetResistance( ResistanceType.Fire, 50, 58 );
|
||||
SetResistance( ResistanceType.Cold, 50, 60 );
|
||||
SetResistance( ResistanceType.Poison, 50, 60 );
|
||||
SetResistance( ResistanceType.Energy, 50, 60 );
|
||||
|
||||
SetSkill( SkillName.Wrestling, 69.9, 105.3 );
|
||||
SetSkill( SkillName.Tactics, 113.0, 117.9 );
|
||||
SetSkill( SkillName.MagicResist, 127.0, 132.8 );
|
||||
SetSkill( SkillName.Magery, 138.1, 143.7 );
|
||||
SetSkill( SkillName.EvalInt, 125.6, 133.8 );
|
||||
SetSkill( SkillName.Necromancy, 125.6, 133.8 );
|
||||
SetSkill( SkillName.SpiritSpeak, 125.6, 133.8 );
|
||||
SetSkill( SkillName.Meditation, 128.8, 132.9 );
|
||||
|
||||
Fame = 18000;
|
||||
Karma = -18000;
|
||||
|
||||
AddItem( new Shoes( 0x537 ) );
|
||||
AddItem( new Robe( 0x452 ) );
|
||||
|
||||
for ( int i = 0; i < 2; ++i )
|
||||
{
|
||||
if ( Utility.RandomBool() )
|
||||
PackNecroScroll( Utility.RandomMinMax( 5, 9 ) );
|
||||
else
|
||||
PackScroll( 4, 7 );
|
||||
}
|
||||
|
||||
PackReg( 7 );
|
||||
PackReg( 7 );
|
||||
PackReg( 8 );
|
||||
}
|
||||
|
||||
public override void GenerateLoot()
|
||||
{
|
||||
AddLoot( LootPack.AosUltraRich, 4 );
|
||||
}
|
||||
|
||||
public override WeaponAbility GetWeaponAbility()
|
||||
{
|
||||
return WeaponAbility.ParalyzingBlow;
|
||||
}
|
||||
|
||||
/*
|
||||
// TODO: Needs verification
|
||||
public override void OnDeath( Container c )
|
||||
{
|
||||
base.OnDeath( c );
|
||||
|
||||
if ( Paragon.ChestChance > Utility.RandomDouble() )
|
||||
c.DropItem( new ParagonChest( Name, TreasureMapLevel ) );
|
||||
}
|
||||
*/
|
||||
|
||||
public override bool GivesMLMinorArtifact{ get{ return true; } }
|
||||
public override bool AlwaysMurderer{ get{ return true; } }
|
||||
public override int TreasureMapLevel{ get{ return 5; } }
|
||||
|
||||
public MasterTheophilus( 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
91
Scripts/Mobiles/Monsters/ML/Bedlam/RedDeath.cs
Normal file
91
Scripts/Mobiles/Monsters/ML/Bedlam/RedDeath.cs
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
[CorpseName( "a Red Death corpse" )]
|
||||
public class RedDeath : SkeletalMount
|
||||
{
|
||||
[Constructable]
|
||||
public RedDeath()
|
||||
: base( "Red Death" )
|
||||
{
|
||||
Hue = 0x21;
|
||||
BaseSoundID = 0x1C3;
|
||||
|
||||
SetStr( 319, 324 );
|
||||
SetDex( 241, 244 );
|
||||
SetInt( 242, 255 );
|
||||
|
||||
SetHits( 1540, 1605 );
|
||||
|
||||
SetDamage( 25, 29 );
|
||||
|
||||
SetDamageType( ResistanceType.Physical, 25 );
|
||||
SetDamageType( ResistanceType.Fire, 75 );
|
||||
SetDamageType( ResistanceType.Cold, 0 );
|
||||
|
||||
SetResistance( ResistanceType.Physical, 60, 70 );
|
||||
SetResistance( ResistanceType.Fire, 90 );
|
||||
SetResistance( ResistanceType.Cold, 0 );
|
||||
SetResistance( ResistanceType.Poison, 100 );
|
||||
SetResistance( ResistanceType.Energy, 0 );
|
||||
|
||||
SetSkill( SkillName.Wrestling, 121.4, 143.7 );
|
||||
SetSkill( SkillName.Tactics, 120.9, 142.2 );
|
||||
SetSkill( SkillName.MagicResist, 120.1, 142.3 );
|
||||
SetSkill( SkillName.Anatomy, 120.2, 144.0 );
|
||||
|
||||
Fame = 28000;
|
||||
Karma = -28000;
|
||||
|
||||
if ( Utility.RandomBool() )
|
||||
PackNecroScroll( Utility.RandomMinMax( 5, 9 ) );
|
||||
else
|
||||
PackScroll( 4, 7 );
|
||||
}
|
||||
|
||||
public override void GenerateLoot()
|
||||
{
|
||||
AddLoot( LootPack.AosUltraRich, 4 );
|
||||
}
|
||||
|
||||
public override WeaponAbility GetWeaponAbility()
|
||||
{
|
||||
return WeaponAbility.WhirlwindAttack;
|
||||
}
|
||||
|
||||
public override void OnDeath( Container c )
|
||||
{
|
||||
base.OnDeath( c );
|
||||
|
||||
c.DropItem( new ResolvesBridle() );
|
||||
}
|
||||
|
||||
public override bool GivesMLMinorArtifact{ get{ return true; } }
|
||||
public override bool AlwaysMurderer{ get{ return true; } }
|
||||
public override bool HasBreath{ get{ return true; } }
|
||||
public override int BreathChaosDamage{ get { return 100; } }
|
||||
public override int BreathFireDamage{ get{ return 0; } }
|
||||
|
||||
public RedDeath( 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
129
Scripts/Mobiles/Monsters/ML/Bedlam/SirPatrick.cs
Normal file
129
Scripts/Mobiles/Monsters/ML/Bedlam/SirPatrick.cs
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
[CorpseName( "a Sir Patrick corpse" )]
|
||||
public class SirPatrick : SkeletalKnight
|
||||
{
|
||||
[Constructable]
|
||||
public SirPatrick()
|
||||
{
|
||||
Name = "Sir Patrick";
|
||||
Hue = 0x47E;
|
||||
|
||||
SetStr( 208, 319 );
|
||||
SetDex( 98, 132 );
|
||||
SetInt( 45, 91 );
|
||||
|
||||
SetHits( 616, 884 );
|
||||
|
||||
SetDamage( 15, 25 );
|
||||
|
||||
SetDamageType( ResistanceType.Physical, 40 );
|
||||
SetDamageType( ResistanceType.Cold, 60 );
|
||||
|
||||
SetResistance( ResistanceType.Physical, 55, 62 );
|
||||
SetResistance( ResistanceType.Fire, 40, 48 );
|
||||
SetResistance( ResistanceType.Cold, 71, 80 );
|
||||
SetResistance( ResistanceType.Poison, 40, 50 );
|
||||
SetResistance( ResistanceType.Energy, 50, 60 );
|
||||
|
||||
SetSkill( SkillName.Wrestling, 126.3, 136.5 );
|
||||
SetSkill( SkillName.Tactics, 128.5, 143.8 );
|
||||
SetSkill( SkillName.MagicResist, 102.8, 117.9 );
|
||||
SetSkill( SkillName.Anatomy, 127.5, 137.2 );
|
||||
|
||||
Fame = 18000;
|
||||
Karma = -18000;
|
||||
}
|
||||
|
||||
public override void GenerateLoot()
|
||||
{
|
||||
AddLoot( LootPack.AosUltraRich, 3 );
|
||||
}
|
||||
|
||||
public override void OnGaveMeleeAttack( Mobile defender )
|
||||
{
|
||||
base.OnGaveMeleeAttack( defender );
|
||||
|
||||
if ( Utility.RandomDouble() < 0.1 )
|
||||
DrainLife();
|
||||
}
|
||||
|
||||
public virtual void DrainLife()
|
||||
{
|
||||
List<Mobile> list = new List<Mobile>();
|
||||
|
||||
foreach ( Mobile m in GetMobilesInRange( 2 ) )
|
||||
{
|
||||
if ( m == this || !CanBeHarmful( m ) )
|
||||
continue;
|
||||
|
||||
if ( m is BaseCreature )
|
||||
{
|
||||
BaseCreature bc = (BaseCreature)m;
|
||||
|
||||
if ( bc.Controlled || bc.Summoned || bc.Team != Team )
|
||||
list.Add( m );
|
||||
}
|
||||
else if ( m.Player )
|
||||
{
|
||||
list.Add( m );
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( Mobile m in list )
|
||||
{
|
||||
DoHarmful( m );
|
||||
|
||||
m.FixedParticles( 0x374A, 10, 15, 5013, 0x455, 0, EffectLayer.Waist );
|
||||
m.PlaySound( 0x1EA );
|
||||
|
||||
int drain = Utility.RandomMinMax( 14, 30 );
|
||||
|
||||
Hits += drain;
|
||||
m.Damage( drain, this );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// TODO: uncomment once added
|
||||
public override void OnDeath( Container c )
|
||||
{
|
||||
base.OnDeath( c );
|
||||
|
||||
if ( Utility.RandomDouble() < 0.15 )
|
||||
c.DropItem( new DisintegratingThesisNotes() );
|
||||
|
||||
if ( Utility.RandomDouble() < 0.05 )
|
||||
c.DropItem( new AssassinChest() );
|
||||
}
|
||||
*/
|
||||
|
||||
public override bool GivesMLMinorArtifact{ get{ return true; } }
|
||||
|
||||
public SirPatrick( 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -19,7 +19,7 @@ namespace Server.Mobiles
|
|||
SetInt( 451, 550 );
|
||||
|
||||
SetHits( 551, 650 );
|
||||
|
||||
|
||||
SetDamage( 21, 25 );
|
||||
|
||||
SetDamageType( ResistanceType.Physical, 30 );
|
||||
|
|
@ -48,7 +48,10 @@ namespace Server.Mobiles
|
|||
{
|
||||
AddLoot( LootPack.FilthyRich );
|
||||
}
|
||||
|
||||
|
||||
public override Poison HitPoison{ get{ return Poison.Deadly; } }
|
||||
public override Poison PoisonImmune{ get{ return Poison.Deadly; } }
|
||||
|
||||
public override int GetAngerSound()
|
||||
{
|
||||
return 0x56d;
|
||||
|
|
|
|||
|
|
@ -41,6 +41,11 @@ namespace Server.Mobiles
|
|||
PackArcanceScroll( 0.05 );
|
||||
}
|
||||
|
||||
public override OppositionGroup OppositionGroup
|
||||
{
|
||||
get { return OppositionGroup.FeyAndUndead; }
|
||||
}
|
||||
|
||||
public override void GenerateLoot()
|
||||
{
|
||||
AddLoot( LootPack.MlRich );
|
||||
|
|
|
|||
|
|
@ -121,9 +121,9 @@ namespace Server.Mobiles
|
|||
|
||||
c.DropItem( new GrizzledBones() );
|
||||
|
||||
/* if (Utility.RandomDouble() < 0.6)
|
||||
c.DropItem(new ParrotItem()); */
|
||||
//TODO Add parrots
|
||||
// TODO: Parrots
|
||||
/*if ( Utility.RandomDouble() < 0.6 )
|
||||
c.DropItem( new ParrotItem() ); */
|
||||
|
||||
if( Utility.RandomDouble() < 0.05 )
|
||||
c.DropItem( new GrizzledMareStatuette() );
|
||||
|
|
@ -131,23 +131,24 @@ namespace Server.Mobiles
|
|||
if( Utility.RandomDouble() < 0.025 )
|
||||
c.DropItem( new CrimsonCincture() );
|
||||
|
||||
/* if (Utility.RandomDouble() < 0.05) //TODO Add armor sets
|
||||
{
|
||||
switch (Utility.Random(5))
|
||||
{
|
||||
case 0: c.DropItem(new GrizzleGauntlets()); break;
|
||||
case 1: c.DropItem(new GrizzleGreaves()); break;
|
||||
case 2: c.DropItem(new GrizzleHelm()); break;
|
||||
case 3: c.DropItem(new GrizzleTunic()); break;
|
||||
case 4: c.DropItem(new GrizzleVambraces()); break;
|
||||
}
|
||||
} */
|
||||
// TODO: Armor sets
|
||||
/*if ( Utility.RandomDouble() < 0.05 )
|
||||
{
|
||||
switch ( Utility.Random(5) )
|
||||
{
|
||||
case 0: c.DropItem( new GrizzleGauntlets() ); break;
|
||||
case 1: c.DropItem( new GrizzleGreaves() ); break;
|
||||
case 2: c.DropItem( new GrizzleHelm() ); break;
|
||||
case 3: c.DropItem( new GrizzleTunic() ); break;
|
||||
case 4: c.DropItem( new GrizzleVambraces() ); break;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
public override bool Unprovokable { get { return true; } }
|
||||
public override bool Uncalmable { get { return true; } }
|
||||
public override Poison PoisonImmune { get { return Poison.Lethal; } }
|
||||
// public override bool GivesMinorArtifact { get { return true; } } //TODO add ML minor artifacts
|
||||
//public override bool GivesMLMinorArtifact { get { return true; } } // TODO: Needs verification
|
||||
public override int TreasureMapLevel { get { return 5; } }
|
||||
|
||||
public override void OnGaveMeleeAttack( Mobile defender )
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue