1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2016 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
26 #include "property_decoder.h"
27 #include "game_share/continuous_action.h"
28 #include "game_share/action_position.h"
31 using namespace NLMISC
;
32 using namespace CLFECOMMON
;
37 CPropertyDecoder::CPropertyDecoder()
42 void CPropertyDecoder::receive(TPacketNumber
/* packetNumber */, CAction
*action
)
44 if (!action
->isContinuous())
47 if (action
->Code
== ACTION_POSITION_CODE
)
49 CActionPosition
*act
= (CActionPosition
*)(action
);
51 CPropertyEntry &px = _Entities[act->Slot].Properties[PROPERTY_POSX];
52 CPropertyEntry &py = _Entities[act->Slot].Properties[PROPERTY_POSY];
53 CPropertyEntry &pz = _Entities[act->Slot].Properties[PROPERTY_POSZ];
55 #ifdef TEST_POSITION_CORRECTNESS
56 //#pragma message ("TEST_POSITION_CORRECTNESS")
57 TCoord posx
= (TCoord
)(act
->Position
[0]);
58 TCoord posy
= (TCoord
)(act
->Position
[1]);
61 if ( act
->IsRelative
)
63 // Relative position (entity in a ferry...)
64 act
->Position
[0] = (sint32
)act
->Position16
[0];
65 act
->Position
[1] = (sint32
)act
->Position16
[1];
66 act
->Position
[2] = (sint32
)act
->Position16
[2];
67 _Entities
[act
->Slot
].PosIsRelative
= true;
68 _Entities
[act
->Slot
].PosIsInterior
= false;
69 nlinfo( "Relative Pos: %d %d %d, Pos16: %hd %hd %hd, Date %u", (sint32
)act
->Position
[0], (sint32
)act
->Position
[1], (sint32
)act
->Position
[2], act
->Position16
[0], act
->Position16
[1], act
->Position16
[2], act
->GameCycle
);
74 //nlinfo( "RefPos: %d %d %d RefBits: %hd %hd %hd", _RefPosX, _RefPosY, _RefPosZ, _RefBitsX, _RefBitsY, _RefBitsZ );
75 decodeAbsPos2D( act
->Position
[0], act
->Position
[1], act
->Position16
[0], act
->Position16
[1] );
76 act
->Position
[2] = ((sint32
)((sint16
)act
->Position16
[2])) << 4;
78 act
->Position
[2] += 2;
79 //act->Position[2] = _RefPosZ + (((sint32)((sint16)(act->Position16[2] - _RefBitsZ))) << 4);
80 //nlinfo( "Pos16: %hd %hd %hd => Pos: %d %d %d", act->Position16[0], act->Position16[1], act->Position16[2], (sint32)px.LastReceived, (sint32)py.LastReceived, (sint32)pz.LastReceived );
81 _Entities
[act
->Slot
].PosIsRelative
= false;
82 _Entities
[act
->Slot
].PosIsInterior
= act
->Interior
;
83 //nlinfo( "Slot %hu: Absolute, Pos: %d %d %d, Pos16: %hu %hu %hu, Date %u", (uint16)act->CLEntityId, (sint32)act->Position[0], (sint32)act->Position[1], (sint32)act->Position[2], act->Position16[0], act->Position16[1], act->Position16[2], act->GameCycle );
84 //nlinfo( " RefPos: %d %d %d, RefBits: %hu %hu %hu", _RefPosX, _RefPosY, _RefPosZ, _RefBitsX, _RefBitsY, _RefBitsZ );
87 px.LastReceived = act->Position[0];
88 py.LastReceived = act->Position[1];
89 pz.LastReceived = act->Position[2];
90 //nldebug("CLPROPD: Received position (Id=%d) %d,%d (Pck=%d)", act->CLEntityId, act->Position[0], act->Position[1], packetNumber);
92 #ifdef TEST_POSITION_CORRECTNESS
93 //#pragma message ("TEST_POSITION_CORRECTNESS")
94 if ( ! (act
->IsRelative
) )
96 // Check if the compression algo for positions worked
97 nlassertex( abs(posx
- (TCoord
)act
->Position
[0]) < 2000, ("Computed posX: %d Real posX: %d PosX16: %hu RefPosX: %d RefBitsX: %hu", (TCoord
)(act
->Position
[0]), posx
, act
->Position16
[0], _RefPosX
, _RefBitsX
) );
98 nlassertex( abs(posy
- (TCoord
)act
->Position
[1]) < 2000, ("Computed posY: %d Real posY: %d PosY16: %hu RefPosY: %d RefBitsY: %hu", (TCoord
)(act
->Position
[1]), posy
, act
->Position16
[1], _RefPosY
, _RefBitsY
) );
100 nlinfo( "Receiving position %d %d %d m", posx
/1000, posy
/1000, (TCoord
)act
->Position
[2]/1000 );
107 CContinuousAction *act = (CContinuousAction *)(action);
109 CPropertyEntry &property = _Entities[act->Slot].Properties[act->Code];
111 property.LastReceived = act->getValue();
113 nldebug("CLPROPD: Received (Id=%d,Act=%d)=(%" NL_I64 "d)(Pck=%d)", act->Slot, act->Code, property.LastReceived, packetNumber);
119 void CPropertyDecoder::receive(TPacketNumber packetNumber
, TPacketNumber
/* ack */, vector
<CAction
*> &actions
)
123 //this->ack(packetNumber, ack);
126 // 2- receive actions, decode them and store values
129 for (i
=0; i
<actions
.size(); ++i
)
131 receive(packetNumber
, actions
[i
]);
138 void CPropertyDecoder::setReferencePosition(const NLMISC::CVectorD
&position
)
140 _RefPosX
= (sint32
)(position
.x
* 1000.0) & ~0xf; // correction here by Sadge: clear low-order to prevent flickering depending on player's reference position
141 _RefPosY
= (sint32
)(position
.y
* 1000.0) & ~0xf; // correction here by Sadge
142 //_RefPosZ = (sint32)(position.z * 1000.0);
144 _RefBitsX
= (uint16
)((_RefPosX
>> 4)&0xffff);
145 _RefBitsY
= (uint16
)((_RefPosY
>> 4)&0xffff);
146 //_RefBitsZ = (uint16)(_RefPosZ >> 4);
152 const CAction::TValue &CPropertyDecoder::getProperty(TCLEntityId entity, TProperty property) const
154 nlassert(entity < _Entities.size() && _Entities[entity].EntryUsed);
156 return _Entities[entity].Properties[property].LastReceived;
159 void CPropertyDecoder::getPosition(TCLEntityId entity, CAction::TValue &posx, CAction::TValue &posy, CAction::TValue &posz) const
161 nlassert(entity < _Entities.size() && _Entities[entity].EntryUsed);
162 const CEntityEntry &entry = _Entities[entity];
163 posx = entry.Properties[PROPERTY_POSX].LastReceived;
164 posy = entry.Properties[PROPERTY_POSY].LastReceived;
165 posz = entry.Properties[PROPERTY_POSZ].LastReceived;
170 void CPropertyDecoder::clear()
172 uint sz
= (uint
)_Entities
.size();
174 _Entities
.resize(sz
);
177 void CPropertyDecoder::setMaximumEntities(uint maximum
)
179 _Entities
.resize(maximum
);
182 void CPropertyDecoder::addEntity(TCLEntityId entity
, TSheetId sheet
)
184 nlassert(entity
< _Entities
.size() && !_Entities
[entity
].EntryUsed
);
186 _Entities
[entity
].EntryUsed
= true;
187 _Entities
[entity
].Sheet
= sheet
;
190 for (i=0; i<=LAST_CONTINUOUS_PROPERTY; ++i)
191 _Entities[entity].Properties[i].init();
195 bool CPropertyDecoder::removeEntity(TCLEntityId entity
)
197 nlassertex(entity
< _Entities
.size(), ("entity=%hu size=%u", (uint16
)entity
,_Entities
.size()) );
199 //Workaround: assert converted to test when failure in vision from the server
200 if ( _Entities
[entity
].EntryUsed
)
202 _Entities
[entity
].EntryUsed
= false;
203 _Entities
[entity
].Sheet
= 0xffff;