rendered paste bodydiff -r 9ba75098736d -r 1339da9a4d8f src/game/RandomMovementGenerator.cpp--- a/src/game/RandomMovementGenerator.cpp Thu Feb 26 17:01:02 2009 -0600+++ b/src/game/RandomMovementGenerator.cpp Mon Feb 23 03:25:19 2009 +0200@@ -22,21 +22,18 @@ #include "MapManager.h" #include "RandomMovementGenerator.h" #include "Traveller.h"-#include "ObjectAccessor.h" #include "DestinationHolderImp.h"-#include "Map.h"-#include "Util.h" #define RUNNING_CHANCE_RANDOMMV 20 //will be "1 / RUNNING_CHANCE_RANDOMMV" template<>-bool+bool RandomMovementGenerator<Creature>::GetDestination(float &x, float &y, float &z) const { if(i_destinationHolder.HasArrived())- return false;-- i_destinationHolder.GetDestination(x, y, z);+ return false; + + i_destinationHolder.GetDestination(x, y, z); return true; } @@ -44,76 +41,96 @@ void RandomMovementGenerator<Creature>::_setRandomLocation(Creature &creature) {- float X,Y,Z,z,nx,ny,nz,ori,dist;+ float i_x,i_y,i_z,n_x,n_y,n_z,ori,dist;+ creature.GetHomePosition(i_x,i_y,i_z,ori); - creature.GetHomePosition(X, Y, Z, ori);+ const float angle = 2*M_PI*rand_norm();+ const float range = rand_norm()*wander_dist;+ const float distX = range*cos(angle);+ const float distY = range*sin(angle); - z = creature.GetPositionZ();- uint32 mapid=creature.GetMapId();- Map const* map = MapManager::Instance().GetBaseMap(mapid);+ n_x = i_x + distX;+ n_y = i_y + distY; - // For 2D/3D system selection- bool is_land_ok = creature.canWalk();- bool is_water_ok = creature.canSwim();- bool is_air_ok = creature.canFly();+ Trinity::NormalizeMapCoord(n_x);+ Trinity::NormalizeMapCoord(n_y); - const float angle = rand_norm()*(M_PI*2);- const float range = rand_norm()*wander_distance;- const float distanceX = range * cos(angle);- const float distanceY = range * sin(angle);+ Map const* map = MapManager::Instance().GetBaseMap(creature.GetMapId()); - nx = X + distanceX;- ny = Y + distanceY;-- // prevent invalid coordinates generation- Trinity::NormalizeMapCoord(nx);- Trinity::NormalizeMapCoord(ny);-- dist = (nx - X)*(nx - X) + (ny - Y)*(ny - Y);-- if (is_air_ok) // 3D system above ground and above water (flying mode)- {- const float distanceZ = rand_norm() * sqrtf(dist)/2; // Limit height change- nz = Z + distanceZ;- float tz = map->GetHeight(nx, ny, nz-2.0f, false); // Map check only, vmap needed here but need to alter vmaps checks for height.- float wz = map->GetWaterLevel(nx, ny);- if (tz >= nz || wz >= nz)- return; // Problem here, we must fly above the ground and water, not under. Let's try on next tick- }- //else if (is_water_ok) // 3D system under water and above ground (swimming mode)- else // 2D only- {- dist = dist>=100.0f ? 10.0f : sqrtf(dist); // 10.0 is the max that vmap high can check (MAX_CAN_FALL_DISTANCE)- // 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.- nz = map->GetHeight(nx,ny,Z+dist-2.0f,false); // Map check- if (fabs(nz-Z)>dist)- {- nz = map->GetHeight(nx,ny,Z-2.0f,true); // Vmap Horizontal or above- if (fabs(nz-Z)>dist)- {- nz = map->GetHeight(nx,ny,Z+dist-2.0f,true); // Vmap Higher- if (fabs(nz-Z)>dist)- return; // let's forget this bad coords where a z cannot be find and retry at next tick- }- }- }+ switch(_InhabitType)+ {+ case INHABIT_AIR:+ {+ //i don't use normalized n_x, n_y because difference is too small.. and this is random movement ;)+ dist = sqrtf(distX*distX + distY*distY);+ const float distanceZ = rand_norm() * dist/2; // Limit height change+ n_z = i_z + distanceZ;+ float tz = map->GetHeight(n_x,n_y,n_z - 2.0f,false);+ if (tz >= n_z || ground >= n_z)+ return;+ //creature.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);+ break;+ }+ case INHABIT_WATER:+ {+ //some small creatures can swim above water level :(+ float water = map->GetWaterLevel(n_x,n_y) - 1.8f;+ float floor = map->GetHeight(n_x,n_y,i_z,false) + 0.2f;+ if (water - floor < 0)+ return;+ float z_diff = 2 * 1.192*creature.GetDistance2d(n_x,n_y); //1.192 = tan(50)+ //if(water - floor > z_diff){+ n_z = z_diff*(1 - 2*rand_norm()) + creature.GetPositionZ();+ n_z = n_z > water ? water : n_z;+ n_z = n_z < floor ? floor : n_z;+ //}else+ //n_z = floor + rand_norm()*(water - floor);+ //creature.AddUnitMovementFlag(MOVEMENTFLAG_SWIMMING);+ break;+ } + case INHABIT_GROUND:+ {+ dist = (distX*distX + distY*distY);+ dist = dist>=100.0f ? 10.0f : sqrtf(dist); // 10.0 is the max that vmap high can check (MAX_CAN_FALL_DISTANCE)+ n_z = map->GetHeight(n_x,n_y,i_z,false);+ if (fabs(n_z - i_z) > dist)+ {+ n_z = map->GetHeight(n_x,n_y,i_z,true); // Vmap Horizontal or above+ if (fabs(n_z - i_z) > dist)+ {+ n_z = map->GetHeight(n_x,n_y,i_z + 8.0f,true); // Vmap Higher+ if (fabs(n_z - i_z) > dist)+ return;+ }+ }+ if (!irand(0,RUNNING_CHANCE_RANDOMMV))+ creature.RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);+ else+ creature.AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);+ break;+ }+ default:+ n_z = i_z;+ break;+ } Traveller<Creature> traveller(creature);- creature.SetOrientation(creature.GetAngle(nx,ny));- i_destinationHolder.SetDestination(traveller, nx, ny, nz);+ creature.SetOrientation(creature.GetAngle(n_x,n_y));+ i_destinationHolder.SetDestination(traveller,n_x,n_y,n_z); creature.addUnitState(UNIT_STAT_ROAMING);- if (is_air_ok)- {- i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime());- creature.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);- }- //else if (is_water_ok) // Swimming mode to be done with more than this check- else- {- i_nextMoveTime.Reset(urand(500+i_destinationHolder.GetTotalTravelTime(),5000+i_destinationHolder.GetTotalTravelTime()));- creature.SetUnitMovementFlags(MOVEMENTFLAG_WALK_MODE);- }++ switch(_InhabitType)+ {+ case INHABIT_AIR:+ i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime());+ break;+ case INHABIT_WATER:+ i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime() + urand(500,3000));+ break;+ default:+ i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime() + urand(500,5000));+ break;+ } } template<>@@ -122,14 +139,48 @@ { if(!creature.isAlive()) return;+ + wander_dist = creature.GetRespawnRadius();+ Map const* map = MapManager::Instance().GetBaseMap(creature.GetMapId()); - wander_distance = creature.GetRespawnRadius();+ _InhabitType = creature.GetCreatureInfo()->InhabitType; - if (creature.canFly())- creature.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);- else- creature.SetUnitMovementFlags(irand(0,RUNNING_CHANCE_RANDOMMV) > 0 ? MOVEMENTFLAG_WALK_MODE : MOVEMENTFLAG_NONE );- _setRandomLocation(creature);+ // Let's select only one movement type+ // TODO: make this check more correct+ float water;+ if(_InhabitType & (INHABIT_WATER | INHABIT_AIR))+ water = map->GetWaterLevel(creature.GetPositionX(),creature.GetPositionY());+ if(_InhabitType & INHABIT_AIR)+ {+ float floor = map->GetHeight(creature.GetPositionX(),creature.GetPositionY(),creature.GetPositionZ(),true);+ ground = floor > water ? floor : water;+ if(ground + 2.0f < creature.GetPositionZ())+ {+ _InhabitType = INHABIT_AIR;+ //creature.addUnitState(UNIT_STAT_IN_FLIGHT);+ creature.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);+ i_nextMoveTime.Reset(urand(0,1000)); //to make them call _setRandomLocation not in one time+ //_setRandomLocation(creature);+ return;+ }else+ _InhabitType &= ~INHABIT_AIR;+ }+ if(_InhabitType & INHABIT_WATER)+ {+ if (water > creature.GetPositionZ()) //don't use "+2.0f" because under-water creatures already has height <= -1.9(if water level is 0)+ {+ _InhabitType = INHABIT_WATER;+ //creature.addUnitState(UNIT_STAT_IN_FLIGHT);+ creature.AddUnitMovementFlag(MOVEMENTFLAG_SWIMMING);+ i_nextMoveTime.Reset(urand(0,1000));+ //_setRandomLocation(creature);+ return;+ }else+ _InhabitType &= ~INHABIT_WATER;+ }+ if(_InhabitType & INHABIT_GROUND)+ i_nextMoveTime.Reset(urand(0,1000));+ //_setRandomLocation(creature); } template<>@@ -156,7 +207,7 @@ i_nextMoveTime.Update(diff); - if(i_destinationHolder.HasArrived() && !creature.IsStopped() && !creature.canFly())+ if(i_destinationHolder.HasArrived() && !creature.IsStopped() && !(_InhabitType & (INHABIT_WATER | INHABIT_AIR))) creature.clearUnitState(UNIT_STAT_ROAMING); if(!i_destinationHolder.HasArrived() && creature.IsStopped())@@ -167,13 +218,7 @@ if( i_destinationHolder.UpdateTraveller(traveller, diff, false, true) ) { if(i_nextMoveTime.Passed())- {- if (creature.canFly())- creature.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);- else- creature.SetUnitMovementFlags(irand(0,RUNNING_CHANCE_RANDOMMV) > 0 ? MOVEMENTFLAG_WALK_MODE : MOVEMENTFLAG_NONE); _setRandomLocation(creature);- } else if(creature.isPet() && creature.GetOwner() && creature.GetDistance(creature.GetOwner()) > PET_FOLLOW_DIST+2.5f) { creature.SetUnitMovementFlags(MOVEMENTFLAG_NONE);@@ -181,5 +226,4 @@ } } return true;-}-+}\ No newline at end of filediff -r 322be19c92f3 -r fe298f81b4ac src/game/RandomMovementGenerator.h--- a/src/game/RandomMovementGenerator.h Tue Feb 17 20:04:19 2009 +0100+++ b/src/game/RandomMovementGenerator.h Tue Feb 17 12:32:10 2009 -1200@@ -30,8 +30,8 @@ : public MovementGeneratorMedium< T, RandomMovementGenerator<T> > { public:- // Wander dist is related on db spawn dist. So what if we wanna set eandom movement on summoned creature?!- RandomMovementGenerator(float spawn_dist = 0.0f) : i_nextMoveTime(0), wander_distance(spawn_dist) {}+ // Wander dist is related on db spawn dist. So what if we wanna set random movement on summoned creature?!+ RandomMovementGenerator(float spawn_dist = 0.0f) : i_nextMoveTime(0), wander_dist(spawn_dist) {} void _setRandomLocation(T &); void Initialize(T &);@@ -48,7 +48,8 @@ TimeTrackerSmall i_nextMoveTime; DestinationHolder< Traveller<T> > i_destinationHolder;- float wander_distance;- uint32 i_nextMove;+ float wander_dist, ground;+ uint32 _InhabitType; }; #endif+