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