Skip to content

Instantly share code, notes, and snippets.

@Emtec
Created August 13, 2015 20:17
Show Gist options
  • Save Emtec/ddb34c77794966bbe05b to your computer and use it in GitHub Desktop.
Save Emtec/ddb34c77794966bbe05b to your computer and use it in GitHub Desktop.
template<>
bool RandomMovementGenerator<Creature>::GeneratePosition(Creature* creature, float& x, float& y, float& z)
{
float respX, respY, respZ, destX, destY, destZ, travelDistZ;
creature->GetCreatureMovementPath().GetCurrentPath()->position.GetPosition(respX, respY, respZ);
Map const* map = creature->GetBaseMap();
// For 2D/3D system selection
//bool is_land_ok = creature.CanWalk(); // not used?
//bool is_water_ok = creature.CanSwim(); // not used?
bool is_air_ok = creature->CanFly();
const float angle = float(rand_norm()) * static_cast<float>(M_PI*2.0f);
const float range = float(rand_norm()) * wander_distance;
const float distanceX = range * std::cos(angle);
const float distanceY = range * std::sin(angle);
destX = respX + distanceX;
destY = respY + distanceY;
Trinity::NormalizeMapCoord(destX);
Trinity::NormalizeMapCoord(destY);
travelDistZ = range; // sin^2+cos^2=1, so travelDistZ=range^2; no need for sqrt below
if (is_air_ok) // 3D system above ground and above water (flying mode)
{
// Limit height change
const float distanceZ = float(rand_norm()) * travelDistZ / 2.0f;
destZ = respZ + distanceZ;
float levelZ = map->GetWaterOrGroundLevel(creature->GetPhaseMask(), destX, destY, destZ - 2.0f);
// Problem here, we must fly above the ground and water, not under. Let's try on next tick
if (levelZ >= destZ)
return false;
}
//else if (is_water_ok) // 3D system under water and above ground (swimming mode)
else // 2D only
{
// 10.0 is the max that vmap high can check (MAX_CAN_FALL_DISTANCE)
travelDistZ = travelDistZ >= 10.0f ? 10.0f : travelDistZ;
// The fastest way to get an accurate result 90% of the time.
// Better result can be obtained like 99% accuracy with a ray light, but the cost is too high and the code is too long.
destZ = map->GetHeight(creature->GetPhaseMask(), destX, destY, respZ + travelDistZ - 2.0f, false);
if (std::fabs(destZ - respZ) > travelDistZ) // Map check
{
// Vmap Horizontal or above
destZ = map->GetHeight(creature->GetPhaseMask(), destX, destY, respZ - 2.0f, true);
if (std::fabs(destZ - respZ) > travelDistZ)
{
// Vmap Higher
destZ = map->GetHeight(creature->GetPhaseMask(), destX, destY, respZ + travelDistZ - 2.0f, true);
// let's forget this bad coords where a z cannot be find and retry at next tick
if (std::fabs(destZ - respZ) > travelDistZ)
return false;
}
}
}
x = destX;
y = destY;
z = destZ;
return true;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment