void GameBase::processTick(const Move * move) { #ifdef TORQUE_DEBUG_NET_MOVES if (!move) mTicksSinceLastMove++; const char * srv = isClientObject() ? "client" : "server"; const char * who = ""; if (isClientObject()) { if (this == (GameBase*)GameConnection::getConnectionToServer()->getControlObject()) who = " player"; else who = " ghost"; if (mIsAiControlled) who = " ai"; } if (isServerObject()) { if (dynamic_cast<AIConnection*>(getControllingClient())) { who = " ai"; mIsAiControlled = true; } else if (getControllingClient()) { who = " player"; mIsAiControlled = false; } else { who = ""; mIsAiControlled = false; } } U32 moveid = mLastMoveId+mTicksSinceLastMove; if (move) moveid = move->id; if (getTypeMask() & GameBaseHiFiObjectType) { if (move) Con::printf("Processing (%s%s id %i) move %i",srv,who,getId(), move->id); else Con::printf("Processing (%s%s id %i) move %i (%i)",srv,who,getId(),mLastMoveId+mTicksSinceLastMove,mTicksSinceLastMove); } if (move) { mLastMoveId = move->id; mTicksSinceLastMove=0; } #endif }
U32 PathCamera::packUpdate(NetConnection *con, U32 mask, BitStream *stream) { Parent::packUpdate(con,mask,stream); if (stream->writeFlag(mask & StateMask)) stream->writeInt(mState,StateBits); if (stream->writeFlag(mask & PositionMask)) stream->write(mPosition); if (stream->writeFlag(mask & TargetMask)) if (stream->writeFlag(mTargetSet)) stream->write(mTarget); if (stream->writeFlag(mask & WindowMask)) { stream->write(mNodeBase); stream->write(mNodeCount); for (S32 i = 0; i < mNodeCount; i++) { CameraSpline::Knot *knot = mSpline.getKnot(i); mathWrite(*stream, knot->mPosition); mathWrite(*stream, knot->mRotation); stream->write(knot->mSpeed); stream->writeInt(knot->mType, CameraSpline::Knot::NUM_TYPE_BITS); stream->writeInt(knot->mPath, CameraSpline::Knot::NUM_PATH_BITS); } } // The rest of the data is part of the control object packet update. // If we're controlled by this client, we don't need to send it. if(stream->writeFlag(getControllingClient() == con && !(mask & InitialUpdateMask))) return 0; return 0; }
void AIPlayer::updateMove(const Move* move) { if (!getControllingClient() && isGhost()) return; Parent::updateMove(move); }
U32 TurretShape::packUpdate(NetConnection *connection, U32 mask, BitStream *stream) { // Handle rotation ourselves (so it is not locked to the Z axis like for Items) U32 retMask = Parent::packUpdate( connection, mask & (~Item::RotationMask), stream ); if (stream->writeFlag(mask & InitialUpdateMask)) { stream->writeFlag(mRespawn); } if ( stream->writeFlag( mask & Item::RotationMask ) ) { QuatF rot( mObjToWorld ); mathWrite( *stream, rot ); } // The rest of the data is part of the control object packet update. // If we're controlled by this client, we don't need to send it. if(stream->writeFlag((NetConnection*)getControllingClient() == connection && !(mask & InitialUpdateMask))) return 0; if (stream->writeFlag(mask & TurretUpdateMask)) { stream->write(mRot.x); stream->write(mRot.z); stream->write(allowManualRotation); stream->write(allowManualFire); } return retMask; }
U32 FlyingVehicle::packUpdate(NetConnection *con, U32 mask, BitStream *stream) { U32 retMask = Parent::packUpdate(con, mask, stream); // The rest of the data is part of the control object packet update. // If we're controlled by this client, we don't need to send it. if(stream->writeFlag(getControllingClient() == con && !(mask & InitialUpdateMask))) return retMask; stream->writeFlag(createHeightOn); stream->writeInt(mThrustDirection,NumThrustBits); return retMask; }
U32 RigidBody::packUpdate(NetConnection *con, U32 mask, BitStream *stream) { U32 retMask = Parent::packUpdate(con, mask, stream); bool hasServerPhysics = !Physics::getPhysics(false) && con->isLocalConnection(); //set hasServerPhysic flag if ((mask&InitialUpdateMask)) { if (!hasServerPhysics && mDataBlock->mOnlyOnClient) { setScopeAlways(); } } //special cases: if (stream->writeFlag((mask&InitialUpdateMask) && (hasServerPhysics || mDataBlock->mOnlyOnClient))) { if (stream->writeFlag(hasServerPhysics)) { PhysShape* shape = mPhysShape; stream->writeBits(8*sizeof(shape),&shape); } else { mathWrite(*stream,getTransform()); } } if (stream->writeFlag(getControllingClient() == con && !(mask & InitialUpdateMask))) { return retMask; } if (!hasServerPhysics && !mDataBlock->mOnlyOnClient && stream->writeFlag(mask & PositionMask)) { /* VectorF linVel = mPhysShape->getLinVelocity(); VectorF force = mPhysShape->getForce(); Con::printf("Pack vel: %f %f %f momentum: %f %f %f ",linVel.x,linVel.y,linVel.z, force.x, force.y, force.z);*/ mPhysShape->pack(stream); } return retMask; }
void TurretShape::unmountObject( SceneObject *obj ) { Parent::unmountObject(obj); if (isClientObject()) { if (obj) { GameConnection* conn = obj->getControllingClient(); if (conn) { // Allow the client to set up any action maps, HUD, etc. Con::executef("turretMountCallback", Con::getIntArg(getId()), Con::getIntArg(obj->getId()), Con::getIntArg(false)); } } } else { mDataBlock->onUnmountObject_callback( this, obj ); } }
U32 Etherform::packUpdate(NetConnection *con, U32 mask, BitStream *bstream) { Parent::packUpdate(con,mask,bstream); // The rest of the data is part of the control object packet update. // If we're controlled by this client, we don't need to send it. if(bstream->writeFlag(getControllingClient() == con && !(mask & InitialUpdateMask))) return 0; if (bstream->writeFlag(mask & MoveMask)) { Point3F pos; mObjToWorld.getColumn(3,&pos); bstream->write(pos.x); bstream->write(pos.y); bstream->write(pos.z); bstream->write(mRot.x); bstream->write(mRot.z); F32 len = mVelocity.len(); if(bstream->writeFlag(len > 0.02f)) { Point3F outVel = mVelocity; outVel *= 1.0f/len; bstream->writeNormalVector(outVel, 10); len *= 32.0f; // 5 bits of fraction if(len > 8191) len = 8191; bstream->writeInt((S32)len, 13); } delta.move.pack(bstream); bstream->writeFlag(!(mask & NoWarpMask)); } return 0; }
void AIPlayer::setAiPose( S32 pose ) { if (!getControllingClient() && isGhost()) return; mAiPose = pose; }
void Etherform::processTick(const Move* move) { Parent::processTick(move); // Warp to catch up to server? if(delta.warpTicks > 0) { delta.warpTicks--; // Set new pos. getTransform().getColumn(3,&delta.pos); delta.pos += delta.warpOffset; delta.rot += delta.rotOffset; this->setPosition(delta.pos,delta.rot); this->setRenderPosition(delta.pos,delta.rot); // Backstepping delta.posVec.x = -delta.warpOffset.x; delta.posVec.y = -delta.warpOffset.y; delta.posVec.z = -delta.warpOffset.z; delta.rotVec.x = -delta.rotOffset.x; delta.rotVec.y = -delta.rotOffset.y; delta.rotVec.z = -delta.rotOffset.z; } else { // If there is no move, the we're either an // unattached etherform on the server, or another etherform's // client ghost. if(!move) { if(isGhost()) { // If we haven't run out of prediction time, // predict using the last known move. if (mPredictionCount-- <= 0) return; move = &delta.move; } else move = &NullMove; } if(isServerObject() || (didRenderLastRender() || getControllingClient())) { delta.move = *move; if(isMounted()) { // If we're mounted then do not perform any collision checks // and clear our previous working list. mConvex.clearWorkingList(); } else { this->updateWorkingCollisionSet(); } this->updateVelocity(move); VectorF contactNormal(0,0,0); this->findContact(&contactNormal ); this->updatePos(); } } // Add node to lasertrails. if(this->isClientObject()) { GameConnection* conn = GameConnection::getConnectionToServer(); if(conn && this == conn->getControlObject()) { if(move->sendCount == 0) this->addLaserTrailNode(this->getPosition()); } else this->addLaserTrailNode(this->getPosition()); } }