diff --git a/include/Game/Systems/DamageIndicatorSystem.h b/include/Game/Systems/DamageIndicatorSystem.h index 053b196b..446ad2d3 100644 --- a/include/Game/Systems/DamageIndicatorSystem.h +++ b/include/Game/Systems/DamageIndicatorSystem.h @@ -15,10 +15,11 @@ #include "Rendering/Util/CommonFunctions.h" -class DamageIndicatorSystem : public System +class DamageIndicatorSystem : public ImpureSystem { public: DamageIndicatorSystem(SystemParams params); + virtual void Update(double dt) override; private: EventRelay m_EPlayerDamage; @@ -28,6 +29,17 @@ private: bool OnSetCamera(const Events::SetCamera& e); EntityID m_CurrentCamera = -1; - + struct DamageIndicatorStruct { + EntityWrapper spriteEntity; + //double timeLeft; + glm::vec3 enemyPosition; + DamageIndicatorStruct(EntityWrapper entity, glm::vec3 pos) + : spriteEntity(entity) + //, timeLeft(time) + , enemyPosition(pos) {} + }; + std::vector updateDamageIndicatorVector; + float CalculateAngle(EntityWrapper player, glm::vec3 enemyPos); + int m_TestVar = 0; }; #endif diff --git a/src/Game/Systems/DamageIndicatorSystem.cpp b/src/Game/Systems/DamageIndicatorSystem.cpp index 99bbb23a..7db30ca8 100644 --- a/src/Game/Systems/DamageIndicatorSystem.cpp +++ b/src/Game/Systems/DamageIndicatorSystem.cpp @@ -12,13 +12,49 @@ DamageIndicatorSystem::DamageIndicatorSystem(SystemParams params) auto entityFile = ResourceManager::Load("Schema/Entities/DamageIndicator.xml"); } +void DamageIndicatorSystem::Update(double dt) { + if (!IsServer) { + for (auto& iter = updateDamageIndicatorVector.begin(); iter != updateDamageIndicatorVector.end(); iter++) { + if (!iter->spriteEntity.Valid()) + //iter->timeLeft -= -dt; + /*if (iter->timeLeft < 0.0)*/ { + updateDamageIndicatorVector.erase(iter); + break; + } + auto angleBetweenVectors = CalculateAngle(LocalPlayer, iter->enemyPosition); + //simply set the rotation z-wise to the angleBetweenVectors + iter->spriteEntity["Transform"]["Orientation"] = glm::vec3(0, 0, angleBetweenVectors); + } + } +} + bool DamageIndicatorSystem::OnPlayerDamage(Events::PlayerDamage& e) { //TEST auto currentPos = (glm::vec3)e.Victim["Transform"]["Position"]; - auto nextPos = glm::vec3(currentPos.x + 2.0f, currentPos.y, currentPos.z); - e.Inflictor["Transform"]["Position"] = nextPos; - + + auto testTempo = 1; + auto testTempo2 = 1; + if (m_TestVar % 4 == 0) { + testTempo = -1; + testTempo2 = 1; + } + if (m_TestVar % 4 == 1) { + testTempo = 1; + testTempo2 = 1; + } + if (m_TestVar % 4 == 2) { + testTempo *= -1; + testTempo2 = -1; + } + if (m_TestVar % 4 == 3) { + testTempo = 1; + testTempo2 = -1; + } + m_TestVar++; + auto inflictorPos = glm::vec3(currentPos.x + testTempo*12.0f, currentPos.y, currentPos.z + testTempo2*12.0f); + //inflictor = real entity... + //SPAWN //load the explosioneffect XML auto deathEffect = ResourceManager::Load("Schema/Entities/PlayerDeathExplosionWithCamera.xml"); @@ -26,29 +62,19 @@ bool DamageIndicatorSystem::OnPlayerDamage(Events::PlayerDamage& e) EntityID deathEffectID = parser2.MergeEntities(m_World); EntityWrapper deathEffectEW = EntityWrapper(m_World, deathEffectID); - LOG_INFO("<- effect camera"); - //components that we need from player - auto playerCamera = e.Victim.FirstChildByName("Camera"); auto playerModel = e.Victim.FirstChildByName("PlayerModel"); auto playerEntityModel = playerModel["Model"]; auto playerEntityAnimation = playerModel["Animation"]; - LOG_INFO("-> effect camera"); - //copy the data from player to explisioneffectmodel + //copy the data from player to explosioneffectmodel playerEntityModel.Copy(deathEffectEW["Model"]); playerEntityAnimation.Copy(deathEffectEW["Animation"]); - //freeze the animation - deathEffectEW["Animation"]["Speed1"] = 0.0; - deathEffectEW["Animation"]["Speed2"] = 0.0; - deathEffectEW["Animation"]["Speed3"] = 0.0; //copy the models position,orientation - deathEffectEW["Transform"]["Position"] = (glm::vec3)e.Inflictor["Transform"]["Position"]; + deathEffectEW["Transform"]["Position"] = inflictorPos; deathEffectEW["Transform"]["Orientation"] = (glm::vec3)e.Victim["Transform"]["Orientation"]; - - //TEST END @@ -66,7 +92,7 @@ bool DamageIndicatorSystem::OnPlayerDamage(Events::PlayerDamage& e) } if (!e.Inflictor.Valid() || !e.Victim.Valid()) { - return false; + return false; } LOG_INFO("- damageindicator"); @@ -74,7 +100,7 @@ bool DamageIndicatorSystem::OnPlayerDamage(Events::PlayerDamage& e) auto playerOrientation = glm::quat((glm::vec3)e.Victim["Transform"]["Orientation"]); //get the position vectors, but ignore the y-height - auto enemyPosition = (glm::vec3)e.Inflictor["Transform"]["Position"]; + auto enemyPosition = inflictorPos; auto playerPosition = (glm::vec3)e.Victim["Transform"]["Position"]; enemyPosition.y = 0.0f; playerPosition.y = 0.0f; @@ -83,8 +109,12 @@ bool DamageIndicatorSystem::OnPlayerDamage(Events::PlayerDamage& e) auto enemyPlayerVector = glm::normalize(playerPosition - enemyPosition); //get angle from players current rotation, this angle is how much you rotate around the y-axis - auto playerAngle = glm::angle(playerOrientation); - auto playerRotationVector = glm::normalize(glm::rotateY(glm::vec3(0, 0, 1), playerAngle)); + //auto playerAngle = glm::angle(playerOrientation); + //auto playerRotationVector = glm::normalize(glm::rotateY(glm::vec3(0, 0, 1), playerAngle)); + auto rotationVector = glm::toMat4(Transform::AbsoluteOrientation(e.Victim))*glm::vec4(0, 0, 1, 0); + auto playerRotationVector = glm::vec3(rotationVector); + auto rotVNinety = glm::rotateY(rotationVector, 1.57f); + auto playerSideVector = glm::vec3(rotVNinety); //dot product of players direction-vector and enemys-to-playervector will give the cos of the angle between the vectors auto playerRotationDot = glm::dot(playerRotationVector, enemyPlayerVector); @@ -92,7 +122,7 @@ bool DamageIndicatorSystem::OnPlayerDamage(Events::PlayerDamage& e) auto angleBetweenVectors = glm::acos(playerRotationDot); //rotate the direction-vector 90 degrees to get the players side-vector - auto playerSideVector = glm::normalize(glm::rotateY(glm::vec3(0, 0, 1), playerAngle + 1.57f)); + //auto playerSideVector = glm::normalize(glm::rotateY(glm::vec3(0, 0, 1), playerAngle + 1.57f)); //dot of sidevector positive = enemy is on the right side, dot sidevector negative = left side auto playerSideVectorDot = glm::dot(playerSideVector, enemyPlayerVector); if (playerSideVectorDot < 0) { @@ -108,6 +138,8 @@ bool DamageIndicatorSystem::OnPlayerDamage(Events::PlayerDamage& e) //simply set the rotation z-wise to the angleBetweenVectors spriteWrapper["Transform"]["Orientation"] = glm::vec3(0, 0, angleBetweenVectors); + updateDamageIndicatorVector.emplace_back(spriteWrapper, enemyPosition); + LOG_INFO("-> damageindicator"); return true; @@ -117,3 +149,39 @@ bool DamageIndicatorSystem::OnSetCamera(const Events::SetCamera& e) { m_CurrentCamera = e.CameraEntity.ID; return true; } +float DamageIndicatorSystem::CalculateAngle(EntityWrapper player, glm::vec3 enemyPos) { + //grab players direction + auto playerOrientation = glm::quat((glm::vec3)player["Transform"]["Orientation"]); + + //get the position vectors, but ignore the y-height + auto enemyPosition = enemyPos; + auto playerPosition = (glm::vec3)player["Transform"]["Position"]; + enemyPosition.y = 0.0f; + playerPosition.y = 0.0f; + + //calculate the enemy to player vector + auto enemyPlayerVector = glm::normalize(playerPosition - enemyPosition); + + //get angle from players current rotation, this angle is how much you rotate around the y-axis + //auto playerAngle = glm::angle(playerOrientation); + //auto playerRotationVector = glm::normalize(glm::rotateY(glm::vec3(0, 0, 1), playerAngle)); + auto rotationVector = glm::toMat4(Transform::AbsoluteOrientation(player))*glm::vec4(0, 0, 1, 0); + auto playerRotationVector = glm::vec3(rotationVector); + auto rotVNinety = glm::rotateY(rotationVector, 1.57f); + auto playerSideVector = glm::vec3(rotVNinety); + + //dot product of players direction-vector and enemys-to-playervector will give the cos of the angle between the vectors + auto playerRotationDot = glm::dot(playerRotationVector, enemyPlayerVector); + //to get the angle between the vectors just do cos-inverse + auto angleBetweenVectors = glm::acos(playerRotationDot); + + //rotate the direction-vector 90 degrees to get the players side-vector + //auto playerSideVector = glm::normalize(glm::rotateY(glm::vec3(0, 0, 1), playerAngle + 1.57f)); + //dot of sidevector positive = enemy is on the right side, dot sidevector negative = left side + auto playerSideVectorDot = glm::dot(playerSideVector, enemyPlayerVector); + if (playerSideVectorDot < 0) { + angleBetweenVectors = -angleBetweenVectors; + } + + return angleBetweenVectors; +}