///////////////////////////////////////////////////////////////////// // Created by [Dennis Andersen] [2013] ///////////////////////////////////////////////////////////////////// #include "..\GameSession.h" #include "..\GameClient.h" #include #include #include #define NOMINMAX #include #include #include #define DELTA_TIME_20 0.05f #define DELTA_TIME_24 0.04166666666666666666666666666667f #define DELTA_TIME_30 0.03333333333333333333333333333333f #define DELTA_TIME_60 0.01666666666666666666666666666667f #define DELTA_TIME_120 0.00833333333333333333333333333333f using namespace Utility::DynamicMemory; using namespace Oyster; using namespace Oyster::Network; using namespace Oyster::Thread; using namespace GameLogic; namespace DanBias { GameSession* GameSession::gameSession = nullptr; GameSession::GameSession() :gameInstance(GameAPI::Instance()) { this->owner = 0; this->isCreated = false; this->isRunning = false; this->gameSession = this; this->logicFrameTime = DELTA_TIME_20; this->networkFrameTime = DELTA_TIME_20; this->networkTimer.reset(); this->logicTimer.reset(); memset(&this->description, 0, sizeof(GameDescription)); } GameSession::~GameSession() { this->worker.Terminate(); this->clients.Clear(); this->gameInstance; this->owner = 0; this->isCreated = false; this->isRunning = false; } bool GameSession::Create(GameDescription& desc) { this->description = desc; /* Do some error checking */ if(desc.clients.Size() == 0) return false; if(!desc.owner) return false; if(this->isCreated) return false; /* standard initialization of some data */ NetworkSession::clients = desc.clients; NetworkSession::clients.Resize((unsigned int)desc.maxClients); this->clients.Resize((unsigned int)desc.maxClients); this->owner = desc.owner; /* Initiate the game instance */ if(!this->gameInstance.Initiate()) { printf("Failed to initiate the game instance\n"); } /* Create the players in the game instance */ GameLogic::IPlayerData* p = 0; for (unsigned int i = 0; i < desc.clients.Size(); i++) { if(desc.clients[i]) { if( (p = this->gameInstance.CreatePlayer()) ) { desc.clients[i]->SetOwner(this); this->clients[i] = (new GameClient(desc.clients[i], p)); } else { printf("Failed to create player (%i)\n", i); } } } /* Create the game level */ if(!(this->levelData = this->gameInstance.CreateLevel())) { printf("Level not created!"); return false; } /* Set some game instance data options */ this->gameInstance.SetSubscription(GameSession::ObjectMove); this->gameInstance.SetSubscription(GameSession::ObjectDisabled); this->gameInstance.SetFPS(60); this->description.clients.Clear(); this->isCreated = true; /* Create the worker thread */ if(this->worker.Create(this, false) != OYSTER_THREAD_ERROR_SUCCESS) return false; return this->isCreated; } void GameSession::Run() { if(this->isRunning) return; if(this->clients.Size() > 0) { this->worker.Start(); this->worker.SetPriority(OYSTER_THREAD_PRIORITY_1); this->isRunning = true; } } void GameSession::ThreadEntry( ) { //List with clients that we are waiting on.. DynamicArray> readyList;// = this->clients; //First we need to clean invalid clients, if any, and tell them to start loading game data for (unsigned int i = 0; i < this->clients.Size(); i++) { if(this->clients[i]) { if(this->clients[i]->IsReady()) { readyList.Push(this->clients[i]); Protocol_LobbyCreateGame p(readyList[i]->GetPlayer()->GetID(), "char_white.dan", readyList[i]->GetPlayer()->GetOrientation()); readyList[readyList.Size() - 1]->GetClient()->Send(p); } } } unsigned int readyCounter = readyList.Size(); //Sync with clients while (readyCounter != 0) { this->ProcessClients(); for (unsigned int i = 0; i < readyList.Size(); i++) { if(readyList[i] && readyList[i]->IsReady()) { //Need to send information about other players, to all players for (unsigned int k = 0; k < this->clients.Size(); k++) { if((this->clients[k] && readyList[i]) && readyList[i]->GetClient()->GetID() != this->clients[k]->GetClient()->GetID()) { //Protocol_ObjectCreatePlayer Protocol_ObjectCreate p( this->clients[k]->GetPlayer()->GetPosition(), this->clients[k]->GetPlayer()->GetRotation(), this->clients[k]->GetPlayer()->GetScale(), this->clients[k]->GetPlayer()->GetID(), "char_white.dan"); //The model name will be custom later.. readyList[i]->GetClient()->Send(p); } } readyCounter-- ; readyList[i] = 0; } } Sleep(5); //TODO: This might not be needed here. } for (unsigned int i = 0; i < this->clients.Size(); i++) { if(this->clients[i]) { this->clients[i]->GetClient()->Send(GameLogic::Protocol_LobbyStartGame(5)); } } } bool GameSession::Attach(Utility::DynamicMemory::SmartPointer client) { if(!this->isCreated) return false; if(this->GetClientCount() == this->clients.Capacity()) return false; client->SetOwner(this); IPlayerData* player = this->gameInstance.CreatePlayer(); if(!player) return false; SmartPointer obj = new GameClient(client, player); // Send the chosen mesh name Protocol_LobbyCreateGame lcg(obj->GetPlayer()->GetID(), "char_white.dan", obj->GetPlayer()->GetOrientation()); obj->GetClient()->Send(lcg); // Send the player data only for (unsigned int i = 0; i < this->clients.Capacity(); i++) { if(this->clients[i]) { Protocol_ObjectCreate oc(this->clients[i]->GetPlayer()->GetOrientation(), this->clients[i]->GetPlayer()->GetID(), "char_white.dan"); this->clients[i]->GetClient()->Send(oc); } } obj->GetClient()->Send(GameLogic::Protocol_LobbyStartGame(0)); for (unsigned int i = 0; i < this->clients.Size(); i++) { if(!clients[i]) { NetworkSession::clients[i] = client; clients[i] = obj; return true; } } return true; } void GameSession::CloseSession( bool dissconnectClients ) { this->worker.Terminate(); NetworkSession::CloseSession(true); this->clients.Clear(); } }//End namespace DanBias