Skip to content
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

Merged
merged 11 commits into from Apr 6, 2018

Conversation

Treeston
Copy link
Member

We currently have a TargetedMovementGenerator, which was originally intended to handle both ChaseMovement and FollowMovement. 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.

@ccrs
Copy link
Member

ccrs commented Mar 28, 2018

@ccrs
Copy link
Member

ccrs commented Mar 28, 2018

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)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

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

@ghost
Copy link

ghost commented Mar 28, 2018

Looks like you have got 3x unused parameter 'owner' there. Should be simple to fix, unless that only uncovers more needed changes.


ChaseMovementGenerator(Unit* target, Optional<float> range = {}, Optional<float> angle = {}) : AbstractFollower(ASSERT_NOTNULL(target)), _range(range), _angle(angle) {}

void Initialize(Unit* owner) override {}
Copy link
Contributor

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 {}
Copy link
Contributor

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 {}
Copy link
Contributor

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/>
Copy link

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

@Treeston Treeston force-pushed the 3.3.5-targetedmovegen branch 4 times, most recently from f7ab8f5 to 1b1d9e8 Compare April 1, 2018 16:35
@Treeston Treeston changed the title [3.3.5] [WIP] Split TargetedMovementGenerator [3.3.5] Split TargetedMovementGenerator Apr 1, 2018
@Treeston
Copy link
Member Author

Treeston commented Apr 1, 2018

done, review please

@ghost
Copy link

ghost commented Apr 1, 2018

Could you fix the travis-ci build error (and maybe the current one in 3.3.5 as well) so we can see what else may need a follow-up?
(edit: https://travis-ci.org/TrinityCore/TrinityCore/builds/360911820#L1436 - in case you want a link)
My bad, I presumed too much. I just realized that TargetedMovementGenerator.cpp et alia gets removed in this PR.

…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.
@Killyana
Copy link
Member

Killyana commented Apr 2, 2018

I got a crash: https://paste2.org/LwEWNvxk
.go xyz -127.13346, 2154.41699, 30.654285 631
and send your pet to attack the npc SpawnID: 201097

Looks like it fixes: #14120 #12817 #13686
Issues related but not fixed: #21237 #14242 #16647

@ghost
Copy link

ghost commented Apr 2, 2018

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.)

@Treeston
Copy link
Member Author

Treeston commented Apr 2, 2018

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())
{

Copy link
Member

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)
Copy link
Member

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 💃

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not a member function

Copy link
Member

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; }
Copy link
Member

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)
Copy link
Member

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

Copy link
Member

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

@TrinityCore TrinityCore deleted a comment Apr 4, 2018
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)
Copy link
Member

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)
Copy link
Member

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); }
Copy link
Member

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)
Copy link
Member

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;
Copy link
Member

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); }
Copy link
Member

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;
Copy link
Member

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 = {})
Copy link
Member

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;
Copy link
Member

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
Copy link
Member

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?

Copy link
Member Author

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

Copy link
Member

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)

Copy link
Member Author

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)

@Shauren
Copy link
Member

Shauren commented Apr 5, 2018

btw the forward declare business of PathGenerator also applies to FollowMovementGenerator

@Treeston
Copy link
Member Author

Treeston commented Apr 5, 2018

right, forgot

@Treeston
Copy link
Member Author

Treeston commented Apr 5, 2018

anything else, @Shauren?

@ccrs
Copy link
Member

ccrs commented Apr 5, 2018

the setinfront part might be still needed, to correct serverside orientation on reach

btw funny how I told you twice about the naming 💃
and also, having a sq inline declared twice might be a good sign to move it to util or w/e

#define TRINITY_CHASEMOVEMENTGENERATOR_H

#include "MovementGenerator.h"
#include "Unit.h"
Copy link
Member

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"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

Copy link
Member

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?

@Treeston
Copy link
Member Author

Treeston commented Apr 5, 2018

the setinfront part might be still needed, to correct serverside orientation on reach

movespline has facing set

@Shauren
Copy link
Member

Shauren commented Apr 5, 2018

movespline does not update facing for MoveSplineFlag::Final_Target (it only does for point and angle)

@Treeston
Copy link
Member Author

Treeston commented Apr 5, 2018

Hrm, alright. Feels like it should?

@Treeston Treeston requested review from Shauren and ccrs April 5, 2018 23:15
@Treeston
Copy link
Member Author

Treeston commented Apr 5, 2018

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;
Copy link
Member

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?

Copy link
Member Author

@Treeston Treeston Apr 6, 2018

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!
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

love the comment ❤️

@Shauren
Copy link
Member

Shauren commented Apr 6, 2018

movespline code is painfully not unit aware

This means its well designed as standalone system

@Treeston
Copy link
Member Author

Treeston commented Apr 6, 2018

careful with that back patting, it includes Creature.h...

@ccrs
Copy link
Member

ccrs commented Apr 6, 2018

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.

@Treeston Treeston merged commit 2a84562 into TrinityCore:3.3.5 Apr 6, 2018
@Treeston Treeston deleted the 3.3.5-targetedmovegen branch April 6, 2018 16:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants