1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
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 Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include "nel/misc/common.h"
21 #include "game_share/utils.h"
23 #include "move_checker.h"
26 /****************************************************************\
27 Static Stats Stuff (temp)
28 \****************************************************************/
33 std::vector
<uint32
> _Distances
;
44 _Distances
.resize(50);
51 _MaxDistTime
=(uint32
)_Distances
.size()/2;
54 void start(TDataSetRow entityIndex
, sint32 x
, sint32 y
, uint32 tick
)
56 std::fill(_Distances
.begin(),_Distances
.end(),0);
63 _MaxDistTime
=(uint32
)_Distances
.size()/2;
66 void add(TDataSetRow entityIndex
, sint32 x
, sint32 y
, uint32 tick
)
68 // if we've just teleported then there's no point worrying about the time since last update...
71 // flag teleporting as finished
76 // check whether entity has been updated recently
77 // if((tick-_LastTick)!=1)
79 // nlwarning("Move Checker Stats: entity %s has only received position update after %d ticks",entityIndex.toString().c_str(),tick-_LastTick);
83 // calculate the distance moved and check whether its a new record
84 uint32 squaredist
= (_X
-x
)*(_X
-x
) + (_Y
-y
)*(_Y
-y
);
85 if (squaredist
>_MaxDist
)
88 _MaxDistTime
= std::max((uint32
)_Counter
,(uint32
)_Distances
.size()/2);
90 _Distances
[_Counter
%_Distances
.size()]= squaredist
;
92 // store away basic info for next time round
97 // increment our counter...
100 // if we've hit a new record recently then display a log message
101 if ( (_Counter
-_MaxDistTime
) == (_Distances
.size()/2) )
104 for (uint32 i
=(uint32
)_Distances
.size();i
!=0;--i
)
106 s
+=NLMISC::toString(" %d",_Distances
[(_Counter
-i
)%_Distances
.size()]);
108 nlinfo("SpeedStats record for %s: %d (%.2f m/s): %s",entityIndex
.toString().c_str(),_MaxDist
,sqrt((double)_MaxDist
)/200,s
.c_str());
113 typedef std::map
<TDataSetRow
,CStatsRecord
> TStats
;
116 static void startStats(TDataSetRow entityIndex
, sint32 x
, sint32 y
, uint32 tick
)
118 Stats
[entityIndex
].start(entityIndex
,x
,y
,tick
);
121 static void addStats(TDataSetRow entityIndex
, sint32 x
, sint32 y
, uint32 tick
)
123 Stats
[entityIndex
].add(entityIndex
,x
,y
,tick
);
126 static void endStats(TDataSetRow entityIndex
)
128 Stats
.erase(entityIndex
);
132 /****************************************************************\
134 \****************************************************************/
136 void CMoveChecker::teleport(TDataSetRow entityIndex
, sint32 x
, sint32 y
, uint32 tick
)
138 // get hold of the entity's record in the move checker (and creat a new entry if need be)
139 SPosition
& thePosition
= _Positions
[entityIndex
];
141 nlinfo("Move checker teleporting player: %s from (%d,%d) @tick: %d to (%d,%d) @tick: %d",
142 entityIndex
.toString().c_str(),thePosition
.X
,thePosition
.Y
,thePosition
.Tick
,x
,y
,tick
);
144 // record the new position
147 thePosition
.Tick
= tick
;
149 // generate a few stats
150 startStats(entityIndex
,x
,y
,tick
);
153 bool CMoveChecker::checkMove(TDataSetRow entityIndex
, sint32
& x
, sint32
& y
, uint32 tick
)
155 // setup a refference to the entity's position record, and bomb if it can't be found
156 TPositions::iterator positionIt
= _Positions
.find(entityIndex
);
157 BOMB_IF(positionIt
==_Positions
.end(),"Ignoring call to 'checkMove' for an entity who doesn't exist in the move checker",return false);
158 SPosition
& thePosition
= positionIt
->second
;
160 // if the character hasn't moved then just return
161 if ( (x
==thePosition
.X
) && (y
==thePosition
.Y
) )
166 // nlinfo("Checking player move: %s from (%d,%d) @tick: %d to (%d,%d) @tick: %d",
167 // entityIndex.toString().c_str(),thePosition.X,thePosition.Y,thePosition.Tick,x,y,tick);
169 // if the tick value is out of order (for instance, after an advanced tp request) then ignore the move
170 DROP_IF(sint32(tick
-thePosition
.Tick
)<0,"Ignoring out of order move for character "+entityIndex
.toString(),return false);
172 // *** todo: perform a speed test here
173 // *** todo: perform collision test here
174 // *** NOTE: If move not legal then we need to change values of x and y and return false
176 // record the new position
179 thePosition
.Tick
= tick
;
181 // generate a few stats
182 addStats(entityIndex
,x
,y
,tick
);
187 void CMoveChecker::remove(TDataSetRow entityIndex
)
189 // remove the entity from our positions map
190 _Positions
.erase(entityIndex
);
192 // generate a few stats
193 endStats(entityIndex
);