-
-
Save Emtec/ddb34c77794966bbe05b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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