Merge remote-tracking branch 'origin/master' into Sound
This commit is contained in:
@@ -8,8 +8,10 @@
|
||||
#include "Systems/PlayerMovementSystem.h"
|
||||
#include "Systems/SpawnerSystem.h"
|
||||
#include "Systems/PlayerSpawnSystem.h"
|
||||
#include "Systems/PlayerDeathSystem.h"
|
||||
#include "Core/EntityFileWriter.h"
|
||||
#include "Game/Systems/CapturePointSystem.h"
|
||||
#include "Game/Systems/PickupSpawnSystem.h"
|
||||
#include "Game/Systems/WeaponSystem.h"
|
||||
#include "Game/Systems/PlayerHUD.h"
|
||||
#include "Game/Systems/LifetimeSystem.h"
|
||||
@@ -91,9 +93,11 @@ Game::Game(int argc, char* argv[])
|
||||
m_SystemPipeline->AddSystem<InterpolationSystem>(updateOrderLevel);
|
||||
m_SystemPipeline->AddSystem<SpawnerSystem>(updateOrderLevel);
|
||||
m_SystemPipeline->AddSystem<PlayerSpawnSystem>(updateOrderLevel);
|
||||
m_SystemPipeline->AddSystem<PlayerDeathSystem>(updateOrderLevel);
|
||||
m_SystemPipeline->AddSystem<WeaponSystem>(updateOrderLevel, m_Renderer);
|
||||
m_SystemPipeline->AddSystem<LifetimeSystem>(updateOrderLevel);
|
||||
m_SystemPipeline->AddSystem<CapturePointSystem>(updateOrderLevel);
|
||||
m_SystemPipeline->AddSystem<PickupSpawnSystem>(updateOrderLevel);
|
||||
// Populate Octree with collidables
|
||||
++updateOrderLevel;
|
||||
m_SystemPipeline->AddSystem<CollidableOctreeSystem>(updateOrderLevel, m_OctreeCollision, "Collidable");
|
||||
|
||||
@@ -11,38 +11,6 @@ HealthSystem::HealthSystem(World* m_World, EventBroker* eventBroker)
|
||||
|
||||
void HealthSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt)
|
||||
{
|
||||
//if entityID of health is 9 then the players ID is also 9 (player,health are connected to the same entity)
|
||||
double maxHealth = (double)component["MaxHealth"];
|
||||
|
||||
//process the DeltaHealthVector and change the entitys health accordingly
|
||||
for (size_t i = m_DeltaHealthVector.size(); i > 0; i--)
|
||||
{
|
||||
auto deltaHP = m_DeltaHealthVector[i - 1];
|
||||
//if we have a healthchange for the current player and health is greater than 0, then apply it
|
||||
if (std::get<0>(deltaHP) == component.EntityID && (double)component["Health"] > 0.0f) {
|
||||
//get the deltaHP value from the tuple and make sure you dont get more than maxHealth
|
||||
double newHealth = std::min((double)component["Health"] + (double)std::get<1>(deltaHP), maxHealth);
|
||||
component["Health"] = newHealth;
|
||||
m_DeltaHealthVector.erase(m_DeltaHealthVector.begin() + i - 1);
|
||||
//check if health is <= 0
|
||||
if ((double)component["Health"] <= 0.0f) {
|
||||
component["Health"] = 0.0;
|
||||
//publish death event
|
||||
Events::PlayerDeath e;
|
||||
e.PlayerID = component.EntityID;
|
||||
m_EventBroker->Publish(e);
|
||||
//clear the remaining hpDeltas for the dead player
|
||||
for (size_t j = m_DeltaHealthVector.size(); j > 0; j--)
|
||||
{
|
||||
if (std::get<0>(m_DeltaHealthVector[j - 1]) == component.EntityID)
|
||||
m_DeltaHealthVector.erase(m_DeltaHealthVector.begin() + j - 1);
|
||||
}
|
||||
//delete the player and break the loop
|
||||
m_World->DeleteEntity(entity.ID);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool HealthSystem::OnPlayerDamaged(Events::PlayerDamage& e)
|
||||
@@ -50,18 +18,24 @@ bool HealthSystem::OnPlayerDamaged(Events::PlayerDamage& e)
|
||||
ComponentWrapper cHealth = e.Player["Health"];
|
||||
double& health = cHealth["Health"];
|
||||
health -= e.Damage;
|
||||
|
||||
|
||||
if (health <= 0.0) {
|
||||
m_World->DeleteEntity(e.Player.ID);
|
||||
Events::PlayerDeath ePlayerDeath;
|
||||
ePlayerDeath.Player = e.Player;
|
||||
m_EventBroker->Publish(ePlayerDeath);
|
||||
//Note: we will delete the entity in PlayerDeathSystem
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HealthSystem::OnPlayerHealthPickup(const Events::PlayerHealthPickup& e)
|
||||
bool HealthSystem::OnPlayerHealthPickup(Events::PlayerHealthPickup& e)
|
||||
{
|
||||
//save the changed HP to a vector. it will be taken care of in UpdateComponent
|
||||
m_DeltaHealthVector.push_back(std::make_tuple(e.PlayerHealedID, e.HealthAmount));
|
||||
ComponentWrapper cHealth = e.Player["Health"];
|
||||
double& health = cHealth["Health"];
|
||||
health += e.HealthAmount;
|
||||
health = std::min(health, (double)cHealth["MaxHealth"]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
#include "Systems/PickupSpawnSystem.h"
|
||||
|
||||
PickupSpawnSystem::PickupSpawnSystem(World* m_World, EventBroker* eventBroker)
|
||||
: System(m_World, eventBroker)
|
||||
{
|
||||
EVENT_SUBSCRIBE_MEMBER(m_ETriggerTouch, &PickupSpawnSystem::OnTriggerTouch);
|
||||
}
|
||||
|
||||
void PickupSpawnSystem::Update(double dt)
|
||||
{
|
||||
for (auto it = m_ETriggerTouchVector.begin(); it != m_ETriggerTouchVector.end(); ++it)
|
||||
{
|
||||
auto& healthPickupPosition = *it;
|
||||
//set the double timer value (value 3)
|
||||
healthPickupPosition.DecreaseThisRespawnTimer -= dt;
|
||||
if (healthPickupPosition.DecreaseThisRespawnTimer < 0) {
|
||||
//spawn and delete the vector item
|
||||
auto entityFile = ResourceManager::Load<EntityFile>("Schema/Entities/HealthPickup.xml");
|
||||
EntityFileParser parser(entityFile);
|
||||
EntityID healthPickupID = parser.MergeEntities(m_World);
|
||||
|
||||
//let the world know a pickup has spawned (graphics effects, etc)
|
||||
Events::PickupSpawned ePickupSpawned;
|
||||
ePickupSpawned.Pickup = EntityWrapper(m_World, healthPickupID);
|
||||
m_EventBroker->Publish(ePickupSpawned);
|
||||
|
||||
//set values from the old entity to the new entity
|
||||
auto& newHealthPickupEntity = EntityWrapper(m_World, healthPickupID);
|
||||
newHealthPickupEntity["Transform"]["Position"] = healthPickupPosition.Pos;
|
||||
newHealthPickupEntity["HealthPickup"]["HealthGain"] = healthPickupPosition.HealthGain;
|
||||
newHealthPickupEntity["HealthPickup"]["RespawnTimer"] = healthPickupPosition.RespawnTimer;
|
||||
|
||||
//erase the current element (healthPickupPosition)
|
||||
m_ETriggerTouchVector.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool PickupSpawnSystem::OnTriggerTouch(Events::TriggerTouch& e)
|
||||
{
|
||||
if (!e.Trigger.HasComponent("HealthPickup")) {
|
||||
return false;
|
||||
}
|
||||
double healthGiven = 0.01*(double)e.Trigger["HealthPickup"]["HealthGain"] * (double)e.Entity["Health"]["MaxHealth"];
|
||||
//cant pick up healthpacks if you are already at MaxHealth
|
||||
if ((double)e.Entity["Health"]["Health"] >= (double)e.Entity["Health"]["MaxHealth"]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//personEntered = e.Entity, thingEntered = e.Trigger
|
||||
Events::PlayerHealthPickup ePlayerHealthPickup;
|
||||
ePlayerHealthPickup.HealthAmount = healthGiven;
|
||||
ePlayerHealthPickup.Player = e.Entity;
|
||||
m_EventBroker->Publish(ePlayerHealthPickup);
|
||||
|
||||
//copy position, healthgain, respawntimer (twice since one of the values will be counted down to 0, the other will be set in the new object)
|
||||
//we need to copy all values since each value can be different for each healthPickup
|
||||
m_ETriggerTouchVector.push_back({ (glm::vec3)e.Trigger["Transform"]["Position"] ,e.Trigger["HealthPickup"]["HealthGain"],
|
||||
e.Trigger["HealthPickup"]["RespawnTimer"],e.Trigger["HealthPickup"]["RespawnTimer"] });
|
||||
|
||||
//delete the healthpickup
|
||||
m_World->DeleteEntity(e.Trigger.ID);
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
#include "Systems/PlayerDeathSystem.h"
|
||||
|
||||
PlayerDeathSystem::PlayerDeathSystem(World* m_World, EventBroker* eventBroker)
|
||||
: System(m_World, eventBroker)
|
||||
{
|
||||
EVENT_SUBSCRIBE_MEMBER(m_OnPlayerDeath, &PlayerDeathSystem::OnPlayerDeath);
|
||||
}
|
||||
|
||||
void PlayerDeathSystem::Update(double dt)
|
||||
{
|
||||
}
|
||||
|
||||
bool PlayerDeathSystem::OnPlayerDeath(Events::PlayerDeath& e)
|
||||
{
|
||||
if (!e.Player.Valid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
createDeathEffect(e.Player);
|
||||
|
||||
// Delete player
|
||||
m_World->DeleteEntity(e.Player.ID);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void PlayerDeathSystem::createDeathEffect(EntityWrapper player)
|
||||
{
|
||||
//load the explosioneffect XML
|
||||
auto deathEffect = ResourceManager::Load<EntityFile>("Schema/Entities/PlayerDeathExplosionWithCamera.xml");
|
||||
EntityFileParser parser(deathEffect);
|
||||
EntityID deathEffectID = parser.MergeEntities(m_World);
|
||||
EntityWrapper deathEffectEW = EntityWrapper(m_World, deathEffectID);
|
||||
|
||||
//components that we need from player
|
||||
auto playerCamera = player.FirstChildByName("Camera");
|
||||
auto playerEntityModel = player.FirstChildByName("PlayerModel")["Model"];
|
||||
auto playerEntityAnimation = player.FirstChildByName("PlayerModel")["Animation"];
|
||||
|
||||
//copy the data from player to explisioneffectmodel
|
||||
playerEntityModel.Copy(deathEffectEW["Model"]);
|
||||
playerEntityAnimation.Copy(deathEffectEW["Animation"]);
|
||||
//freeze the animation
|
||||
deathEffectEW["Animation"]["Speed"] = 0.0;
|
||||
|
||||
//copy the models position,orientation
|
||||
deathEffectEW["Transform"]["Position"] = (glm::vec3)player["Transform"]["Position"];
|
||||
deathEffectEW["Transform"]["Orientation"] = (glm::vec3)player["Transform"]["Orientation"];
|
||||
//effect,camera is relative to playersPosition
|
||||
//deathEffectEW["ExplosionEffect"]["ExplosionOrigin"] = glm::vec3(0, 0, 0);
|
||||
|
||||
//camera (with lifetime) behind the player
|
||||
auto cam = deathEffectEW.FirstChildByName("Camera");
|
||||
Events::SetCamera eSetCamera;
|
||||
eSetCamera.CameraEntity = cam;
|
||||
m_EventBroker->Publish(eSetCamera);
|
||||
}
|
||||
@@ -63,11 +63,13 @@ void PlayerMovementSystem::Update(double dt)
|
||||
}
|
||||
}
|
||||
glm::vec3& velocity = cPhysics["Velocity"];
|
||||
ImGui::Text("velocity: (%f, %f, %f)", velocity.x, velocity.y, velocity.z);
|
||||
bool isOnGround = (bool)cPhysics["IsOnGround"];
|
||||
ImGui::Text(isOnGround ? "On ground" : "In air");
|
||||
ImGui::Text("velocity: (%f, %f, %f) |%f|", velocity.x, velocity.y, velocity.z, glm::length(velocity));
|
||||
glm::vec3 groundVelocity(0.f, 0.f, 0.f);
|
||||
groundVelocity.x = glm::dot(velocity, glm::vec3(1.f, 0.f, 0.f));
|
||||
groundVelocity.z = glm::dot(velocity, glm::vec3(0.f, 0.f, 1.f));
|
||||
ImGui::Text("groundVelocity: (%f, %f, %f) |%f|", groundVelocity.x, groundVelocity.y, groundVelocity.z, glm::length(wishDirection));
|
||||
groundVelocity.x = velocity.x;
|
||||
groundVelocity.z = velocity.z;
|
||||
ImGui::Text("groundVelocity: (%f, %f, %f) |%f|", groundVelocity.x, groundVelocity.y, groundVelocity.z, glm::length(groundVelocity));
|
||||
ImGui::Text("wishDirection: (%f, %f, %f) |%f|", wishDirection.x, wishDirection.y, wishDirection.z, glm::length(wishDirection));
|
||||
float currentSpeedProj = glm::dot(groundVelocity, wishDirection);
|
||||
float addSpeed = wishSpeed - currentSpeedProj;
|
||||
@@ -80,7 +82,7 @@ void PlayerMovementSystem::Update(double dt)
|
||||
ImGui::InputFloat("accel", &accel);
|
||||
static float airAccel = 0.5f;
|
||||
ImGui::InputFloat("airAccel", &airAccel);
|
||||
float actualAccel = (velocity.y != 0) ? airAccel : accel;
|
||||
float actualAccel = isOnGround ? accel : airAccel;
|
||||
static float surfaceFriction = 5.f;
|
||||
ImGui::InputFloat("surfaceFriction", &surfaceFriction);
|
||||
float accelerationSpeed = actualAccel * (float)dt * wishSpeed * surfaceFriction;
|
||||
@@ -92,7 +94,8 @@ void PlayerMovementSystem::Update(double dt)
|
||||
}
|
||||
|
||||
//you cant jump and dash at the same time - since there is no friction in the air and we would thus dash much further in the air
|
||||
if (!controller->PlayerIsDashing() && controller->Jumping() && !controller->Crouching() && (velocity.y == 0.f || !controller->DoubleJumping())) {
|
||||
if (!controller->PlayerIsDashing() && controller->Jumping() && !controller->Crouching() && (isOnGround || !controller->DoubleJumping())) {
|
||||
(bool)cPhysics["IsOnGround"] = false;
|
||||
if (velocity.y == 0.f) {
|
||||
controller->SetDoubleJumping(false);
|
||||
} else {
|
||||
@@ -153,6 +156,7 @@ void PlayerMovementSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapp
|
||||
|
||||
ComponentWrapper& cPhysics = entity["Physics"];
|
||||
glm::vec3& velocity = cPhysics["Velocity"];
|
||||
bool isOnGround = (bool)cPhysics["IsOnGround"];
|
||||
|
||||
// Ground friction
|
||||
float speed = glm::length(velocity);
|
||||
@@ -160,7 +164,7 @@ void PlayerMovementSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapp
|
||||
ImGui::InputFloat("groundFriction", &groundFriction);
|
||||
static float airFriction = 0.f;
|
||||
ImGui::InputFloat("airFriction", &airFriction);
|
||||
float friction = (velocity.y != 0) ? airFriction : groundFriction;
|
||||
float friction = isOnGround ? groundFriction : airFriction;
|
||||
if (speed > 0) {
|
||||
float drop = speed * friction * (float)dt;
|
||||
float multiplier = glm::max(speed - drop, 0.f) / speed;
|
||||
|
||||
@@ -75,7 +75,9 @@ bool PlayerSpawnSystem::OnPlayerSpawned(Events::PlayerSpawned& e)
|
||||
// Check if a player already exists
|
||||
if (m_PlayerEntities.count(e.PlayerID) != 0) {
|
||||
// TODO: Disallow infinite respawning here
|
||||
m_World->DeleteEntity(m_PlayerEntities[e.PlayerID].ID);
|
||||
if (m_PlayerEntities[e.PlayerID].Valid()) {
|
||||
m_World->DeleteEntity(m_PlayerEntities[e.PlayerID].ID);
|
||||
}
|
||||
}
|
||||
|
||||
// Store the player for future reference
|
||||
|
||||
Reference in New Issue
Block a user