Beispiel #1
0
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 );
}
Beispiel #2
0
//----------------------------------------------------------------------------
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) >>
}
Beispiel #4
0
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
}
Beispiel #5
0
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);
   }
}
Beispiel #6
0
void PlayerMenuUserInterface::processSelection(U32 index)
{
   StringTableEntry e(menuItems[index].mText);
   GameConnection *gc = gClientGame->getConnectionToServer();
   if(gc)
      gc->c2sAdminPlayerAction(e, action);
   gGameUserInterface.activate();
}
Beispiel #7
0
static GameBase * getControlObj()
{
   GameConnection * connection = GameConnection::getLocalClientConnection();
   ShapeBase* control = 0;
   if(connection)
      control = dynamic_cast<ShapeBase*>(connection->getControlObject());
   return(control);
}
Beispiel #8
0
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);
}
Beispiel #9
0
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 );
   }
}
Beispiel #11
0
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
}
Beispiel #12
0
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 );

  

}
Beispiel #14
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;
         }
      }
   }
Beispiel #15
0
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 );
}
Beispiel #16
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);
   }
Beispiel #17
0
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 ) );
   }
}
Beispiel #20
0
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
}
Beispiel #22
0
// 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();
   }
}
Beispiel #25
0
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 ) );
   }
}
Beispiel #27
0
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;
         }
      }
   }
}
Beispiel #29
0
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;
      }
   }
}
Beispiel #30
0
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));
      }
   }
}