stdMoveList.cpp
Engine/source/T3D/gameBase/std/stdMoveList.cpp
Public Defines
define
Detailed Description
Public Defines
MAX_MOVE_PACKET_SENDS() 4
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#include "platform/platform.h" 25#include "T3D/gameBase/std/stdMoveList.h" 26 27#include "T3D/gameBase/gameConnection.h" 28#include "core/stream/bitStream.h" 29 30#define MAX_MOVE_PACKET_SENDS 4 31 32 33StdMoveList::StdMoveList() 34{ 35 mMoveCredit = MaxMoveCount; 36} 37 38U32 StdMoveList::getMoves(Move** movePtr,U32* numMoves) 39{ 40 if (!mConnection->isConnectionToServer()) 41 { 42 if (mMoveVec.size() > mMoveCredit) 43 mMoveVec.setSize(mMoveCredit); 44 } 45 return Parent::getMoves(movePtr,numMoves); 46} 47 48void StdMoveList::clearMoves(U32 count) 49{ 50 if (!mConnection->isConnectionToServer()) 51 { 52 count = mClamp(count,0,mMoveCredit); 53 mMoveCredit -= count; 54 } 55 56 Parent::clearMoves(count); 57} 58 59void StdMoveList::advanceMove() 60{ 61 AssertFatal(!mConnection->isConnectionToServer(), "Cannot inc move credit on the client."); 62 63 // Game tick increment 64 mMoveCredit++; 65 if (mMoveCredit > MaxMoveCount) 66 mMoveCredit = MaxMoveCount; 67 68 // Clear pending moves for the elapsed time if there 69 // is no control object. 70 if ( mConnection->getControlObject() == NULL ) 71 mMoveVec.clear(); 72} 73 74void StdMoveList::clientWriteMovePacket(BitStream *bstream) 75{ 76 AssertFatal(mLastMoveAck == mFirstMoveIndex, "Invalid move index."); 77 U32 count = mMoveVec.size(); 78 79 Move * move = mMoveVec.address(); 80 U32 start = mLastMoveAck; 81 U32 offset; 82 for(offset = 0; offset < count; offset++) 83 if(move[offset].sendCount < MAX_MOVE_PACKET_SENDS) 84 break; 85 if(offset == count && count != 0) 86 offset--; 87 88 start += offset; 89 count -= offset; 90 91 if (count > MaxMoveCount) 92 count = MaxMoveCount; 93 bstream->writeInt(start,32); 94 bstream->writeInt(count,MoveCountBits); 95 Move * prevMove = NULL; 96 for (S32 i = 0; i < count; i++) 97 { 98 move[offset + i].sendCount++; 99 move[offset + i].pack(bstream,prevMove); 100 bstream->writeInt(move[offset + i].checksum & (~(0xFFFFFFFF << Move::ChecksumBits)),Move::ChecksumBits); 101 prevMove = &move[offset+i]; 102 } 103} 104 105void StdMoveList::serverReadMovePacket(BitStream *bstream) 106{ 107 // Server side packet read. 108 U32 start = bstream->readInt(32); 109 U32 count = bstream->readInt(MoveCountBits); 110 111 Move * prevMove = NULL; 112 Move prevMoveHolder; 113 114 // Skip forward (must be starting up), or over the moves 115 // we already have. 116 S32 skip = mLastMoveAck - start; 117 if (skip < 0) 118 { 119 mLastMoveAck = start; 120 } 121 else 122 { 123 if (skip > count) 124 skip = count; 125 for (S32 i = 0; i < skip; i++) 126 { 127 prevMoveHolder.unpack(bstream,prevMove); 128 prevMoveHolder.checksum = bstream->readInt(Move::ChecksumBits); 129 prevMove = &prevMoveHolder; 130 S32 idx = mMoveVec.size()-skip+i; 131 if (idx>=0) 132 { 133#ifdef TORQUE_DEBUG_NET_MOVES 134 if (mMoveVec[idx].checksum != prevMoveHolder.checksum) 135 Con::printf("updated checksum on move %i from %i to %i",mMoveVec[idx].id,mMoveVec[idx].checksum,prevMoveHolder.checksum); 136#endif 137 mMoveVec[idx].checksum = prevMoveHolder.checksum; 138 } 139 } 140 start += skip; 141 count = count - skip; 142 } 143 144 // Put the rest on the move list. 145 S32 index = mMoveVec.size(); 146 mMoveVec.increment(count); 147 while (index < mMoveVec.size()) 148 { 149 mMoveVec[index].unpack(bstream,prevMove); 150 mMoveVec[index].checksum = bstream->readInt(Move::ChecksumBits); 151 prevMove = &mMoveVec[index]; 152 mMoveVec[index].id = start++; 153 index ++; 154 } 155 156 mLastMoveAck += count; 157} 158 159void StdMoveList::serverWriteMovePacket(BitStream * bstream) 160{ 161#ifdef TORQUE_DEBUG_NET_MOVES 162 Con::printf("ack %i minus %i",mLastMoveAck,mMoveVec.size()); 163#endif 164 165 // acknowledge only those moves that have been ticked 166 bstream->writeInt(mLastMoveAck - mMoveVec.size(),32); 167} 168 169void StdMoveList::clientReadMovePacket(BitStream * bstream) 170{ 171#ifdef TORQUE_DEBUG_NET_MOVES 172 Con::printf("pre move ack: %i", mLastMoveAck); 173#endif 174 175 mLastMoveAck = bstream->readInt(32); 176 177#ifdef TORQUE_DEBUG_NET_MOVES 178 Con::printf("post move ack %i, first move %i, last move %i", mLastMoveAck, mFirstMoveIndex, mLastClientMove); 179#endif 180 181 if (mLastMoveAck < mFirstMoveIndex) 182 mLastMoveAck = mFirstMoveIndex; 183 184 if(mLastMoveAck > mLastClientMove) 185 mLastClientMove = mLastMoveAck; 186 while(mFirstMoveIndex < mLastMoveAck) 187 { 188 if (mMoveVec.size()) 189 { 190 mMoveVec.pop_front(); 191 mFirstMoveIndex++; 192 } 193 else 194 { 195 AssertWarn(1, "Popping off too many moves!"); 196 mFirstMoveIndex = mLastMoveAck; 197 } 198 } 199} 200