Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
RandomMovementGenerator.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6#include "Creature.h"
7#include "CreatureGroups.h"
8#include "Map.h"
9#include "MapManager.h"
10#include "MoveSpline.h"
11#include "MoveSplineInit.h"
12#include "ObjectAccessor.h"
14#include "Util.h"
15
16#define RUNNING_CHANCE_RANDOMMV 20 //will be "1 / RUNNING_CHANCE_RANDOMMV"
17
18#ifdef MAP_BASED_RAND_GEN
19#define rand_norm() creature.rand_norm()
20#endif
21
22template<>
24{
25 float respX, respY, respZ, respO, destX, destY, destZ, travelDistZ;
26 creature->GetHomePosition(respX, respY, respZ, respO);
27 Map const* map = creature->GetBaseMap();
28
29 // For 2D/3D system selection
30 //bool is_land_ok = creature.CanWalk(); // not used?
31 //bool is_water_ok = creature.CanSwim(); // not used?
32 bool is_air_ok = creature->CanFly();
33
34 const float angle = float(rand_norm()) * static_cast<float>(M_PI * 2.0f);
35 const float range = float(rand_norm()) * wander_distance;
36 const float distanceX = range * std::cos(angle);
37 const float distanceY = range * std::sin(angle);
38
39 destX = respX + distanceX;
40 destY = respY + distanceY;
41
42 // prevent invalid coordinates generation
45
46 travelDistZ = distanceX * distanceX + distanceY * distanceY;
47
48 if (is_air_ok) // 3D system above ground and above water (flying mode)
49 {
50 // Limit height change
51 const float distanceZ = float(rand_norm()) * sqrtf(travelDistZ) / 2.0f;
52 destZ = respZ + distanceZ;
53 float levelZ = map->GetWaterOrGroundLevel(destX, destY, destZ - 2.0f);
54
55 // Problem here, we must fly above the ground and water, not under. Let's try on next tick
56 if (levelZ >= destZ)
57 return;
58 }
59 //else if (is_water_ok) // 3D system under water and above ground (swimming mode)
60 else // 2D only
61 {
62 // 10.0 is the max that vmap high can check (MAX_CAN_FALL_DISTANCE)
63 travelDistZ = travelDistZ >= 100.0f ? 10.0f : sqrtf(travelDistZ);
64
65 // The fastest way to get an accurate result 90% of the time.
66 // Better result can be obtained like 99% accuracy with a ray light, but the cost is too high and the code is too long.
67 destZ = map->GetHeight(creature->GetPhaseMask(), destX, destY, respZ + travelDistZ - 2.0f, false);
68
69 if (fabs(destZ - respZ) > travelDistZ) // Map check
70 {
71 // Vmap Horizontal or above
72 destZ = map->GetHeight(creature->GetPhaseMask(), destX, destY, respZ - 2.0f, true);
73
74 if (fabs(destZ - respZ) > travelDistZ)
75 {
76 // Vmap Higher
77 destZ = map->GetHeight(creature->GetPhaseMask(), destX, destY, respZ + travelDistZ - 2.0f, true);
78
79 // let's forget this bad coords where a z cannot be find and retry at next tick
80 if (fabs(destZ - respZ) > travelDistZ)
81 return;
82 }
83 }
84
85 creature->UpdateAllowedPositionZ(destX, destY, destZ);
86 }
87
88 if (is_air_ok)
89 i_nextMoveTime.Reset(0);
90 else
91 i_nextMoveTime.Reset(std::rand() % 10000 + 500);
92
94
95 Movement::MoveSplineInit init(creature);
96 init.MoveTo(destX, destY, destZ);
97 init.SetWalk(true);
98 init.Launch();
99
100 //Call for creature group update
101 if (creature->GetFormation() && creature->GetFormation()->getLeader() == creature)
102 creature->GetFormation()->LeaderMoveTo(destX, destY, destZ);
103}
104
105template<>
107{
108 if (!creature->IsAlive())
109 return;
110
111 if (!wander_distance)
112 wander_distance = creature->GetRespawnRadius();
113
115 _setRandomLocation(creature);
116}
117
118template<>
120{
121 DoInitialize(creature);
122}
123
124template<>
130
131template<>
133{
134 if (creature->IsInCombat())
135 return true;
136
138 {
139 i_nextMoveTime.Reset(0); // Expire the timer
141 return true;
142 }
143
144 if (creature->movespline->Finalized())
145 {
146 i_nextMoveTime.Update(diff);
147 if (i_nextMoveTime.Passed())
148 _setRandomLocation(creature);
149 }
150 return true;
151}
152
153template<>
154bool RandomMovementGenerator<Creature>::GetResetPos(Creature* creature, float& x, float& y, float& z)
155{
156 float radius;
157 creature->GetRespawnPosition(x, y, z, NULL, &radius);
158
159 // use current if in range
160 if (creature->IsWithinDist2d(x, y, radius))
161 creature->GetPosition(x, y, z);
162
163 return true;
164}
#define M_PI
Definition Common.h:192
std::uint32_t uint32
Definition Define.h:77
@ UNIT_STATE_DISTRACTED
Definition Unit.h:524
@ UNIT_STATE_ROAMING_MOVE
Definition Unit.h:534
@ UNIT_STATE_ROOT
Definition Unit.h:522
@ UNIT_STATE_ROAMING
Definition Unit.h:516
@ UNIT_STATE_STUNNED
Definition Unit.h:515
double rand_norm(void)
Definition Util.cpp:50
void LeaderMoveTo(float x, float y, float z)
Creature * getLeader() const
void GetHomePosition(float &x, float &y, float &z, float &ori) const
Definition Creature.h:628
float GetRespawnRadius() const
Definition Creature.h:605
bool CanFly() const OVERRIDE
Definition Creature.h:458
void GetRespawnPosition(float &x, float &y, float &z, float *ori=NULL, float *dist=NULL) const
CreatureGroup * GetFormation()
Definition Creature.h:643
Definition Map.h:238
float GetHeight(float x, float y, float z, bool checkVMap=true, float maxSearchDist=DEFAULT_HEIGHT_SEARCH) const
Definition Map.cpp:1959
float GetWaterOrGroundLevel(float x, float y, float z, float *ground=NULL, bool swim=false) const
Definition Map.cpp:1941
void SetWalk(bool enable)
void MoveTo(const Vector3 &destination, bool generatePath=true, bool forceDestination=false)
bool DoUpdate(T *, const uint32)
bool GetResetPos(T *, float &x, float &y, float &z)
void ClearUnitState(uint32 f)
Definition Unit.h:1489
bool IsAlive() const
Definition Unit.h:2032
void AddUnitState(uint32 f)
Definition Unit.h:1481
bool SetWalk(bool enable)
Definition Unit.cpp:9137
bool HasUnitState(const uint32 f) const
Definition Unit.h:1485
std::unique_ptr< Movement::MoveSpline > movespline
Definition Unit.h:2837
bool IsInCombat() const
Definition Unit.h:1896
uint32 GetPhaseMask() const
Definition Object.h:643
bool IsWithinDist2d(float x, float y, float dist) const
Definition Object.cpp:1720
void UpdateAllowedPositionZ(float x, float y, float &z) const
Definition Object.cpp:1985
Map const * GetBaseMap() const
Definition Object.cpp:2544
void NormalizeMapCoord(float &c)
void GetPosition(float &x, float &y) const
Definition Object.h:333