home *** CD-ROM | disk | FTP | other *** search
/ Game Programming in C++ - Start to Finish / GameProgrammingS.iso / developer_install / ReplicaNetFreewareV5_4.exe / data1.cab / Program_Executable_Files / Example4 / MainGame.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2005-10-30  |  19.3 KB  |  627 lines

  1. /* START_LICENSE_HEADER
  2.  
  3. Copyright (C) 2000 Martin Piper, original design and program code
  4. Copyright (C) 2001-2005 Replica Software
  5.  
  6. This program file is copyright (C) Replica Software and can only be used under license.
  7. For more information visit: http://www.replicanet.com/
  8. Or email: info@replicanet.com
  9.  
  10. END_LICENSE_HEADER */
  11. /*
  12. This file contains the main parts of the game that deal with ReplicaNet objects.
  13. There are three mains parts. The init routine (DoGameStuff), the frame tick (FrameMove) and the render (Render)
  14. */
  15. #define STRICT
  16. #include <math.h>
  17. #include <stdio.h>
  18.  
  19. #include "Network.h"
  20.  
  21. #include "Plane.h"
  22. #include "Camera.h"
  23. #include "Projectile.h"
  24. #include "Enemy.h"
  25.  
  26. #include "GameClass.h"
  27.  
  28. #include <assert.h>
  29. #include <D3D8.h>
  30. #define DIRECTINPUT_VERSION 0x0800
  31. #include <DInput.h>
  32. #include "DIInterface.h"
  33.  
  34. #include "External.h"
  35. #include "GameDatabase.h"
  36.  
  37. using namespace RNReplicaNet;
  38.  
  39.  
  40. /**
  41.  * This initialises the game state.
  42.  */
  43. void CMyD3DApplication::DoGameStuff(void)
  44. {
  45.     gDIHandler = new TDIHandler();
  46.     gDIHandler->Initialise();
  47.  
  48.     /* This starts the ReplicaNet session and allows the user to create or join a game */
  49.     Network::Network_Init(gCommandLine);
  50.  
  51.     mLastFrameTime = Network::mNetwork->GetLocalTime();
  52.  
  53.     /*
  54.     All of the game objects inherit from GameObject and a ReplicaObject derived network class.
  55.     Each GameObject class is able to report position and calculate distances by using virtual functions.
  56.     The GameObject manager makes sure that the list of in game objects is maintained and polled.
  57.     It is probably best to step in to Plane() and other objects as they are being constructed to see the various stages that are used.
  58.     */
  59.     // If we are not a dedicated server and we are not playing back a recording
  60.     if (!Network::mDedicatedServer && !Network::mNetwork->GetSessionPlayback())
  61.     {
  62.         /* Allocate our plane */
  63.         mPlayerConrolledPlane = new Plane();
  64.         mPlayerConrolledPlane->SetPosition(D3DXVECTOR4(10,0,0,0));
  65.         /* Publish our plane */
  66.         mPlayerConrolledPlane->Publish();
  67.  
  68.         /* Allocate a camera */
  69.         mPlayerConrolledCamera = new Camera();
  70.         /* Publish our camera */
  71.         mPlayerConrolledCamera->Publish();
  72.         /* Set the observer for this game session to be this camera object */
  73.         /* This is used by the prediction algorithm so calculate the distance to other objects in the scene */
  74.         /* The greater the distance then the less bandwidth the object can use. Each object's parameters for prediction */
  75.         /* are defined in the ROL file for the object */
  76.         Network::mNetwork->SetObserver(mPlayerConrolledCamera);
  77.     }
  78.  
  79.     // Spawn some enemies if we are not playing back a recording.
  80.     if (!Network::mNetwork->GetSessionPlayback())
  81.     {
  82.         for (int i=0;i<5;i++)
  83.         {
  84.             Enemy::SpawnEnemy();
  85.         }
  86.     }
  87. }
  88.  
  89. static float firetimeout = 0.0f;
  90.  
  91. bool autofly = false;
  92.  
  93. float repnettime;
  94. float framemovetime;
  95. float rendertime;
  96. bool stableyet = false;
  97.  
  98. /**
  99.  * Called once per frame, this call is the entry point for animating
  100.  */
  101. HRESULT CMyD3DApplication::FrameMove()
  102. {
  103.     float ttime;
  104.  
  105.     repnettime = Network::mNetwork->GetLocalTime();
  106.     Network::mNetwork->Poll();
  107.     repnettime = Network::mNetwork->GetLocalTime() - repnettime;
  108.  
  109.     framemovetime = Network::mNetwork->GetLocalTime();
  110.     ttime = Network::mNetwork->GetLocalTime();
  111.     GameDatabase::mGameFrameTick = ttime - mLastFrameTime;
  112.  
  113.     // For good thread management we give the OS time to do a context switch as this app is quite a heavy graphics user
  114.     Sleep(0);
  115.  
  116.     // If our session isn't stable yet then just return quickly while we wait for the connection to be made
  117.     if (!stableyet)
  118.     {
  119.         if (Network::mNetwork->IsStable())
  120.         {
  121.             stableyet = true;
  122.             mLastFrameTime = ttime;
  123.         }
  124.         else
  125.         {
  126.             return S_OK;
  127.         }
  128.     }
  129.  
  130.     mLastFrameTime = ttime;
  131.     if (GameDatabase::mGameFrameTick > 1.0f)
  132.     {
  133.         GameDatabase::mGameFrameTick = 1.0f;
  134.     }
  135.  
  136.     // Lock the object list
  137.     // This tells ReplicaNet that we don't want to have objects allocated or freed while scanning the object list
  138.     Network::mNetwork->LockObjects();
  139.     int i;
  140.     for (i=0;i<(int)GameDatabase::mGameObjects.size();i++)
  141.     {
  142.         // Call each object's PollIt() function
  143.         GameDatabase::mGameObjects[i]->PollIt();
  144.     }
  145.     for (i=0;i<(int)GameDatabase::mGameObjects.size();i++)
  146.     {
  147.         // If the Delete() function got called then delete the object properly
  148.         if (GameDatabase::mGameObjects[i]->GetDelete())
  149.         {
  150.             delete GameDatabase::mGameObjects[i];
  151.             i--;
  152.         }
  153.     }
  154.     // Tell ReplicaNet that the object list is no longer being used and unlock it
  155.     Network::mNetwork->UnLockObjects();
  156.  
  157.     D3DXMatrixTranslation( &m_matTerrainMatrix, 0.0f, 0.0f, 0.0f );
  158.  
  159.     // Move the light
  160.     FLOAT Lx =   5;
  161.     FLOAT Ly =   5;
  162.     FLOAT Lz =  -5;
  163.     D3DLIGHT8 light;
  164.     D3DUtil_InitLight( light, D3DLIGHT_POINT, Lx, Ly, Lz );
  165.     light.Attenuation0 = 0.9f;
  166.     light.Attenuation1 = 0.0f;
  167.     m_pd3dDevice->SetLight( 0, &light );
  168.  
  169.     // Get user input
  170.     gDIHandler->ReadAllInputs();
  171.  
  172.     // If playing a recording this allows the recording to be played in slow-motion, faster than normal, pause and skip 10 seconds
  173.     if (Network::mNetwork->GetSessionPlayback())
  174.     {
  175.         if (SysKeyDown(DIK_1))
  176.         {
  177.             Network::mNetwork->SetPlaybackSpeed(0.1f);
  178.         }
  179.         if (SysKeyDown(DIK_2))
  180.         {
  181.             Network::mNetwork->SetPlaybackSpeed(0.5f);
  182.         }
  183.         if (SysKeyDown(DIK_3))
  184.         {
  185.             Network::mNetwork->SetPlaybackSpeed(1.0f);
  186.         }
  187.         if (SysKeyDown(DIK_4))
  188.         {
  189.             Network::mNetwork->SetPlaybackSpeed(1.5f);
  190.         }
  191.         if (SysKeyDown(DIK_5))
  192.         {
  193.             Network::mNetwork->SetPlaybackSpeed(2.0f);
  194.         }
  195.         if (SysKeyDown(DIK_0))
  196.         {
  197.             Network::mNetwork->SetPlaybackSpeed(0.0f);
  198.         }
  199.         if (SysKeyDownOnce(DIK_9))
  200.         {
  201.             Network::mNetwork->PlaybackAdvanceTo(Network::mNetwork->GetTime()+10.0f);
  202.         }
  203.     }
  204.  
  205.  
  206.     // If we are not a dedicated server and we are not playing back a recording then run through the player control stuff
  207.     if (!Network::mDedicatedServer && !Network::mNetwork->GetSessionPlayback())
  208.     {
  209.         D3DXVECTOR4 rot = mPlayerConrolledPlane->GetRotation();
  210.  
  211.         if (firetimeout > 0)
  212.         {
  213.             firetimeout -= GameDatabase::mGameFrameTick;
  214.         }
  215.  
  216. #ifndef EXTERNALMODE
  217.         if (SysKeyDown(DIK_A))
  218.         {
  219.             autofly = true;
  220.         }
  221.  
  222.         if (SysKeyDown(DIK_S))
  223.         {
  224.             autofly = false;
  225.         }
  226. #endif
  227.  
  228.         // Test for the shoot key
  229.         if ((SysKeyDown(DIK_LCONTROL) || autofly) && firetimeout <= 0.0)
  230.         {
  231.             Projectile *proj = new Projectile();
  232.             proj->SetPosition(mPlayerConrolledPlane->GetPosition());
  233.             proj->SetRotation(mPlayerConrolledPlane->GetRotation());
  234.             proj->Publish();
  235.             // Delay for our auto-fire repeat rate
  236.             firetimeout += 0.05f;
  237.             firetimeout += 0.15f;
  238.         }
  239.  
  240.  
  241.         if (SysKeyDown(DIK_D))
  242.         {
  243.             float speed = mPlayerConrolledPlane->GetSpeed();
  244.             speed -= 40.0f * GameDatabase::mGameFrameTick;
  245.             if (speed < 0.0f)
  246.             {
  247.                 speed = 0.0f;
  248.             }
  249.             mPlayerConrolledPlane->SetSpeed(speed);
  250.         }
  251.         if (SysKeyDown(DIK_F))
  252.         {
  253.             float speed = mPlayerConrolledPlane->GetSpeed();
  254.             speed += 40.0f * GameDatabase::mGameFrameTick;
  255.             if (speed > 40.0f)
  256.             {
  257.                 speed = 40.0f;
  258.             }
  259.             mPlayerConrolledPlane->SetSpeed(speed);
  260.         }
  261.  
  262.         if (SysKeyDown(DIK_LEFT) || autofly)
  263.         {
  264.             rot.z -= D3DXToRadian(100.0f) * GameDatabase::mGameFrameTick;
  265.             if (rot.z > 0)
  266.             {
  267.                 rot.z -= D3DXToRadian(100.0f) * GameDatabase::mGameFrameTick;
  268.             }
  269.         }
  270.         if (SysKeyDown(DIK_RIGHT))
  271.         {
  272.             rot.z += D3DXToRadian(100.0f) * GameDatabase::mGameFrameTick;
  273.             if (rot.z < 0)
  274.             {
  275.                 rot.z += D3DXToRadian(100.0f) * GameDatabase::mGameFrameTick;
  276.             }
  277.         }
  278.         if (rot.z > D3DXToRadian(80.0f))
  279.         {
  280.             rot.z = D3DXToRadian(80.0f);
  281.         }
  282.         if (rot.z < -D3DXToRadian(80.0f))
  283.         {
  284.             rot.z = -D3DXToRadian(80.0f);
  285.         }
  286.  
  287.         if (!((SysKeyDown(DIK_LEFT)||autofly)||SysKeyDown(DIK_RIGHT)))
  288.         {
  289.             float max = (float)fabs(rot.z);
  290.             if (max > (D3DXToRadian(80.0f) * GameDatabase::mGameFrameTick))
  291.             {
  292.                 max = (D3DXToRadian(80.0f) * GameDatabase::mGameFrameTick);
  293.             }
  294.             if (rot.z > 0)
  295.             {
  296.                 rot.z -= max;
  297.             }
  298.             else
  299.             {
  300.                 rot.z += max;
  301.             }
  302.         }
  303.         rot.y += (rot.z*1.2f) * GameDatabase::mGameFrameTick;
  304.         D3DXVECTOR4 planepos = mPlayerConrolledPlane->GetPosition();
  305.         if ((SysKeyDown(DIK_UP) && planepos.y > -5.0f))
  306.         {
  307.             rot.x -= D3DXToRadian(80.0f) * GameDatabase::mGameFrameTick;
  308.         }
  309.         if (SysKeyDown(DIK_DOWN))
  310.         {
  311.             rot.x += D3DXToRadian(80.0f) * GameDatabase::mGameFrameTick;
  312.         }
  313.         if (rot.x > D3DXToRadian(45.0f))
  314.         {
  315.             rot.x = D3DXToRadian(45.0f);
  316.         }
  317.         if (rot.x < -D3DXToRadian(45.0f))
  318.         {
  319.             rot.x = -D3DXToRadian(45.0f);
  320.         }
  321.         if (!(  (SysKeyDown(DIK_UP) && planepos.y > -5.0f)||SysKeyDown(DIK_DOWN)))
  322.         {
  323.             float max = (float)fabs(rot.x);
  324.             if (max > (D3DXToRadian(40.0f) * GameDatabase::mGameFrameTick))
  325.             {
  326.                 max = D3DXToRadian(40.0f) * GameDatabase::mGameFrameTick;
  327.             }
  328.             if (rot.x > 0)
  329.             {
  330.                 rot.x -= max;
  331.             }
  332.             else
  333.             {
  334.                 rot.x += max;
  335.             }
  336.         }
  337.         mPlayerConrolledPlane->SetRotation(rot);
  338.     }
  339.  
  340.     // If there is a valid player controlled plane allocated then use it to render the camera with
  341.     if (mPlayerConrolledPlane)
  342.     {
  343.         D3DXVECTOR4 campt = D3DXVECTOR4(0,5,15,0);
  344.         D3DXVec4Transform(&campt,&campt,&mPlayerConrolledPlane->m_matObjectMatrix);
  345.  
  346.         campt += mPlayerConrolledPlane->GetPosition();
  347.  
  348.         D3DXMATRIX matWorld, matView, matProj;
  349.  
  350.         // Set the transform matrices
  351.         D3DXVECTOR3 vEyePt    = D3DXVECTOR3( campt.x, campt.y, campt.z );
  352.         D3DXVECTOR3 vLookatPt = D3DXVECTOR3( mPlayerConrolledPlane->GetPosition().x,  mPlayerConrolledPlane->GetPosition().y,   mPlayerConrolledPlane->GetPosition().z  );
  353.  
  354.         D3DXVECTOR4 vUpVec2    = D3DXVECTOR3( 0.0f,  1.0f,   0.0f  );
  355.  
  356.         D3DXMATRIX planemat;
  357.         D3DXMatrixRotationYawPitchRoll(&planemat,mPlayerConrolledPlane->GetRotation().y,mPlayerConrolledPlane->GetRotation().x,mPlayerConrolledPlane->GetRotation().z/2.0f);
  358.         D3DXVECTOR4 vUpVec3    = D3DXVECTOR3( 0.0f,  1.0f,   0.0f  );
  359.         D3DXVec4Transform(&vUpVec3,&vUpVec2,&planemat);
  360.  
  361.         D3DXVECTOR3 vUpVec    = D3DXVECTOR3( vUpVec3.x,  vUpVec3.y,   vUpVec3.z  );
  362.  
  363.         D3DXMatrixIdentity( &matWorld );
  364.         D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
  365.         FLOAT fAspect = m_d3dsdBackBuffer.Width / (FLOAT)m_d3dsdBackBuffer.Height;
  366.         D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, fAspect, 1.0f, 200.0f );
  367.  
  368.  
  369.         m_pd3dDevice->SetTransform( D3DTS_WORLD,      &matWorld );
  370.         m_pd3dDevice->SetTransform( D3DTS_VIEW,       &matView );
  371.         m_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
  372.  
  373.         if (mPlayerConrolledCamera)
  374.         {
  375.             mPlayerConrolledCamera->mPosition.x = vEyePt.x;
  376.             mPlayerConrolledCamera->mPosition.y = vEyePt.y;
  377.             mPlayerConrolledCamera->mPosition.z = vEyePt.z;
  378.         }
  379.     }
  380.  
  381.     framemovetime = Network::mNetwork->GetLocalTime() - framemovetime;
  382.  
  383.     return S_OK;
  384. }
  385.  
  386. /**
  387.  * Called once per frame, the call is the entry point for 3d
  388.  *       rendering. This function sets up render states, clears the
  389.  *       viewport, and renders the scene.
  390.  */
  391. static int total;
  392. HRESULT CMyD3DApplication::Render()
  393. {
  394.     rendertime = Network::mNetwork->GetLocalTime();
  395.  
  396.     char buffer[256];
  397.  
  398.     total = 0;
  399.     HRESULT ret = m_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,0xff0000ff, 1.0f, 0L );
  400.  
  401.     if (ret == D3DERR_INVALIDCALL)
  402.     {
  403.         OutputDebugString("Invalid call\n");
  404.     }
  405.  
  406.     // Begin the scene
  407.     if( FAILED( m_pd3dDevice->BeginScene() ) )
  408.     {
  409.         return S_OK;
  410.     }
  411.  
  412.     if (Network::mNetwork->IsStable())
  413.     {
  414.         RenderModels();
  415.     }
  416.     else
  417.     {
  418.         sprintf(buffer,"Waiting on the server");
  419.         m_pFont->DrawText( 128, 128, D3DCOLOR_ARGB(255,255,255,0), buffer );
  420.     }
  421.  
  422.     if (Network::mNetwork->GetStatus() == ReplicaNet::Error::kReplicaNet_EERROR)
  423.     {
  424.         if (Network::mNetwork->GetSessionPlayback())
  425.         {
  426.             sprintf(buffer,"The playback of the recording has finished");
  427.             m_pFont->DrawText( 64, 138, D3DCOLOR_ARGB(255,255,255,0), buffer );
  428.         }
  429.         else
  430.         {
  431.             sprintf(buffer,"There is a session error as there is no defined master");
  432.             m_pFont->DrawText( 64, 138, D3DCOLOR_ARGB(255,255,255,0), buffer );
  433.         }
  434.     }
  435.  
  436.  
  437.     rendertime = Network::mNetwork->GetLocalTime() - rendertime;
  438.  
  439.     // Output statistics
  440.     m_pFont->DrawText( 2,  0, D3DCOLOR_ARGB(255,255,255,0), m_strFrameStats );
  441.     m_pFont->DrawText( 2, 10, D3DCOLOR_ARGB(255,255,255,0), m_strDeviceStats );
  442.  
  443.     char buffer2[32];
  444.     if (Network::mNetwork->IsMaster())
  445.     {
  446.         strcpy(buffer2,"Master");
  447.     }
  448.     else
  449.     {
  450.         strcpy(buffer2,"Client");
  451.     }
  452.  
  453.     if (Network::mNetwork->GetCanBecomeMaster())
  454.     {
  455.         strcat(buffer2,"Cbm");
  456.     }
  457.     if (Network::mNetwork->GetCanSpider())
  458.     {
  459.         strcat(buffer2,"Spd");
  460.     }
  461.     if (Network::mNetwork->GetCanAcceptObjects())
  462.     {
  463.         strcat(buffer2,"Cao");
  464.     }
  465.  
  466.     if (Network::mNetwork->GetStatus() == ReplicaNet::Error::kReplicaNet_EERROR)
  467.     {
  468.         strcat(buffer2,"ERROR");
  469.     }
  470.  
  471.     sprintf(buffer,"%s ID %d Send bytes/sec %d Recv %d bytes/sec",buffer2,Network::mNetwork->GetSessionID(),(int) Network::mNetwork->GetNetworkSendRate(),(int) Network::mNetwork->GetNetworkReceiveRate());
  472.     m_pFont->DrawText( 2, 20, D3DCOLOR_ARGB(255,255,255,0), buffer );
  473.     sprintf(buffer,"Packets resent %d",Network::mNetwork->GetNetworkPacketsLost());
  474.     m_pFont->DrawText( 2, 30, D3DCOLOR_ARGB(255,255,255,0), buffer );
  475.     sprintf(buffer,"URL: %s",Network::mNetwork->SessionExportURL().c_str());
  476.     m_pFont->DrawText( 2, 40, D3DCOLOR_ARGB(255,255,255,0), buffer );
  477.     sprintf(buffer,"Players %d Network time %.2f Latency %.2fms",total,Network::mNetwork->GetTime(),Network::mNetwork->GetLatencyToMasterSession()*1000.0f);
  478.     m_pFont->DrawText( 2, 50, D3DCOLOR_ARGB(255,255,255,0), buffer );
  479. #ifndef EXTERNALMODE
  480.     sprintf(buffer,"ReplicaNet %.2fms Frame move %.2fms Render %.2fms",repnettime*1000.0f,framemovetime*1000.0f,rendertime*1000.0f);
  481.     m_pFont->DrawText( 2, 60, D3DCOLOR_ARGB(255,255,255,0), buffer );
  482. #endif
  483.  
  484.     // End the scene.
  485.     m_pd3dDevice->EndScene();
  486.  
  487.     return S_OK;
  488. }
  489.  
  490. HRESULT CMyD3DApplication::RenderModels()
  491. {
  492. #ifndef EXTERNALMODE
  493.     char buffer[256];
  494. #endif
  495.  
  496.     if (Network::mRenderModels)
  497.     {
  498.         D3DXMatrixTranslation( &m_matTerrainMatrix,   0.0f, 0.0f, 0.0f );
  499.         m_pd3dDevice->SetTransform( D3DTS_WORLD, &m_matTerrainMatrix );
  500.         m_pTerrainObject->Render( m_pd3dDevice );
  501.         D3DXMatrixTranslation( &m_matTerrainMatrix,  80.0f, 0.0f, 0.0f );
  502.         m_pd3dDevice->SetTransform( D3DTS_WORLD, &m_matTerrainMatrix );
  503.         m_pTerrainObject->Render( m_pd3dDevice );
  504.         D3DXMatrixTranslation( &m_matTerrainMatrix, -80.0f, 0.0f, 0.0f );
  505.         m_pd3dDevice->SetTransform( D3DTS_WORLD, &m_matTerrainMatrix );
  506.         m_pTerrainObject->Render( m_pd3dDevice );
  507.         D3DXMatrixTranslation( &m_matTerrainMatrix,   0.0f, 0.0f, 80.0f );
  508.         m_pd3dDevice->SetTransform( D3DTS_WORLD, &m_matTerrainMatrix );
  509.         m_pTerrainObject->Render( m_pd3dDevice );
  510.         D3DXMatrixTranslation( &m_matTerrainMatrix,  80.0f, 0.0f, 80.0f );
  511.         m_pd3dDevice->SetTransform( D3DTS_WORLD, &m_matTerrainMatrix );
  512.         m_pTerrainObject->Render( m_pd3dDevice );
  513.         D3DXMatrixTranslation( &m_matTerrainMatrix, -80.0f, 0.0f, 80.0f );
  514.         m_pd3dDevice->SetTransform( D3DTS_WORLD, &m_matTerrainMatrix );
  515.         m_pTerrainObject->Render( m_pd3dDevice );
  516.         D3DXMatrixTranslation( &m_matTerrainMatrix,   0.0f, 0.0f, -80.0f );
  517.         m_pd3dDevice->SetTransform( D3DTS_WORLD, &m_matTerrainMatrix );
  518.         m_pTerrainObject->Render( m_pd3dDevice );
  519.         D3DXMatrixTranslation( &m_matTerrainMatrix,  80.0f, 0.0f, -80.0f );
  520.         m_pd3dDevice->SetTransform( D3DTS_WORLD, &m_matTerrainMatrix );
  521.         m_pTerrainObject->Render( m_pd3dDevice );
  522.         D3DXMatrixTranslation( &m_matTerrainMatrix, -80.0f, 0.0f, -80.0f );
  523.         m_pd3dDevice->SetTransform( D3DTS_WORLD, &m_matTerrainMatrix );
  524.         m_pTerrainObject->Render( m_pd3dDevice );
  525.     }
  526.  
  527.     int starty = 70;
  528.  
  529.     /* Again lock our game objects list while we render */
  530.     Network::mNetwork->LockObjects();
  531.  
  532.     int i;
  533.     for (i=0;i<(int)GameDatabase::mGameObjects.size();i++)
  534.     {
  535.         ReplicaObject *robject;
  536.         // Get the derived class object pointer that contains a base class type of ReplicaObject from the GameObject class
  537.         robject = GameDatabase::mGameObjects[i]->GetReplicaObject();
  538.         // If there is no object pointer then ignore this object for rendering
  539.         if (!robject)
  540.         {
  541.             continue;
  542.         }
  543.         // Count the number of plane models as the number of players active
  544.         if (robject->GetClassID() == _MAKE_RO(Plane)::StaticGetClassID())
  545.         {
  546.             total++;
  547.         }
  548.         if (Network::mRenderModels)
  549.         {
  550.             // Compare the class id of the ReplicaObject with the class ID of the ReplicaObject Plane object
  551.             // If they are the same then we can assume the type cast to a Plane class is valid
  552.             if (robject->GetClassID() == _MAKE_RO(Plane)::StaticGetClassID())
  553.             {
  554.                 // Perform the type cast
  555.                 Plane *theplane = (Plane *) GameDatabase::mGameObjects[i];
  556.  
  557.                 // Calculate the real matrix for the object
  558.                 D3DXMatrixRotationYawPitchRoll(&theplane->m_matObjectMatrix,theplane->GetRotation().y,theplane->GetRotation().x,theplane->GetRotation().z);
  559.                 D3DXMATRIX transmat;
  560.                 D3DXMatrixTranslation(&transmat,theplane->GetPosition().x,theplane->GetPosition().y,theplane->GetPosition().z);
  561.                 D3DXMatrixMultiply( &theplane->m_matObjectMatrix, &theplane->m_matObjectMatrix, &transmat);
  562.                 m_matObjectMatrix = theplane->m_matObjectMatrix;
  563.                 m_pd3dDevice->SetTransform( D3DTS_WORLD, &theplane->m_matObjectMatrix );
  564.                 theplane->mMesh->Render( m_pd3dDevice );
  565.  
  566.                 m_pShadowVolume = 0;
  567.             }
  568.             if (robject->GetClassID() == _MAKE_RO(Projectile)::StaticGetClassID())
  569.             {
  570.                 // Perform the type cast
  571.                 Projectile *theprojectile = (Projectile *) GameDatabase::mGameObjects[i];
  572.  
  573.                 // Calculate the real matrix for the object
  574.                 D3DXMatrixRotationYawPitchRoll(&theprojectile->m_matObjectMatrix,theprojectile->GetRotation().y,theprojectile->GetRotation().x,theprojectile->GetRotation().z);
  575.  
  576.                 D3DXMATRIX transmat;
  577.                 D3DXMatrixTranslation(&transmat,theprojectile->GetPosition().x,theprojectile->GetPosition().y,theprojectile->GetPosition().z);
  578.                 D3DXMatrixMultiply( &theprojectile->m_matObjectMatrix, &theprojectile->m_matObjectMatrix, &transmat);
  579.                 m_matObjectMatrix = theprojectile->m_matObjectMatrix;
  580.                 m_pd3dDevice->SetTransform( D3DTS_WORLD, &theprojectile->m_matObjectMatrix );
  581.  
  582.                 gpProjectileMesh->Render(m_pd3dDevice);
  583.  
  584.                 m_pShadowVolume = 0;
  585.             }
  586.             if (robject->GetClassID() == _MAKE_RO(Enemy)::StaticGetClassID())
  587.             {
  588.                 // Perform the type cast
  589.                 Enemy *theobject = (Enemy *) GameDatabase::mGameObjects[i];
  590.  
  591.                 // Calculate the real matrix for the object
  592.                 D3DXMATRIX matrix;
  593.                 D3DXMatrixRotationYawPitchRoll(&matrix,theobject->GetRotation().y,theobject->GetRotation().x,theobject->GetRotation().z);
  594.  
  595.                 D3DXMATRIX temp;
  596.                 D3DXMatrixScaling(&temp,0.05f,0.05f,0.05f);
  597.                 D3DXMatrixMultiply(&matrix, &matrix, &temp);
  598.  
  599.                 D3DXMatrixRotationYawPitchRoll(&temp,D3DXToRadian(-90.0f),0,0);
  600.                 D3DXMatrixMultiply(&matrix, &temp,&matrix);
  601.  
  602.                 D3DXMATRIX transmat;
  603.                 D3DXMatrixTranslation(&transmat,theobject->GetPosition().x,theobject->GetPosition().y,theobject->GetPosition().z);
  604.                 D3DXMatrixMultiply( &matrix, &matrix, &transmat);
  605.                 m_matObjectMatrix = matrix;
  606.                 m_pd3dDevice->SetTransform( D3DTS_WORLD, &matrix );
  607.  
  608.                 gpEnemyMesh->Render(m_pd3dDevice);
  609.  
  610.                 m_pShadowVolume = 0;
  611.             }
  612.         } // if (!gDedicatedServer)
  613.  
  614. #ifndef EXTERNALMODE
  615.         sprintf(buffer,"Object mst %d sessid %d uni %d clsid %d ",robject->IsMaster(),robject->GetSessionID(),robject->GetUniqueID(),robject->GetClassID());
  616.         m_pFont->DrawText( 2.0f, (float)starty, D3DCOLOR_ARGB(255,255,255,0), buffer );
  617.         starty += 10;
  618. #endif
  619.     }
  620.  
  621.     /* Now unlock our game objects list since we don't access it from now on */
  622.     Network::mNetwork->UnLockObjects();
  623.  
  624.     return S_OK;
  625. }
  626.  
  627.