void StdServerProcessList::onPreTickObject( ProcessObject *pobj ) { if ( pobj->mIsGameObject ) { SimObjectPtr<GameObject> obj = getGameObject( pobj ); // Each object is either advanced a single tick, or if it's // being controlled by a client, ticked once for each pending move. GameConnection *con = obj->getControllingClient(); if ( con && con->getControlObject() == obj ) { Move* movePtr; U32 numMoves; con->mMoveList->getMoves( &movePtr, &numMoves ); if ( numMoves == 0 ) { #ifdef TORQUE_DEBUG_NET_MOVES Con::printf("no moves on object %i, skip tick",obj->getId()); #endif return; } } } Parent::onPreTickObject (pobj ); }
//---------------------------------------------------------------------------- void StdClientProcessList::onAdvanceObjects() { PROFILE_SCOPE( StdClientProcessList_OnAdvanceObjects ); GameConnection* connection = GameConnection::getServerConnection(); if ( connection ) { // process any demo blocks that are NOT moves, and exactly one move // we advance time in the demo stream by a move inserted on // each tick. So before doing the tick processing we advance // the demo stream until a move is ready if ( connection->isPlayingBack() ) { U32 blockType; do { blockType = connection->getNextBlockType(); bool res = connection->processNextBlock(); // if there are no more blocks, exit out of this function, // as no more client time needs to process right now - we'll // get it all on the next advanceClientTime() if(!res) return; } while ( blockType != GameConnection::BlockTypeMove ); } connection->mMoveList->collectMove(); advanceObjects(); } else advanceObjects(); }
void SimDataBlockEvent::pack(NetConnection *conn, BitStream *bstream) { #ifdef AFX_CAP_DATABLOCK_CACHE // AFX CODE BLOCK (db-cache) << ((GameConnection *)conn)->tempDisableStringBuffering(bstream); #endif // AFX CODE BLOCK (db-cache) >> SimDataBlock* obj; Sim::findObject(id,obj); GameConnection *gc = (GameConnection *) conn; if(bstream->writeFlag(gc->getDataBlockModifiedKey() < obj->getModifiedKey())) { if(obj->getModifiedKey() > gc->getMaxDataBlockModifiedKey()) gc->setMaxDataBlockModifiedKey(obj->getModifiedKey()); AssertFatal(obj, "SimDataBlockEvent:: Data blocks cannot be deleted"); bstream->writeInt(id - DataBlockObjectIdFirst,DataBlockObjectIdBitSize); S32 classId = obj->getClassId(conn->getNetClassGroup()); bstream->writeClassId(classId, NetClassTypeDataBlock, conn->getNetClassGroup()); bstream->writeInt(mIndex, DataBlockObjectIdBitSize); bstream->writeInt(mTotal, DataBlockObjectIdBitSize + 1); obj->packData(bstream); #ifdef TORQUE_DEBUG_NET bstream->writeInt(classId ^ DebugChecksum, 32); #endif } #ifdef AFX_CAP_DATABLOCK_CACHE // AFX CODE BLOCK (db-cache) << ((GameConnection *)conn)->restoreStringBuffering(bstream); #endif // AFX CODE BLOCK (db-cache) >> }
void HifiClientProcessList::advanceObjects() { #ifdef TORQUE_DEBUG_NET_MOVES Con::printf("Advance client time..."); #endif // client re-computes this each time objects are advanced gMaxHiFiVelSq = 0; Parent::advanceObjects(); // We need to consume a move on the connections whether // there is a control object to consume the move or not, // otherwise client and server can get out of sync move-wise // during startup. If there is a control object, we cleared // a move above. Handle case where no control object here. // Note that we might consume an extra move here and there when // we had a control object in above loop but lost it during tick. // That is no big deal so we don't bother trying to carefully // track it. GameConnection * client = GameConnection::getConnectionToServer(); if (client && client->getControlObject() == NULL) client->mMoveList->clearMoves(1); #ifdef TORQUE_DEBUG_NET_MOVES Con::printf("---------"); #endif }
void CTFGameType::shipTouchFlag(Ship *theShip, FlagItem *theFlag) { GameConnection *controlConnection = theShip->getControllingClient(); ClientRef *cl = controlConnection->getClientRef(); if(!cl) return; if(cl->teamId == theFlag->getTeam()) { if(!theFlag->isAtHome()) { static StringTableEntry returnString("%e0 returned the %e1 flag."); Vector<StringTableEntry> e; e.push_back(cl->name); e.push_back(mTeams[theFlag->getTeam()].name); for(S32 i = 0; i < mClientList.size(); i++) mClientList[i]->clientConnection->s2cDisplayMessageE(GameConnection::ColorNuclearGreen, SFXFlagReturn, returnString, e); theFlag->sendHome(); cl->score += ReturnScore; } else { // check if this client has an enemy flag mounted for(S32 i = 0; i < theShip->mMountedItems.size(); i++) { Item *theItem = theShip->mMountedItems[i]; FlagItem *mountedFlag = dynamic_cast<FlagItem *>(theItem); if(mountedFlag) { setTeamScore(cl->teamId, mTeams[cl->teamId].score + 1); static StringTableEntry capString("%e0 captured the %e1 flag!"); Vector<StringTableEntry> e; e.push_back(cl->name); e.push_back(mTeams[mountedFlag->getTeam()].name); for(S32 i = 0; i < mClientList.size(); i++) mClientList[i]->clientConnection->s2cDisplayMessageE(GameConnection::ColorNuclearGreen, SFXFlagCapture, capString, e); // score the flag for the client's team... mountedFlag->dismount(); mountedFlag->sendHome(); cl->score += CapScore; } } } } else { static StringTableEntry takeString("%e0 took the %e1 flag!"); Vector<StringTableEntry> e; e.push_back(cl->name); e.push_back(mTeams[theFlag->getTeam()].name); for(S32 i = 0; i < mClientList.size(); i++) mClientList[i]->clientConnection->s2cDisplayMessageE(GameConnection::ColorNuclearGreen, SFXFlagSnatch, takeString, e); theFlag->mountToShip(theShip); } }
void PlayerMenuUserInterface::processSelection(U32 index) { StringTableEntry e(menuItems[index].mText); GameConnection *gc = gClientGame->getConnectionToServer(); if(gc) gc->c2sAdminPlayerAction(e, action); gGameUserInterface.activate(); }
static GameBase * getControlObj() { GameConnection * connection = GameConnection::getLocalClientConnection(); ShapeBase* control = 0; if(connection) control = dynamic_cast<ShapeBase*>(connection->getControlObject()); return(control); }
void GameTSCtrl::onRender(Point2I offset, const RectI &updateRect) { // check if should bother with a render GameConnection * con = GameConnection::getConnectionToServer(); bool skipRender = !con || (con->getWhiteOut() >= 1.f) || (con->getDamageFlash() >= 1.f) || (con->getBlackOut() >= 1.f); if(!skipRender || true) Parent::onRender(offset, updateRect); }
void GamePool::initialize(EventLoop* loop) { pLoop = loop; for (int i = 0; i < 1;i++) { GameConnection* gConn = new GameConnection(pLoop); gConn->setConnectHandler(EV_CB(this,GamePool::onConnected)); gConn->setCloseHandler(EV_CB(this, GamePool::onClose)); } }
void LightManager::registerGlobalLights( const Frustum *frustum, bool staticLighting ) { PROFILE_SCOPE( LightManager_RegisterGlobalLights ); // TODO: We need to work this out... // // 1. Why do we register and unregister lights on every // render when they don't often change... shouldn't we // just register once and keep them? // // 2. If we do culling of lights should this happen as part // of registration or somewhere else? // // Grab the lights to process. Vector<SceneObject*> activeLights; const U32 lightMask = LightObjectType; if ( staticLighting || !frustum ) { // We're processing static lighting or want all the lights // in the container registerd... so no culling. getSceneManager()->getContainer()->findObjectList( lightMask, &activeLights ); } else { // Cull the lights using the frustum. getSceneManager()->getContainer()->findObjectList( *frustum, lightMask, &activeLights ); // Store the culling position for sun placement // later... see setSpecialLight. mCullPos = frustum->getPosition(); // HACK: Make sure the control object always gets // processed as lights mounted to it don't change // the shape bounds and can often get culled. GameConnection *conn = GameConnection::getConnectionToServer(); if ( conn->getControlObject() ) { GameBase *conObject = conn->getControlObject(); activeLights.push_back_unique( conObject ); } } // Let the lights register themselves. for ( U32 i = 0; i < activeLights.size(); i++ ) { ISceneLight *lightInterface = dynamic_cast<ISceneLight*>( activeLights[i] ); if ( lightInterface ) lightInterface->submitLights( this, staticLighting ); } }
void GameTSCtrl::onRender(Point2I offset, const RectI &updateRect) { // check if should bother with a render GameConnection * con = GameConnection::getConnectionToServer(); bool skipRender = !con || (con->getWhiteOut() >= 1.f) || (con->getDamageFlash() >= 1.f) || (con->getBlackOut() >= 1.f); if(!skipRender || true) Parent::onRender(offset, updateRect); #ifdef TORQUE_DEMO_WATERMARK mWatermark.render(getExtent()); #endif }
void WaterObject::updateUnderwaterEffect( SceneRenderState *state ) { AssertFatal( isClientObject(), "uWaterObject::updateUnderwaterEffect() called on the server" ); PostEffect *effect = getUnderwaterEffect(); if ( !effect ) return; // Never use underwater postFx with Basic Lighting, we don't have depth. if ( mBasicLighting ) { effect->disable(); return; } GameConnection *conn = GameConnection::getConnectionToServer(); if ( !conn ) return; GameBase *control = conn->getControlObject(); if ( !control ) return; WaterObject *water = control->getCurrentWaterObject(); if ( water == NULL ) effect->disable(); else if ( water == this ) { MatrixF mat; conn->getControlCameraTransform( 0, &mat ); if ( mUnderwater ) { effect->enable(); effect->setOnThisFrame( true ); mWaterFogData.depthGradMax = mDepthGradientMax; state->getSceneManager()->setWaterFogData( mWaterFogData ); // Register our depthGradient texture with a name so it can // be fetched by the effect when it renders. if ( !mNamedDepthGradTex.isRegistered() ) mNamedDepthGradTex.registerWithName( "waterDepthGradMap" ); mNamedDepthGradTex.setTexture( mDepthGradientTex ); } else effect->disable(); } }
void ExtendedClientProcessList::onTickObject( ProcessObject *obj ) { PROFILE_SCOPE( ExtendedClientProcessList_OnTickObject ); // In case the object deletes itself during its processTick. SimObjectPtr<SceneObject> safePtr = static_cast<SceneObject*>( obj ); // Each object is either advanced a single tick, or if it's // being controlled by a client, ticked once for each pending move. ExtendedMove* extMovePtr; U32 numMoves; GameConnection* con = obj->getControllingClient(); if ( con && con->getControlObject() == obj ) { ExtendedMoveList* extMoveList = static_cast<ExtendedMoveList*>(con->mMoveList); extMoveList->getExtMoves( &extMovePtr, &numMoves ); if ( numMoves ) { // Note: should only have a single move at this point AssertFatal(numMoves==1,"ClientProccessList::onTickObject: more than one move in queue"); #ifdef TORQUE_DEBUG_NET_MOVES U32 sum = Move::ChecksumMask & obj->getPacketDataChecksum(obj->getControllingClient()); #endif if ( obj->isTicking() ) obj->processTick( extMovePtr ); if ( bool(safePtr) && obj->getControllingClient() ) { U32 newsum = Move::ChecksumMask & obj->getPacketDataChecksum( obj->getControllingClient() ); // set checksum if not set or check against stored value if set extMovePtr->checksum = newsum; #ifdef TORQUE_DEBUG_NET_MOVES Con::printf("move checksum: %i, (start %i), (move %f %f %f)", movePtr->checksum,sum,movePtr->yaw,movePtr->y,movePtr->z); #endif } con->mMoveList->clearMoves( 1 ); } } else if ( obj->isTicking() ) obj->processTick( 0 ); }
static void checkGameTimeouts() { // Look for people who have been connected longer than the threshold and // disconnect them. U32 currentTime = Platform::getRealMilliseconds(); for(GameConnection *walk = gClientList.mNext; walk != &gClientList; walk = walk->mNext) { if(currentTime - walk->mCreateTime > 15000) { walk->disconnect("You're done!"); break; } } }
void HifiServerProcessList::onTickObject(ProcessObject * pobj) { // Each object is advanced a single tick // If it's controlled by a client, tick using a move. Move *movePtr; U32 numMoves; GameConnection *con = pobj->getControllingClient(); SimObjectPtr<GameBase> obj = getGameBase( pobj ); if ( obj && con && con->getControlObject() == obj && con->mMoveList->getMoves( &movePtr, &numMoves ) ) { #ifdef TORQUE_DEBUG_NET_MOVES U32 sum = Move::ChecksumMask & obj->getPacketDataChecksum( obj->getControllingClient() ); #endif obj->processTick(movePtr); if ( bool(obj) && obj->getControllingClient() ) { U32 newsum = Move::ChecksumMask & obj->getPacketDataChecksum( obj->getControllingClient() ); // check move checksum if ( movePtr->checksum != newsum ) { #ifdef TORQUE_DEBUG_NET_MOVES if ( !obj->mIsAiControlled ) Con::printf( "move %i checksum disagree: %i != %i, (start %i), (move %f %f %f)", movePtr->id, movePtr->checksum, newsum, sum, movePtr->yaw, movePtr->y, movePtr->z ); #endif movePtr->checksum = Move::ChecksumMismatch; } else { #ifdef TORQUE_DEBUG_NET_MOVES Con::printf( "move %i checksum agree: %i == %i, (start %i), (move %f %f %f)", movePtr->id, movePtr->checksum, newsum, sum, movePtr->yaw, movePtr->y, movePtr->z ); #endif } // Adding this seems to fix constant corrections, but is it // really a sound fix? con->mMoveList->clearMoves( 1 ); } } else if ( pobj->isTicking() ) pobj->processTick( 0 ); }
void shipTouchFlag(Ship *theShip, FlagItem *theFlag) { // see if the ship is already carrying a flag - can only carry one at a time for(S32 i = 0; i < theShip->mMountedItems.size(); i++) if(theShip->mMountedItems[i].isValid() && (theShip->mMountedItems[i]->getObjectTypeMask() & FlagType)) return; S32 flagIndex; for(flagIndex = 0; flagIndex < mFlags.size(); flagIndex++) if(mFlags[flagIndex] == theFlag) break; GameConnection *controlConnection = theShip->getControllingClient(); ClientRef *cl = controlConnection->getClientRef(); if(!cl) return; // see if this flag is already in a flag zone owned by the ship's team if(theFlag->getZone() != NULL && theFlag->getZone()->getTeam() == theShip->getTeam()) return; static StringTableEntry stealString("%e0 stole a flag from team %e1!"); static StringTableEntry takeString("%e0 of team %e1 took a flag!"); static StringTableEntry oneFlagTakeString("%e0 of team %e1 took the flag!"); StringTableEntry r = takeString; if(mFlags.size() == 1) r = oneFlagTakeString; S32 teamIndex; if(theFlag->getZone() == NULL) teamIndex = cl->teamId; else { r = stealString; teamIndex = theFlag->getZone()->getTeam(); setTeamScore(teamIndex, mTeams[teamIndex].score - 1); } Vector<StringTableEntry> e; e.push_back(cl->name); e.push_back(mTeams[teamIndex].name); for(S32 i = 0; i < mClientList.size(); i++) mClientList[i]->clientConnection->s2cDisplayMessageE( GameConnection::ColorNuclearGreen, SFXFlagSnatch, r, e); theFlag->mountToShip(theShip); theFlag->setZone(NULL); }
void HifiClientProcessList::onTickObject(ProcessObject * pobj) { // Each object is advanced a single tick // If it's controlled by a client, tick using a move. Move *movePtr; U32 numMoves; GameConnection *con = pobj->getControllingClient(); SimObjectPtr<GameBase> obj = getGameBase( pobj ); if ( obj && con && con->getControlObject() == obj && con->mMoveList->getMoves( &movePtr, &numMoves) ) { #ifdef TORQUE_DEBUG_NET_MOVES U32 sum = Move::ChecksumMask & obj->getPacketDataChecksum( obj->getControllingClient() ); #endif obj->processTick( movePtr ); if ( bool(obj) && obj->getControllingClient() ) { U32 newsum = Move::ChecksumMask & obj->getPacketDataChecksum( obj->getControllingClient() ); // set checksum if not set or check against stored value if set movePtr->checksum = newsum; #ifdef TORQUE_DEBUG_NET_MOVES Con::printf( "move checksum: %i, (start %i), (move %f %f %f)", movePtr->checksum,sum,movePtr->yaw,movePtr->y,movePtr->z ); #endif } con->mMoveList->clearMoves( 1 ); } else if ( pobj->isTicking() ) pobj->processTick( 0 ); if ( obj && ( obj->getTypeMask() & GameBaseHiFiObjectType ) ) { GameConnection * serverConnection = GameConnection::getConnectionToServer(); TickCacheEntry * tce = obj->getTickCache().addCacheEntry(); BitStream bs( tce->packetData, TickCacheEntry::MaxPacketSize ); obj->writePacketData( serverConnection, &bs ); Point3F vel = obj->getVelocity(); F32 velSq = mDot( vel, vel ); gMaxHiFiVelSq = getMax( gMaxHiFiVelSq, velSq ); } }
void SimDataBlockEvent::process(NetConnection *cptr) { if(mProcess) { //call the console function to set the number of blocks to be sent Con::executef("onDataBlockObjectReceived", Con::getIntArg(mIndex), Con::getIntArg(mTotal)); SimDataBlock* obj = NULL; String &errorBuffer = NetConnection::getErrorBuffer(); if( Sim::findObject( id,obj ) && dStrcmp( obj->getClassName(),mObj->getClassName() ) == 0 ) { U8 buf[1500]; BitStream stream(buf, 1500); mObj->packData(&stream); stream.setPosition(0); obj->unpackData(&stream); obj->preload(false, errorBuffer); } else { if( obj != NULL ) { Con::warnf( "A '%s' datablock with id: %d already existed. " "Clobbering it with new '%s' datablock from server.", obj->getClassName(), id, mObj->getClassName() ); obj->deleteObject(); } bool ret = mObj->registerObject(id); if(ret) { cptr->addObject(mObj); GameConnection *conn = dynamic_cast<GameConnection *>(cptr); if(conn) { conn->preloadDataBlock(mObj); mObj = NULL; } } } } }
void ForestWindEmitter::_renderEmitterInfo( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat ) { if ( overrideMat ) return; GFXTransformSaver saver; GFXDrawUtil *drawer = GFX->getDrawUtil(); AssertFatal( drawer, "Got NULL GFXDrawUtil!" ); const Point3F &pos = getPosition(); const VectorF &windVec = mWind->getDirection(); GFXStateBlockDesc desc; desc.setBlend( true ); desc.setZReadWrite( true, false ); // Draw an arrow pointing // in the wind direction. drawer->drawArrow( desc, pos, pos + (windVec * mWindStrength), ColorI( 0, 0, 255, 255 ) );//Point3F( -235.214, 219.589, 34.0991 ), Point3F( -218.814, 244.731, 37.5587 ), ColorI( 255, 255, 0, 255 ) );// drawer->drawArrow( desc, pos, pos + (mWind->getTarget() * mWindStrength ), ColorI( 255, 0, 0, 85 ) ); S32 useRadius = mWindRadius; // Draw a 2D circle for the wind radius. if ( isRadialEmitter() ) { //WLE - Vince //So the problem is that when your inside the sphere it won't render so it might make someone //think that it's not working right. So what I did was determine if the camera is inside the sphere. //If the camera is inside the sphere, then I find the distance from the center of the sphere to the camera //Round down and use that as the radius to draw the sphere. //That way if someone zooms in or out, their screen is still showing the sphere. GameConnection * gc = GameConnection::getConnectionToServer(); GameBase* gb = gc->getCameraObject(); if (gb) { Point3F camPos = gb->getPosition(); if ( getPosition().isInsideSphere( camPos, mWindRadius ) ) useRadius = getPosition().distanceTo(camPos); } drawer->drawSphere( desc, useRadius, pos, ColorI( 255, 0, 0, 80 ) ); } }
void VTorque::setCamera( SceneObjectType *pObject ) { // Fetch Game Base. GameBase *object = dynamic_cast<GameBase*>( pObject ); // Fetch Client Group. SimGroup* clientGroup = Sim::getClientGroup(); for ( SimGroup::iterator itr = clientGroup->begin(); itr != clientGroup->end(); itr++ ) { GameConnection *connection = dynamic_cast<GameConnection*>( *itr ); if ( connection ) { // Set Camera Object. connection->setCameraObject( object ); } } }
void LevelMenuSelectUserInterface::processSelection(U32 index) { Parent::onActivate(); GameConnection *gc = getGame()->getConnectionToServer(); if((index & UPLOAD_LEVELS_BIT) && (index & (~UPLOAD_LEVELS_BIT)) < U32(mMenuDisplayItems.size())) { FolderManager *folderManager = mGameSettings->getFolderManager(); string filename = strictjoindir(folderManager->getLevelDir(), mMenuDisplayItems[index & (~UPLOAD_LEVELS_BIT)]); if(!gc->TransferLevelFile(filename.c_str())) getGame()->displayErrorMessage("!!! Can't upload level: unable to read file"); } else gc->c2sRequestLevelChange(index, false); // The selection index is the level to load getUIManager()->reactivateGameUI(); // Back to the game }
// Checks collisions with a SpeedZone bool SpeedZone::collide(BfObject *hitObject) { if(ignoreThisCollision) return false; // This is run on both server and client side to reduce lag if(isShipType(hitObject->getObjectTypeNumber())) // Only ships & robots collide { #ifndef ZAP_DEDICATED if(isGhost()) // On client, don't process speedZone on all moveObjects except the controlling one { ClientGame *client = static_cast<ClientGame *>(getGame()); GameConnection *gc = client->getConnectionToServer(); if(gc && gc->getControlObject() != hitObject) return false; } #endif return true; } return false; }
void SimDataBlockEvent::notifyDelivered(NetConnection *conn, bool ) { // if the modified key for this event is not the current one, // we've already resorted and resent some blocks, so fall out. if(conn->isRemoved()) return; GameConnection *gc = (GameConnection *) conn; if(gc->getDataBlockSequence() != mMissionSequence) return; U32 nextIndex = mIndex + DataBlockQueueCount; SimDataBlockGroup *g = Sim::getDataBlockGroup(); if(mIndex == g->size() - 1) { gc->setDataBlockModifiedKey(gc->getMaxDataBlockModifiedKey()); gc->sendConnectionMessage(GameConnection::DataBlocksDone, mMissionSequence); } if(g->size() <= nextIndex) return; SimDataBlock *blk = (SimDataBlock *) (*g)[nextIndex]; gc->postNetEvent(new SimDataBlockEvent(blk, nextIndex, g->size(), mMissionSequence)); }
void SFX3DObject::getEarTransform( MatrixF& transform ) const { // If it's not a ShapeBase, just use the object transform. ShapeBase* shape = dynamic_cast< ShapeBase* >( mObject ); if ( !shape ) { transform = mObject->getTransform(); return; } // It it's ShapeBase, use the earNode transform if one was defined. // Otherwise, use the camera transform. TSShapeInstance* shapeInstance = shape->getShapeInstance(); if ( !shapeInstance ) { // Just in case. transform = mObject->getTransform(); return; } ShapeBaseData* datablock = dynamic_cast< ShapeBaseData* >( shape->getDataBlock() ); AssertFatal( datablock, "SFX3DObject::getEarTransform() - shape without ShapeBaseData datablock!" ); // Get the transform for the ear node. const S32 earNode = datablock->earNode; if ( earNode != -1 && earNode != datablock->eyeNode ) { transform = shape->getTransform(); transform *= shapeInstance->mNodeTransforms[ earNode ]; } else { GameConnection* connection = dynamic_cast<GameConnection *>(NetConnection::getConnectionToServer()); if ( !connection || !connection->getControlCameraTransform( 0.0f, &transform ) ) transform = mObject->getTransform(); } }
void Etherform::interpolateTick(F32 dt) { Parent::interpolateTick(dt); if(dt != 0.0f) { Point3F pos = delta.pos + delta.posVec * dt; Point3F rot = delta.rot + delta.rotVec * dt; this->setRenderPosition(pos, rot, dt); // update laser trails... for( S32 i=0; i < NUM_ETHERFORM_LASERTRAILS; i++ ) { if(mLaserTrailList[i]) mLaserTrailList[i]->setLastNodePos(pos); } // apply camera effects - is this the best place? - bramage GameConnection* connection = GameConnection::getConnectionToServer(); if(connection->isFirstPerson()) { GameBase* obj = connection->getControlObject(); if( obj == this ) { MatrixF curTrans = this->getRenderTransform(); curTrans.mul( gCamFXMgr.getTrans() ); Parent::setRenderTransform( curTrans ); } } } else { this->setRenderPosition(delta.pos, delta.rot, 0); } // Save last interpolation delta value. delta.dt = dt; }
void ForestWindEmitter::_renderEmitterInfo( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat ) { if ( overrideMat ) return; GFXTransformSaver saver; GFXDrawUtil *drawer = GFX->getDrawUtil(); AssertFatal( drawer, "Got NULL GFXDrawUtil!" ); const Point3F &pos = getPosition(); const VectorF &windVec = mWind->getDirection(); GFXStateBlockDesc desc; desc.setBlend( true ); desc.setZReadWrite( true, false ); // Draw an arrow pointing // in the wind direction. drawer->drawArrow( desc, pos, pos + (windVec * mWindStrength), ColorI( 0, 0, 255, 255 ) );//Point3F( -235.214, 219.589, 34.0991 ), Point3F( -218.814, 244.731, 37.5587 ), ColorI( 255, 255, 0, 255 ) );// drawer->drawArrow( desc, pos, pos + (mWind->getTarget() * mWindStrength ), ColorI( 255, 0, 0, 85 ) ); S32 useRadius = mWindRadius; // Draw a 2D circle for the wind radius. if ( isRadialEmitter() ) { // If the camera is close to the sphere, shrink the sphere so it remains visible. GameConnection* gc = GameConnection::getConnectionToServer(); GameBase* gb; if ( gc && (gb = gc->getCameraObject()) ) { F32 camDist = (gb->getPosition() - getPosition()).len(); if ( camDist < mWindRadius ) useRadius = camDist; } drawer->drawSphere( desc, useRadius, pos, ColorI( 255, 0, 0, 80 ) ); } }
void GameMenuUserInterface::onActivate() { Parent::onActivate(); menuItems.clear(); menuItems.push_back(MenuItem("OPTIONS",1)); menuItems.push_back(MenuItem("INSTRUCTIONS",2)); GameType *theGameType = gClientGame->getGameType(); if(theGameType) { mGameType = theGameType; theGameType->addClientGameMenuOptions(menuItems); } GameConnection *gc = gClientGame->getConnectionToServer(); if(gc) { if(gc->isAdmin()) menuItems.push_back(MenuItem("ADMIN",4)); else menuItems.push_back(MenuItem("ENTER ADMIN PASSWORD",5)); } menuItems.push_back(MenuItem("LEAVE GAME",3)); }
void Lightning::scheduleThunder(Strike* newStrike) { AssertFatal(isClientObject(), "Lightning::scheduleThunder: server objects should not enter this version of the function"); // If no thunder sounds, don't schedule anything! if (mDataBlock->numThunders == 0) return; GameConnection* connection = GameConnection::getConnectionToServer(); if (connection) { MatrixF cameraMatrix; if (connection->getControlCameraTransform(0, &cameraMatrix)) { Point3F worldPos; cameraMatrix.getColumn(3, &worldPos); worldPos.x -= newStrike->xVal; worldPos.y -= newStrike->yVal; worldPos.z = 0.0f; F32 dist = worldPos.len(); F32 t = dist / 330.0f; // Ok, we need to schedule a random strike sound t secs in the future... // if (t <= 0.03f) { // If it's really close, just play it... U32 thunder = sgLightningRand.randI(0, mDataBlock->numThunders - 1); SFX->playOnce(mDataBlock->thunderSounds[thunder]); } else { Thunder* pThunder = new Thunder; pThunder->tRemaining = t; pThunder->next = mThunderListHead; mThunderListHead = pThunder; } } } }
void SimDataBlockEvent::process(NetConnection *cptr) { if(mProcess) { //call the console function to set the number of blocks to be sent Con::executef("onDataBlockObjectReceived", mIndex, mTotal); String &errorBuffer = NetConnection::getErrorBuffer(); // Register the datablock object if this is a new DB // and not for a modified datablock event. if( !mObj->isProperlyAdded() ) { // This is a fresh datablock object. // Perform preload on datablock and register // the object. GameConnection* conn = dynamic_cast< GameConnection* >( cptr ); if( conn ) conn->preloadDataBlock( mObj ); if( mObj->registerObject(id) ) { cptr->addObject( mObj ); mObj = NULL; } } else { // This is an update to an existing datablock. Preload // to finish this. mObj->preload( false, errorBuffer ); mObj = NULL; } } }
void LevelMenuUserInterface::processSelection(U32 index) { Parent::onActivate(); GameConnection *gc = gClientGame->getConnectionToServer(); if(mTypeSelectDone) { // The selection index is the level to load. logprintf("load level %s", gc->mLevelNames[index].getString()); gc->c2sRequestLevelChange(index); gGameUserInterface.activate(); } else { mTypeSelectDone = true; StringTableEntry s = gc->mLevelTypes[index]; menuItems.clear(); for(S32 i = 0; i < gc->mLevelTypes.size();i++) { if(gc->mLevelTypes[i] == s) menuItems.push_back(MenuItem(gc->mLevelNames[i].getString(), i)); } } }