384 lines
13 KiB
C++
384 lines
13 KiB
C++
#include "PrecompiledHeader.h"
|
|
#include "TowerSystem.h"
|
|
#include "World.h"
|
|
|
|
void Systems::TowerSystem::RegisterComponents( ComponentFactory* cf )
|
|
{
|
|
cf->Register<Components::Tower>([]() { return new Components::Tower(); });
|
|
cf->Register<Components::Turret>([]() { return new Components::Turret(); });
|
|
cf->Register<Components::TurretShot>([]() {return new Components::TurretShot(); });
|
|
cf->Register<Components::TowerDebris>([]() {return new Components::TowerDebris(); });
|
|
}
|
|
|
|
void Systems::TowerSystem::Initialize()
|
|
{
|
|
//EVENT_SUBSCRIBE_MEMBER(m_eDamage, &Systems::TowerSystem::Damage);
|
|
EVENT_SUBSCRIBE_MEMBER(m_ECollision, &Systems::TowerSystem::OnCollision);
|
|
EVENT_SUBSCRIBE_MEMBER(m_eDamage, &Systems::TowerSystem::Damage);
|
|
|
|
Temp_m_TimeSinceLastShot = 0;
|
|
}
|
|
|
|
void Systems::TowerSystem::Update( double dt )
|
|
{
|
|
|
|
}
|
|
|
|
bool Systems::TowerSystem::Damage( const Events::Damage &event )
|
|
{
|
|
auto debrisComponent = m_World->GetComponent<Components::TowerDebris>(event.Entity);
|
|
if(!debrisComponent)
|
|
{
|
|
return false;
|
|
}
|
|
LOG_INFO("TowerSystem::Damage");
|
|
|
|
// Change to damage model
|
|
|
|
auto wallhealthcomponent = m_World->GetComponent<Components::Health>(event.Entity);
|
|
if(wallhealthcomponent->Amount > 0)
|
|
{
|
|
return false;
|
|
}
|
|
LOG_INFO("Entity %i is dead", event.Entity);
|
|
auto entitytransform = m_World->GetComponent<Components::Transform>(event.Entity);
|
|
if(!entitytransform)
|
|
return false;
|
|
//auto transformComponent = m_World->GetComponent<Components::Transform>(event.Entity);
|
|
Components::Transform transformComponent = m_World->GetSystem<Systems::TransformSystem>()->AbsoluteTransform(event.Entity);
|
|
|
|
// Spawn debris
|
|
for(auto d : debrisComponent->TowerDebrisIDs)
|
|
{
|
|
auto debris = m_World->CloneEntity(d);
|
|
|
|
auto transform = m_World->GetComponent<Components::Transform>(debris);
|
|
Components::Transform absolutetransformComponent = m_World->GetSystem<Systems::TransformSystem>()->AbsoluteTransform(debris);
|
|
transform->Orientation = transform->Orientation * transformComponent.Orientation;
|
|
transform->Position = transform->Orientation * transform->Position + transformComponent.Position;
|
|
|
|
//DO STUFF! :D
|
|
float distance = glm::distance(transform->Position, transformComponent.Position);
|
|
float radius = 15.f;
|
|
float strength = (1.f - pow(distance / radius, 2)) * 2000.f;
|
|
glm::vec3 direction = glm::normalize(transformComponent.Position - transform->Position);
|
|
|
|
Events::ApplyPointImpulse e;
|
|
e.Entity = debris;
|
|
e.Impulse = direction * strength;
|
|
e.Position = transformComponent.Position;
|
|
EventBroker->Publish(e);
|
|
|
|
}
|
|
|
|
entitytransform->Position = glm::vec3(0.f, -50000000.f, 0.f);
|
|
|
|
return true;
|
|
}
|
|
|
|
void Systems::TowerSystem::UpdateEntity( double dt, EntityID entity, EntityID parent )
|
|
{
|
|
auto towerComponent = m_World->GetComponent<Components::Tower>(entity);
|
|
if(!towerComponent)
|
|
return;
|
|
|
|
Components::Transform absoluteTowerGunTransform = m_World->GetSystem<Systems::TransformSystem>()->AbsoluteTransform(towerComponent->Gun);
|
|
|
|
auto towerGunTransformComponent = m_World->GetComponent<Components::Transform>(towerComponent->Gun);
|
|
if(!towerGunTransformComponent)
|
|
return;
|
|
|
|
auto towerGunBaseTransformComponent = m_World->GetComponent<Components::Transform>(towerComponent->GunBase);
|
|
if(!towerGunBaseTransformComponent)
|
|
return;
|
|
|
|
auto turretComponent = m_World->GetComponent<Components::Turret>(entity);
|
|
if(!turretComponent)
|
|
return;
|
|
|
|
auto players = m_World->GetComponentsOfType<Components::Player>();
|
|
if (!players)
|
|
return;
|
|
|
|
for(auto player : *players)
|
|
{
|
|
auto playerComponent = std::dynamic_pointer_cast<Components::Player>(player);
|
|
if(towerComponent->ID == playerComponent->ID) //!= betyder att den bara targetar sitt eget lag, == fienden.
|
|
continue;
|
|
|
|
auto playerTransform = m_World->GetComponent<Components::Transform>(player->Entity);
|
|
if(!playerTransform)
|
|
continue;
|
|
|
|
Components::Transform absolutePlayerTransform = m_World->GetSystem<Systems::TransformSystem>()->AbsoluteTransform(player->Entity);
|
|
|
|
if(glm::distance(absolutePlayerTransform.Position, absoluteTowerGunTransform.Position) > 45.f)
|
|
continue;
|
|
//Rotate the turret towards the enemy player
|
|
glm::quat baseLookAt = glm::inverse(glm::quat_cast(glm::lookAt(absoluteTowerGunTransform.Position, glm::vec3(absolutePlayerTransform.Position.x, absoluteTowerGunTransform.Position.y, absolutePlayerTransform.Position.z), glm::vec3(0, 1, 0))));
|
|
glm::quat gunLookAt = glm::inverse(glm::quat_cast(glm::lookAt(absoluteTowerGunTransform.Position, glm::vec3(absolutePlayerTransform.Position.x, absolutePlayerTransform.Position.y, absolutePlayerTransform.Position.z ), glm::vec3(0, 1, 0))));
|
|
|
|
towerGunTransformComponent->Orientation = glm::inverse(baseLookAt) * gunLookAt;
|
|
towerGunBaseTransformComponent->Orientation = baseLookAt;
|
|
|
|
#pragma region GetShotDirectionAndLaunchShot
|
|
Temp_m_TimeSinceLastShot += dt;
|
|
if(Temp_m_TimeSinceLastShot > 1)
|
|
{
|
|
{
|
|
//Shoot code
|
|
EntityID clone = m_World->CloneEntity(turretComponent->ShotTemplate);
|
|
auto templateAbsoluteTransform = m_World->GetSystem<Systems::TransformSystem>()->AbsoluteTransform(turretComponent->ShotTemplate);
|
|
auto cloneTransform = m_World->GetComponent<Components::Transform>(clone);
|
|
cloneTransform->Orientation = templateAbsoluteTransform.Orientation;
|
|
cloneTransform->Position = templateAbsoluteTransform.Position - (cloneTransform->Orientation* glm::vec3(0.97163f, 0.f, 0.f));
|
|
|
|
|
|
Events::SetVelocity eSetVelocity;
|
|
eSetVelocity.Entity = clone;
|
|
eSetVelocity.Velocity = gunLookAt * glm::vec3(0.f, 0.f, -1.f) * turretComponent->ShotSpeed;
|
|
EventBroker->Publish(eSetVelocity);
|
|
|
|
{
|
|
Events::CreateExplosion e;
|
|
e.LifeTime = 1.5;
|
|
e.ParticleScale.push_back(0.6);
|
|
e.ParticleScale.push_back(1.8);
|
|
e.ParticlesToSpawn = 1;
|
|
e.Position = cloneTransform->Position;
|
|
e.RelativeUpOrientation = glm::angleAxis(glm::pi<float>() / 2, glm::vec3(1,0,0));
|
|
e.Speed = 1.7;
|
|
e.SpreadAngle = glm::pi<float>()/100;
|
|
e.spritePath = "Textures/Sprites/Smoke1.png";
|
|
e.Emitting = true;
|
|
e.SpawnFrequency = 0.2;
|
|
e.Color = glm::vec4(0.6,0.6,0.6,1);
|
|
EventBroker->Publish(e);
|
|
}
|
|
{
|
|
Events::CreateExplosion e;
|
|
e.LifeTime = 0.2;
|
|
e.ParticleScale.push_back(1);
|
|
//e.ParticleScale.push_back(2);
|
|
e.ParticlesToSpawn = 1;
|
|
e.Position = cloneTransform->Position;
|
|
e.Speed = 0;
|
|
e.SpreadAngle = glm::pi<float>();
|
|
e.spritePath = "Textures/Sprites/MuzzleFlash.png";
|
|
e.Color = glm::vec4(2, 2, 2, 0.2);
|
|
EventBroker->Publish(e);
|
|
}
|
|
}
|
|
|
|
{
|
|
EntityID clone = m_World->CloneEntity(turretComponent->ShotTemplate);
|
|
auto templateAbsoluteTransform = m_World->GetSystem<Systems::TransformSystem>()->AbsoluteTransform(turretComponent->ShotTemplate);
|
|
auto cloneTransform = m_World->GetComponent<Components::Transform>(clone);
|
|
cloneTransform->Orientation = templateAbsoluteTransform.Orientation;
|
|
cloneTransform->Position = templateAbsoluteTransform.Position + (cloneTransform->Orientation * glm::vec3(0.97163f, 0.f, 0.f));
|
|
|
|
|
|
Events::SetVelocity eSetVelocity;
|
|
eSetVelocity.Entity = clone;
|
|
eSetVelocity.Velocity = gunLookAt * glm::vec3(0.f, 0.f, -1.f) * turretComponent->ShotSpeed;
|
|
EventBroker->Publish(eSetVelocity);
|
|
|
|
{
|
|
Events::CreateExplosion e;
|
|
e.LifeTime = 1.5;
|
|
e.ParticleScale.push_back(0.6);
|
|
e.ParticleScale.push_back(1.8);
|
|
e.ParticlesToSpawn = 1;
|
|
e.Position = cloneTransform->Position;
|
|
e.RelativeUpOrientation = glm::angleAxis(glm::pi<float>() / 2, glm::vec3(1,0,0));
|
|
e.Speed = 1.7;
|
|
e.SpreadAngle = glm::pi<float>()/100;
|
|
e.spritePath = "Textures/Sprites/Smoke1.png";
|
|
e.Emitting = true;
|
|
e.SpawnFrequency = 0.2;
|
|
e.Color = glm::vec4(0.6,0.6,0.6,1);
|
|
EventBroker->Publish(e);
|
|
}
|
|
{
|
|
Events::CreateExplosion e;
|
|
e.LifeTime = 0.2;
|
|
e.ParticleScale.push_back(1);
|
|
//e.ParticleScale.push_back(2);
|
|
e.ParticlesToSpawn = 1;
|
|
e.Position = cloneTransform->Position;
|
|
e.Speed = 0;
|
|
e.SpreadAngle = glm::pi<float>();
|
|
e.spritePath = "Textures/Sprites/MuzzleFlash.png";
|
|
e.Color = glm::vec4(2, 2, 2, 0.2);
|
|
EventBroker->Publish(e);
|
|
}
|
|
}
|
|
|
|
Temp_m_TimeSinceLastShot = 0;
|
|
#pragma endregion
|
|
}
|
|
}
|
|
}
|
|
|
|
bool Systems::TowerSystem::OnCollision(const Events::Collision &e)
|
|
{
|
|
if(m_World->ValidEntity(e.Entity1) && m_World->ValidEntity(e.Entity2))
|
|
{
|
|
auto tankShell1 = m_World->GetComponent<Components::TurretShot>(e.Entity1);
|
|
auto tankShell2 = m_World->GetComponent<Components::TurretShot>(e.Entity2);
|
|
|
|
EntityID shellEntity = 0;
|
|
Components::TurretShot* shellComponent;
|
|
EntityID otherEntity = 0;
|
|
|
|
if (tankShell1)
|
|
{
|
|
shellEntity = e.Entity1;
|
|
otherEntity = e.Entity2;
|
|
shellComponent = tankShell1;
|
|
}
|
|
else if (tankShell2)
|
|
{
|
|
shellEntity = e.Entity2;
|
|
otherEntity = e.Entity1;
|
|
shellComponent = tankShell2;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if(m_World->GetComponent<Components::Template>(shellEntity))
|
|
return false;
|
|
|
|
//auto physicsComponents = m_World->GetComponentsOfType<Components::Physics>();
|
|
auto shellTransform = m_World->GetComponent<Components::Transform>(shellEntity);
|
|
//auto otherTransform = m_World->GetComponent<Components::Transform>(otherEntity);
|
|
|
|
|
|
{
|
|
Events::CreateExplosion e;
|
|
e.LifeTime = 2;
|
|
e.ParticleScale.push_back(3);
|
|
e.ParticlesToSpawn = 10;
|
|
e.Position = shellTransform->Position;
|
|
e.RelativeUpOrientation = glm::angleAxis(glm::pi<float>() / 2, glm::vec3(1, 0, 0));
|
|
e.Speed = 3;
|
|
e.SpreadAngle = glm::pi<float>();
|
|
e.spritePath = "Textures/Sprites/Smoke1.png";
|
|
e.Color = glm::vec4(0.6, 0.6, 0.6, 0.1);
|
|
EventBroker->Publish(e);
|
|
e.LifeTime = 0.7;
|
|
e.ParticleScale.push_back(5);
|
|
e.ParticlesToSpawn = 10;
|
|
e.Position = shellTransform->Position;
|
|
e.RelativeUpOrientation = glm::angleAxis(glm::pi<float>() / 2, glm::vec3(1, 0, 0));
|
|
e.Speed = 17;
|
|
e.SpreadAngle = glm::pi<float>();
|
|
e.spritePath = "Textures/Sprites/Fire.png";
|
|
EventBroker->Publish(e);
|
|
e.LifeTime = 0.2;
|
|
e.ParticleScale.push_back(1);
|
|
e.ParticleScale.push_back(5);
|
|
e.ParticlesToSpawn = 5;
|
|
e.Position = shellTransform->Position;
|
|
e.RelativeUpOrientation = glm::angleAxis(glm::pi<float>() / 2, glm::vec3(1, 0, 0));
|
|
e.Speed = 6;
|
|
e.SpreadAngle = glm::pi<float>();
|
|
e.spritePath = "Textures/Sprites/Blast1.png";
|
|
e.Color = glm::vec4(2, 2, 2, 0.2);
|
|
EventBroker->Publish(e);
|
|
}
|
|
|
|
//{
|
|
// Events::CreateExplosion e;
|
|
// e.LifeTime = 1.5;
|
|
// e.ParticleScale.push_back(1);
|
|
// e.ParticleScale.push_back(6);
|
|
// e.ParticlesToSpawn = 20;
|
|
// e.Position = shellTransform->Position;
|
|
// e.SpreadAngle = glm::radians<float>(180) / 4;
|
|
// e.RelativeUpOrientation = glm::angleAxis(glm::radians<float>(90), glm::vec3(1,0,0));
|
|
// e.UseGoalVector = true;
|
|
// e.GoalVelocity = glm::vec3(0,-12,0);
|
|
// e.Speed = 12;
|
|
// e.spritePath = "Textures/Sprites/Splash.png";
|
|
// e.Color = glm::vec4(5.f,5.f,5.f,1);
|
|
|
|
// EventBroker->Publish(e);
|
|
// e.LifeTime = 1.5;
|
|
// e.ParticleScale.push_back(1);
|
|
// e.ParticleScale.push_back(6);
|
|
// e.ParticlesToSpawn = 20;
|
|
// e.Position = shellTransform->Position;
|
|
// e.SpreadAngle = glm::radians<float>(180)/ 4;
|
|
// e.RelativeUpOrientation = glm::angleAxis(glm::radians<float>(90), glm::vec3(1,0,0));
|
|
// e.UseGoalVector = true;
|
|
// e.GoalVelocity = glm::vec3(0,-12,0);
|
|
// e.Speed = 12;
|
|
// e.spritePath = "Textures/Sprites/Splash.png";
|
|
// e.Color = glm::vec4(1.f,1.f,1.f,1);
|
|
// EventBroker->Publish(e);
|
|
//}
|
|
|
|
|
|
//{
|
|
// Events::PlaySFX e;
|
|
// e.MinDistance = 150.f;
|
|
// e.Position = shellTransform->Position;
|
|
// e.Resource = "Sounds/SFX/Explosion.wav";
|
|
// EventBroker->Publish(e);
|
|
//}
|
|
|
|
// Direct damage
|
|
auto health = m_World->GetComponent<Components::Health>(otherEntity);
|
|
if (health)
|
|
{
|
|
Events::Damage d;
|
|
d.Entity = otherEntity;
|
|
d.Amount = shellComponent->Damage;
|
|
EventBroker->Publish(d);
|
|
}
|
|
|
|
// Splash damage
|
|
//for (auto &physComponent : *physicsComponents)
|
|
//{
|
|
// EntityID physicsEntity = physComponent->Entity;
|
|
// // No splash damage to the direct hit target
|
|
// if (physicsEntity == otherEntity)
|
|
// continue;
|
|
// auto physEntityTransform = m_World->GetSystem<Systems::TransformSystem>()->AbsoluteTransform(physicsEntity);
|
|
|
|
// float distance = glm::distance(physEntityTransform.Position, shellTransform->Position);
|
|
// if (distance <= shellComponent->ExplosionRadius)
|
|
// {
|
|
// // DO STUFF! :D
|
|
// float radius = shellComponent->ExplosionRadius;
|
|
// float strength = (1.f - pow(distance / radius, 2)) * shellComponent->ExplosionStrength;
|
|
// glm::vec3 direction = glm::normalize(physEntityTransform.Position - shellTransform->Position);
|
|
|
|
// Events::ApplyPointImpulse e;
|
|
// e.Entity = physicsEntity;
|
|
// e.Impulse = direction * strength;
|
|
// e.Position = physEntityTransform.Position;
|
|
// EventBroker->Publish(e);
|
|
|
|
// auto health = m_World->GetComponent<Components::Health>(physicsEntity);
|
|
// if (health && health->VulnerableToSplash)
|
|
// {
|
|
// Events::Damage d;
|
|
// d.Entity = physicsEntity;
|
|
// d.Amount = (1.f - pow(distance / radius, 2)) * shellComponent->Damage;
|
|
// EventBroker->Publish(d);
|
|
// }
|
|
//
|
|
//
|
|
// }
|
|
//}
|
|
m_World->RemoveEntity(shellEntity);
|
|
|
|
}
|
|
return true;
|
|
}
|
|
|