Update ConfusedMovementGenerator with some coordinate sanity checks.
Please leave feedback on how this affects: - Confused movement (polymorph, blind, etc) - Stability with vmaps enabled --HG-- branch : trunk
This commit is contained in:
@@ -47,36 +47,44 @@ ConfusedMovementGenerator<T>::Initialize(T &unit)
|
|||||||
bool is_water_ok, is_land_ok;
|
bool is_water_ok, is_land_ok;
|
||||||
_InitSpecific(unit, is_water_ok, is_land_ok);
|
_InitSpecific(unit, is_water_ok, is_land_ok);
|
||||||
|
|
||||||
VMAP::IVMapManager *vMaps = VMAP::VMapFactory::createOrGetVMapManager();
|
|
||||||
|
|
||||||
for (uint8 idx = 0; idx <= MAX_CONF_WAYPOINTS; ++idx)
|
for (uint8 idx = 0; idx <= MAX_CONF_WAYPOINTS; ++idx)
|
||||||
{
|
{
|
||||||
const float wanderX = wander_distance*rand_norm() - wander_distance/2;
|
float wanderX = x + wander_distance*rand_norm() - wander_distance/2;
|
||||||
const float wanderY = wander_distance*rand_norm() - wander_distance/2;
|
float wanderY = y + wander_distance*rand_norm() - wander_distance/2;
|
||||||
i_waypoints[idx][0] = x + wanderX;
|
Trinity::NormalizeMapCoord(wanderX);
|
||||||
i_waypoints[idx][1] = y + wanderY;
|
Trinity::NormalizeMapCoord(wanderY);
|
||||||
|
|
||||||
const bool isInLoS = vMaps->isInLineOfSight(unit.GetMapId(), x, y, z + 2.0f, i_waypoints[idx][0], i_waypoints[idx][1], z + 2.0f);
|
float new_z = map->GetHeight(wanderX, wanderY, z, true);
|
||||||
if (!isInLoS)
|
if (new_z > INVALID_HEIGHT && unit.IsWithinLOS(wanderX, wanderY, new_z))
|
||||||
{
|
{
|
||||||
i_waypoints[idx][0] = x;
|
// Don't move in water if we're not already in
|
||||||
i_waypoints[idx][1] = y;
|
// Don't move on land if we're not already on it either
|
||||||
|
bool is_water_now = map->IsInWater(x, y, z);
|
||||||
|
bool is_water_next = map->IsInWater(wanderX, wanderY, new_z);
|
||||||
|
if ((is_water_now && !is_water_next && !is_land_ok) || (!is_water_now && is_water_next && !is_water_ok))
|
||||||
|
{
|
||||||
|
i_waypoints[idx][0] = idx > 0 ? i_waypoints[idx-1][0] : x; // Back to previous location
|
||||||
|
i_waypoints[idx][1] = idx > 0 ? i_waypoints[idx-1][1] : y;
|
||||||
|
i_waypoints[idx][2] = idx > 0 ? i_waypoints[idx-1][2] : z;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// prevent invalid coordinates generation
|
// Taken from FleeingMovementGenerator
|
||||||
Trinity::NormalizeMapCoord(i_waypoints[idx][0]);
|
if (!(new_z - z) || wander_distance / fabs(new_z - z) > 1.0f)
|
||||||
Trinity::NormalizeMapCoord(i_waypoints[idx][1]);
|
{
|
||||||
|
i_waypoints[idx][0] = wanderX;
|
||||||
bool is_water = map->IsInWater(i_waypoints[idx][0],i_waypoints[idx][1],z);
|
i_waypoints[idx][1] = wanderY;
|
||||||
// if generated wrong path just ignore
|
i_waypoints[idx][2] = new_z;
|
||||||
if ((is_water && !is_water_ok) || (!is_water && !is_land_ok))
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // Back to previous location
|
||||||
{
|
{
|
||||||
i_waypoints[idx][0] = idx > 0 ? i_waypoints[idx-1][0] : x;
|
i_waypoints[idx][0] = idx > 0 ? i_waypoints[idx-1][0] : x;
|
||||||
i_waypoints[idx][1] = idx > 0 ? i_waypoints[idx-1][1] : y;
|
i_waypoints[idx][1] = idx > 0 ? i_waypoints[idx-1][1] : y;
|
||||||
|
i_waypoints[idx][2] = idx > 0 ? i_waypoints[idx-1][2] : z;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
unit.UpdateGroundPositionZ(i_waypoints[idx][0],i_waypoints[idx][1],z);
|
|
||||||
i_waypoints[idx][2] = z;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unit.SetUInt64Value(UNIT_FIELD_TARGET, 0);
|
unit.SetUInt64Value(UNIT_FIELD_TARGET, 0);
|
||||||
|
|||||||
Reference in New Issue
Block a user