diff --git a/Code/DanBias.sln b/Code/DanBias.sln index 033e050e..51ad5665 100644 --- a/Code/DanBias.sln +++ b/Code/DanBias.sln @@ -697,7 +697,8 @@ Global {6391E709-D9FA-4FEF-A3B9-4343DB5A0C63}.MinSizeRel|Mixed Platforms.Build.0 = Release|Win32 {6391E709-D9FA-4FEF-A3B9-4343DB5A0C63}.MinSizeRel|Win32.ActiveCfg = Release|Win32 {6391E709-D9FA-4FEF-A3B9-4343DB5A0C63}.MinSizeRel|Win32.Build.0 = Release|Win32 - {6391E709-D9FA-4FEF-A3B9-4343DB5A0C63}.MinSizeRel|x64.ActiveCfg = Release|Win32 + {6391E709-D9FA-4FEF-A3B9-4343DB5A0C63}.MinSizeRel|x64.ActiveCfg = Release|x64 + {6391E709-D9FA-4FEF-A3B9-4343DB5A0C63}.MinSizeRel|x64.Build.0 = Release|x64 {6391E709-D9FA-4FEF-A3B9-4343DB5A0C63}.MinSizeRel|x86.ActiveCfg = Release|Win32 {6391E709-D9FA-4FEF-A3B9-4343DB5A0C63}.MinSizeRel|x86.Build.0 = Release|Win32 {6391E709-D9FA-4FEF-A3B9-4343DB5A0C63}.Release|Any CPU.ActiveCfg = Release|Win32 @@ -714,7 +715,8 @@ Global {6391E709-D9FA-4FEF-A3B9-4343DB5A0C63}.RelWithDebInfo|Mixed Platforms.Build.0 = Release|Win32 {6391E709-D9FA-4FEF-A3B9-4343DB5A0C63}.RelWithDebInfo|Win32.ActiveCfg = Release|Win32 {6391E709-D9FA-4FEF-A3B9-4343DB5A0C63}.RelWithDebInfo|Win32.Build.0 = Release|Win32 - {6391E709-D9FA-4FEF-A3B9-4343DB5A0C63}.RelWithDebInfo|x64.ActiveCfg = Release|Win32 + {6391E709-D9FA-4FEF-A3B9-4343DB5A0C63}.RelWithDebInfo|x64.ActiveCfg = Release|x64 + {6391E709-D9FA-4FEF-A3B9-4343DB5A0C63}.RelWithDebInfo|x64.Build.0 = Release|x64 {6391E709-D9FA-4FEF-A3B9-4343DB5A0C63}.RelWithDebInfo|x86.ActiveCfg = Release|Win32 {6391E709-D9FA-4FEF-A3B9-4343DB5A0C63}.RelWithDebInfo|x86.Build.0 = Release|Win32 {67D0FB00-FF1F-4DE4-84BD-664AE93D25EE}.Debug|Any CPU.ActiveCfg = Debug|Win32 @@ -731,7 +733,8 @@ Global {67D0FB00-FF1F-4DE4-84BD-664AE93D25EE}.MinSizeRel|Mixed Platforms.Build.0 = Release|Win32 {67D0FB00-FF1F-4DE4-84BD-664AE93D25EE}.MinSizeRel|Win32.ActiveCfg = Release|Win32 {67D0FB00-FF1F-4DE4-84BD-664AE93D25EE}.MinSizeRel|Win32.Build.0 = Release|Win32 - {67D0FB00-FF1F-4DE4-84BD-664AE93D25EE}.MinSizeRel|x64.ActiveCfg = Release|Win32 + {67D0FB00-FF1F-4DE4-84BD-664AE93D25EE}.MinSizeRel|x64.ActiveCfg = Release|x64 + {67D0FB00-FF1F-4DE4-84BD-664AE93D25EE}.MinSizeRel|x64.Build.0 = Release|x64 {67D0FB00-FF1F-4DE4-84BD-664AE93D25EE}.MinSizeRel|x86.ActiveCfg = Release|Win32 {67D0FB00-FF1F-4DE4-84BD-664AE93D25EE}.MinSizeRel|x86.Build.0 = Release|Win32 {67D0FB00-FF1F-4DE4-84BD-664AE93D25EE}.Release|Any CPU.ActiveCfg = Release|Win32 @@ -748,7 +751,8 @@ Global {67D0FB00-FF1F-4DE4-84BD-664AE93D25EE}.RelWithDebInfo|Mixed Platforms.Build.0 = Release|Win32 {67D0FB00-FF1F-4DE4-84BD-664AE93D25EE}.RelWithDebInfo|Win32.ActiveCfg = Release|Win32 {67D0FB00-FF1F-4DE4-84BD-664AE93D25EE}.RelWithDebInfo|Win32.Build.0 = Release|Win32 - {67D0FB00-FF1F-4DE4-84BD-664AE93D25EE}.RelWithDebInfo|x64.ActiveCfg = Release|Win32 + {67D0FB00-FF1F-4DE4-84BD-664AE93D25EE}.RelWithDebInfo|x64.ActiveCfg = Release|x64 + {67D0FB00-FF1F-4DE4-84BD-664AE93D25EE}.RelWithDebInfo|x64.Build.0 = Release|x64 {67D0FB00-FF1F-4DE4-84BD-664AE93D25EE}.RelWithDebInfo|x86.ActiveCfg = Release|Win32 {67D0FB00-FF1F-4DE4-84BD-664AE93D25EE}.RelWithDebInfo|x86.Build.0 = Release|Win32 EndGlobalSection @@ -764,7 +768,6 @@ Global {C83A6FAD-E71F-4B1E-9D63-E93E61DDC012} = {20720CA7-795C-45AD-A302-9383A6DD503A} {8690FDDF-C5B7-4C42-A337-BD5243F29B85} = {20720CA7-795C-45AD-A302-9383A6DD503A} {2A1BC987-AF42-4500-802D-89CD32FC1309} = {20720CA7-795C-45AD-A302-9383A6DD503A} - {6391E709-D9FA-4FEF-A3B9-4343DB5A0C63} = {20720CA7-795C-45AD-A302-9383A6DD503A} {C4C76A8D-44C5-4452-9F61-39C7E01CBDB4} = {F156EEBC-0195-4020-8700-4433208DE12B} {3EA5F14D-2A71-4588-A69D-87C4571C580F} = {F156EEBC-0195-4020-8700-4433208DE12B} {7E3990D2-3D94-465C-B58D-64A74B3ECF9B} = {1322B12B-5E37-448A-AAAF-F637460DCB23} @@ -773,6 +776,5 @@ Global {2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE} = {1322B12B-5E37-448A-AAAF-F637460DCB23} {604A12A7-07BF-4482-BDF3-7101C811F121} = {C83A6FAD-E71F-4B1E-9D63-E93E61DDC012} {C8CBA520-5D7D-4D61-A8DA-6E05FD132BCB} = {C83A6FAD-E71F-4B1E-9D63-E93E61DDC012} - {67D0FB00-FF1F-4DE4-84BD-664AE93D25EE} = {C83A6FAD-E71F-4B1E-9D63-E93E61DDC012} EndGlobalSection EndGlobal diff --git a/Code/Game/GameClient/GameClientState/GameState.cpp b/Code/Game/GameClient/GameClientState/GameState.cpp index 078bc74b..4686018f 100644 --- a/Code/Game/GameClient/GameClientState/GameState.cpp +++ b/Code/Game/GameClient/GameClientState/GameState.cpp @@ -581,7 +581,7 @@ const GameClientState::NetEvent & GameState::DataRecieved( const GameClientState return GameClientState::event_processed; case protocol_Gameplay_ObjectDisconnectPlayer: { - //Removes + //Remove the disconnected player Protocol_ObjectDisconnectPlayer decoded(data); auto object = this->privData->dynamicObjects->find( decoded.objectID ); if( object != this->privData->dynamicObjects->end() ) diff --git a/Code/Game/GameClient/GameClientState/GamingUI.cpp b/Code/Game/GameClient/GameClientState/GamingUI.cpp index 03840881..6d8c0d37 100644 --- a/Code/Game/GameClient/GameClientState/GamingUI.cpp +++ b/Code/Game/GameClient/GameClientState/GamingUI.cpp @@ -105,7 +105,7 @@ void GamingUI::ReadKeyInput() float yaw = this->input->GetYaw(); //if( yaw != 0.0f ) //This made the camera reset to a specific rotation. { - this->netClient->Send( Protocol_PlayerLeftTurn(yaw * mouseSensitivity) ); + this->netClient->Send( Protocol_PlayerLeftTurn(yaw * mouseSensitivity,camera->GetLook()) ); } } diff --git a/Code/Game/GameLogic/AttatchmentMassDriver.cpp b/Code/Game/GameLogic/AttatchmentMassDriver.cpp index 89de1f3e..a092c81e 100644 --- a/Code/Game/GameLogic/AttatchmentMassDriver.cpp +++ b/Code/Game/GameLogic/AttatchmentMassDriver.cpp @@ -66,6 +66,7 @@ void AttatchmentMassDriver::Update(float dt) //state.centerPos = pos; heldObject->SetPosition(pos); + heldObject->SetLinearVelocity(Oyster::Math::Float3::null); //heldObject->SetState(state); } @@ -82,8 +83,7 @@ void AttatchmentMassDriver::ForcePush(const GameLogic::WEAPON_FIRE &usage, float if(hasObject) { - Oyster::Physics::API::Instance().ReleaseFromLimbo(heldObject); - pushForce = Oyster::Math::Float4(this->owner->GetLookDir()) * (400); + pushForce = Oyster::Math::Float4(this->owner->GetLookDir()) * (800); heldObject->ApplyImpulse((Oyster::Math::Float3)pushForce); hasObject = false; diff --git a/Code/Game/GameLogic/CollisionManager.cpp b/Code/Game/GameLogic/CollisionManager.cpp index 7b2b7ce1..3e042765 100644 --- a/Code/Game/GameLogic/CollisionManager.cpp +++ b/Code/Game/GameLogic/CollisionManager.cpp @@ -20,37 +20,50 @@ using namespace GameLogic; void Teleport(Oyster::Physics::ICustomBody &obj, Oyster::Math::Float3 target); //Physics::ICustomBody::SubscriptMessage - void Player::PlayerCollision(Oyster::Physics::ICustomBody *rigidBodyPlayer, Oyster::Physics::ICustomBody *obj, Oyster::Math::Float kineticEnergyLoss) + void Player::PlayerCollision(Oyster::Physics::ICustomBody *objA, Oyster::Physics::ICustomBody *objB, Oyster::Math::Float kineticEnergyLoss) { - Player *player = ((Player*)(rigidBodyPlayer->GetCustomTag())); - Object *realObj = (Object*)obj->GetCustomTag(); //needs to be changed? + Object *realObjA = ((Object*)(objA->GetCustomTag())); + Player *player; + Object *realObjB = (Object*)objB->GetCustomTag(); //needs to be changed? - if(!realObj) + if(!realObjA) return; - if(!player) + if(!realObjB) return; - switch (realObj->GetObjectType()) + //check who is player and who is the object + if(realObjA->GetObjectType() == ObjectSpecialType::ObjectSpecialType_Player) + { + player = (Player*)realObjA; + } + else + { + player = (Player*)realObjB; + realObjB = realObjA; + } + + + switch (realObjB->GetObjectType()) { case ObjectSpecialType::ObjectSpecialType_Generic: - PlayerVObject(*player,*realObj, kineticEnergyLoss); + PlayerVObject(*player,*realObjB, kineticEnergyLoss); //return Physics::ICustomBody::SubscriptMessage_none; break; case ObjectSpecialType::ObjectSpecialType_StandardBox: - PlayerVObject(*player,*realObj, kineticEnergyLoss); + PlayerVObject(*player,*realObjB, kineticEnergyLoss); //return Physics::ICustomBody::SubscriptMessage_none; break; case ObjectSpecialType::ObjectSpecialType_Player: //return Physics::ICustomBody::SubscriptMessage_none; break; case ObjectSpecialType::ObjectSpecialType_World: - PlayerVObject(*player,*realObj, kineticEnergyLoss); + PlayerVObject(*player,*realObjB, kineticEnergyLoss); //player->playerState = PLAYER_STATE::PLAYER_STATE_WALKING; break; case ObjectSpecialType::ObjectSpecialType_CrystalFormation: - PlayerVLethalObject(*player,*realObj, kineticEnergyLoss,realObj->GetExtraDamageOnCollision()); + PlayerVLethalObject(*player,*realObjB, kineticEnergyLoss,realObjB->GetExtraDamageOnCollision()); //player->playerState = PLAYER_STATE::PLAYER_STATE_WALKING; break; } @@ -160,12 +173,31 @@ using namespace GameLogic; //Collision between a player and a general static or dynamic object //use kinetic energyloss of the collision in order too determin how much damage to take //use as part of the damage algorithm - int damageDone = 0; - int forceThreashHold = 200000; + Oyster::Math::Float3 objPrevVel = obj.GetRigidBody()->GetState().previousVelocity; + Oyster::Math::Float3 playerPrevVel = player.GetRigidBody()->GetState().previousVelocity; - if(kineticEnergyLoss > forceThreashHold) //should only take damage if the force is high enough + Oyster::Math::Float3 deltaPos = (player.GetPosition() - obj.GetPosition()); + Oyster::Math::Float deltaSpeed = (objPrevVel - playerPrevVel).GetMagnitude(); + Oyster::Math::Float angularFactor = deltaPos.GetNormalized().Dot( (objPrevVel - playerPrevVel).GetNormalized()); + + Oyster::Math::Float impactPower = deltaSpeed * angularFactor; + Oyster::Math::Float damageFactor = 0.1f; + + + int damageDone = 0; + int forceThreashHold = 100; //FIX: balance this + + if(impactPower > forceThreashHold) //should only take damage if the force is high enough { - damageDone = (int)(kineticEnergyLoss * 0.10f); + if(obj.GetRigidBody()->GetState().mass == 0) + { + damageDone = impactPower * damageFactor; + } + else + { + damageDone = (impactPower * obj.GetRigidBody()->GetState().mass)* damageFactor; + } + //player.DamageLife(damageDone); } @@ -236,6 +268,7 @@ using namespace GameLogic; case ObjectSpecialType::ObjectSpecialType_StandardBox: weapon->heldObject = obj; //weapon now holds the object weapon->hasObject = true; + break; } diff --git a/Code/Game/GameLogic/DynamicObject.cpp b/Code/Game/GameLogic/DynamicObject.cpp index 6df5bef0..e6d9ff49 100644 --- a/Code/Game/GameLogic/DynamicObject.cpp +++ b/Code/Game/GameLogic/DynamicObject.cpp @@ -2,37 +2,76 @@ #include "CollisionManager.h" using namespace GameLogic; +using namespace Oyster::Math; DynamicObject::DynamicObject() :Object() { - + this->isReleased = false; + this->isActive = true; } DynamicObject::DynamicObject(Oyster::Physics::ICustomBody *rigidBody , void (*EventOnCollision)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter,Oyster::Math::Float kineticEnergyLoss), ObjectSpecialType type, int objectID) :Object(rigidBody, EventOnCollision, type, objectID) { - + this->isReleased = false; + this->isActive = true; } DynamicObject::DynamicObject(Oyster::Physics::ICustomBody *rigidBody , Oyster::Physics::ICustomBody::SubscriptMessage (*EventOnCollision)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter,Oyster::Math::Float kineticEnergyLoss), ObjectSpecialType type, int objectID) :Object(rigidBody, EventOnCollision, type, objectID) { - + this->isReleased = false; + this->isActive = true; } DynamicObject::DynamicObject(Oyster::Physics::ICustomBody *rigidBody , void (*EventOnCollision)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter,Oyster::Math::Float kineticEnergyLoss), ObjectSpecialType type, int objectID, Oyster::Math::Float extraDamageOnCollision) :Object(rigidBody, EventOnCollision, type, objectID) { this->extraDamageOnCollision = extraDamageOnCollision; + this->isReleased = false; + this->isActive = true; } DynamicObject::DynamicObject(Oyster::Physics::ICustomBody *rigidBody , Oyster::Physics::ICustomBody::SubscriptMessage (*EventOnCollision)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter,Oyster::Math::Float kineticEnergyLoss), ObjectSpecialType type, int objectID, Oyster::Math::Float extraDamageOnCollision) :Object(rigidBody, EventOnCollision, type, objectID) { this->extraDamageOnCollision = extraDamageOnCollision; + this->isReleased = false; + this->isActive = true; } DynamicObject::~DynamicObject(void) { +} + +void DynamicObject::ReleaseDynamicObject() +{ + //TODO: Inactivate the physics object + if(this->isReleased) return; + + this->isReleased = true; + this->isActive = false; + this->lookDirection = Float3::null; + this->forwardDirection = Float3::null; + this->scale = Float3::null; + this->extraDamageOnCollision = 0; + +} +bool DynamicObject::IsReleased() +{ + return this->isReleased; +} +bool DynamicObject::IsActive() +{ + return this->isActive; +} +void DynamicObject::Inactivate() +{ + this->isActive = false; +} +void DynamicObject::Activate() +{ + this->isActive = true; + this->isReleased = false; } \ No newline at end of file diff --git a/Code/Game/GameLogic/DynamicObject.h b/Code/Game/GameLogic/DynamicObject.h index 2d5fa617..8a32e849 100644 --- a/Code/Game/GameLogic/DynamicObject.h +++ b/Code/Game/GameLogic/DynamicObject.h @@ -22,7 +22,15 @@ namespace GameLogic ~DynamicObject(void); + void ReleaseDynamicObject(); + bool IsReleased(); + bool IsActive(); + void Inactivate(); + void Activate(); + private: + bool isActive; + bool isReleased; }; diff --git a/Code/Game/GameLogic/Game.cpp b/Code/Game/GameLogic/Game.cpp index 8dd7ffa6..c599fecf 100644 --- a/Code/Game/GameLogic/Game.cpp +++ b/Code/Game/GameLogic/Game.cpp @@ -67,6 +67,17 @@ void Game::GetAllPlayerPositions() const Game::PlayerData* Game::CreatePlayer() { + //Se if there is a free player somewhere in our list + for (unsigned int i = 0; i < this->players.Size(); i++) + { + if(this->players[i] && this->players[i]->player->IsReleased()) + { + //We give the body to someone else + this->players[i]->player->Activate(); + return this->players[i]; + } + } + // Find a free space in array or insert at end int insert = InsertObject(this->players, (PlayerData*)0); int freeID = 0; diff --git a/Code/Game/GameLogic/Game.h b/Code/Game/GameLogic/Game.h index 5ab19ba2..81410ac8 100644 --- a/Code/Game/GameLogic/Game.h +++ b/Code/Game/GameLogic/Game.h @@ -40,11 +40,11 @@ namespace GameLogic Oyster::Math::Float3 GetScale() override; Oyster::Math::Float4x4 GetOrientation() override; int GetID() const override; - void Rotate(const Oyster::Math3D::Float3& lookDir, const Oyster::Math3D::Float3& right) override; + void SetLookDir(const Oyster::Math3D::Float3& lookDir) override; void TurnLeft(Oyster::Math3D::Float deltaLeftRadians ) override; ObjectSpecialType GetObjectType() const override; - - + void Inactivate() override; + void Release() override; Player *player; }; diff --git a/Code/Game/GameLogic/GameAPI.h b/Code/Game/GameLogic/GameAPI.h index 66cf5ea2..290b1c30 100644 --- a/Code/Game/GameLogic/GameAPI.h +++ b/Code/Game/GameLogic/GameAPI.h @@ -85,7 +85,7 @@ namespace GameLogic * @param x: The relative x axis * @param y: The relative y axis **/ - virtual void Rotate(const Oyster::Math3D::Float3& lookDir, const Oyster::Math3D::Float3& right) = 0; + virtual void SetLookDir(const Oyster::Math3D::Float3& lookDir) = 0; /** Relative rotation around given axis * @param leftRadians: The relative amount of radians to turn @@ -106,6 +106,9 @@ namespace GameLogic * @return The current player state ********************************************************/ virtual PLAYER_STATE GetState() const = 0; + + virtual void Inactivate() = 0; + virtual void Release() = 0; }; class ILevelData :public IObjectData diff --git a/Code/Game/GameLogic/Game_PlayerData.cpp b/Code/Game/GameLogic/Game_PlayerData.cpp index 045da742..ad409e3b 100644 --- a/Code/Game/GameLogic/Game_PlayerData.cpp +++ b/Code/Game/GameLogic/Game_PlayerData.cpp @@ -86,11 +86,19 @@ ObjectSpecialType Game::PlayerData::GetObjectType() const { return this->player->GetObjectType(); } -void Game::PlayerData::Rotate(const Oyster::Math3D::Float3& lookDir, const Oyster::Math3D::Float3& right) +void Game::PlayerData::SetLookDir(const Oyster::Math3D::Float3& lookDir) { - this->player->Rotate(lookDir, right); + this->player->SetLookDir(lookDir); } void Game::PlayerData::TurnLeft(Oyster::Math3D::Float deltaLeftRadians ) { this->player->TurnLeft(deltaLeftRadians); +} +void Game::PlayerData::Inactivate() +{ + this->player->Inactivate(); +} +void Game::PlayerData::Release() +{ + this->player->ReleaseDynamicObject(); } \ No newline at end of file diff --git a/Code/Game/GameLogic/Player.cpp b/Code/Game/GameLogic/Player.cpp index 5b855785..7166f539 100644 --- a/Code/Game/GameLogic/Player.cpp +++ b/Code/Game/GameLogic/Player.cpp @@ -74,7 +74,7 @@ Player::~Player(void) void Player::BeginFrame() { - //weapon->Update(0.002f); + weapon->Update(0.002f); //Object::BeginFrame(); Oyster::Math::Float maxSpeed = 30; @@ -264,10 +264,10 @@ void Player::Respawn(Oyster::Math::Float3 spawnPoint) this->rigidBody->SetPosition(spawnPoint); } -void Player::Rotate(const Oyster::Math3D::Float3& lookDir, const Oyster::Math3D::Float3& right) +void Player::SetLookDir(const Oyster::Math3D::Float3& lookDir) { // this is the camera right vector - this->lookDir = lookDir; + this->lookDir = -lookDir; } void Player::TurnLeft(Oyster::Math3D::Float deltaRadians) @@ -293,6 +293,11 @@ bool Player::IsIdle() return (this->playerState == PLAYER_STATE::PLAYER_STATE_IDLE); } +void Player::Inactivate() +{ + //this-> +} + Oyster::Math::Float3 Player::GetPosition() const { return (Oyster::Math::Float3) this->rigidBody->GetState().centerPos; diff --git a/Code/Game/GameLogic/Player.h b/Code/Game/GameLogic/Player.h index 13c6e300..1fc3443a 100644 --- a/Code/Game/GameLogic/Player.h +++ b/Code/Game/GameLogic/Player.h @@ -46,7 +46,7 @@ namespace GameLogic void Respawn(Oyster::Math::Float3 spawnPoint); - void Rotate(const Oyster::Math3D::Float3& lookDir, const Oyster::Math3D::Float3& right); + void SetLookDir(const Oyster::Math3D::Float3& lookDir); void TurnLeft(Oyster::Math3D::Float deltaRadians); @@ -56,13 +56,15 @@ namespace GameLogic * @param rigidBodyPlayer: physics object of the player * @param obj: physics object for the object that collided with the player ********************************************************/ - static void PlayerCollision(Oyster::Physics::ICustomBody *rigidBodyPlayer, Oyster::Physics::ICustomBody *obj, Oyster::Math::Float kineticEnergyLoss); + static void PlayerCollision(Oyster::Physics::ICustomBody *objA, Oyster::Physics::ICustomBody *objB, Oyster::Math::Float kineticEnergyLoss); bool IsWalking(); bool IsJumping(); bool IsIdle(); + void Inactivate(); + Oyster::Math::Float3 GetPosition() const; Oyster::Math::Float3 GetLookDir() const; Oyster::Math::Float4x4 GetOrientation() const; diff --git a/Code/Game/GameProtocols/ObjectProtocols.h b/Code/Game/GameProtocols/ObjectProtocols.h index cae7c7f5..22f8213e 100644 --- a/Code/Game/GameProtocols/ObjectProtocols.h +++ b/Code/Game/GameProtocols/ObjectProtocols.h @@ -292,6 +292,7 @@ namespace GameLogic Oyster::Network::CustomNetProtocol protocol; }; + //#define protocol_Gameplay_ObjectEnabled 356 struct Protocol_ObjectPositionRotation :public Oyster::Network::CustomProtocolObject { short object_ID; @@ -366,7 +367,7 @@ namespace GameLogic Oyster::Network::CustomNetProtocol protocol; }; - //#define protocol_Gameplay_ObjectEnabled 356 + //#define protocol_Gameplay_ObjectEnabled 357 struct Protocol_ObjectEnable :public Oyster::Network::CustomProtocolObject { int objectID; @@ -399,7 +400,7 @@ namespace GameLogic Oyster::Network::CustomNetProtocol protocol; }; - //#define protocol_Gameplay_ObjectDisabled 357 + //#define protocol_Gameplay_ObjectDisabled 358 struct Protocol_ObjectDisable :public Oyster::Network::CustomProtocolObject { int objectID; @@ -439,7 +440,7 @@ namespace GameLogic Oyster::Network::CustomNetProtocol protocol; }; - //#define protocol_Gameplay_ObjectCreate 358 + //#define protocol_Gameplay_ObjectCreate 359 struct Protocol_ObjectCreate :public Oyster::Network::CustomProtocolObject { //ObjectType type; //ie player, box or whatever @@ -543,7 +544,7 @@ namespace GameLogic Oyster::Network::CustomNetProtocol protocol; }; - //#define protocol_Gameplay_ObjectCreatePlayer 359 + //#define protocol_Gameplay_ObjectCreatePlayer 360 struct Protocol_ObjectCreatePlayer :public Oyster::Network::CustomProtocolObject { /*1*/ int object_ID; @@ -673,7 +674,7 @@ namespace GameLogic Oyster::Network::CustomNetProtocol protocol; }; - //#define protocol_Gameplay_ObjectJoinTeam 360 + //#define protocol_Gameplay_ObjectJoinTeam 361 struct Protocol_ObjectJoinTeam :public Oyster::Network::CustomProtocolObject { int objectID; @@ -713,7 +714,7 @@ namespace GameLogic Oyster::Network::CustomNetProtocol protocol; }; - //#define protocol_Gameplay_ObjectLeaveTeam 361 + //#define protocol_Gameplay_ObjectLeaveTeam 362 struct Protocol_ObjectLeaveTeam :public Oyster::Network::CustomProtocolObject { int objectID; @@ -745,7 +746,7 @@ namespace GameLogic Oyster::Network::CustomNetProtocol protocol; }; - //#define protocol_Gameplay_ObjectWeaponCooldown 362 + //#define protocol_Gameplay_ObjectWeaponCooldown 363 struct Protocol_ObjectWeaponCooldown :public Oyster::Network::CustomProtocolObject { float seconds; @@ -777,7 +778,7 @@ namespace GameLogic Oyster::Network::CustomNetProtocol protocol; }; - //#define protocol_Gameplay_ObjectWeaponEnergy 363 + //#define protocol_Gameplay_ObjectWeaponEnergy 364 struct Protocol_ObjectWeaponEnergy :public Oyster::Network::CustomProtocolObject { float energy; @@ -809,7 +810,7 @@ namespace GameLogic Oyster::Network::CustomNetProtocol protocol; }; - //#define protocol_Gameplay_ObjectRespawn 364 + //#define protocol_Gameplay_ObjectRespawn 365 struct Protocol_ObjectRespawn :public Oyster::Network::CustomProtocolObject { float position[3]; @@ -852,7 +853,7 @@ namespace GameLogic Oyster::Network::CustomNetProtocol protocol; }; - //#define protocol_Gameplay_ObjectDie 365 + //#define protocol_Gameplay_ObjectDie 366 struct Protocol_ObjectDie :public Oyster::Network::CustomProtocolObject { int objectID; diff --git a/Code/Game/GameProtocols/PlayerProtocols.h b/Code/Game/GameProtocols/PlayerProtocols.h index 350c2cf6..eb34c07c 100644 --- a/Code/Game/GameProtocols/PlayerProtocols.h +++ b/Code/Game/GameProtocols/PlayerProtocols.h @@ -79,6 +79,7 @@ namespace GameLogic { public: float deltaRadian; + float lookdir[3]; Protocol_PlayerLeftTurn() { @@ -86,25 +87,40 @@ namespace GameLogic this->protocol[0].type = ::Oyster::Network::NetAttributeType_Short; // deltaRadian this->protocol[1].type = ::Oyster::Network::NetAttributeType_Float; + this->protocol[2].type = Oyster::Network::NetAttributeType_Float; + this->protocol[3].type = Oyster::Network::NetAttributeType_Float; + this->protocol[4].type = Oyster::Network::NetAttributeType_Float; + deltaRadian = 0.0f; + memset(&lookdir[0], 0, sizeof(float) * 3); } Protocol_PlayerLeftTurn( const ::Oyster::Network::CustomNetProtocol &p ) { this->deltaRadian = p[1].value.netFloat; + lookdir[0] = p[2].value.netFloat; + lookdir[1] = p[3].value.netFloat; + lookdir[2] = p[4].value.netFloat; } - Protocol_PlayerLeftTurn( float deltaRadian ) + Protocol_PlayerLeftTurn( float deltaRadian,float v[3] ) { this->protocol[0].value = protocol_Gameplay_PlayerLeftTurn; this->protocol[0].type = ::Oyster::Network::NetAttributeType_Short; - // deltaRadian this->protocol[1].type = ::Oyster::Network::NetAttributeType_Float; + this->protocol[2].type = Oyster::Network::NetAttributeType_Float; + this->protocol[3].type = Oyster::Network::NetAttributeType_Float; + this->protocol[4].type = Oyster::Network::NetAttributeType_Float; this->deltaRadian = deltaRadian; + memcpy(&lookdir[0], &v[0], sizeof(float) * 3); + } ::Oyster::Network::CustomNetProtocol GetProtocol() override { this->protocol[1].value = this->deltaRadian; + this->protocol[2].value = this->lookdir[0]; + this->protocol[3].value = this->lookdir[1]; + this->protocol[4].value = this->lookdir[2]; return protocol; } diff --git a/Code/Game/GameProtocols/ProtocolIdentificationID.h b/Code/Game/GameProtocols/ProtocolIdentificationID.h index cb630012..79235e2f 100644 --- a/Code/Game/GameProtocols/ProtocolIdentificationID.h +++ b/Code/Game/GameProtocols/ProtocolIdentificationID.h @@ -69,7 +69,6 @@ #define protocol_Gameplay_ObjectWeaponEnergy 364 #define protocol_Gameplay_ObjectRespawn 365 #define protocol_Gameplay_ObjectDie 366 -//Disconnect #define protocol_Gameplay_ObjectDisconnectPlayer 367 #define protocol_GameplayMAX 399 diff --git a/Code/Game/GameServer/GameClient.h b/Code/Game/GameServer/GameClient.h index 497e6c2e..aace26c7 100644 --- a/Code/Game/GameServer/GameClient.h +++ b/Code/Game/GameServer/GameClient.h @@ -55,6 +55,7 @@ namespace DanBias GameLogic::IPlayerData* ReleasePlayer(); Oyster::Network::NetClient ReleaseClient(); + bool IsInvalid(); void Invalidate(); int IncrementFailedProtocol(); void ResetFailedProtocolCount(); diff --git a/Code/Game/GameServer/Implementation/GameClient.cpp b/Code/Game/GameServer/Implementation/GameClient.cpp index 3293a383..e8e78ab0 100644 --- a/Code/Game/GameServer/Implementation/GameClient.cpp +++ b/Code/Game/GameServer/Implementation/GameClient.cpp @@ -25,12 +25,15 @@ GameClient::GameClient(Utility::DynamicMemory::SmartPointerclient = 0; - this->player = 0; + if(this->player) + this->player->Inactivate(); + this->isReady = false; this->character = L"crate_colonists.dan"; this->alias = L"Unknown"; this->secondsSinceLastResponse = 0.0f; + this->client = 0; + this->player = 0; } void GameClient::SetPlayer(GameLogic::IPlayerData* player) @@ -58,8 +61,14 @@ void GameClient::SetState(ClientState state) this->state = state; } +bool GameClient::IsInvalid() +{ + return this->isInvalid; +} void GameClient::Invalidate() { + this->player->Release(); + this->player = 0; this->isInvalid = true; this->isReady = false; this->state = ClientState_Invalid; diff --git a/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp b/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp index 0c52dfff..1b3f6cb5 100644 --- a/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp +++ b/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp @@ -62,24 +62,31 @@ using namespace DanBias; { case NetworkClient::ClientEventArgs::EventType_Disconnect: { - //Send disconnect message to all the other players so the player can be removed from the client. - Protocol_ObjectDisconnectPlayer dp(cl->GetClient()->GetID()); - for(int i = 0; i < this->gClients.Size(); i++) - { - if(this->gClients[i] && this->gClients[i] != cl) - { - this->gClients[i]->GetClient()->Send(dp); - } - } printf("\t(%i : %s) - EventType_Disconnect\n", cl->GetClient()->GetID(), e.sender->GetIpAddress().c_str()); + Protocol_ObjectDisconnectPlayer prot(this->gClients[temp]->GetPlayer()->GetID()); + for (unsigned int i = 0; i < this->gClients.Size(); i++) + { + if(i != temp && this->gClients[i]) this->gClients[i]->GetClient()->Send(prot); + } + this->gClients[temp]->Invalidate(); } break; case NetworkClient::ClientEventArgs::EventType_ProtocolFailedToRecieve: break; case NetworkClient::ClientEventArgs::EventType_ProtocolFailedToSend: + { if(this->gClients[temp]->IncrementFailedProtocol() >= 5/*client->threshold*/) + { + printf("\t(%i : %s) - EventType_Disconnect\n", cl->GetClient()->GetID(), e.sender->GetIpAddress().c_str()); + Protocol_ObjectDisconnectPlayer prot(this->gClients[temp]->GetPlayer()->GetID()); + for (unsigned int i = 0; i < this->gClients.Size(); i++) + { + if(i != temp && this->gClients[i]) this->gClients[i]->GetClient()->Send(prot); + } this->gClients[temp]->Invalidate(); + } + } break; case NetworkClient::ClientEventArgs::EventType_ProtocolRecieved: this->ParseProtocol(e.args.data.protocol, cl); @@ -224,6 +231,7 @@ using namespace DanBias; void GameSession::Gameplay_PlayerLeftTurn ( Protocol_PlayerLeftTurn& p, DanBias::GameClient* c ) { c->GetPlayer()->TurnLeft( p.deltaRadian ); + c->GetPlayer()->SetLookDir(p.lookdir); } void GameSession::Gameplay_PlayerChangeWeapon ( Protocol_PlayerChangeWeapon& p, DanBias::GameClient* c ) { @@ -267,10 +275,17 @@ using namespace DanBias; switch (p.status) { case GameLogic::Protocol_General_Status::States_disconected: + { printf("Client with ID [%i] dissconnected\n", c->GetClient()->GetID()); - //TODO: Tell other clients - //Protocol_ + + Protocol_ObjectDisconnectPlayer prot(c->GetPlayer()->GetID()); + for (unsigned int i = 0; i < this->gClients.Size(); i++) + { + if( this->gClients[i] && c->GetClient()->GetID() != this->gClients[i]->GetClient()->GetID() ) this->gClients[i]->GetClient()->Send(prot); + } + c->Invalidate(); this->Detach(c->GetClient()->GetID()); + } break; case GameLogic::Protocol_General_Status::States_idle: diff --git a/Code/Game/GameServer/Implementation/GameSession_General.cpp b/Code/Game/GameServer/Implementation/GameSession_General.cpp index 2b8a7d5c..fb4c9246 100644 --- a/Code/Game/GameServer/Implementation/GameSession_General.cpp +++ b/Code/Game/GameServer/Implementation/GameSession_General.cpp @@ -214,14 +214,21 @@ bool GameSession::Join(gClient gameClient) { for (unsigned int i = 0; i < this->gClients.Size(); i++) { - if(this->gClients[i]) + if(this->gClients[i] && !this->gClients[i]->IsInvalid()) { IPlayerData* temp = this->gClients[i]->GetPlayer(); - Protocol_ObjectCreatePlayer oc( temp->GetPosition(), temp->GetRotation(), temp->GetScale(), + Protocol_ObjectCreatePlayer p1( temp->GetPosition(), temp->GetRotation(), temp->GetScale(), temp->GetID(), false, temp->GetTeamID(), Utility::String::WStringToString(this->gClients[i]->GetAlias(), std::string()), Utility::String::WStringToString(this->gClients[i]->GetCharacter(), std::string())); - nwClient->Send(oc); + nwClient->Send(p1); + + temp = playerData; + Protocol_ObjectCreatePlayer p2( temp->GetPosition(), temp->GetRotation(), temp->GetScale(), + temp->GetID(), false, temp->GetTeamID(), + Utility::String::WStringToString(gameClient->GetAlias(), std::string()), + Utility::String::WStringToString(gameClient->GetCharacter(), std::string())); + this->gClients[i]->GetClient()->Send(p2); } } } diff --git a/Code/Network/NetworkAPI/NetworkServer.h b/Code/Network/NetworkAPI/NetworkServer.h index 593c3847..82693310 100644 --- a/Code/Network/NetworkAPI/NetworkServer.h +++ b/Code/Network/NetworkAPI/NetworkServer.h @@ -22,16 +22,16 @@ namespace Oyster { struct BroadcastOptions { - //bool broadcast; - //float broadcastInterval; - //std::wstring subnetToBroadcast; - //CustomNetProtocol broadcastMessage; - //BroadcastOptions() - //{ - // broadcast = true; - // broadcastInterval = 1.0f; - // subnetToBroadcast = L"192.168.0.1"; - //} + bool broadcast; + float broadcastInterval; + std::wstring subnetToBroadcast; + CustomNetProtocol broadcastMessage; + BroadcastOptions() + { + broadcast = true; + broadcastInterval = 1.0f; + subnetToBroadcast = L"192.168.0.1"; + } } broadcastOptions; struct MainOptions @@ -117,6 +117,23 @@ namespace Oyster */ int NetworkServer::GetPort(); + + + /*************************************** + Broadcast functions + ***************************************/ + //Set broadcast settings. + void SetBroadcast(CustomNetProtocol& broadcastMessage, float interval = 1.0f, bool enable = true); + + //Set broadcast settings. + void SetBroadcastMessage(CustomNetProtocol& broadcastMessage); + + //Enable/disable broadcast. + void SetBroadcast(bool enable); + + //Set interval between each broadcast message in seconds. + void SetBroadcastInterval(float interval); + private: struct PrivateData; PrivateData* privateData;