// Ryzom - MMORPG Framework // Copyright (C) 2010 Winch Gate Property Limited // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as // published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . #include "stdpch.h" #include "property_decoder.h" #include "game_share/continuous_action.h" #include "game_share/action_position.h" using namespace std; using namespace NLMISC; using namespace CLFECOMMON; /* * Constructor */ CPropertyDecoder::CPropertyDecoder() { } void CPropertyDecoder::receive(TPacketNumber /* packetNumber */, CAction *action) { if (!action->isContinuous()) return; if (action->Code == ACTION_POSITION_CODE) { CActionPosition *act = (CActionPosition *)(action); /* CPropertyEntry &px = _Entities[act->Slot].Properties[PROPERTY_POSX]; CPropertyEntry &py = _Entities[act->Slot].Properties[PROPERTY_POSY]; CPropertyEntry &pz = _Entities[act->Slot].Properties[PROPERTY_POSZ]; */ #ifdef TEST_POSITION_CORRECTNESS //#pragma message ("TEST_POSITION_CORRECTNESS") TCoord posx = (TCoord)(act->Position[0]); TCoord posy = (TCoord)(act->Position[1]); #endif if ( act->IsRelative ) { // Relative position (entity in a ferry...) act->Position[0] = (sint32)act->Position16[0]; act->Position[1] = (sint32)act->Position16[1]; act->Position[2] = (sint32)act->Position16[2]; _Entities[act->Slot].PosIsRelative = true; _Entities[act->Slot].PosIsInterior = false; 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 ); } else { // Absolute position //nlinfo( "RefPos: %d %d %d RefBits: %hd %hd %hd", _RefPosX, _RefPosY, _RefPosZ, _RefBitsX, _RefBitsY, _RefBitsZ ); decodeAbsPos2D( act->Position[0], act->Position[1], act->Position16[0], act->Position16[1] ); act->Position[2] = ((sint32)((sint16)act->Position16[2])) << 4; if (act->Interior) act->Position[2] += 2; //act->Position[2] = _RefPosZ + (((sint32)((sint16)(act->Position16[2] - _RefBitsZ))) << 4); //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 ); _Entities[act->Slot].PosIsRelative = false; _Entities[act->Slot].PosIsInterior = act->Interior; //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 ); //nlinfo( " RefPos: %d %d %d, RefBits: %hu %hu %hu", _RefPosX, _RefPosY, _RefPosZ, _RefBitsX, _RefBitsY, _RefBitsZ ); } /* px.LastReceived = act->Position[0]; py.LastReceived = act->Position[1]; pz.LastReceived = act->Position[2]; //nldebug("CLPROPD: Received position (Id=%d) %d,%d (Pck=%d)", act->CLEntityId, act->Position[0], act->Position[1], packetNumber); */ #ifdef TEST_POSITION_CORRECTNESS //#pragma message ("TEST_POSITION_CORRECTNESS") if ( ! (act->IsRelative) ) { // Check if the compression algo for positions worked 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) ); 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) ); } nlinfo( "Receiving position %d %d %d m", posx/1000, posy/1000, (TCoord)act->Position[2]/1000 ); #endif } /* else { CContinuousAction *act = (CContinuousAction *)(action); CPropertyEntry &property = _Entities[act->Slot].Properties[act->Code]; property.LastReceived = act->getValue(); nldebug("CLPROPD: Received (Id=%d,Act=%d)=(%"NL_I64"d)(Pck=%d)", act->Slot, act->Code, property.LastReceived, packetNumber); } */ } void CPropertyDecoder::receive(TPacketNumber packetNumber, TPacketNumber /* ack */, vector &actions) { // 1- process ack //this->ack(packetNumber, ack); // 2- receive actions, decode them and store values uint i; for (i=0; i> 4)&0xffff); _RefBitsY = (uint16)((_RefPosY >> 4)&0xffff); //_RefBitsZ = (uint16)(_RefPosZ >> 4); } // /* const CAction::TValue &CPropertyDecoder::getProperty(TCLEntityId entity, TProperty property) const { nlassert(entity < _Entities.size() && _Entities[entity].EntryUsed); return _Entities[entity].Properties[property].LastReceived; } void CPropertyDecoder::getPosition(TCLEntityId entity, CAction::TValue &posx, CAction::TValue &posy, CAction::TValue &posz) const { nlassert(entity < _Entities.size() && _Entities[entity].EntryUsed); const CEntityEntry &entry = _Entities[entity]; posx = entry.Properties[PROPERTY_POSX].LastReceived; posy = entry.Properties[PROPERTY_POSY].LastReceived; posz = entry.Properties[PROPERTY_POSZ].LastReceived; } */ // void CPropertyDecoder::clear() { uint sz = (uint)_Entities.size(); _Entities.clear(); _Entities.resize(sz); } void CPropertyDecoder::setMaximumEntities(uint maximum) { _Entities.resize(maximum); } void CPropertyDecoder::addEntity(TCLEntityId entity, TSheetId sheet) { nlassert(entity < _Entities.size() && !_Entities[entity].EntryUsed); _Entities[entity].EntryUsed = true; _Entities[entity].Sheet = sheet; /* uint i; for (i=0; i<=LAST_CONTINUOUS_PROPERTY; ++i) _Entities[entity].Properties[i].init(); */ } bool CPropertyDecoder::removeEntity(TCLEntityId entity) { nlassertex(entity < _Entities.size(), ("entity=%hu size=%u", (uint16)entity,_Entities.size()) ); //Workaround: assert converted to test when failure in vision from the server if ( _Entities[entity].EntryUsed ) { _Entities[entity].EntryUsed = false; _Entities[entity].Sheet = 0xffff; } return true; }