GameServer - Multiplayer now working properly

This commit is contained in:
Dennis Andersen 2014-02-09 16:42:26 +01:00
parent 201a07f0dc
commit 310ed3dfc5
30 changed files with 282 additions and 208 deletions

View File

@ -167,16 +167,7 @@ namespace DanBias
stateVal = true;
break;
case Client::GameClientState::ClientState_Game:
//if(m_data->serverOwner)
//Initiate the game server through the server API
//if(m_data->serverOwner)
//{
// ((Client::GameState*)m_data->recieverObj->gameClientState)->setClientId(2);
//}
//else
// ((Client::GameState*)m_data->recieverObj->gameClientState)->setClientId(3);
break;
default:
return E_FAIL;
@ -198,15 +189,7 @@ namespace DanBias
HRESULT DanBiasGame::Render(float deltaTime)
{
int isPressed = 0;
if(m_data->inputObj->IsKeyPressed(DIK_A))
{
isPressed = 1;
}
wchar_t title[255];
swprintf(title, sizeof(title), L"| Pressing A: %d | \n", (int)(isPressed));
SetWindowText(m_data->window->GetHWND(), title);
m_data->recieverObj->gameClientState->Render();

View File

@ -110,16 +110,17 @@ namespace DanBias
((Client::GameState*)gameClientState)->Protocol(&protocolData);
}
break;
case protocol_Lobby_Start:
case protocol_Lobby_Create:
{
if(dynamic_cast<Client::LobbyState*>(gameClientState))
{
int id = p[1].value.netInt;
GameLogic::Protocol_LobbyCreateGame tp();
int id = p.Get(1).value.netInt;
std::string name = p.Get(19).value.netCharPtr;
Oyster::Math::Float4x4 w;
for(int i = 0; i< 16; i++)
{
w[i] = p[i+3].value.netFloat;
w[i] = p[i+2].value.netFloat;
}
gameClientState->Release();
@ -130,6 +131,20 @@ namespace DanBias
std::wstring temp;
Utility::String::StringToWstring(name, temp);
((Client::GameState*)gameClientState)->InitiatePlayer(id, temp, w);
//Do some wait state?
}
}
break;
case protocol_Lobby_Start:
{
if(dynamic_cast<Client::GameState*>(gameClientState))
{
//Game state should start in n seconds
GameLogic::Protocol_LobbyStartGame p(p);
p.seconds;
//Sleep((int)(p.seconds * 1000));
}
}
break;

View File

@ -15,7 +15,6 @@ struct GameState::myData
Oyster::Math3D::Float4x4 view;
Oyster::Math3D::Float4x4 proj;
std::vector<C_Object*> object;
int modelCount;
Oyster::Network::NetworkClient* nwClient;
gameStateState state;
@ -88,11 +87,12 @@ bool GameState::LoadModels(std::wstring mapFile)
// open file
// read file
// init models
int nrOfBoxex = 5;
privData->modelCount = 3 + nrOfBoxex;
int nrOfBoxex = 5;
int id = 100;
// add world model
ModelInitData modelData;
Oyster::Math3D::Float4x4 translate;
C_Object* obj;
@ -105,6 +105,7 @@ bool GameState::LoadModels(std::wstring mapFile)
privData->object.push_back(obj);
privData->object[privData->object.size() -1 ]->Init(modelData);
/*
// add box model
modelData.world = Oyster::Math3D::Float4x4::identity;
modelData.modelPath = L"box.dan";
@ -148,6 +149,7 @@ bool GameState::LoadModels(std::wstring mapFile)
privData->object.push_back(obj);
privData->object[privData->object.size() -1 ]->Init(modelData);
*/
return true;
}
bool GameState::InitCamera(Oyster::Math::Float3 startPos)
@ -184,6 +186,34 @@ void GameState::InitiatePlayer(int id, std::wstring modelName, Oyster::Math::Flo
privData->object.push_back(obj);
privData->object[privData->object.size() -1 ]->Init(modelData);
//printf("Move message recieved!");
Oyster::Math::Float3 right = Oyster::Math::Float3(world[0], world[1], world[2]);
Oyster::Math::Float3 up = Oyster::Math::Float3(world[4], world[5], world[6]);
Oyster::Math::Float3 objForward = (Oyster::Math::Float3(world[8], world[9], world[10]));
Oyster::Math::Float3 pos = Oyster::Math::Float3(world[12], world[13], world[14]);
Oyster::Math::Float3 cameraLook = camera->GetLook();
Oyster::Math::Float3 cameraUp = camera->GetUp();
/*Oyster::Math::Float3 newUp = cameraUp.Dot(up);
up *= newUp;
up.Normalize();
Oyster::Math::Float3 newLook = up.Cross(right);
newLook.Normalize();*/
camera->setRight(right);
camera->setUp(up);
camera->setLook(objForward);
up *= 2;
objForward *= -3;
Oyster::Math::Float3 cameraPos = up + pos + objForward;
camera->SetPosition(cameraPos);
camera->UpdateViewMatrix();
}
GameClientState::ClientState GameState::Update(float deltaTime, InputClass* KeyInput)
{
@ -422,8 +452,9 @@ void GameState::Protocol( ObjPos* pos )
{
privData->object[i]->setPos(world);
if(i == myId) // playerobj
if(pos->object_ID == myId) // playerobj
{
//printf("Move message recieved!");
Oyster::Math::Float3 right = Oyster::Math::Float3(world[0], world[1], world[2]);
Oyster::Math::Float3 up = Oyster::Math::Float3(world[4], world[5], world[6]);
Oyster::Math::Float3 objForward = (Oyster::Math::Float3(world[8], world[9], world[10]));

View File

@ -97,7 +97,7 @@ GameClientState::ClientState LoginState::Update(float deltaTime, InputClass* Key
DanBias::GameServerAPI::ServerInitiate(desc);
DanBias::GameServerAPI::ServerStart();
// my ip
nwClient->Connect(15151, "127.0.0.1");
nwClient->Connect(15152, "127.0.0.1");
if (!nwClient->IsConnected())
{
@ -110,7 +110,8 @@ GameClientState::ClientState LoginState::Update(float deltaTime, InputClass* Key
if( KeyInput->IsKeyPressed(DIK_J))
{
// game ip
nwClient->Connect(15151, "127.0.0.1");
nwClient->Connect(15152, "127.0.0.1");
//nwClient->Connect(15152, "193.11.187.187");
if (!nwClient->IsConnected())
{

View File

@ -83,7 +83,7 @@ using namespace GameLogic;
if(kineticEnergyLoss > forceThreashHold) //should only take damage if the force is high enough
{
damageDone = (int)kineticEnergyLoss * 0.10f;
damageDone = (int)(kineticEnergyLoss * 0.10f);
//player.DamageLife(damageDone);
}

View File

@ -68,12 +68,12 @@ void Game::GetAllPlayerPositions() const
Game::PlayerData* Game::CreatePlayer()
{
// Find a free space in array or insert at end
int id = InsertObject(this->players, (PlayerData*)0);
int i = InsertObject(this->players, (PlayerData*)0);
this->players[id] = new PlayerData();
this->players[id]->player->GetRigidBody()->SetSubscription(Game::PhysicsOnMove);
this->players[i] = new PlayerData();
this->players[i]->player->GetRigidBody()->SetSubscription(Game::PhysicsOnMove);
return this->players[id];
return this->players[i];
}
Game::LevelData* Game::CreateLevel()
@ -105,8 +105,7 @@ bool Game::NewFrame()
if(this->players[i]->player) this->players[i]->player->EndFrame();
}
gameInstance.onMoveFnc(this->level);
//gameInstance.onMoveFnc(this->level);
return true;
}
@ -121,17 +120,13 @@ void Game::SetFrameTimeLength( float seconds )
this->frameTime = seconds;
}
void Game::SetSubscription(GameEvent::ObjectEventFunctionType type, GameEvent::ObjectEventFunction functionPointer)
void Game::SetSubscription(GameEvent::ObjectMovedFunction functionPointer)
{
switch (type)
{
case GameLogic::GameEvent::ObjectEventFunctionType_OnMove:
this->onMoveFnc = functionPointer;
break;
case GameLogic::GameEvent::ObjectEventFunctionType_OnDead:
this->onDisableFnc = functionPointer;
break;
}
void Game::SetSubscription(GameEvent::ObjectDisabledFunction functionPointer)
{
this->onDisableFnc = functionPointer;
}
@ -139,7 +134,7 @@ bool Game::Initiate()
{
API::Instance().Init((int)pow(2u, 9u), 1u, Oyster::Math::Float3());
API::Instance().SetSubscription(Game::PhysicsOnDestroy);
API::Instance().SetFrameTimeLength(1.0f/120.0f);
API::Instance().SetFrameTimeLength(this->frameTime);
this->initiated = true;
return true;
}
@ -162,6 +157,6 @@ void Game::PhysicsOnMove(const ICustomBody *object)
}
void Game::PhysicsOnDestroy(::Utility::DynamicMemory::UniquePointer<ICustomBody> proto)
{
if(gameInstance.onDisableFnc) gameInstance.onDisableFnc(0);
if(gameInstance.onDisableFnc) gameInstance.onDisableFnc(0, 0);
}

View File

@ -69,7 +69,8 @@ namespace GameLogic
bool NewFrame() override;
void SetFPS( int FPS ) override;
void SetFrameTimeLength( float seconds ) override;
void SetSubscription(GameEvent::ObjectEventFunctionType type, GameEvent::ObjectEventFunction functionPointer) override;
void SetSubscription(GameEvent::ObjectMovedFunction functionPointer) override;
void SetSubscription(GameEvent::ObjectDisabledFunction functionPointer) override;
bool Initiate() override;
float GetFrameTime() const;
@ -81,8 +82,8 @@ namespace GameLogic
LevelData* level;
float frameTime;
bool initiated;
GameEvent::ObjectEventFunction onDisableFnc;
GameEvent::ObjectEventFunction onMoveFnc;
GameEvent::ObjectDisabledFunction onDisableFnc;
GameEvent::ObjectMovedFunction onMoveFnc;
};
}

View File

@ -23,16 +23,8 @@ namespace GameLogic
*/
namespace GameEvent
{
/**
* The type of event to listen on.
*/
enum ObjectEventFunctionType
{
ObjectEventFunctionType_OnMove,
ObjectEventFunctionType_OnDead,
};
typedef void(*ObjectEventFunction)(IObjectData* object); // Callback method that recieves and object
typedef void(*ObjectMovedFunction)(IObjectData* object); // Callback method that recieves and object
typedef void(*ObjectDisabledFunction)(IObjectData* object, float seconds); // Callback method that recieves and object
//etc...
};
@ -147,17 +139,22 @@ namespace GameLogic
/** Set the frame time in fps
* @param FPS The fps to set
*/
virtual void SetFPS( int FPS = 60 ) = 0;
virtual void SetFPS( int FPS = 120 ) = 0;
/** Set the frames time in seconds
* @param seconds The frame length
*/
virtual void SetFrameTimeLength( float seconds ) = 0;
virtual void SetFrameTimeLength( float seconds = (1.0f/120.0f) ) = 0;
/** Set a specific object event subscription callback
* @param
*/
virtual void SetSubscription(GameEvent::ObjectEventFunctionType type, GameEvent::ObjectEventFunction functionPointer) = 0;
virtual void SetSubscription(GameEvent::ObjectMovedFunction functionPointer) = 0;
/** Set a specific object event subscription callback
* @param
*/
virtual void SetSubscription(GameEvent::ObjectDisabledFunction functionPointer) = 0;
};
}

View File

@ -7,13 +7,14 @@ Game::PlayerData::PlayerData()
{
//set some stats that are appropriate to a player
Oyster::Physics::API::SimpleBodyDescription sbDesc;
sbDesc.centerPosition = Oyster::Math::Float3(0,308,0);
sbDesc.size = Oyster::Math::Float3(4,7,4);
sbDesc.size = Oyster::Math::Float3(4.0f ,4.0f,4.0f);
sbDesc.mass = 70;
sbDesc.restitutionCoeff = 0.5;
sbDesc.frictionCoeff_Static = 0.4;
sbDesc.frictionCoeff_Dynamic = 0.3;
sbDesc.rotation = Oyster::Math::Float3(0, Oyster::Math::pi, 0);
sbDesc.centerPosition = Oyster::Math::Float3(0,308,0);
sbDesc.restitutionCoeff = 0.5f;
sbDesc.frictionCoeff_Static = 0.4f;
sbDesc.frictionCoeff_Dynamic = 0.3f;
sbDesc.rotation = Oyster::Math::Float3(0.0f, Oyster::Math::pi, 0.0f);
//create rigid body
Oyster::Physics::ICustomBody *rigidBody = Oyster::Physics::API::Instance().CreateRigidBody(sbDesc).Release();
@ -21,11 +22,6 @@ Game::PlayerData::PlayerData()
//create player with this rigid body
this->player = new Player(rigidBody,Player::PlayerCollisionBefore, Player::PlayerCollision, OBJECT_TYPE::OBJECT_TYPE_PLAYER);
this->player->GetRigidBody()->SetCustomTag(this);
/*Oyster::Physics::ICustomBody::State state;
this->player->GetRigidBody()->GetState(state);
state.SetRotation(Oyster::Math::Float3(0, Oyster::Math::pi, 0));
this->player->GetRigidBody()->SetState(state);
player->EndFrame();*/
}
Game::PlayerData::PlayerData(int playerID,int teamID)
{

View File

@ -1,5 +1,6 @@
#include "Level.h"
#include "CollisionManager.h"
#include "Game.h"
using namespace GameLogic;
using namespace Utility::DynamicMemory;
@ -70,9 +71,10 @@ void Level::InitiateLevel(float radius)
rigidBody->SetState(state);
levelObj = new StaticObject(rigidBody, LevelCollisionBefore, LevelCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_WORLD);
levelObj->objectID = idCount++;
rigidBody->SetCustomTag(levelObj);
//this->dynamicObjects = new DynamicArray< DynamicObject>;
/*
// add box
API::SimpleBodyDescription sbDesc_TestBox;
sbDesc_TestBox.centerPosition = Oyster::Math::Float4(10,320,0,0);
@ -91,14 +93,12 @@ void Level::InitiateLevel(float radius)
rigidBody_TestBox = API::Instance().CreateRigidBody(sbDesc_TestBox).Release();
rigidBody_TestBox->SetSubscription(Level::PhysicsOnMoveLevel);
this->dynamicObjects.Push(new DynamicObject(rigidBody_TestBox,Object::DefaultCollisionBefore, Object::DefaultCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_BOX));
DynamicObject *box = new DynamicObject(rigidBody_TestBox,Object::DefaultCollisionBefore, Object::DefaultCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_BOX);
box->objectID = idCount++;
this->dynamicObjects.Push(box);
rigidBody_TestBox->SetCustomTag(this->dynamicObjects[i]);
}
// add crystal
API::SimpleBodyDescription sbDesc_Crystal;
sbDesc_Crystal.centerPosition = Oyster::Math::Float4(10, 305, 0, 0);
@ -108,7 +108,9 @@ void Level::InitiateLevel(float radius)
ICustomBody* rigidBody_Crystal = API::Instance().CreateRigidBody(sbDesc_Crystal).Release();
rigidBody_Crystal->SetSubscription(Level::PhysicsOnMoveLevel);
this->dynamicObjects.Push(new DynamicObject(rigidBody_Crystal,Object::DefaultCollisionBefore, Object::DefaultCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_BOX));
DynamicObject *cry = new DynamicObject(rigidBody_Crystal,Object::DefaultCollisionBefore, Object::DefaultCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_BOX);
cry->objectID = idCount++;
this->dynamicObjects.Push(cry);
rigidBody_Crystal->SetCustomTag(this->dynamicObjects[nrOfBoxex]);
@ -123,9 +125,11 @@ void Level::InitiateLevel(float radius)
ICustomBody* rigidBody_House = API::Instance().CreateRigidBody(sbDesc_House).Release();
rigidBody_House->SetSubscription(Level::PhysicsOnMoveLevel);
this->staticObjects.Push(new StaticObject(rigidBody_House,Object::DefaultCollisionBefore, Object::DefaultCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_GENERIC));
StaticObject* house = new StaticObject(rigidBody_House,Object::DefaultCollisionBefore, Object::DefaultCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_GENERIC);
house->objectID = idCount++;
this->staticObjects.Push(house);
rigidBody_House->SetCustomTag(this->staticObjects[0]);
*/
// add gravitation
API::Gravity gravityWell;
@ -167,4 +171,6 @@ void Level::PhysicsOnMoveLevel(const ICustomBody *object)
{
// function call from physics update when object was moved
Object* temp = (Object*)object->GetCustomTag();
((Game*)&Game::Instance())->onMoveFnc(temp);
}

View File

@ -118,8 +118,6 @@ Oyster::Physics::ICustomBody* Object::GetRigidBody()
void Object::BeginFrame()
{
if(currPhysicsState.GetLinearMomentum() !=currPhysicsState.GetLinearMomentum())
{
//error

View File

@ -43,7 +43,8 @@ namespace GameLogic
static Oyster::Physics::ICustomBody::SubscriptMessage DefaultCollisionBefore(Oyster::Physics::ICustomBody *rigidBodyLevel, Oyster::Physics::ICustomBody *obj);
static Oyster::Physics::ICustomBody::SubscriptMessage DefaultCollisionAfter(Oyster::Physics::ICustomBody *rigidBodyLevel, Oyster::Physics::ICustomBody *obj, Oyster::Math::Float kineticEnergyLoss);
private:
public: //TODO: Hax This should be private when level is dynamic
OBJECT_TYPE type;
int objectID;

View File

@ -208,7 +208,7 @@ void Player::DamageLife(int damage)
{
this->life = 0;
playerState = PLAYER_STATE_DEAD;
this->gameInstance->onDisableFnc(this);
this->gameInstance->onDisableFnc(this, 0.0f);
}
}

View File

@ -85,8 +85,8 @@ namespace GameLogic
int teamID;
Weapon *weapon;
PLAYER_STATE playerState;
Oyster::Math::Float3 lookDir;
Oyster::Math::Float dx;
Oyster::Math::Float3 lookDir; //Duplicate in Object.h?
Oyster::Math::Float dx; //dx of what?
bool hasTakenDamage;
float invincibleCooldown;

View File

@ -35,13 +35,11 @@ TeamManager::~TeamManager(void)
void TeamManager::RespawnPlayerRandom(Player *player)
{
// Whats going on here?
int teamID = player->GetTeamID(); // ?
// ?
Player *respawnOnThis = this->teams[teamID]->GetPlayer(0); // ?
// ?
player->Respawn(respawnOnThis->GetPosition()); // ?
// player->Respawn(player->GetPosition()); ?
int teamID = player->GetTeamID();
Player *respawnOnThis = this->teams[teamID]->GetPlayer(0);
player->Respawn(respawnOnThis->GetPosition());
}
void TeamManager::CreateTeam(int teamSize)

View File

@ -21,46 +21,16 @@
namespace GameLogic
{
/*
struct Protocol_LobbyCreateGame :public Oyster::Network::CustomProtocolObject
{
char* mapName;
char gameId;
Protocol_LobbyCreateGame()
{
this->protocol[0].value = protocol_Lobby_Create;
this->protocol[0].type = Oyster::Network::NetAttributeType_Short;
this->protocol[1].type = Oyster::Network::NetAttributeType_CharArray;
this->protocol[2].type = Oyster::Network::NetAttributeType_Char;
}
Protocol_LobbyCreateGame(Oyster::Network::CustomNetProtocol& o)
{
mapName = o[1].value.netCharPtr;
gameId = o[2].value.netChar;
}
Oyster::Network::CustomNetProtocol GetProtocol() override
{
protocol[1].value = mapName;
protocol[2].value = gameId;
return &protocol;
}
private:
Oyster::Network::CustomNetProtocol protocol;
};
*/
struct Protocol_LobbyStartGame :public Oyster::Network::CustomProtocolObject
{
short clientID; // The unuiqe id reprsenting a specific client
std::string modelName;
float worldMatrix[16];
Protocol_LobbyStartGame()
Protocol_LobbyCreateGame()
{
int c = 0;
this->protocol[c].value = protocol_Lobby_Start;
this->protocol[c].value = protocol_Lobby_Create;
this->protocol[c++].type = Oyster::Network::NetAttributeType_Short;
this->protocol[c++].type = Oyster::Network::NetAttributeType_Short;
@ -70,10 +40,10 @@ namespace GameLogic
}
this->protocol[c++].type = Oyster::Network::NetAttributeType_CharArray;
}
Protocol_LobbyStartGame(short _clientID, std::string name, float world[16])
Protocol_LobbyCreateGame(short _clientID, std::string name, float world[16])
{
int c = 0;
this->protocol[c].value = protocol_Lobby_Start;
this->protocol[c].value = protocol_Lobby_Create;
this->protocol[c++].type = Oyster::Network::NetAttributeType_Short;
this->protocol[c++].type = Oyster::Network::NetAttributeType_Short;
@ -88,7 +58,7 @@ namespace GameLogic
modelName = name;
memcpy(&worldMatrix[0], &world[0], sizeof(float) * 16);
}
Protocol_LobbyStartGame(Oyster::Network::CustomNetProtocol& o)
Protocol_LobbyCreateGame(Oyster::Network::CustomNetProtocol o)
{
int c = 1;
clientID = o[c++].value.netInt;
@ -96,7 +66,7 @@ namespace GameLogic
{
this->worldMatrix[i] = o[c++].value.netFloat;
}
modelName = o[c++].value.netCharPtr;
modelName.assign(o[c++].value.netCharPtr);
}
Oyster::Network::CustomNetProtocol GetProtocol() override
{
@ -116,6 +86,39 @@ namespace GameLogic
};
struct Protocol_LobbyStartGame :public Oyster::Network::CustomProtocolObject
{
float seconds;
Protocol_LobbyStartGame()
{
this->protocol[0].value = protocol_Lobby_Start;
this->protocol[0].type = Oyster::Network::NetAttributeType_Short;
this->protocol[1].type = Oyster::Network::NetAttributeType_Float;
seconds = 0;
}
Protocol_LobbyStartGame(float _seconds)
{
this->protocol[0].value = protocol_Lobby_Start;
this->protocol[0].type = Oyster::Network::NetAttributeType_Short;
this->protocol[1].type = Oyster::Network::NetAttributeType_Float;
seconds = _seconds;
}
Protocol_LobbyStartGame(Oyster::Network::CustomNetProtocol& o)
{
seconds = o[1].value.netFloat;
}
Oyster::Network::CustomNetProtocol GetProtocol() override
{
this->protocol[1].value = seconds;
return protocol;
}
private:
Oyster::Network::CustomNetProtocol protocol;
};
struct Protocol_LobbyLogin :public Oyster::Network::CustomProtocolObject
{
// Login stuff

View File

@ -24,7 +24,7 @@ namespace DanBias
GameLogic::IPlayerData* ReleasePlayer();
Utility::DynamicMemory::SmartPointer<Oyster::Network::NetworkClient> GetClient();
Utility::DynamicMemory::SmartPointer<Oyster::Network::NetworkClient> ReleaseClient();
int GetID() const;
float GetSinceLastResponse() const;
bool IsReady() const;
bool Equals(const Oyster::Network::NetworkClient* c);
@ -35,7 +35,6 @@ namespace DanBias
private:
GameLogic::IPlayerData* player;
Utility::DynamicMemory::SmartPointer<Oyster::Network::NetworkClient> client;
int id;
bool isReady;
float secondsSinceLastResponse;
};

View File

@ -35,7 +35,7 @@ namespace DanBias
bool broadcast; //Not fully implemented!
ServerInitDesc()
: serverName("Game Server")
, listenPort(15151)
, listenPort(15152)
, broadcast(true)
{};
};

View File

@ -63,7 +63,6 @@ namespace DanBias
// TODO: find out what this method does..
void ClientEventCallback(Oyster::Network::NetEvent<Oyster::Network::NetworkClient*, Oyster::Network::NetworkClient::ClientEventArgs> e) override;
//Sends a client to the owner, if obj is NULL then all clients is sent
void SendToOwner(DanBias::GameClient* obj);
@ -91,6 +90,7 @@ namespace DanBias
//Callback method recieving from gamelogic
static void ObjectMove ( GameLogic::IObjectData* movedObject );
static void ObjectDisabled ( GameLogic::IObjectData* movedObject, float seconds );
//Private member variables
private:
@ -102,7 +102,8 @@ namespace DanBias
NetworkSession* owner;
bool isCreated;
bool isRunning;
float logicDeltaTime;
float logicFrameTime;
float networkFrameTime;
Utility::WinTimer logicTimer;
Utility::WinTimer networkTimer;
GameDescription description;

View File

@ -11,12 +11,10 @@ using namespace Oyster::Network;
using namespace DanBias;
using namespace GameLogic;
static int gameClientIDCount = 1;
GameClient::GameClient(SmartPointer<NetworkClient> client, GameLogic::IPlayerData* player)
{
this->client = client;
this->id = gameClientIDCount++;
this->player = player;
isReady = false;
}
@ -24,7 +22,6 @@ GameClient::~GameClient()
{
this->client->Disconnect();
this->player = 0;
this->id = -1;
isReady = false;
}
@ -48,10 +45,7 @@ SmartPointer<Oyster::Network::NetworkClient> GameClient::ReleaseClient()
this->client = 0;
return temp;
}
int GameClient::GetID() const
{
return this->id;
}
float GameClient::GetSinceLastResponse() const
{
return this->secondsSinceLastResponse;

View File

@ -89,7 +89,7 @@ namespace DanBias
if(this->gameSession)
{
this->gameSession.ClientConnectedEvent(client);
this->gameSession.Attach(client);
}
else
{

View File

@ -3,19 +3,16 @@
/////////////////////////////////////////////////////////////////////
#include "..\GameSession.h"
#include "..\GameClient.h"
#include <WinTimer.h>
#include <Protocols.h>
#include <PostBox\PostBox.h>
#include <GameLogicStates.h>
#include <OysterMath.h>
#define NOMINMAX
#include <Windows.h>
#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;
@ -25,19 +22,20 @@ using namespace GameLogic;
namespace DanBias
{
Utility::WinTimer testTimer;
int testID = -1;
bool GameSession::DoWork( )
{
if(this->isRunning)
{
float dt = (float)this->logicTimer.getElapsedSeconds();
this->logicDeltaTime += dt;
this->logicTimer.reset();
while( logicDeltaTime >= DELTA_TIME_120 )
if( dt >= this->logicFrameTime )
{
this->ProcessClients();
this->gameInstance.NewFrame();
logicDeltaTime -= DELTA_TIME_120;
this->logicTimer.reset();
}
}
@ -70,11 +68,16 @@ namespace DanBias
case NetworkClient::ClientEventArgs::EventType_ProtocolFailedToRecieve:
break;
case NetworkClient::ClientEventArgs::EventType_ProtocolFailedToSend:
printf("\t(%i : %s) - EventType_ProtocolFailedToSend\n", e.sender->GetID(), e.sender->GetIpAddress().c_str());
printf("\t(%i : %s) - EventType_ProtocolFailedToSend\n", cl->GetClient()->GetID(), e.sender->GetIpAddress().c_str());
this->Detach(e.sender);
break;
case NetworkClient::ClientEventArgs::EventType_ProtocolRecieved:
printf("\t(%i : %s) - EventType_ProtocolRecieved\n", e.sender->GetID(), e.sender->GetIpAddress().c_str());
printf("\t(%i : %s) - EventType_ProtocolRecieved\n", cl->GetClient()->GetID(), e.sender->GetIpAddress().c_str());
testID = 2;
if(cl->GetPlayer()->GetID() == testID)//TODO: TEST
{
testTimer.reset();
}
this->ParseProtocol(e.args.data.protocol, cl);
break;
}
@ -82,21 +85,32 @@ namespace DanBias
void GameSession::ObjectMove(GameLogic::IObjectData* movedObject)
{
if(gameSession->networkTimer.getElapsedSeconds() >= DELTA_TIME_60)
float dt = GameSession::gameSession->networkTimer.getElapsedSeconds();
//Duh... This was causing alot of problems, it's in the wrong place...
//Need to figure out where to put this frame locker.
//We only need to send network packages when necessary, ie not 120 times per frame.
//I think it would be enough with 60-70 packages per second due to the nature of
//graphics update (60 fps) on the client side. To send more than this would be lost
//bandwidth.
//if( dt >= GameSession::gameSession->networkFrameTime )
{
gameSession->networkTimer.reset();
GameSession::gameSession->networkTimer.reset();
GameLogic::IObjectData* obj = movedObject;
if(dynamic_cast<IPlayerData*> (movedObject))
if(movedObject->GetID() == testID) //TODO: TEST
{
int id = obj->GetID();
Oyster::Math::Float4x4 world = obj->GetOrientation();
Protocol_ObjectPosition p(world, id);
GameSession::gameSession->Send(p.GetProtocol());
float sec = (float)testTimer.getElapsedSeconds();
sec = 0;
}
else if(dynamic_cast<GameLogic::ILevelData*>(obj))
int id = obj->GetID();
Protocol_ObjectPosition p(obj->GetOrientation(), id);
//if(id != 1)
GameSession::gameSession->Send(p.GetProtocol());
/*
if(dynamic_cast<GameLogic::ILevelData*>(obj))
{
obj = ((GameLogic::ILevelData*)movedObject)->GetObjectAt(0);
if(obj)
@ -135,9 +149,14 @@ namespace DanBias
}
}
}
*/
}
}
void GameSession::ObjectDisabled( GameLogic::IObjectData* movedObject, float seconds )
{
GameSession::gameSession->Send(Protocol_ObjectDisable(movedObject->GetID(), seconds).GetProtocol());
}
//*****************************************************//
//****************** Protocol methods *****************//
@ -258,7 +277,7 @@ namespace DanBias
}
void GameSession::General_Text ( Protocol_General_Text& p, DanBias::GameClient* c )
{
printf("Message recieved from (%i):\t %s\n", c->GetID(), p.text.c_str());
printf("Message recieved from (%i):\t %s\n", c->GetClient()->GetID(), p.text.c_str());
}
}//End namespace DanBias

View File

@ -11,6 +11,12 @@
#include <Windows.h>
#include <Queue.h>
#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;
@ -29,7 +35,10 @@ namespace DanBias
this->isCreated = false;
this->isRunning = false;
this->gameSession = this;
this->logicDeltaTime = 0.0f;
this->logicFrameTime = DELTA_TIME_20;
this->networkFrameTime = DELTA_TIME_20;
this->networkTimer.reset();
this->logicTimer.reset();
memset(&this->description, 0, sizeof(GameDescription));
}
@ -54,7 +63,7 @@ namespace DanBias
/* standard initialization of some data */
NetworkSession::clients = desc.clients;
this->clients.Resize(desc.clients.Size());
this->clients.Reserve(desc.clients.Size());
this->owner = desc.owner;
/* Initiate the game instance */
@ -63,13 +72,6 @@ namespace DanBias
printf("Failed to initiate the game instance\n");
}
/* Create the game level */
if(!(this->levelData = this->gameInstance.CreateLevel()))
{
printf("Level not created!");
return false;
}
/* Create the players in the game instance */
GameLogic::IPlayerData* p = 0;
for (unsigned int i = 0; i < desc.clients.Size(); i++)
@ -77,7 +79,7 @@ namespace DanBias
if( (p = this->gameInstance.CreatePlayer()) )
{
desc.clients[i]->SetOwner(this);
this->clients[i] = new GameClient(desc.clients[i], p);
this->clients.Push(new GameClient(desc.clients[i], p));
}
else
{
@ -85,19 +87,26 @@ namespace DanBias
}
}
/* Create the worker thread */
if(this->worker.Create(this, false) != OYSTER_THREAD_ERROR_SUCCESS)
/* Create the game level */
if(!(this->levelData = this->gameInstance.CreateLevel()))
{
printf("Level not created!");
return false;
this->worker.SetPriority(Oyster::Thread::OYSTER_THREAD_PRIORITY_3);
}
/* Set some game instance data options */
this->gameInstance.SetSubscription(GameLogic::GameEvent::ObjectEventFunctionType_OnMove, GameSession::ObjectMove);
//this->gameInstance.SetSubscription(GameLogic::GameEvent::ObjectEventFunctionType_OnDead, GameSession::ObjectDead);
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;
}
@ -115,9 +124,7 @@ namespace DanBias
void GameSession::ThreadEntry( )
{
//A timer so we dont lock because 1 client disconnected..
Utility::WinTimer t;
//List with clients that we are waiting on..
DynamicArray<SmartPointer<GameClient>> readyList = this->clients;
//First we need to clean invalid clients, if any, and tell them to start loading game data
@ -129,12 +136,13 @@ namespace DanBias
}
else
{
Protocol_LobbyStartGame p(readyList[i]->GetPlayer()->GetID(), "char_white.dan", readyList[i]->GetPlayer()->GetOrientation());
Protocol_LobbyCreateGame p(readyList[i]->GetPlayer()->GetID(), "char_white.dan", readyList[i]->GetPlayer()->GetOrientation());
readyList[i]->GetClient()->Send(p);
}
}
unsigned int readyCounter = readyList.Size();
//Sync with clients
while (readyCounter != 0)
{
@ -143,10 +151,10 @@ namespace DanBias
{
if(readyList[i] && readyList[i]->IsReady())
{
//Need to send information about other players to all players
for (unsigned int k = 0; k < readyList.Size(); k++)
//Need to send information about other players, to all players
for (unsigned int k = 0; k < this->clients.Size(); k++)
{
if(k != i && this->clients[k])
if((this->clients[k] && readyList[i]) && readyList[i]->GetClient()->GetID() != this->clients[k]->GetClient()->GetID())
{
Protocol_ObjectCreate p(this->clients[k]->GetPlayer()->GetOrientation(), this->clients[k]->GetPlayer()->GetID(), "char_white.dan"); //The model name will be custom later..
readyList[i]->GetClient()->Send(p);
@ -159,6 +167,14 @@ namespace DanBias
}
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<NetworkClient> client)
@ -166,7 +182,11 @@ namespace DanBias
if(!this->isCreated) return false;
client->SetOwner(this);
SmartPointer<GameClient> obj = new GameClient(client, this->gameInstance.CreatePlayer());
IPlayerData* player = this->gameInstance.CreatePlayer();
if(!player) return false;
SmartPointer<GameClient> obj = new GameClient(client, player);
for (unsigned int i = 0; i < clients.Size(); i++)
{
@ -184,6 +204,7 @@ namespace DanBias
void GameSession::CloseSession( bool dissconnectClients )
{
this->worker.Terminate();
NetworkSession::CloseSession(true);
this->clients.Clear();
}

View File

@ -333,6 +333,12 @@ namespace Oyster
this->isDisturbed = true;
}
inline void CustomBodyState::ApplyFriction( const ::Oyster::Math::Float3 &j )
{
this->linearImpulse += j;
this->isDisturbed = true;
}
inline void CustomBodyState::ApplyForwarding( const ::Oyster::Math::Float3 &deltaPos, const ::Oyster::Math::Float3 &deltaAxis )
{
this->deltaPos += deltaPos;

View File

@ -109,6 +109,7 @@ namespace Oyster { namespace Physics
void ApplyLinearImpulse( const ::Oyster::Math::Float3 &j );
void ApplyAngularImpulse( const ::Oyster::Math::Float3 &j );
void ApplyImpulse( const ::Oyster::Math::Float3 &j, const ::Oyster::Math::Float3 &at, const ::Oyster::Math::Float3 &normal );
void CustomBodyState::ApplyFriction( const ::Oyster::Math::Float3 &j);
void ApplyForwarding( const ::Oyster::Math::Float3 &deltaPos, const ::Oyster::Math::Float3 &deltaAxis );
bool IsSpatiallyAltered() const;

View File

@ -117,7 +117,7 @@ namespace Utility
template <typename T> const T& DynamicArray<T>::operator[](unsigned int index) const
{
assert(index < this->size);
assert((int)index < this->size);
return this->data[index];
}

View File

@ -300,6 +300,7 @@ void NetworkClient::Disconnect()
privateData->thread.Terminate();
privateData->connection.Disconnect();
this->privateData->sendQueue.Clear();
this->privateData->recieveQueue.Clear();
}

View File

@ -516,7 +516,7 @@ namespace Oyster { namespace Collision3D { namespace Utility
Float4 C = sphereA.center;
C -= sphereB.center;
Float r = (sphereA.radius + sphereB.radius);
Float dotprod = C.Dot(C);
if (r*r >= C.Dot(C))
{
return true; // Intersect detected!

View File

@ -279,7 +279,7 @@ namespace Oyster { namespace Physics3D
******************************************************************/
inline ::Oyster::Math::Float ForceField( ::Oyster::Math::Float g, ::Oyster::Math::Float massA, ::Oyster::Math::Float massB, ::Oyster::Math::Float radiusSquared )
{
return g * massA * massB / radiusSquared;
return g * massB / radiusSquared;
}
/******************************************************************

View File

@ -51,11 +51,18 @@ void RigidBody::Update_LeapFrog( Float updateFrameLength )
// updating the linear
//Decrease momentum with 1% as "fall-off"
//! HACK: @todo Add real solution with fluid drag
this->momentum_Linear = this->momentum_Linear*0.9999f;
this->momentum_Angular = this->momentum_Angular*0.9999f;
this->momentum_Linear = this->momentum_Linear*0.99f;
this->momentum_Angular = this->momentum_Angular*0.99f;
// ds = dt * Formula::LinearVelocity( m, avg_G ) = dt * avg_G / m = (dt / m) * avg_G
this->centerPos += ( updateFrameLength / this->mass ) * AverageWithDelta( this->momentum_Linear, this->impulse_Linear );
Float3 delta = AverageWithDelta( this->momentum_Linear, this->impulse_Linear );
Float3 newPos = ( updateFrameLength)*this->momentum_Linear;
this->centerPos += newPos;
if(this->mass == 70)
{
const char *breakpoint = "STOP";
}
// updating the angular
// dO = dt * Formula::AngularVelocity( (RI)^-1, avg_H ) = dt * (RI)^-1 * avg_H