1 | /* |
---|
2 | * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/> |
---|
3 | * |
---|
4 | * Copyright (C) 2008 Trinity <http://www.trinitycore.org/> |
---|
5 | * |
---|
6 | * This program is free software; you can redistribute it and/or modify |
---|
7 | * it under the terms of the GNU General Public License as published by |
---|
8 | * the Free Software Foundation; either version 2 of the License, or |
---|
9 | * (at your option) any later version. |
---|
10 | * |
---|
11 | * This program is distributed in the hope that it will be useful, |
---|
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
14 | * GNU General Public License for more details. |
---|
15 | * |
---|
16 | * You should have received a copy of the GNU General Public License |
---|
17 | * along with this program; if not, write to the Free Software |
---|
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
---|
19 | */ |
---|
20 | |
---|
21 | #include "Creature.h" |
---|
22 | #include "MapManager.h" |
---|
23 | #include "Opcodes.h" |
---|
24 | #include "ConfusedMovementGenerator.h" |
---|
25 | #include "DestinationHolderImp.h" |
---|
26 | |
---|
27 | template<class T> |
---|
28 | void |
---|
29 | ConfusedMovementGenerator<T>::Initialize(T &unit) |
---|
30 | { |
---|
31 | const float wander_distance=11; |
---|
32 | float x,y,z; |
---|
33 | x = unit.GetPositionX(); |
---|
34 | y = unit.GetPositionY(); |
---|
35 | z = unit.GetPositionZ(); |
---|
36 | uint32 mapid=unit.GetMapId(); |
---|
37 | |
---|
38 | Map const* map = MapManager::Instance().GetBaseMap(mapid); |
---|
39 | |
---|
40 | i_nextMove = 1; |
---|
41 | |
---|
42 | bool is_water_ok, is_land_ok; |
---|
43 | _InitSpecific(unit, is_water_ok, is_land_ok); |
---|
44 | |
---|
45 | for(unsigned int idx=0; idx < MAX_CONF_WAYPOINTS+1; ++idx) |
---|
46 | { |
---|
47 | const float wanderX=wander_distance*rand_norm() - wander_distance/2; |
---|
48 | const float wanderY=wander_distance*rand_norm() - wander_distance/2; |
---|
49 | |
---|
50 | i_waypoints[idx][0] = x + wanderX; |
---|
51 | i_waypoints[idx][1] = y + wanderY; |
---|
52 | |
---|
53 | // prevent invalid coordinates generation |
---|
54 | Trinity::NormalizeMapCoord(i_waypoints[idx][0]); |
---|
55 | Trinity::NormalizeMapCoord(i_waypoints[idx][1]); |
---|
56 | |
---|
57 | bool is_water = map->IsInWater(i_waypoints[idx][0],i_waypoints[idx][1],z); |
---|
58 | // if generated wrong path just ignore |
---|
59 | if( is_water && !is_water_ok || !is_water && !is_land_ok ) |
---|
60 | { |
---|
61 | i_waypoints[idx][0] = idx > 0 ? i_waypoints[idx-1][0] : x; |
---|
62 | i_waypoints[idx][1] = idx > 0 ? i_waypoints[idx-1][1] : y; |
---|
63 | } |
---|
64 | unit.UpdateGroundPositionZ(i_waypoints[idx][0],i_waypoints[idx][1],z); |
---|
65 | i_waypoints[idx][2] = z; |
---|
66 | } |
---|
67 | |
---|
68 | unit.StopMoving(); |
---|
69 | unit.RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); |
---|
70 | unit.addUnitState(UNIT_STAT_CONFUSED); |
---|
71 | } |
---|
72 | |
---|
73 | template<> |
---|
74 | void |
---|
75 | ConfusedMovementGenerator<Creature>::_InitSpecific(Creature &creature, bool &is_water_ok, bool &is_land_ok) |
---|
76 | { |
---|
77 | is_water_ok = creature.canSwim(); |
---|
78 | is_land_ok = creature.canWalk(); |
---|
79 | } |
---|
80 | |
---|
81 | template<> |
---|
82 | void |
---|
83 | ConfusedMovementGenerator<Player>::_InitSpecific(Player &, bool &is_water_ok, bool &is_land_ok) |
---|
84 | { |
---|
85 | is_water_ok = true; |
---|
86 | is_land_ok = true; |
---|
87 | } |
---|
88 | |
---|
89 | template<class T> |
---|
90 | void |
---|
91 | ConfusedMovementGenerator<T>::Reset(T &unit) |
---|
92 | { |
---|
93 | i_nextMove = 1; |
---|
94 | i_nextMoveTime.Reset(0); |
---|
95 | i_destinationHolder.ResetUpdate(); |
---|
96 | unit.StopMoving(); |
---|
97 | } |
---|
98 | |
---|
99 | template<class T> |
---|
100 | bool |
---|
101 | ConfusedMovementGenerator<T>::Update(T &unit, const uint32 &diff) |
---|
102 | { |
---|
103 | if(!&unit) |
---|
104 | return true; |
---|
105 | |
---|
106 | if(unit.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED)) |
---|
107 | return true; |
---|
108 | |
---|
109 | if( i_nextMoveTime.Passed() ) |
---|
110 | { |
---|
111 | // currently moving, update location |
---|
112 | Traveller<T> traveller(unit); |
---|
113 | if( i_destinationHolder.UpdateTraveller(traveller, diff, false)) |
---|
114 | { |
---|
115 | if( i_destinationHolder.HasArrived()) |
---|
116 | { |
---|
117 | // arrived, stop and wait a bit |
---|
118 | unit.StopMoving(); |
---|
119 | |
---|
120 | i_nextMove = urand(1,MAX_CONF_WAYPOINTS); |
---|
121 | i_nextMoveTime.Reset(urand(0, 1500-1)); // TODO: check the minimum reset time, should be probably higher |
---|
122 | } |
---|
123 | } |
---|
124 | } |
---|
125 | else |
---|
126 | { |
---|
127 | // waiting for next move |
---|
128 | i_nextMoveTime.Update(diff); |
---|
129 | if( i_nextMoveTime.Passed() ) |
---|
130 | { |
---|
131 | // start moving |
---|
132 | assert( i_nextMove <= MAX_CONF_WAYPOINTS ); |
---|
133 | const float x = i_waypoints[i_nextMove][0]; |
---|
134 | const float y = i_waypoints[i_nextMove][1]; |
---|
135 | const float z = i_waypoints[i_nextMove][2]; |
---|
136 | Traveller<T> traveller(unit); |
---|
137 | i_destinationHolder.SetDestination(traveller, x, y, z); |
---|
138 | } |
---|
139 | } |
---|
140 | return true; |
---|
141 | } |
---|
142 | |
---|
143 | template<class T> |
---|
144 | void |
---|
145 | ConfusedMovementGenerator<T>::Finalize(T &unit) |
---|
146 | { |
---|
147 | unit.clearUnitState(UNIT_STAT_CONFUSED); |
---|
148 | } |
---|
149 | |
---|
150 | template void ConfusedMovementGenerator<Player>::Initialize(Player &player); |
---|
151 | template void ConfusedMovementGenerator<Creature>::Initialize(Creature &creature); |
---|
152 | template void ConfusedMovementGenerator<Player>::Finalize(Player &player); |
---|
153 | template void ConfusedMovementGenerator<Creature>::Finalize(Creature &creature); |
---|
154 | template void ConfusedMovementGenerator<Player>::Reset(Player &player); |
---|
155 | template void ConfusedMovementGenerator<Creature>::Reset(Creature &creature); |
---|
156 | template bool ConfusedMovementGenerator<Player>::Update(Player &player, const uint32 &diff); |
---|
157 | template bool ConfusedMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff); |
---|