- PreventInaccess class, moves staff characters to jail or green acres in Felucca or Trammel randomly if they disconnect during the login process.

- Added a [TileAvg command, which tiles items/mobiles on the average Z of the map instead of a fixed Z.
- For all the tile commands ([Tile, [TileRXYZ, [TileXYZ, [TileZ, [TileAvg), added outline commands to only put items/mobiles on the outside of the area ([Outline, [OutlineRXYZ, [OutlineXYZ, [OutlineZ, [OutlineAvg).
- Removed the [OpenBrowser confirmation messages when using the command on multiple mobiles at the same time.
- Added a label showing the type of the object currently being viewed to the top of the properties gump.
- Added SA skills (Mysticism, Throwing and Imbuing) to the [Skills gump.
- Fixed DeathRobe decay when automatically dropped by self looting your corpse.
- Removed the (summoned) property on mouseover from clones summoned through Mirror Image.
- The Z of the Magincia destination of the public moongates is now calculated when the server starts, so both old and new maps will have the correct Z (34 and 31 respectively).
- KeywordTeleporters no longer teleport if you're not within the trigger range when the delay ends.
- Added WaitTeleporter, which is a KeywordTeleporter supporting adding messages when a character starts the process and showing the remaining time. When a character logs and times out, any running teleport timer is stopped.
- Fixed BaseWaterContainer single click behavior.
- Fixed MageAI reveal behavior.
- House placement will now return the correct message when targeting inside a TempNoHousingRegion.
- Tracking will no longer be able to track characters with higher access after they hide.
- Added CorpseNameOverride to BaseCreature to override the name used for the generated corpse.
- Pet ghosts will no longer be deleted when (auto)stabled.
This commit is contained in:
eos 2012-02-12 01:59:30 +00:00
parent 68922c1eeb
commit 72c4dc6018
15 changed files with 685 additions and 155 deletions

View file

@ -357,75 +357,66 @@ namespace Server.Mobiles
if( spell != null )
return spell;
if (m_Mobile.Combatant.Hidden && Utility.RandomDouble() < .25)
switch (Utility.Random(16))
{
spell = new RevealSpell(m_Mobile, null);
}
else
{
switch (Utility.Random(16))
{
case 0:
case 1: // Poison them
{
//m_Mobile.DebugSay( "Attempting to poison" );
case 0:
case 1: // Poison them
{
//m_Mobile.DebugSay( "Attempting to poison" );
if (!c.Poisoned)
spell = new PoisonSpell(m_Mobile, null);
if (!c.Poisoned)
spell = new PoisonSpell(m_Mobile, null);
break;
}
case 2: // Bless ourselves.
{
//m_Mobile.DebugSay( "Blessing myself" );
break;
}
case 2: // Bless ourselves.
{
//m_Mobile.DebugSay( "Blessing myself" );
spell = new BlessSpell(m_Mobile, null);
break;
}
case 3:
case 4: // Curse them.
{
//m_Mobile.DebugSay( "Attempting to curse" );
spell = new BlessSpell(m_Mobile, null);
break;
}
case 3:
case 4: // Curse them.
{
//m_Mobile.DebugSay( "Attempting to curse" );
spell = GetRandomCurse();
break;
}
case 5: // Paralyze them.
{
//m_Mobile.DebugSay( "Attempting to paralyze" );
spell = GetRandomCurse();
break;
}
case 5: // Paralyze them.
{
//m_Mobile.DebugSay( "Attempting to paralyze" );
if (m_Mobile.Skills[SkillName.Magery].Value > 50.0)
spell = new ParalyzeSpell(m_Mobile, null);
if (m_Mobile.Skills[SkillName.Magery].Value > 50.0)
spell = new ParalyzeSpell(m_Mobile, null);
break;
}
case 6: // Drain mana
{
//m_Mobile.DebugSay( "Attempting to drain mana" );
break;
}
case 6: // Drain mana
{
//m_Mobile.DebugSay( "Attempting to drain mana" );
spell = GetRandomManaDrainSpell();
break;
}
case 7:
{
//m_Mobile.DebugSay( "Attempting to Invis" );
spell = GetRandomManaDrainSpell();
break;
}
case 7:
{
//m_Mobile.DebugSay( "Attempting to Invis" );
if (spell == null && Utility.RandomBool())
{
spell = new InvisibilitySpell(m_Mobile, null);
}
if (Utility.RandomBool())
spell = new InvisibilitySpell(m_Mobile, null);
break;
}
break;
}
default: // Damage them.
{
//m_Mobile.DebugSay( "Just doing damage" );
default: // Damage them.
{
//m_Mobile.DebugSay( "Just doing damage" );
spell = GetRandomDamage();
break;
}
}
spell = GetRandomDamage();
break;
}
}
return spell;
@ -551,15 +542,25 @@ namespace Server.Mobiles
return spell;
}
private TimeSpan GetDelay()
private TimeSpan GetDelay( Spell spell )
{
double del = ScaleByMagery( 3.0 );
double min = 6.0 - ( del * 0.75 );
double max = 6.0 - ( del * 1.25 );
if( SmartAI || ( spell is DispelSpell ) )
{
return TimeSpan.FromSeconds( m_Mobile.ActiveSpeed );
}
else
{
double del = ScaleByMagery( 3.0 );
double min = 6.0 - ( del * 0.75 );
double max = 6.0 - ( del * 1.25 );
return TimeSpan.FromSeconds( min + ( ( max - min ) * Utility.RandomDouble() ) );
return TimeSpan.FromSeconds( min + ( ( max - min ) * Utility.RandomDouble() ) );
}
}
private Mobile m_LastTarget;
private Point3D m_LastTargetLoc;
public override bool DoActionCombat()
{
Mobile c = m_Mobile.Combatant;
@ -592,7 +593,7 @@ namespace Server.Mobiles
if( AcquireFocusMob( m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true ) )
{
m_Mobile.DebugSay( "Nobody else is around" );
m_Mobile.DebugSay( "I will switch to {0}", m_Mobile.FocusMob.Name );
m_Mobile.Combatant = c = m_Mobile.FocusMob;
m_Mobile.FocusMob = null;
}
@ -708,25 +709,45 @@ namespace Server.Mobiles
if( spell != null )
spell.Cast();
TimeSpan delay;
if( SmartAI || ( spell is DispelSpell ) )
delay = TimeSpan.FromSeconds( m_Mobile.ActiveSpeed );
else
delay = GetDelay();
m_NextCastTime = DateTime.Now;
m_NextCastTime = DateTime.Now + GetDelay( spell );
}
else if( m_Mobile.Spell == null || !m_Mobile.Spell.IsCasting )
{
RunTo( c );
}
m_LastTarget = c;
m_LastTargetLoc = c.Location;
return true;
}
private LandTarget m_RevealTarget;
public override bool DoActionGuard()
{
if( m_LastTarget != null && m_LastTarget.Hidden )
{
Map map = m_Mobile.Map;
if( map == null || !m_Mobile.InRange( m_LastTargetLoc, Core.ML ? 10 : 12 ) )
{
m_LastTarget = null;
}
else if( m_Mobile.Spell == null && DateTime.Now > m_NextCastTime )
{
m_Mobile.DebugSay( "I am going to reveal my last target" );
m_RevealTarget = new LandTarget( m_LastTargetLoc, map );
Spell spell = new RevealSpell( m_Mobile, null );
if( spell.Cast() )
m_LastTarget = null; // only do it once
m_NextCastTime = DateTime.Now + GetDelay( spell );
}
}
if( AcquireFocusMob( m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true ) )
{
m_Mobile.DebugSay( "I am going to attack {0}", m_Mobile.FocusMob.Name );
@ -934,7 +955,7 @@ namespace Server.Mobiles
if( targ == null )
return false;
bool isReveal = (targ is RevealSpell.InternalTarget);
bool isReveal = ( targ is RevealSpell.InternalTarget );
bool isDispel = ( targ is DispelSpell.InternalTarget );
bool isParalyze = ( targ is ParalyzeSpell.InternalTarget );
bool isTeleport = ( targ is TeleportSpell.InternalTarget );
@ -956,7 +977,7 @@ namespace Server.Mobiles
else if( toTarget != null && m_Mobile.InRange( toTarget, 10 ) )
RunFrom( toTarget );
}
else if( SmartAI && ( isParalyze || isTeleport || isReveal ) )
else if( SmartAI && ( isParalyze || isTeleport ) )
{
toTarget = FindDispelTarget( true );
@ -1000,6 +1021,13 @@ namespace Server.Mobiles
{
targ.Invoke( m_Mobile, m_Mobile );
}
else if( isReveal && m_RevealTarget != null )
{
targ.Invoke( m_Mobile, m_RevealTarget );
if( SmartAI )
m_Mobile.NextReacquireTime = DateTime.Now;
}
else if( isTeleport && toTarget != null )
{
Map map = m_Mobile.Map;

View file

@ -243,10 +243,18 @@ namespace Server.Mobiles
private bool m_IsPrisoner;
private string m_CorpseNameOverride;
#endregion
public virtual InhumanSpeech SpeechType{ get{ return null; } }
[CommandProperty( AccessLevel.GameMaster )]
public string CorpseNameOverride
{
get { return m_CorpseNameOverride; }
set { m_CorpseNameOverride = value; }
}
[CommandProperty( AccessLevel.GameMaster, AccessLevel.Administrator )]
public bool IsStabled
{
@ -1560,7 +1568,7 @@ namespace Server.Mobiles
{
base.Serialize( writer );
writer.Write( (int) 17 ); // version
writer.Write( (int) 18 ); // version
writer.Write( (int)m_CurrentAI );
writer.Write( (int)m_DefaultAI );
@ -1676,6 +1684,9 @@ namespace Server.Mobiles
writer.Write( TimeSpan.Zero );
else
writer.Write( DeleteTimeLeft );
// Version 18
writer.Write( m_CorpseNameOverride );
}
private static double[] m_StandardActiveSpeeds = new double[]
@ -1897,6 +1908,9 @@ namespace Server.Mobiles
m_DeleteTimer.Start();
}
if ( version >= 18 )
m_CorpseNameOverride = reader.ReadString();
if( version <= 14 && m_Paragon && Hue == 0x31 )
{
Hue = Paragon.Hue; //Paragon hue fixed, should now be 0x501.
@ -4186,7 +4200,7 @@ namespace Server.Mobiles
list.Add( 1080078 ); // guarding
}
if ( Summoned && !IsAnimatedDead && !IsNecroFamiliar )
if ( Summoned && !IsAnimatedDead && !IsNecroFamiliar && !( this is Clone ) )
list.Add( 1049646 ); // (summoned)
else if ( Controlled && Commandable )
{
@ -5314,7 +5328,7 @@ namespace Server.Mobiles
{
Mobile owner = c.ControlMaster;
if ( owner == null || owner.Deleted || owner.Map != c.Map || !owner.InRange( c, 12 ) || !c.CanSee( owner ) || !c.InLOS( owner ) )
if ( !c.IsStabled && ( owner == null || owner.Deleted || owner.Map != c.Map || !owner.InRange( c, 12 ) || !c.CanSee( owner ) || !c.InLOS( owner ) ) )
{
if ( c.OwnerAbandonTime == DateTime.MinValue )
c.OwnerAbandonTime = DateTime.Now;