New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[3.3.5] Split TargetedMovementGenerator #21722
Conversation
https://trinitycore.atlassian.net/wiki/spaces/tc/pages/2130103/C+Development+Standards
|
I agree with this, the separation is needed. Sadly I dont have the time to go through the new logic and review it. |
Optional<float> const _angle; | ||
|
||
void startMovement(Unit* owner); | ||
void pause(Milliseconds duration = 100ms) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
currently implemented in WaypointMovementGenerator only, called in several places for movement slot 0
Looks like you have got 3x |
|
||
ChaseMovementGenerator(Unit* target, Optional<float> range = {}, Optional<float> angle = {}) : AbstractFollower(ASSERT_NOTNULL(target)), _range(range), _angle(angle) {} | ||
|
||
void Initialize(Unit* owner) override {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change to /*owner*/
ChaseMovementGenerator(Unit* target, Optional<float> range = {}, Optional<float> angle = {}) : AbstractFollower(ASSERT_NOTNULL(target)), _range(range), _angle(angle) {} | ||
|
||
void Initialize(Unit* owner) override {} | ||
void Reset(Unit* owner) override {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change to /*owner*/
} | ||
void Initialize(Unit* owner) override {} | ||
void Finalize(Unit* owner) override {} | ||
void Reset(Unit* owner) override {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change to
void Initialize(Unit* /*owner*/) override { }
void Finalize(Unit* /*owner*/) override { }
void Reset(Unit* /*owner*/) override { }
@@ -0,0 +1,182 @@ | |||
/* | |||
* Copyright (C) 2008-2018 TrinityCore <https://www.trinitycore.org/> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cosmetic/codestyle: missing 1 space indent for lines 2-16
f7ab8f5
to
1b1d9e8
Compare
done, review please |
Could you fix the travis-ci build error |
…ntGenerator and FollowMovementGenerator, full rewrite for both. - Chase to angle is now functional. Pets use this to chase behind the target. Closes TrinityCore#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 TrinityCore#8924.
1aa917d
to
831f5cf
Compare
I noticed that in current 3.3.5 source (as of e350cfc), hunter pet positions itself in front of the player instead of to the left. Does this PR revert that change? edit: (you don't need a pet class player to see this happening, it is enough to watch Warp-Huntress Kula (entry 32711) in Dalaran or any other moving pet class NPC to see the pet move through the creature to stay in front of it.) |
In this PR, the pet will always follow the player somewhere in the rear 90° arc (though this could easily be adjusted). |
// the owner might be unable to move (rooted or casting), pause movement | ||
if (owner->HasUnitState(UNIT_STATE_NOT_MOVE) || owner->IsMovementPreventedByCasting()) | ||
{ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hello there
#include "MoveSplineInit.h" | ||
#include "G3DPosition.hpp" | ||
|
||
static bool isMutualChase(Unit* owner, Unit* target) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
naming sitll, UpperCamelCase unless u want to change the standard 💃
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not a member function
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so? this applies to ALL functions, not just members (the only exceptions are begin/end for range loops)
return (static_cast<ChaseMovementGenerator const*>(gen)->GetTarget() == owner); | ||
} | ||
|
||
inline static float sq(float a) { return a*a; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe move this to somewhere else?
static bool isMutualChase(Unit* owner, Unit* target) | ||
{ | ||
MovementGenerator const* gen = target->GetMotionMaster()->top(); | ||
if (gen->GetMovementGeneratorType() != CHASE_MOTION_TYPE) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
gen can be null, updating slots, expiring top or w/e
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
though this should only be called on top... guess its ok
ChaseRange(float min, float tMin, float tMax, float max) : minRange(min), minTolerance(tMin), maxRange(max), maxTolerance(tMax) {} | ||
|
||
// this contains info that informs how we should path! | ||
float minRange; // we have to move if we are within this range... (min. attack range) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Naming - public members
{ | ||
ChaseAngle(float angle, float tol = M_PI_4) : relativeAngle(Position::NormalizeOrientation(angle)), tolerance(tol) {} | ||
|
||
float relativeAngle; // we want to be at this angle relative to the target (0 = front, M_PI = back) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Naming - public members
float relativeAngle; // we want to be at this angle relative to the target (0 = front, M_PI = back) | ||
float tolerance; // but we'll tolerate anything within +- this much | ||
|
||
float upperBound() const { return Position::NormalizeOrientation(relativeAngle + tolerance); } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Naming - functions
#include "MoveSplineInit.h" | ||
#include "G3DPosition.hpp" | ||
|
||
static bool isMutualChase(Unit* owner, Unit* target) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so? this applies to ALL functions, not just members (the only exceptions are begin/end for range loops)
return !angle || angle->isAngleOkay(target->GetRelativeAngle(owner)); | ||
} | ||
|
||
static const Optional<float> NONE; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove this
|
||
ChaseMovementGenerator(Unit* target, Optional<ChaseRange> range = {}, Optional<ChaseAngle> angle = {}) : AbstractFollower(ASSERT_NOTNULL(target)), _range(range), _angle(angle) {} | ||
|
||
void Initialize(Unit* owner) override { owner->AddUnitState(UNIT_STATE_CHASE); owner->SetWalk(false); } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is walk/run mode tied to chasing? (http://www.wowhead.com/npc=20064/thaladred-the-darkener)
Optional<ChaseRange> const _range; | ||
Optional<ChaseAngle> const _angle; | ||
|
||
std::unique_ptr<PathGenerator> _path; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
forward declare PathGenerator instead of including, move constructor body to .cpp and add ~ChaseMovementGenerator::ChaseMovementGenerator() = default
to .cpp
#include "Pet.h" | ||
|
||
static inline float sq(float a) { return a*a; } | ||
static bool positionOkay(Unit* owner, Unit* target, float range, Optional<ChaseAngle> angle = {}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
naming
void UnitSpeedChanged() override { _lastTargetPosition.Relocate(0.0f, 0.0f, 0.0f); } | ||
|
||
private: | ||
static const uint32 CHECK_INTERVAL = 500; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
constexpr
@@ -5498,7 +5499,7 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint | |||
else if (m_preGeneratedPath->IsInvalidDestinationZ(target)) // Check position z, if in a straight line | |||
return SPELL_FAILED_NOPATH; | |||
|
|||
m_preGeneratedPath->ReducePathLenghtByDist(objSize); // move back | |||
m_preGeneratedPath->ShortenPathUntilDist(PositionToVector3(target), objSize); // move back |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just pass x,y,z separately?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure - but in how many places do we have to do that before it's unneeded code duplication? helpers are lightweight
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you know what I'm hinting at here (include hater)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the only thing new is the .hpp
- we already had Vector3
(from PathGenerator
itself)
btw the forward declare business of PathGenerator also applies to FollowMovementGenerator |
right, forgot |
anything else, @Shauren? |
the setinfront part might be still needed, to correct serverside orientation on reach btw funny how I told you twice about the naming 💃 |
#define TRINITY_CHASEMOVEMENTGENERATOR_H | ||
|
||
#include "MovementGenerator.h" | ||
#include "Unit.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
move Initialize to cpp to remove this
#define TRINITY_FOLLOWMOVEMENTGENERATOR_H | ||
|
||
#include "MovementGenerator.h" | ||
#include "Unit.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if its necessary for abstractfollower, maybe move it to a separate h?
movespline has facing set |
movespline does not update facing for MoveSplineFlag::Final_Target (it only does for point and angle) |
Hrm, alright. Feels like it should? |
changes done. i still feel like the orientation should be set by the spline logic (since the spline specifies a facing target), but don't see any quick way to do it - movespline code is painfully not unit aware, and just setting stuff to public and handling it outside feels like a hack. so i re-added setinfront as a temporary workaround. |
if (PositionOkay(owner, target, _movingTowards ? Optional<float>() : minTarget, _movingTowards ? maxTarget : Optional<float>(), angle)) | ||
{ | ||
owner->StopMoving(); | ||
_path = nullptr; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
consider maybe adding a return true here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no - if the position is invalid, we want to immediately start pathfinding again (maybe the target moved?)
scratch that, was thinking of a different (similar) branch
else if (i == 0) // at second point | ||
// we know that pathPoints[i] is too close already (from the previous iteration) | ||
if ((_pathPoints[i-1] - target).squaredLength() >= distSq) | ||
break; // bingo! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
love the comment ❤️
This means its well designed as standalone system |
careful with that back patting, it includes |
tbf I dont recall it being his entirely 😄 btw cant do much more, dont have the time to test. I feel its a really solid work, as always ❤️, so trusting your logic I'd say its merge ready. |
We currently have a
TargetedMovementGenerator
, which was originally intended to handle bothChaseMovement
andFollowMovement
. On paper, this seems sensible, as they function similarly.However, there are quite some differences between the two, which has left
TargetedMovementGenerator
an unreadable mess of special cases. I am splitting the two apart so as to make work on them easier.Ref issue #19925.