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
[WIP] Core/Movement: Targeted MoveGen Improvements #17850
Conversation
This logic is really interesting. @r00ty-tc I know you'll appreciate. |
/home/travis/build/TrinityCore/TrinityCore/src/server/game/Movement/PathGenerator.cpp:933:17: fatal error: |
Naughty infinite loop. |
uint32 idx = _pathPoints.size() - 2; | ||
float totalLengthSoFar = 0.0f; | ||
G3D::Vector3 diffVec; | ||
uint32 newPathSize; |
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.
C:\projects\trinitycore\src\server\game\Movement\PathGenerator.cpp(932): error C2220: warning treated as error
- no 'object' file generated [C:\projects\trinitycore\build\src\server\game\game.vcxproj]
C:\projects\trinitycore\src\server\game\Movement\PathGenerator.cpp(932): warning C4101: 'newPathSize':
unreferenced local variable [C:\projects\trinitycore\build\src\server\game\game.vcxproj]
First version ready for testing. Only creatures chasing another unit work for now (to be more precise, only MoveChase without offset has been implemented. MoveChase with offset and MoveFollow as a whole are broken for now). There is probably a lot more work to do but for now it looks stable and it should fix A LOT of movement related issues. At least the first 3 issues exposed here. Maybe more. To summarize, this PR should fix: |
41af431
to
d571172
Compare
@@ -106,6 +107,7 @@ void TargetedMovementGeneratorMedium<T, D>::_setTargetLocation(T* owner, bool up | |||
&& owner->HasUnitState(UNIT_STATE_FOLLOW)); | |||
|
|||
bool result = i_path->CalculatePath(x, y, z, forceDest); | |||
i_path->ReducePathLenghtByDist(owner->GetObjectSize() + i_target->GetObjectSize() + CONTACT_DISTANCE, i_target->ToUnit()); // this distance is correct only for MoveChase with no offset |
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 is little point reducing the path length before checking the result in the lines below (also it's length, not lenght)
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.
ReducePathLenghtByDist also valide the last point of the path and if no right point is found in range and in los of the target, the path is set to flagged as unusable. This is why. (regarding the spelling, i didn't create the method. i just rewrote it, but yeah i will fix that)
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's no point to set the path as unusable (PATHFIND_NOPATH) if the path is already unusable, so if i_path->GetPathType() & PATHFIND_NOPATH is already true before this call.
could you describe more in detail how pathfinding calls are handled in this PR, in particular the "Now it's the other way around" part ? Does this change very little how and when pathfinding is used or does it change some things we should check (i.e. more/less queries, more/less detailed queries, etc). |
@@ -904,7 +904,7 @@ float PathGenerator::Dist3DSqr(G3D::Vector3 const& p1, G3D::Vector3 const& p2) c | |||
return (p1 - p2).squaredLength(); | |||
} | |||
|
|||
void PathGenerator::ReducePathLenghtByDist(float dist) | |||
void PathGenerator::ReducePathLenghtByDist(const float dist, 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.
It would be nice if target wouldn't be mandatory (right now the code crashes with NULL dereference exception of the caller passes NULL since there's no validation at all), PathGenerator is not supposed to always have a Unit as 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.
this method is called for now only at 2 points and for each of those cases, if i'm not mistaken, unit will never be null.
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 it will never be null then add an ASSERT( )
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.
please add an ASSERT(target); here
Current logic:
New logic:
|
could you provide test cases with previous and new behavior ? |
I haven't tested, but this should fix any issue where NPCs would path to just below you, then be unable to attack you due to range. Ex.: Central storm peaks, stand on the rocks and pull a Magnataur. |
if (!IsValidFinalPoint(_pathPoints[_pathPoints.size() - 1], target, dist)) | ||
{ | ||
// even the last position of the generated path, which should be close if not on top of the target, was not good enough. we mark the path as unusable. | ||
_type = PATHFIND_NOPATH; |
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.
this code doesn't handle PATHFIND_INCOMPLETE/PATHFIND_SHORT cases (and it's still to be defined after which distance it should be set to PATHFIND_INCOMPLETE)
isn't the current 1st step "find a point close to target" https://github.com/TrinityCore/TrinityCore/pull/17850/files#diff-268a0e4eced8ee7bb5139f6c2b47034cL61 ? Basically your code is trying to fix
|
2nd SS looks better, I think a 3rd SS with both "try different angles and try to shorten the path" will get the best of both. |
OK - that's exactly what I wanted. 👍 from me. |
as suggested at #17850 (comment) , I think a mix of both New and Angle solutions should be implemented, in particular using your New method first, check LoS with target and then apply Angle to find a point in LoS (the way angles are chosen could be changed to jump from a side to the other instead of checking them like around the clock). I'm not sure if a 2nd path should be calculated to reach the new point, maybe just from the last point of New. I'd suggest to merge this PR with the above suggestion first, then we can check how to modify Detour (what would you like to modify in Detour btw ?) |
Could you describe as clearly as possible a situation where using a combination of the New method and the Angle method would be more suitable than just the New method?
Indeed. It would be an improvement compared to the current way of doing. Nonetheless, it's still asymmetrical. And therefore, some situations will be handled awkwardly, depending on if the NPC approaches by the left or by the right (like in the blade's edge arena, when you go up on the platform. i will provide more details later).
Detour allows to find a walkable path from point A to point B. Ideally, the concept of LoS and combat reach should be integrated into Detour as well We don't need to move to a certain point. We need to move close enough and in LoS of this point. It would solve the situation mentioned above. |
Imagine an enemy hiding behind a crate: the New method finds a path (that would walk throught the crate), reduces the length by the combat reach and sets the end point in front of the crate with the enemy not in LoS. |
Would it be more efficient and good enough to walk along the originally calculated path rather than calculate the path to different spots around the target? For example calculate path to target (use the new method proposed). Cut it by the combat reach. Check LOS at that point. Reduce the cut by X. Check LOS at that point. Reduce the cut by X. Repeat reducing cut until our cut is 0. Sorry if this was somehow not possible. Not informed on the pathfinding. :/ |
@jackpoz detour would route you around the crate, no? |
@Rochet2 Yes. I didn't mentioned it in the example above because i wanted to keep it simple. But yes, my algorithm works exactly the way you described. @jackpoz I agree with @Treeston. Detour will find a path that will go around the obstacle. Unless the crate is a DynObj. In which case, the problem is the same if you increase the size of the crate. The Angle approach would not help. A true solution to this situation would be to support Dynamic Objects in the pathfinding. Which is an entirely different topic. |
If you think Detour will find a path around a GameObject then you should go back studying how TC uses Recast and Detour. |
I said exactly the opposite. In your previous post, you didn't specify if the obstacle was a GO or not (sorry, in my previous post, by dynobj i meant GO). So there are 2 cases:
The Angle approach doesn't completely solve the GO issue on its own. At the same time, along with it comes a lot of issues because of its unreliability (point under the map, asymmetrical, ...). Therefore, I don't think it's a good approach. |
And dont forget about slopes. Path calculated -> path reduced -> movegen checks real distance -> recalculates path (loop) |
really ? why do you think I chose a crate ? it was obviously a GO.
which point under map ? which asymmetrical ? where are all these "lot of issues" ? Why is it so hard for you to just implement a part of algo that fixes some corner cases that your algo totally ignores ? are we discussing about philosophy here or are we trying to improve TC ? Just add it at the end so we can merge this PR and move on. |
@chaodhib does that means the cutting will notice that the target is not in LoS in my crate example and as result make the creature move to the exact location as the target ? that would mean the creature will be able to attack it and will cause pretty much no issue. If this is the case then this is how your New algo handles the crate case and it looks good to me. Please confirm if that's the case, then we can merge it. |
Yes, in worst case scenario, the creature will move to the exact location of the target. It will cut less and less until it finds a position where the creature is both close enough and in LoS of the target. And that point can be the position of the target itself. |
Out of curiosity, does this do anything to address #20173 too? |
it should |
No it doesn't. Last time I checked, that issue was relatively simple to solve (I could be mistaken though). I will take a look again when I can. EDIT: Indeed. I mentioned the issue HERE in the second point. The problem is this value. It's too high. Will submit PR when I can. |
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.
Couple of minor things and we can merge this one
Besides your 2 points @jackpoz, there are remaining things to implement before this PR can be merged: support of MoveChase with offset. And support of MoveFollow. I'll get into it as soon as i can. |
Conflicting files |
@chaodhib , do you have any plan to continue working on this ? |
@jackpoz At the moment, I'm focused on other PRs. I still believe the idea behind this one is sound though. Maybe I'll get back to it in the future. Until then, if someone wants to pick up where I left off and work on this, I'm more than happy to give the reins. Help is welcome. |
Add the label [help wanted] , maybe? |
Sure |
Closing this PR as it seems abandoned. Feel free to ask here to reopen it if anyone would like to work on it. |
Work in progress PR
Planned changes:
Major changes:
In the only commit yet, this is already implemented but only for MoveChase. Also, ReducePathLenghtByDist needs to be improved in order to make sure that after that method call, the last point of the path is always in LoS of the target & at the right distance.
Minor changes:
Target branch(es): 3.3.5
Issues addressed: Seems to at least
fix #16549
fix #9206
fix #16647
Tests performed: WIP. Build and tested IG for what I have so far.