uncontrolled summons will not be acquired by hostile mobiles, unless they attacked the mobile first. Necro familiars should be pretty much unlosable now... as well as not acquired by mobiles.

This commit is contained in:
xavier 2012-11-23 21:57:03 +00:00
parent 9dfdf757a2
commit e773309f17
3 changed files with 124 additions and 54 deletions

View file

@ -2491,7 +2491,7 @@ namespace Server.Mobiles
continue;
// Let's not target ourselves...
if ( m == m_Mobile )
if ( m == m_Mobile || m is BaseFamiliar )
continue;
// Dead targets are invalid.
@ -2537,35 +2537,33 @@ namespace Server.Mobiles
if ( m is PlayerMobile && ( (PlayerMobile)m ).HonorActive && !( m_Mobile.Combatant == m ))
continue;
if( acqType == FightMode.Aggressor || acqType == FightMode.Evil )
if( acqType == FightMode.Aggressor || acqType == FightMode.Evil || ( m is BaseCreature ) && ( ( BaseCreature )m ).Summoned )
{
// Only acquire this mobile if it attacked us, or if it's evil.
bool bValid = false;
BaseCreature bc = m as BaseCreature;
for ( int a = 0; !bValid && a < m_Mobile.Aggressors.Count; ++a )
bValid = ( m_Mobile.Aggressors[a].Attacker == m );
bool bValid = IsHostile( m );
for ( int a = 0; !bValid && a < m_Mobile.Aggressed.Count; ++a )
bValid = ( m_Mobile.Aggressed[a].Defender == m );
#region Ethics & Faction checks
if ( !bValid )
if( !bValid && ( !( m is BaseCreature ) || !bc.Summoned || bc.Controlled ) )
{
bValid = ( m_Mobile.GetFactionAllegiance( m ) == BaseCreature.Allegiance.Enemy || m_Mobile.GetEthicAllegiance( m ) == BaseCreature.Allegiance.Enemy );
#endregion
if ( acqType == FightMode.Evil && !bValid )
{
if( m is BaseCreature && ((BaseCreature)m).Controlled && ((BaseCreature)m).ControlMaster != null )
bValid = ( ((BaseCreature)m).ControlMaster.Karma < 0 );
else
bValid = ( (Core.AOS || m.Player) && m.Karma < 0 );
if( acqType == FightMode.Evil && !bValid )
{
if( m is BaseCreature && bc.Controlled && bc.ControlMaster != null )
{
bValid = ( bc.ControlMaster.Karma < 0 );
}
else
{
bValid = ( ( Core.AOS || m.Player ) && m.Karma < 0 );
}
}
}
if ( !bValid )
continue;
} else {
// Same goes for faction enemies.
if ( bFacFoe && !m_Mobile.IsEnemy( m ) )
continue;
@ -2587,11 +2585,45 @@ namespace Server.Mobiles
eable.Free();
m_Mobile.FocusMob = newFocusMob;
if( m_Mobile.FocusMob is BaseFamiliar )
{
m_Mobile.FocusMob = null;
}
}
return (m_Mobile.FocusMob != null);
}
private bool IsHostile( Mobile from )
{
int count = Math.Max( m_Mobile.Aggressors.Count, m_Mobile.Aggressed.Count );
if( m_Mobile.Combatant == from || from.Combatant == m_Mobile )
{
return true;
}
if( count > 0 )
{
for( int a = 0; a < count; ++a )
{
if( a < m_Mobile.Aggressed.Count && m_Mobile.Aggressed[ a ].Attacker == from )
{
return true;
}
if( a < m_Mobile.Aggressors.Count && m_Mobile.Aggressors[ a ].Defender == from )
{
return true;
}
}
}
return false;
}
public virtual void DetectHidden()
{
if( m_Mobile.Deleted || m_Mobile.Map == null )

View file

@ -1294,9 +1294,11 @@ namespace Server.Mobiles
public HonorContext ReceivedHonorContext{ get{ return m_ReceivedHonorContext; } set{ m_ReceivedHonorContext = value; } }
public virtual void CheckStopFollow( Mobile from )
public virtual bool CanBeDistracted { get { return true; } }
public virtual void CheckDistracted( Mobile from )
{
if( ControlOrder == OrderType.Follow && Utility.RandomDouble() < .10 )
if( Utility.RandomDouble() < .10 )
{
ControlTarget = from;
ControlOrder = OrderType.Attack;
@ -1342,7 +1344,10 @@ namespace Server.Mobiles
if( !willKill )
{
CheckStopFollow( from );
if( CanBeDistracted && ControlOrder == OrderType.Follow )
{
CheckDistracted( from );
}
}
else if( from is PlayerMobile )
{
@ -1354,7 +1359,10 @@ namespace Server.Mobiles
public virtual void OnDamagedBySpell( Mobile from )
{
CheckStopFollow( from );
if( CanBeDistracted && ControlOrder == OrderType.Follow )
{
CheckDistracted( from );
}
}
public virtual void OnHarmfulSpell( Mobile from )

View file

@ -9,7 +9,8 @@ namespace Server.Mobiles
{
public abstract class BaseFamiliar : BaseCreature
{
public BaseFamiliar() : base( AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4 )
public BaseFamiliar()
: base( AIType.AI_Melee, FightMode.Closest, 10, 1, -1, -1 )
{
}
@ -17,54 +18,83 @@ namespace Server.Mobiles
public override Poison PoisonImmune{ get{ return Poison.Lethal; } }
public override bool Commandable{ get{ return false; } }
public override bool PlayerRangeSensitive { get { return false; } }
private bool m_LastHidden;
public virtual void RangeCheck()
{
if( !Deleted && ControlMaster != null && !ControlMaster.Deleted )
{
int range = ( RangeHome - 2 );
if( !InRange( ControlMaster.Location, RangeHome ) )
{
Mobile master = ControlMaster;
Point3D m_Loc = Point3D.Zero;
if( Map == master.Map )
{
int x = ( X > master.X ) ? ( master.X + range ) : ( master.X - range );
int y = ( Y > master.Y ) ? ( master.Y + range ) : ( master.Y - range );
for( int i = 0; i < 10; i++ )
{
m_Loc.X = x + Utility.RandomMinMax( -1, 1 );
m_Loc.Y = y + Utility.RandomMinMax( -1, 1 );
m_Loc.Z = Map.GetAverageZ( m_Loc.X, m_Loc.Y );
if( Map.CanSpawnMobile( m_Loc ) )
{
break;
}
m_Loc = master.Location;
}
if( !Deleted )
{
SetLocation( m_Loc, true );
}
}
}
}
}
public override void OnThink()
{
base.OnThink();
Mobile master = ControlMaster;
if ( master == null )
if( Deleted )
{
return;
if ( master.Deleted )
}
if( master == null || master.Deleted )
{
DropPackContents();
EndRelease( null );
return;
}
if ( m_LastHidden != master.Hidden )
RangeCheck();
if( m_LastHidden != master.Hidden )
Hidden = m_LastHidden = master.Hidden;
Mobile toAttack = null;
if ( !Hidden )
if( AIObject != null && AIObject.WalkMobileRange( master, 5, true, 1, 1 ))
{
toAttack = master.Combatant;
Warmode = master.Warmode;
Combatant = master.Combatant;
if ( toAttack == this )
toAttack = master;
else if ( toAttack == null )
toAttack = this.Combatant;
CurrentSpeed = 0.10;
}
if ( Combatant != toAttack )
Combatant = null;
if ( toAttack == null )
else
{
if ( ControlTarget != master || ControlOrder != OrderType.Follow )
{
ControlTarget = master;
ControlOrder = OrderType.Follow;
}
}
else if ( ControlTarget != toAttack || ControlOrder != OrderType.Attack )
{
ControlTarget = toAttack;
ControlOrder = OrderType.Attack;
Warmode = false;
FocusMob = Combatant = null;
CurrentSpeed = .01;
}
}