Merge remote-tracking branch 'origin/master' into DefenderShield

# Conflicts:
#	resources/Schema/Components.xsd
This commit is contained in:
Tleety
2016-02-08 12:30:41 +01:00
62 changed files with 1654 additions and 429 deletions
+4
View File
@@ -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"
@@ -88,9 +90,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 -37
View File
@@ -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;
}
+3 -3
View File
@@ -5,7 +5,7 @@ InterpolationSystem::InterpolationSystem(World* world, EventBroker* eventBroker)
, PureSystem("Transform")
{
ConfigFile* config = ResourceManager::Load<ConfigFile>("Config.ini");
m_SnapshotInterval = config->Get<float>("Networking.SnapshotInterval", 0.05);
m_SnapshotInterval = config->Get<float>("Networking.SnapshotInterval", 0.05f);
EVENT_SUBSCRIBE_MEMBER(m_EInterpolate, &InterpolationSystem::OnInterpolate);
EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &InterpolationSystem::OnPlayerSpawned);
}
@@ -18,9 +18,9 @@ void InterpolationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrappe
}
if (m_NextTransform.find(transform.EntityID) != m_NextTransform.end()) { // Exists in map
m_NextTransform[transform.EntityID].interpolationTime += dt;
m_NextTransform[transform.EntityID].interpolationTime += static_cast<float>(dt);
Transform sTransform = m_NextTransform[transform.EntityID];
double time = sTransform.interpolationTime;
float time = sTransform.interpolationTime;
if (time > m_SnapshotInterval) {
if (m_LastReceivedTransform.find(transform.EntityID) != m_LastReceivedTransform.end()) {
m_NextTransform[transform.EntityID] = m_LastReceivedTransform[transform.EntityID];
+66
View File
@@ -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;
}
+57
View File
@@ -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);
}
+26 -12
View File
@@ -1,6 +1,6 @@
#include "Systems/PlayerMovementSystem.h"
PlayerMovementSystem::PlayerMovementSystem(World* world, EventBroker* eventBroker)
PlayerMovementSystem::PlayerMovementSystem(World* world, EventBroker* eventBroker)
: System(world, eventBroker)
, PureSystem("Player")
{
@@ -41,8 +41,15 @@ void PlayerMovementSystem::Update(double dt)
if (player.HasComponent("Physics")) {
ComponentWrapper cPhysics = player["Physics"];
//Assault Dash Check
if (player.HasComponent("DashAbility")) {
controller->AssaultDashCheck(dt, ((glm::vec3)cPhysics["Velocity"]).y != 0.0f, player["DashAbility"]["CoolDownMaxTimer"]);
}
glm::vec3 wishDirection = controller->Movement() * glm::inverse(glm::quat(ori));
//this makes sure you can only dash in the 4 directions: forw,backw,left,right
if (controller->AssaultDashDoubleTapped() && controller->Movement().z != 0 && controller->Movement().x != 0) {
wishDirection = glm::vec3(controller->Movement().x, 0, 0)* glm::inverse(glm::quat(ori));
}
float wishSpeed;
if (controller->Crouching()) {
wishSpeed = playerCrouchSpeed;
@@ -50,11 +57,13 @@ void PlayerMovementSystem::Update(double dt)
wishSpeed = playerMovementSpeed;
}
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;
@@ -67,20 +76,23 @@ 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;
accelerationSpeed = glm::min(accelerationSpeed, addSpeed);
//if doubleTapped do Assault Dash - but only boost maximum 50.0f
float doubleTapDashBoost = controller->AssaultDashDoubleTapped() ? 40.0f : 1.0f;
accelerationSpeed = glm::min(doubleTapDashBoost*glm::min(accelerationSpeed, addSpeed), 50.0f);
velocity += accelerationSpeed * wishDirection;
ImGui::Text("velocity: (%f, %f, %f) |%f|", velocity.x, velocity.y, velocity.z, glm::length(velocity));
}
if (controller->Jumping() && !controller->Crouching() && (velocity.y == 0.f || !controller->DoubleJumping())) {
//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() && (isOnGround || !controller->DoubleJumping())) {
(bool)cPhysics["IsOnGround"] = false;
if (velocity.y == 0.f) {
controller->SetDoubleJumping(false);
}
else {
} else {
controller->SetDoubleJumping(true);
}
velocity.y += 4.f;
@@ -101,6 +113,7 @@ void PlayerMovementSystem::Update(double dt)
ComponentWrapper cAnimation = playerModel["Animation"];
float movementLength = glm::length(groundVelocity);
//TODO: add assault dash animation here
if (glm::length(controller->Movement()) > 0.f) {
if (controller->Crouching()) {
cAnimation["Name"] = "Crouch Walk";
@@ -134,6 +147,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);
@@ -141,7 +155,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;
+3 -1
View File
@@ -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