-
Notifications
You must be signed in to change notification settings - Fork 87
Fix waiting attackers becoming stuck when target flag becomes unreachable. #1865
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
base: master
Are you sure you want to change the base?
Conversation
…able. When the defender kills the current attacker (at the flag) `FindAttackerNearBuilding` is used to get the next one for the defender to fight. This takes the closest attacker that is ready, i.e. waiting around the flag and calls `AttackDefenderAtFlag` which usually causes the attacker to start walking to the flag. However if there is no path to the flag (anymore, e.g. after destroying a road) the attacker won't do anything and the function returns `false`. As this isn't checked the defender will keep waiting for it. This can lead to use-after-free if the attacker is destroyed (defeated in free fight, went back home, ...) as the defender will then have a dangling pointer to it. Fixes Return-To-The-Roots#1863
The point can be considered invalid if it is too far and the attacker would abort on the next event handling. Defenders with now missing attackers will still come out of the building and go right back in which looks weird.
8bddd93 to
0860af4
Compare
| // Check all points around the flag and take shortest | ||
| unsigned min_length = std::numeric_limits<unsigned>::max(); | ||
| MapPoint minPt = MapPoint::Invalid(); | ||
| ret_radius = 100; |
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.
should this then start at MAX_ATTACKING_RUN_DISTANCE too?
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.
Actually this assignment could be removed. It is never used because the value will be overwritten when minPt gets set and if it isn't then ret_radius has no meaning
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.
can we explicitly make it std::optional then? maybe its even eases up the do-while?
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.
Wait, this is used as the max value in the loop.
So it corresponds to GetPointsInRadius.
Added a constant to clarify
When the defender kills the current attacker (at the flag)
FindAttackerNearBuildingis used to get the next one for the defender to fight. This takes the closest attacker that is ready, i.e. waiting around the flag and callsAttackDefenderAtFlagwhich usually causes the attacker to start walking to the flag. However if there is no path to the flag (anymore, e.g. after destroying a road) the attacker won't do anything and the function returnsfalse.As this isn't checked the defender will keep waiting for it.
This can lead to use-after-free if the attacker is destroyed (defeated in free fight, went back home, ...) as the defender will then have a dangling pointer to it.
Fixes #1863