Resolve "Toggle Free Look with Hotkey"
[ryzomcore.git] / ryzom / client / src / property_decoder.cpp
blobf0d2358a0e583779ccb292c8188cb15fa2a394c5
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2016 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
6 //
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/>.
22 #include "stdpch.h"
26 #include "property_decoder.h"
27 #include "game_share/continuous_action.h"
28 #include "game_share/action_position.h"
30 using namespace std;
31 using namespace NLMISC;
32 using namespace CLFECOMMON;
35 * Constructor
37 CPropertyDecoder::CPropertyDecoder()
42 void CPropertyDecoder::receive(TPacketNumber /* packetNumber */, CAction *action)
44 if (!action->isContinuous())
45 return;
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]);
59 #endif
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 );
71 else
73 // Absolute position
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;
77 if (act->Interior)
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 );
101 #endif
105 else
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)
121 // 1- process ack
123 //this->ack(packetNumber, ack);
126 // 2- receive actions, decode them and store values
128 uint i;
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();
173 _Entities.clear();
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;
189 uint i;
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;
206 return true;