From 4d967b995deb5e8e422890ef0787417411c3475c Mon Sep 17 00:00:00 2001 From: Linda Andersson Date: Tue, 25 Feb 2014 11:46:05 +0100 Subject: [PATCH] Added player stats. Added players to level. Respawn logic in level. --- Code/Game/GameLogic/Game.cpp | 5 +- Code/Game/GameLogic/Game.h | 13 +- Code/Game/GameLogic/GameAPI.h | 2 + Code/Game/GameLogic/GameLogicStates.h | 3 +- Code/Game/GameLogic/Game_LevelData.cpp | 14 +- Code/Game/GameLogic/Game_PlayerData.cpp | 4 + Code/Game/GameLogic/Level.cpp | 56 ++++++- Code/Game/GameLogic/Level.h | 14 +- Code/Game/GameLogic/Player.cpp | 141 ++++++------------ Code/Game/GameLogic/Player.h | 35 +++-- .../Implementation/GameSession_Gameplay.cpp | 5 - 11 files changed, 167 insertions(+), 125 deletions(-) diff --git a/Code/Game/GameLogic/Game.cpp b/Code/Game/GameLogic/Game.cpp index 0e1ab178..a33ce03c 100644 --- a/Code/Game/GameLogic/Game.cpp +++ b/Code/Game/GameLogic/Game.cpp @@ -108,6 +108,7 @@ Game::PlayerData* Game::CreatePlayer() this->players[insert] = new PlayerData(freeID, 0); // user constructor with objectID and teamID this->players[insert]->player->GetRigidBody()->SetSubscription(Game::PhysicsOnMove); + this->level->AddPlayerToGame(this->players[insert]); return this->players[insert]; } @@ -128,6 +129,9 @@ void Game::CreateTeam() bool Game::NewFrame() { + // HACK need dynamic delta time + this->level->Update(this->frameTime); + for (unsigned int i = 0; i < this->players.Size(); i++) { if(this->players[i] && this->players[i]->player) this->players[i]->player->BeginFrame(); @@ -202,4 +206,3 @@ void Game::PhysicsOnDestroy(::Utility::DynamicMemory::UniquePointer { if(gameInstance.onDisableFnc) gameInstance.onDisableFnc(0, 0); } - diff --git a/Code/Game/GameLogic/Game.h b/Code/Game/GameLogic/Game.h index 37abe97f..c03de2ed 100644 --- a/Code/Game/GameLogic/Game.h +++ b/Code/Game/GameLogic/Game.h @@ -45,7 +45,7 @@ namespace GameLogic ObjectSpecialType GetObjectType() const override; void Inactivate() override; void Release() override; - + Player* GetPlayer(); Player *player; }; @@ -63,7 +63,8 @@ namespace GameLogic int getNrOfDynamicObj()const override; IObjectData* GetObjectAt(int ID) const override; void GetAllDynamicObjects(Utility::DynamicMemory::DynamicArray& mem) const override; - + void Update(float deltaTime); + void AddPlayerToGame(IPlayerData *player); Level *level; }; @@ -80,16 +81,16 @@ namespace GameLogic void SetFrameTimeLength( float seconds ) override; void SetSubscription(GameEvent::ObjectMovedFunction functionPointer) override; void SetSubscription(GameEvent::ObjectDisabledFunction functionPointer) override; - void SetHpSubscription(GameEvent::ObjectHpFunction functionPointer) override; - void SetRespawnSubscription(GameEvent::ObjectRespawnedFunction functionPointer) override; - void SetDeadSubscription(GameEvent::ObjectDeadFunction functionPointer) override; - + void SetHpSubscription(GameEvent::ObjectHpFunction functionPointer) override; + void SetRespawnSubscription(GameEvent::ObjectRespawnedFunction functionPointer) override; + void SetDeadSubscription(GameEvent::ObjectDeadFunction functionPointer) override; bool Initiate() override; float GetFrameTime() const; static void PhysicsOnMove(const Oyster::Physics::ICustomBody *object); static void PhysicsOnDestroy(::Utility::DynamicMemory::UniquePointer proto); + static void PhysicsOnDead(const Oyster::Physics::ICustomBody *object); Utility::DynamicMemory::DynamicArray players; LevelData* level; diff --git a/Code/Game/GameLogic/GameAPI.h b/Code/Game/GameLogic/GameAPI.h index 0c79f33d..627ea547 100644 --- a/Code/Game/GameLogic/GameAPI.h +++ b/Code/Game/GameLogic/GameAPI.h @@ -117,8 +117,10 @@ namespace GameLogic class ILevelData :public IObjectData { public: + virtual void Update(float deltaTime) = 0; virtual int getNrOfDynamicObj()const = 0; virtual IObjectData* GetObjectAt(int ID) const = 0; + virtual void AddPlayerToGame(IPlayerData *player) = 0; virtual void GetAllDynamicObjects(Utility::DynamicMemory::DynamicArray& destMem) const = 0; }; diff --git a/Code/Game/GameLogic/GameLogicStates.h b/Code/Game/GameLogic/GameLogicStates.h index ae4e192f..f006ad27 100644 --- a/Code/Game/GameLogic/GameLogicStates.h +++ b/Code/Game/GameLogic/GameLogicStates.h @@ -20,7 +20,8 @@ namespace GameLogic PLAYER_STATE_WALKING = 1, PLAYER_STATE_IDLE = 2, PLAYER_STATE_DEAD = 4, - PLAYER_STATE_INVALID = 8, + PLAYER_STATE_DIED = 8, + PLAYER_STATE_INVALID = 16, }; enum WEAPON_FIRE diff --git a/Code/Game/GameLogic/Game_LevelData.cpp b/Code/Game/GameLogic/Game_LevelData.cpp index 903cb959..f16f4072 100644 --- a/Code/Game/GameLogic/Game_LevelData.cpp +++ b/Code/Game/GameLogic/Game_LevelData.cpp @@ -54,9 +54,17 @@ IObjectData* Game::LevelData::GetObjectAt(int ID) const void Game::LevelData::GetAllDynamicObjects(Utility::DynamicMemory::DynamicArray& mem) const { - mem.Resize(level->dynamicObjects.Size()); - for(int i = 0; i < (int)level->dynamicObjects.Size(); i++) + mem.Resize(level->GetDynamicObject().Size()); + for(int i = 0; i < (int)level->GetDynamicObject().Size(); i++) { - mem[i] = level->dynamicObjects[i]; + mem[i] = level->GetDynamicObject()[i]; } +} +void Game::LevelData::Update(float deltaTime) +{ + this->level->Update(deltaTime); +} +void Game::LevelData::AddPlayerToGame(IPlayerData *player) +{ + this->level->AddPlayerToGame(((PlayerData*)player)->GetPlayer()); } \ No newline at end of file diff --git a/Code/Game/GameLogic/Game_PlayerData.cpp b/Code/Game/GameLogic/Game_PlayerData.cpp index ad409e3b..88b4bbbe 100644 --- a/Code/Game/GameLogic/Game_PlayerData.cpp +++ b/Code/Game/GameLogic/Game_PlayerData.cpp @@ -101,4 +101,8 @@ void Game::PlayerData::Inactivate() void Game::PlayerData::Release() { this->player->ReleaseDynamicObject(); +} +Player* Game::PlayerData::GetPlayer() +{ + return this->player; } \ No newline at end of file diff --git a/Code/Game/GameLogic/Level.cpp b/Code/Game/GameLogic/Level.cpp index a4252bc4..f3a763d0 100644 --- a/Code/Game/GameLogic/Level.cpp +++ b/Code/Game/GameLogic/Level.cpp @@ -12,7 +12,7 @@ using namespace GameLogic; using namespace Utility::DynamicMemory; using namespace Oyster::Physics; - +using namespace Oyster::Math; Level::Level(void) { @@ -69,7 +69,7 @@ Object* Level::CreateGameObj(ObjectHeader* obj, ICustomBody* rigidBody) break; case ObjectSpecialType_RedExplosiveBox: { - Oyster::Math::Float dmg = 90; + Oyster::Math::Float dmg = 120; Oyster::Math::Float force = 500; Oyster::Math::Float radie = 3; gameObj = new ExplosiveCrate(rigidBody, (ObjectSpecialType)obj->specialTypeID, objID++, dmg, force, radie); @@ -393,7 +393,20 @@ void Level::AddPlayerToTeam(Player *player, int teamID) { this->teamManager.AddPlayerToTeam(player,teamID); } - +void Level::AddPlayerToGame(Player *player) +{ + this->playerObjects.Push(player); +} +void Level::RemovePlayerFromGame(Player *player) +{ + for(int i = 0; i < (int)this->playerObjects.Size(); i++) + { + if ((Player*)this->playerObjects[i] == player) + { + //this->playerObjects[i]. + } + } +} void Level::CreateTeam(int teamSize) { this->teamManager.CreateTeam(teamSize); @@ -401,9 +414,29 @@ void Level::CreateTeam(int teamSize) void Level::RespawnPlayer(Player *player) { - this->teamManager.RespawnPlayerRandom(player); -} + //this->teamManager.RespawnPlayerRandom(player); + Float3 spawnPoint = spawnPoints[0]; + player->Respawn(spawnPoint); +} +void Level::Update(float deltaTime) +{ + // update lvl-things + for(int i = 0; i < (int)this->playerObjects.Size(); i++) + { + if (this->playerObjects[i]->GetState() == PLAYER_STATE::PLAYER_STATE_DEAD) + { + // true when timer reaches 0 + if(this->playerObjects[i]->deathTimerTick(deltaTime)) + RespawnPlayer(this->playerObjects[i]); + } + else if (this->playerObjects[i]->GetState() == PLAYER_STATE::PLAYER_STATE_DIED) + { + this->playerObjects[i]->setDeathTimer(DEATH_TIMER); + ((Game*)&Game::Instance())->onDeadFnc(this->playerObjects[i], DEATH_TIMER); // add killer ID + } + } +} int Level::getNrOfDynamicObj() { return this->dynamicObjects.Size(); @@ -417,10 +450,23 @@ Object* Level::GetObj( int ID) const } return NULL; } + 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); } +Utility::DynamicMemory::DynamicArray> Level::GetPlayers() +{ + return this->playerObjects; +} +Utility::DynamicMemory::DynamicArray> Level::GetStaticObjects() +{ + return this->staticObjects; +} +Utility::DynamicMemory::DynamicArray> Level::GetDynamicObject() +{ + return this->dynamicObjects; +} diff --git a/Code/Game/GameLogic/Level.h b/Code/Game/GameLogic/Level.h index 27f0bab6..9fb3dbad 100644 --- a/Code/Game/GameLogic/Level.h +++ b/Code/Game/GameLogic/Level.h @@ -16,6 +16,7 @@ #include "DynamicArray.h" #include "LevelLoader.h" +const int DEATH_TIMER = 5; namespace GameLogic { @@ -48,7 +49,8 @@ namespace GameLogic * @param teamID: ArrayPos of the team you want to add the player to ********************************************************/ void AddPlayerToTeam(Player *player, int teamID); - + void AddPlayerToGame(Player *player); + void RemovePlayerFromGame(Player *player); /******************************************************** * Respawns a player on a random teammate @@ -64,13 +66,21 @@ namespace GameLogic ********************************************************/ static Oyster::Physics::ICustomBody::SubscriptMessage LevelCollisionAfter(Oyster::Physics::ICustomBody *rigidBodyLevel, Oyster::Physics::ICustomBody *obj, Oyster::Math::Float kineticEnergyLoss); + void Update(float deltaTime); + int getNrOfDynamicObj(); Object* GetObj( int ID ) const; + static void PlayerDied( Player* player ); static void PhysicsOnMoveLevel(const Oyster::Physics::ICustomBody *object); + Utility::DynamicMemory::DynamicArray> GetPlayers(); + Utility::DynamicMemory::DynamicArray> GetStaticObjects(); + Utility::DynamicMemory::DynamicArray> GetDynamicObject(); - //private: + private: + Utility::DynamicMemory::DynamicArray> playerObjects; + Utility::DynamicMemory::DynamicArray> deadPlayerObjects; TeamManager teamManager; Utility::DynamicMemory::DynamicArray> staticObjects; Utility::DynamicMemory::DynamicArray> dynamicObjects; diff --git a/Code/Game/GameLogic/Player.cpp b/Code/Game/GameLogic/Player.cpp index d8ba38ba..91f09c56 100644 --- a/Code/Game/GameLogic/Player.cpp +++ b/Code/Game/GameLogic/Player.cpp @@ -11,36 +11,17 @@ const float KEY_TIMER = 0.03f; Player::Player() :DynamicObject() { - + Player::initPlayerData(); + this->teamID = -1; } Player::Player(Oyster::Physics::ICustomBody *rigidBody, void (*EventOnCollision)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter,Oyster::Math::Float kineticEnergyLoss), ObjectSpecialType type, int objectID, int teamID) :DynamicObject(rigidBody, EventOnCollision, type, objectID) { weapon = new Weapon(2,this); - AffectedObjects.Reserve(15); - - this->life = 100; + Player::initPlayerData(); this->teamID = teamID; - this->playerState = PLAYER_STATE_IDLE; - this->lookDir = Oyster::Math::Float3(0,0,-1); - key_forward = 0; - key_backward = 0; - key_strafeRight = 0; - key_strafeLeft = 0; - key_jump = 0; - invincibleCooldown = 0; - this->deathTimeLeft = 0; - this->deathTime = 5; - - this->previousPosition = Oyster::Math::Float3(0,0,0); - - this->moveDir = Oyster::Math::Float3(0,0,0); - this->moveSpeed = 100; - this->previousMoveSpeed = Oyster::Math::Float3(0,0,0); - - this->rotationUp = 0; } Player::Player(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, int teamID) @@ -48,27 +29,8 @@ Player::Player(Oyster::Physics::ICustomBody *rigidBody, Oyster::Physics::ICustom { weapon = new Weapon(2,this); - AffectedObjects.Reserve(15); - - - this->life = 100; + Player::initPlayerData(); this->teamID = teamID; - this->playerState = PLAYER_STATE_IDLE; - this->lookDir = Oyster::Math::Float3(0,0,-1); - key_forward = 0; - key_backward = 0; - key_strafeRight = 0; - key_strafeLeft = 0; - key_jump = 0; - invincibleCooldown = 0; - this->deathTimeLeft = 0; - this->deathTime = 5; - this->previousPosition = Oyster::Math::Float3(0,0,0); - this->moveDir = Oyster::Math::Float3(0,0,0); - this->moveSpeed = 20; - this->previousMoveSpeed = Oyster::Math::Float3(0,0,0); - - this->rotationUp = 0; } Player::~Player(void) @@ -79,10 +41,29 @@ Player::~Player(void) weapon = NULL; } } +void Player::initPlayerData() +{ + this->playerStats.hp = MAX_HP; + this->playerStats.movementSpeed = BASIC_SPEED; + this->playerScore.killScore = 0; + this->playerScore.deathScore = 0; + this->playerState = PLAYER_STATE_IDLE; + this->lookDir = Oyster::Math::Float3(0,0,-1); + + this->key_forward = 0; + this->key_backward = 0; + this->key_strafeRight = 0; + this->key_strafeLeft = 0; + this->key_jump = 0; + this->invincibleCooldown = 0; + this->deathTimer = 0; + + this->rotationUp = 0; +} void Player::BeginFrame() { - if( this->playerState != PLAYER_STATE_DEAD) + if( this->playerState != PLAYER_STATE_DEAD && PLAYER_STATE_DIED) { weapon->Update(0.002f); @@ -117,7 +98,7 @@ void Player::BeginFrame() // Walking data Oyster::Math::Float3 walkDirection = Oyster::Math::Float3(0.0, 0.0, 0.0); - Oyster::Math::Float walkSpeed = this->moveSpeed*0.2f; + Oyster::Math::Float walkSpeed = this->playerStats.movementSpeed*0.2f; // Check for input if(key_forward > 0.001) @@ -199,36 +180,15 @@ void Player::BeginFrame() if(this->rigidBody->GetLambda() < 0.9f) { Oyster::Math::Float3 up = this->rigidBody->GetState().centerPos.GetNormalized(); - this->rigidBody->ApplyImpulse(up*this->rigidBody->GetState().mass*20); + this->rigidBody->ApplyImpulse(up*this->rigidBody->GetState().mass * 20); this->playerState = PLAYER_STATE::PLAYER_STATE_JUMPING; } } } - else - { - // player is dead - // TODO move this logic to lvl - this->deathTimeLeft -= gameInstance->GetFrameTime(); - if( this->deathTimeLeft <= 0) - { - Respawn( Oyster::Math::Float3( -50, 180, 0)); - } - } } void Player::EndFrame() { - //check if there are any objects that can be removed from the AffectedObjects list - for(int i = 0; i < this->AffectedObjects.Size(); i++) - { - if(this->AffectedObjects[i] && (this->AffectedObjects[i]->GetRigidBody()->GetState().previousVelocity).GetMagnitude() <= 0.1f) - { - this->AffectedObjects[i]->RemoveAffectedBy(); - this->AffectedObjects.Remove(i); - } - - } - } void Player::Move(const PLAYER_MOVEMENT &movement) @@ -283,12 +243,10 @@ void Player::Respawn(Oyster::Math::Float3 spawnPoint) { if( this->playerState == PLAYER_STATE_DEAD) { - this->life = 100; - this->playerState = PLAYER_STATE::PLAYER_STATE_IDLE; - //this->lookDir = Oyster::Math::Float4(1,0,0); + Player::initPlayerData(); this->rigidBody->SetPosition(spawnPoint); this->gameInstance->onRespawnFnc( this, spawnPoint); - this->gameInstance->onDamageTakenFnc( this, this->life); + this->gameInstance->onDamageTakenFnc( this, this->playerStats.hp); } } @@ -349,31 +307,30 @@ PLAYER_STATE Player::GetState() const void Player::DamageLife(int damage) { - - this->life -= damage; - this->gameInstance->onDamageTakenFnc( this, this->life); - - if(this->life <= 0) + if( this->playerState != PLAYER_STATE_DEAD) { - this->life = 0; - playerState = PLAYER_STATE_DEAD; - this->deathTimeLeft = this->deathTime; - this->gameInstance->onDeadFnc(this, this->deathTimeLeft); - } + this->playerStats.hp -= damage; + // send hp to client + this->gameInstance->onDamageTakenFnc( this, this->playerStats.hp); -} - -void Player::AddAffectedObject(DynamicObject &AffectedObject) -{ - //check if object already exists in the list, if so then do not add - for(int i = 0; i < AffectedObjects.Size(); i++) - { - if(AffectedObjects[i]->GetID() == AffectedObject.GetID()) + if(this->playerStats.hp <= 0) { - //object already exists, exit function - return; + this->playerStats.hp = 0; + this->playerState = PLAYER_STATE_DIED; } } - //else you add the object to the stack - AffectedObjects.Push(&AffectedObject); } +bool Player::deathTimerTick(float dt) +{ + this->deathTimer -= dt; + if( this->deathTimer <= 0) + { + return true; + } + return false; +} +void Player::setDeathTimer(float deathTimer) +{ + this->deathTimer = deathTimer; + this->playerState = PLAYER_STATE_DEAD; +} \ No newline at end of file diff --git a/Code/Game/GameLogic/Player.h b/Code/Game/GameLogic/Player.h index 99af52c5..2d6f0a35 100644 --- a/Code/Game/GameLogic/Player.h +++ b/Code/Game/GameLogic/Player.h @@ -9,6 +9,8 @@ #include "DynamicObject.h" #include "DynamicArray.h" +const float MAX_HP = 100.0f; +const float BASIC_SPEED = 30.0f; namespace GameLogic { @@ -16,6 +18,21 @@ namespace GameLogic class Player : public DynamicObject { public: + struct PlayerStats + { + Oyster::Math::Float hp; + Oyster::Math::Float movementSpeed; + //Oyster::Math::Float resistance; + }; + + struct PlayerScore + { + int killScore; + int deathScore; + // int assistScore; + // int suicideScore; + }; + Player(void); Player(Oyster::Physics::ICustomBody *rigidBody, void (*EventOnCollision)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter,Oyster::Math::Float kineticEnergyLoss), ObjectSpecialType type, int objectID, int teamID); @@ -75,20 +92,21 @@ namespace GameLogic PLAYER_STATE GetState() const; void DamageLife(int damage); + void setDeathTimer(float deathTimer); + bool deathTimerTick(float dt); void BeginFrame(); void EndFrame(); static Oyster::Physics::ICustomBody::SubscriptMessage PlayerCollisionAfter(Oyster::Physics::ICustomBody *rigidBodyLevel, Oyster::Physics::ICustomBody *obj, Oyster::Math::Float kineticEnergyLoss); - private: void Jump(); + void initPlayerData(); private: - Utility::DynamicMemory::DynamicArray AffectedObjects; + - Oyster::Math::Float life; int teamID; Weapon *weapon; PLAYER_STATE playerState; @@ -100,18 +118,15 @@ namespace GameLogic float key_jump; - Oyster::Math::Float3 previousPosition; - Oyster::Math::Float3 moveDir; - Oyster::Math::Float moveSpeed; - Oyster::Math::Float3 previousMoveSpeed; - Oyster::Math::Float rotationUp; - float deathTime; - float deathTimeLeft; + float deathTimer; bool hasTakenDamage; float invincibleCooldown; + PlayerStats playerStats; + PlayerScore playerScore; + }; } #endif \ No newline at end of file diff --git a/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp b/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp index 8cc47dcc..5d3f2a71 100644 --- a/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp +++ b/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp @@ -188,7 +188,6 @@ using namespace DanBias; break; case protocol_Gameplay_PlayerShot: this->Gameplay_PlayerShot ( Protocol_PlayerShot (p), c ); break; - case protocol_Gameplay_ObjectPickup: this->Gameplay_ObjectPickup ( Protocol_ObjectPickup (p), c ); break; case protocol_Gameplay_ObjectDamage: this->Gameplay_ObjectDamage ( Protocol_ObjectDamage (p), c ); @@ -201,7 +200,6 @@ using namespace DanBias; break; case protocol_Gameplay_ObjectCreate: this->Gameplay_ObjectCreate ( Protocol_ObjectCreate (p), c ); break; - case protocol_General_Status: this->General_Status ( Protocol_General_Status (p), c ); break; case protocol_General_Text: this->General_Text ( Protocol_General_Text (p), c ); @@ -242,11 +240,8 @@ using namespace DanBias; { if(p.secondaryPressed) c->GetPlayer()->UseWeapon(GameLogic::WEAPON_USE_SECONDARY_PRESS); if(p.primaryPressed) c->GetPlayer()->UseWeapon(GameLogic::WEAPON_USE_PRIMARY_PRESS); - if(p.utilityPressed) c->GetPlayer()->UseWeapon(GameLogic::WEAPON_USE_UTILLITY_PRESS); } - - void GameSession::Gameplay_ObjectPickup ( Protocol_ObjectPickup& p, DanBias::GameClient* c ) {