using System;
using System.Collections.Generic;
using Server.Targeting;
using Server.Network;
namespace Server.Mobiles
{
public class DireWolfAI : BaseAI
{
public DireWolfAI(BaseCreature m) : base(m)
{
}
public override bool DoActionWander()
{
if (AcquireMyFocusMob(3, m_Mobile.FightMode))
{
Action = ActionType.Combat;
m_Mobile.FightMode = FightMode.Closest;
}
if (AcquireMyFocusMob(6, m_Mobile.FightMode))
{
m_Mobile.Combatant = m_Mobile.FocusMob;
Action = ActionType.Combat;
m_Mobile.FightMode = FightMode.Closest;
m_Mobile.DebugSay("I have noticed someone, my guard is up.");
}
else
{
Action = ActionType.Wander;
m_Mobile.FightMode = FightMode.Aggressor;
base.DoActionWander();
}
return true;
}
public override bool DoActionCombat()
{
Mobile combatant = m_Mobile.Combatant;
if (combatant == null || combatant.Deleted || combatant.Map != m_Mobile.Map)
{
m_Mobile.DebugSay("My combatant is gone..");
Action = ActionType.Wander;
return true;
}
else
{
if (m_Mobile.GetDistanceToSqrt(combatant) > 11) // If target has run farther than 11 tiles away..
{
m_Mobile.DebugSay("I cannot find {0}", combatant.Name);
Action = ActionType.Wander;
m_Mobile.FightMode = FightMode.Closest;
return true;
}
else
{
if (m_Mobile.Debug)
m_Mobile.DebugSay("I should be closer to {0}", combatant.Name);
}
}
if (!m_Mobile.Controlled && !m_Mobile.Summoned)
{
double hitPercent = (double)m_Mobile.Hits / m_Mobile.HitsMax;
if (hitPercent < 0.1)
{
m_Mobile.DebugSay("I am low on health!");
Action = ActionType.Flee;
}
}
return true;
}
public override bool DoActionGuard()
{
return base.DoActionGuard();
}
public override bool DoActionFlee()
{
// AcquireFocusMob(m_Mobile.RangePerception * 2, m_Mobile.FightMode, true, false, true);
m_Mobile.FightMode = FightMode.Aggressor;
if (m_Mobile.FocusMob == null)
m_Mobile.FocusMob = m_Mobile.Combatant;
return base.DoActionFlee();
}
public override bool DoActionBackoff()
{
double hitPercent = (double)m_Mobile.Hits / m_Mobile.HitsMax;
if (!m_Mobile.Summoned && !m_Mobile.Controlled && hitPercent < 0.1) // Less than 10% health
{
Action = ActionType.Flee;
}
else
{
if (!AcquireMyFocusMob(6, m_Mobile.FightMode))
{
if (WalkMobileRange(m_Mobile.FocusMob, 1, Utility.RandomBool(), m_Mobile.RangePerception, m_Mobile.RangePerception * 2))
{
m_Mobile.DebugSay("Well, here I am safe");
Action = ActionType.Wander;
}
else
{
Action = ActionType.Combat;
}
}
else
{
m_Mobile.DebugSay("I have lost my focus, lets relax");
Action = ActionType.Wander;
}
}
return true;
}
public override bool DoActionWanderSlow()
{
return base.DoActionWander(); // Temp re-route untill method is created.
}
public virtual bool AcquireMyFocusMob(int iRange, FightMode acqType)
{
TimeSpan reacquireDelay = TimeSpan.FromSeconds(5); //a custom reacquire delay (Dian)
if (m_Mobile.Deleted)
return false;
if (m_Mobile.BardProvoked)
{
if (m_Mobile.BardTarget == null || m_Mobile.BardTarget.Deleted)
{
m_Mobile.FocusMob = null;
return false;
}
else
{
m_Mobile.FocusMob = m_Mobile.BardTarget;
return (m_Mobile.FocusMob != null);
}
}
else if (m_Mobile.Controlled)
{
if (m_Mobile.ControlTarget == null || m_Mobile.ControlTarget.Deleted || !m_Mobile.ControlTarget.Alive || m_Mobile.ControlTarget.IsDeadBondedPet || !m_Mobile.InRange(m_Mobile.ControlTarget, m_Mobile.RangePerception * 2))
{
m_Mobile.FocusMob = null;
return false;
}
else
{
m_Mobile.FocusMob = m_Mobile.ControlTarget;
return (m_Mobile.FocusMob != null);
}
}
if (m_Mobile.ConstantFocus != null)
{
m_Mobile.DebugSay("Acquired my constant focus");
m_Mobile.FocusMob = m_Mobile.ConstantFocus;
return true;
}
if (acqType == FightMode.None)
{
m_Mobile.FocusMob = null;
return false;
}
if (m_Mobile.Aggressors.Count == 0 && m_Mobile.Aggressed.Count == 0)
{
m_Mobile.FocusMob = null;
return false;
}
// We dont ReAcquire a new FocusMob untill the following property of NextReacquireTime is older than DateTime.Now
if (m_Mobile.NextReacquireTime > DateTime.Now)
{
return false;
}
// NextReacquireTime adjusts only after the above 'IF' statement is false
m_Mobile.NextReacquireTime = DateTime.Now + reacquireDelay;
m_Mobile.DebugSay("Acquiring...");
Map map = m_Mobile.Map;
if (map != null)
{
Mobile newFocusMob = null;
// double val = double.MinValue;
IPooledEnumerable eable = map.GetMobilesInRange(m_Mobile.Location, iRange);
foreach (Mobile m in eable)
{
bool bCheckIt = false;
//
// Basic check
// Of the Mobiles in range, if one or more are Players...
if (m.Player)
{
// And, Accesslevel equals Player, they are alive, not blessed, not deleted, excluding myself, and I am permitted to 'see' the other players..
if (m.AccessLevel == AccessLevel.Player && m.Alive && !m.Blessed && !m.Deleted && m != m_Mobile && m_Mobile.CanSee(m))
{
newFocusMob = m;
bCheckIt = true;
}
}
// If passed this far, and I am not Controlled, but I am a Summoned Pet (like from a spell, SummonDeamon)
if (bCheckIt && !m_Mobile.Controlled && m_Mobile.Summoned && m_Mobile.SummonMaster != null)
{
// If so, do not focus on my creator/owners..
bCheckIt = (m != m_Mobile.SummonMaster && Server.Spells.SpellHelper.ValidIndirectTarget(m_Mobile.SummonMaster, m));
if (bCheckIt && m is PlayerMobile && m_Mobile.IsAnimatedDead)
bCheckIt = false;
}
//
// Team check
//
if (bCheckIt)
{
bCheckIt = false;
// If there is an aggressor in range, bCheckit is true, so continue..
for (int a = 0; !bCheckIt && a < m_Mobile.Aggressors.Count; ++a)
bCheckIt = (((AggressorInfo)m_Mobile.Aggressors[a]).Attacker == m);
// If there is an old aggressor in range, bCheckit is true, so continue..
for (int a = 0; !bCheckIt && a < m_Mobile.Aggressed.Count; ++a)
bCheckIt = (((AggressorInfo)m_Mobile.Aggressed[a]).Defender == m);
}
if (bCheckIt && !m_Mobile.CanBeHarmful(m, false))
bCheckIt = false;
}
eable.Free();
m_Mobile.FocusMob = newFocusMob;
}
return (m_Mobile.FocusMob != null);
}
}
}