Core/Creatures: creatures will now reposition themself if they are too close to their victim

This commit is contained in:
Ovalord
2018-01-19 20:32:02 +01:00
parent f256d388ac
commit 2deecabc17
4 changed files with 53 additions and 2 deletions

View File

@@ -390,6 +390,19 @@ void CreatureAI::SetBoundary(CreatureBoundary const* boundary, bool negateBounda
me->DoImmediateBoundaryCheck();
}
void CreatureAI::CheckDistanceToCurrentVictim()
{
if (Unit* victim = me->GetVictim())
{
Position victimPos;
victimPos.Relocate(victim->GetPosition());
// If we are closer than 50% of the combat reach we are going to reposition ourself
if (me->GetDistance(victimPos) < CalculatePct(me->GetCombatReach(), 50))
me->MoveAdvanceTo(victim);
}
}
Creature* CreatureAI::DoSummon(uint32 entry, const Position& pos, uint32 despawnTime, TempSummonType summonType)
{
return me->SummonCreature(entry, pos, summonType, despawnTime);

View File

@@ -206,6 +206,9 @@ class TC_GAME_API CreatureAI : public UnitAI
static bool IsInBounds(CreatureBoundary const& boundary, Position const* who);
// Called every 3 Seconds to check if the creature needs to reposition itself
void CheckDistanceToCurrentVictim();
protected:
virtual void MoveInLineOfSight(Unit* /*who*/);

View File

@@ -182,7 +182,7 @@ bool ForcedDespawnDelayEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
Creature::Creature(bool isWorldObject): Unit(isWorldObject), MapObject(),
m_groupLootTimer(0), lootingGroupLowGUID(0), m_PlayerDamageReq(0),
m_lootRecipient(), m_lootRecipientGroup(0), _skinner(), _pickpocketLootRestore(0), m_corpseRemoveTime(0), m_respawnTime(0),
m_respawnDelay(300), m_corpseDelay(60), m_respawnradius(0.0f), m_boundaryCheckTime(2500), m_combatPulseTime(0), m_combatPulseDelay(0), m_reactState(REACT_AGGRESSIVE),
m_respawnDelay(300), m_corpseDelay(60), m_respawnradius(0.0f), m_boundaryCheckTime(2500), m_combatPulseTime(0), m_combatPulseDelay(0), m_andvanceMovementTime(3000), m_reactState(REACT_AGGRESSIVE),
m_defaultMovementType(IDLE_MOTION_TYPE), m_spawnId(0), m_equipmentId(0), m_originalEquipmentId(0), m_AlreadyCallAssistance(false),
m_AlreadySearchedAssistance(false), m_regenHealth(true), m_cannotReachTarget(false), m_cannotReachTimer(0), m_AI_locked(false), m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL),
m_originalEntry(0), m_homePosition(), m_transportHomePosition(), m_creatureInfo(nullptr), m_creatureData(nullptr), m_waypointID(0), m_path_id(0), m_formation(nullptr), m_focusSpell(nullptr), m_focusDelay(0), m_shouldReacquireTarget(false), m_suppressedOrientation(0.0f)
@@ -619,7 +619,8 @@ void Creature::Update(uint32 diff)
LastCharmerGUID.Clear();
}
// periodic check to see if the creature has passed an evade boundary
// periodic check to see if the creature has passed an evade boundary...
// or if the creature needs to reposition itself
if (IsAIEnabled && !IsInEvadeMode() && IsInCombat())
{
if (diff >= m_boundaryCheckTime)
@@ -628,6 +629,15 @@ void Creature::Update(uint32 diff)
m_boundaryCheckTime = 2500;
} else
m_boundaryCheckTime -= diff;
if (diff >= m_andvanceMovementTime)
{
AI()->CheckDistanceToCurrentVictim();
m_andvanceMovementTime = 3000;
}
else
m_andvanceMovementTime -= diff;
}
// if periodic combat pulse is enabled and we are both in combat and in a dungeon, do this now
@@ -718,6 +728,27 @@ void Creature::Update(uint32 diff)
}
}
void Creature::MoveAdvanceTo(Unit* target)
{
if (!target) // Just in case
return;
// Do not reposition ourself when we are not allowed to move
if (HasUnitState(UNIT_STATE_CASTING) || isMoving() || !CanFreeMove())
return;
float x, y, z;
GetNearPoint(target, x, y, z, 0.0f, 0.0f, target->GetAngle(this));
Movement::MoveSplineInit init(this);
init.MoveTo(x, y, z, true, false);
// Beasts move backwards instead of turning arround
if (GetCreatureTemplate()->type == CREATURE_TYPE_BEAST)
init.SetOrientationFixed(true);
init.Launch();
}
void Creature::RegenerateMana()
{
uint32 curValue = GetPower(POWER_MANA);

View File

@@ -734,6 +734,9 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
bool CanGiveExperience() const;
// Handles the repositioning to the current target
void MoveAdvanceTo(Unit* target);
protected:
bool CreateFromProto(ObjectGuid::LowType guidlow, uint32 entry, CreatureData const* data = nullptr, uint32 vehId = 0);
bool InitEntry(uint32 entry, CreatureData const* data = nullptr);
@@ -757,6 +760,7 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
uint32 m_boundaryCheckTime; // (msecs) remaining time for next evade boundary check
uint32 m_combatPulseTime; // (msecs) remaining time for next zone-in-combat pulse
uint32 m_combatPulseDelay; // (secs) how often the creature puts the entire zone in combat (only works in dungeons)
uint32 m_andvanceMovementTime; // (msecs) remaining time for next reposition update to avoid creatures standing inside each other
ReactStates m_reactState; // for AI, not charmInfo
void RegenerateMana();