Skip to content

Commit

Permalink
Core/Movement: Replace old TargetedMovementGenerator into ChaseMoveme…
Browse files Browse the repository at this point in the history
…ntGenerator and FollowMovementGenerator, full rewrite for both.

- Chase to angle is now functional. Pets use this to chase behind the target. Closes #19925.
- Chase to arbitrary range interval works. Not used anywhere, but you can technically make hunter-like mobs.
- Pets now follow the hunter cleanly and without stutter stepping. Also fix some other things. Closes #8924.
  • Loading branch information
Treeston committed Apr 6, 2018
1 parent 9f03743 commit 2a84562
Show file tree
Hide file tree
Showing 28 changed files with 700 additions and 768 deletions.
3 changes: 3 additions & 0 deletions src/common/Utilities/Util.h
Expand Up @@ -89,6 +89,9 @@ inline T RoundToInterval(T& num, T floor, T ceil)
return num = std::min(std::max(num, floor), ceil);
}

template <class T>
inline T square(T x) { return x*x; }

// UTF8 handling
TC_COMMON_API bool Utf8toWStr(const std::string& utf8str, std::wstring& wstr);

Expand Down
2 changes: 1 addition & 1 deletion src/server/game/AI/CoreAI/PetAI.cpp
Expand Up @@ -482,7 +482,7 @@ void PetAI::DoAttack(Unit* target, bool chase)
ClearCharmInfoFlags();
me->GetCharmInfo()->SetIsCommandAttack(oldCmdAttack); // For passive pets commanded to attack so they will use spells
me->GetMotionMaster()->Clear();
me->GetMotionMaster()->MoveChase(target, me->GetPetChaseDistance());
me->GetMotionMaster()->MoveChase(target, me->GetPetChaseDistance(), (float)M_PI);
}
else // (Stay && ((Aggressive || Defensive) && In Melee Range)))
{
Expand Down
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2008-2018 TrinityCore <https://www.trinitycore.org/>
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
Expand All @@ -16,21 +15,15 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "Unit.h"
#include "TargetedMovementGenerator.h"
#include "FollowerReference.h"
#ifndef TRINITY_G3DPOSITION_HPP
#define TRINITY_G3DPOSITION_HPP

void FollowerReference::targetObjectBuildLink()
{
getTarget()->addFollower(this);
}
#include "Position.h"
#include <G3D/Vector3.h>
#include "Errors.h"

void FollowerReference::targetObjectDestroyLink()
{
getTarget()->removeFollower(this);
}
inline G3D::Vector3 PositionToVector3(Position p) { return { p.m_positionX, p.m_positionY, p.m_positionZ }; }
inline G3D::Vector3 PositionToVector3(Position const* p) { return { ASSERT_NOTNULL(p)->m_positionX, p->m_positionY, p->m_positionZ }; }
inline Position Vector3ToPosition(G3D::Vector3 v) { return { v.x, v.y, v.z }; }

void FollowerReference::sourceObjectDestroyLink()
{
GetSource()->stopFollowing();
}
#endif
2 changes: 1 addition & 1 deletion src/server/game/Entities/Pet/PetDefines.h
Expand Up @@ -75,6 +75,6 @@ enum PetTalk
};

#define PET_FOLLOW_DIST 1.0f
#define PET_FOLLOW_ANGLE float(M_PI/2)
#define PET_FOLLOW_ANGLE float(M_PI)

#endif
59 changes: 33 additions & 26 deletions src/server/game/Entities/Unit/Unit.cpp
Expand Up @@ -17,6 +17,7 @@
*/

#include "Unit.h"
#include "AbstractFollower.h"
#include "Battlefield.h"
#include "BattlefieldMgr.h"
#include "Battleground.h"
Expand Down Expand Up @@ -538,14 +539,14 @@ bool Unit::IsWithinCombatRange(Unit const* obj, float dist2compare) const
return distsq < maxdist * maxdist;
}

bool Unit::IsWithinMeleeRange(Unit const* obj) const
bool Unit::IsWithinMeleeRangeAt(Position const& pos, Unit const* obj) const
{
if (!obj || !IsInMap(obj) || !InSamePhase(obj))
return false;

float dx = GetPositionX() - obj->GetPositionX();
float dy = GetPositionY() - obj->GetPositionY();
float dz = GetPositionZ() - obj->GetPositionZ();
float dx = pos.GetPositionX() - obj->GetPositionX();
float dy = pos.GetPositionY() - obj->GetPositionY();
float dz = pos.GetPositionZ() - obj->GetPositionZ();
float distsq = dx*dx + dy*dy + dz*dz;

float maxdist = GetMeleeRange(obj);
Expand Down Expand Up @@ -8509,25 +8510,7 @@ void Unit::UpdateSpeed(UnitMoveType mtype)
{
// Set creature speed rate
if (GetTypeId() == TYPEID_UNIT)
{
Unit* pOwner = GetCharmerOrOwner();
if ((IsPet() || IsGuardian()) && !IsInCombat() && pOwner) // Must check for owner or crash on "Tame Beast"
{
// For every yard over 5, increase speed by 0.01
// to help prevent pet from lagging behind and despawning
float dist = GetDistance(pOwner);
float base_rate = 1.00f; // base speed is 100% of owner speed

if (dist < 5)
dist = 5;

float mult = base_rate + ((dist - 5) * 0.01f);

speed *= pOwner->GetSpeedRate(mtype) * mult; // pets derive speed from owner when not in combat
}
else
speed *= ToCreature()->GetCreatureTemplate()->speed_run; // at this point, MOVE_WALK is never reached
}
speed *= ToCreature()->GetCreatureTemplate()->speed_run; // at this point, MOVE_WALK is never reached

// Normalize speed by 191 aura SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED if need
/// @todo possible affect only on MOVE_RUN
Expand All @@ -8551,11 +8534,27 @@ void Unit::UpdateSpeed(UnitMoveType mtype)
break;
}

// for creature case, we check explicit if mob searched for assistance
if (GetTypeId() == TYPEID_UNIT)
if (Creature* creature = ToCreature())
{
if (ToCreature()->HasSearchedAssistance())
// for creature case, we check explicit if mob searched for assistance
if (creature->HasSearchedAssistance())
speed *= 0.66f; // best guessed value, so this will be 33% reduction. Based off initial speed, mob can then "run", "walk fast" or "walk".

if (creature->HasUnitTypeMask(UNIT_MASK_MINION) && !creature->IsInCombat())
{
MovementGenerator* top = creature->GetMotionMaster()->top();
if (top && top->GetMovementGeneratorType() == FOLLOW_MOTION_TYPE)
{
Unit* followed = ASSERT_NOTNULL(dynamic_cast<AbstractFollower*>(top))->GetTarget();
if (followed && followed->GetGUID() == GetOwnerGUID() && !followed->IsInCombat())
{
float ownerSpeed = followed->GetSpeedRate(mtype);
if (speed < ownerSpeed || creature->IsWithinDist3d(followed, 10.0f))
speed = ownerSpeed;
speed *= std::min(std::max(1.0f, 0.75f + (GetDistance(followed) - PET_FOLLOW_DIST) * 0.05f), 1.3f);
}
}
}
}

// Apply strongest slow aura mod to speed
Expand Down Expand Up @@ -8656,6 +8655,12 @@ void Unit::SetSpeedRate(UnitMoveType mtype, float rate)
}
}

void Unit::RemoveAllFollowers()
{
while (!m_followingMe.empty())
(*m_followingMe.begin())->SetTarget(nullptr);
}

bool Unit::IsGhouled() const
{
return HasAura(SPELL_DK_RAISE_ALLY);
Expand Down Expand Up @@ -9437,6 +9442,8 @@ void Unit::RemoveFromWorld()

RemoveAreaAurasDueToLeaveWorld();

RemoveAllFollowers();

if (IsCharmed())
RemoveCharmedBy(nullptr);

Expand Down
13 changes: 7 additions & 6 deletions src/server/game/Entities/Unit/Unit.h
Expand Up @@ -20,8 +20,6 @@
#define __UNIT_H

#include "Object.h"
#include "FollowerReference.h"
#include "FollowerRefManager.h"
#include "CombatManager.h"
#include "OptionalFwd.h"
#include "SpellAuraDefines.h"
Expand Down Expand Up @@ -61,6 +59,7 @@ enum InventorySlot
NULL_SLOT = 255
};

struct AbstractFollower;
struct FactionTemplateEntry;
struct LiquidData;
struct LiquidTypeEntry;
Expand Down Expand Up @@ -789,7 +788,8 @@ class TC_GAME_API Unit : public WorldObject
virtual void SetCanDualWield(bool value) { m_canDualWield = value; }
float GetCombatReach() const override { return m_floatValues[UNIT_FIELD_COMBATREACH]; }
bool IsWithinCombatRange(Unit const* obj, float dist2compare) const;
bool IsWithinMeleeRange(Unit const* obj) const;
bool IsWithinMeleeRange(Unit const* obj) const { return IsWithinMeleeRangeAt(GetPosition(), obj); }
bool IsWithinMeleeRangeAt(Position const& pos, Unit const* obj) const;
float GetMeleeRange(Unit const* target) const;
virtual SpellSchoolMask GetMeleeDamageSchoolMask(WeaponAttackType attackType = BASE_ATTACK, uint8 damageIndex = 0) const = 0;
uint32 m_extraAttacks;
Expand Down Expand Up @@ -1526,8 +1526,9 @@ class TC_GAME_API Unit : public WorldObject

float CalculateSpellpowerCoefficientLevelPenalty(SpellInfo const* spellInfo) const;

void addFollower(FollowerReference* pRef) { m_FollowingRefManager.insertFirst(pRef); }
void removeFollower(FollowerReference* /*pRef*/) { /* nothing to do yet */ }
void FollowerAdded(AbstractFollower* f) { m_followingMe.insert(f); }
void FollowerRemoved(AbstractFollower* f) { m_followingMe.erase(f); }
void RemoveAllFollowers();

MotionMaster* GetMotionMaster() { return i_motionMaster; }
MotionMaster const* GetMotionMaster() const { return i_motionMaster; }
Expand Down Expand Up @@ -1781,7 +1782,7 @@ class TC_GAME_API Unit : public WorldObject
friend class ThreatManager;
ThreatManager m_threatManager;

FollowerRefManager m_FollowingRefManager;
std::unordered_set<AbstractFollower*> m_followingMe;

Unit* m_comboTarget;
int8 m_comboPoints;
Expand Down
30 changes: 15 additions & 15 deletions src/server/game/Loot/LootItemStorage.cpp
@@ -1,19 +1,19 @@
/*
* Copyright (C) 2008-2018 TrinityCore <https://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
* Copyright (C) 2008-2018 TrinityCore <https://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "LootItemStorage.h"
#include "DatabaseEnv.h"
Expand Down
30 changes: 15 additions & 15 deletions src/server/game/Loot/LootItemStorage.h
@@ -1,19 +1,19 @@
/*
* Copyright (C) 2008-2018 TrinityCore <https://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
* Copyright (C) 2008-2018 TrinityCore <https://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef __LOOTITEMSTORAGE_H
#define __LOOTITEMSTORAGE_H
Expand Down
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2008-2018 TrinityCore <https://www.trinitycore.org/>
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
Expand All @@ -15,17 +14,18 @@
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "AbstractFollower.h"
#include "Unit.h"

#ifndef _FOLLOWERREFMANAGER
#define _FOLLOWERREFMANAGER

#include "RefManager.h"

class Unit;
class TargetedMovementGeneratorBase;

class FollowerRefManager : public RefManager<Unit, TargetedMovementGeneratorBase>
void AbstractFollower::SetTarget(Unit* unit)
{
if (unit == _target)
return;

};
#endif
if (_target)
_target->FollowerRemoved(this);
_target = unit;
if (_target)
_target->FollowerAdded(this);
}
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2008-2018 TrinityCore <https://www.trinitycore.org/>
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
Expand All @@ -16,19 +15,22 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef _FOLLOWERREFERENCE_H
#define _FOLLOWERREFERENCE_H
#ifndef TRINITY_ABSTRACTFOLLOWER_H
#define TRINITY_ABSTRACTFOLLOWER_H

#include "Reference.h"

class TargetedMovementGeneratorBase;
class Unit;

class FollowerReference : public Reference<Unit, TargetedMovementGeneratorBase>
struct AbstractFollower
{
protected:
void targetObjectBuildLink() override;
void targetObjectDestroyLink() override;
void sourceObjectDestroyLink() override;
public:
AbstractFollower(Unit* target = nullptr) { SetTarget(target); }
~AbstractFollower() { SetTarget(nullptr); }

void SetTarget(Unit* unit);
Unit* GetTarget() const { return _target; }

private:
Unit* _target = nullptr;
};

#endif

0 comments on commit 2a84562

Please sign in to comment.