All pastes #1348397 Raw Edit

mov

public cpp v1 · immutable
#1348397 ·published 2009-02-27 01:30 UTC
rendered paste body
diff -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 + dist - 2.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+