diff --git a/assets b/assets index 5357a0c..8ab7df0 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 5357a0c4e1020317bb8745a057d6da62ab6c6504 +Subproject commit 8ab7df0d7fdb3bd0a1355192670c28826a860bb1 diff --git a/src/Components/Model.h b/src/Components/Model.h index 7ac792f..e58319c 100755 --- a/src/Components/Model.h +++ b/src/Components/Model.h @@ -10,12 +10,13 @@ namespace Components struct Model : Component { - Model() : Color(glm::vec4(1.0f, 1.0f, 1.0f, 1.0f)), Visible(true), ShadowCaster(true), Transparent(false) { } + Model() : Color(glm::vec4(1.0f, 1.0f, 1.0f, 1.0f)), Visible(true), ShadowCaster(true), Transparent(false), AverageNormals(false) { } std::string ModelFile; glm::vec4 Color; bool Visible; bool ShadowCaster; bool Transparent; + bool AverageNormals; virtual Model* Clone() const override { return new Model(*this); } }; diff --git a/src/Components/ParticleEmitter.h b/src/Components/ParticleEmitter.h index edd92b5..c403b6d 100755 --- a/src/Components/ParticleEmitter.h +++ b/src/Components/ParticleEmitter.h @@ -21,7 +21,7 @@ struct ParticleEmitter : Component , LifeTime(0) , TimeSinceLastSpawn(100) , Emitting(false) - , Color(glm::vec4(0)) { } + , Color(glm::vec4(1)) { } EntityID ParticleTemplate; float SpawnFrequency; diff --git a/src/Components/Tower.h b/src/Components/Tower.h new file mode 100644 index 0000000..fc51d3d --- /dev/null +++ b/src/Components/Tower.h @@ -0,0 +1,24 @@ +#ifndef Tower_h__ +#define Tower_h__ + +#include "Component.h" + +namespace Components +{ + + struct Tower : Component + { + Tower() + : ID(0) { } + + int ID; + EntityID GunBase; + EntityID Gun; + + + virtual Tower* Clone() const override { return new Tower(*this); } + }; + +} + +#endif // Tower_h__ \ No newline at end of file diff --git a/src/Components/Turret.h b/src/Components/Turret.h new file mode 100644 index 0000000..50abdfa --- /dev/null +++ b/src/Components/Turret.h @@ -0,0 +1,22 @@ +#ifndef Components_Turret_h__ +#define Components_Turret_h__ + +#include "Component.h" + +namespace Components +{ + + struct Turret : Component + { + Turret() + : ShotSpeed(1.0f) { } + + EntityID ShotTemplate; + float ShotSpeed; + + virtual Turret* Clone() const override { return new Turret(*this); } + }; + +} + +#endif // BarrelSteering_h__ \ No newline at end of file diff --git a/src/Components/TurretShot.h b/src/Components/TurretShot.h new file mode 100644 index 0000000..aa0ec00 --- /dev/null +++ b/src/Components/TurretShot.h @@ -0,0 +1,25 @@ +#ifndef Components_TurretShot_h__ +#define Components_TurretShot_h__ + +#include "Component.h" + +namespace Components +{ + + struct TurretShot : Component + { + TurretShot() + : Damage(1.0f), + ExplosionRadius(1.0f), + ExplosionStrength(100.0f) { } + + float Damage; + float ExplosionRadius; + float ExplosionStrength; + + virtual TurretShot* Clone() const override { return new TurretShot(*this); } + }; + +} + +#endif // Components_TurretShot_h__ diff --git a/src/Components/Vehicle.h b/src/Components/Vehicle.h index 8d9dfed..b8705e8 100644 --- a/src/Components/Vehicle.h +++ b/src/Components/Vehicle.h @@ -12,7 +12,7 @@ struct Vehicle : Component Vehicle() : MaxTorque(1000.0f), MinRPM(200.0f), OptimalRPM(2500.0f), MaxRPM(4000.0f), MaxSteeringAngle(35), TopSpeed(90.0f), MaxSpeedFullSteeringAngle(40.0f), SpringDamping(1.f), UpshiftRPM(3500.0f), DownshiftRPM(1000.0f), - gearsRatio0(3.0f), gearsRatio1(2.25f), gearsRatio2(1.5f), gearsRatio3(1.0f){ } + gearsRatio0(3.0f), gearsRatio1(2.25f), gearsRatio2(1.5f), gearsRatio3(1.0f), currentRPM(0.0f){ } float MaxTorque; float MinRPM; float OptimalRPM; @@ -29,6 +29,7 @@ struct Vehicle : Component float gearsRatio1; float gearsRatio2; float gearsRatio3; + float currentRPM; Vehicle* Clone() const override { return new Vehicle(*this); } }; diff --git a/src/Engine.h b/src/Engine.h index a8e7ef6..1da9d8e 100755 --- a/src/Engine.h +++ b/src/Engine.h @@ -22,7 +22,8 @@ public: m_ResourceManager = std::make_shared(); m_ResourceManager->RegisterType("OBJ", [](std::string resourceName) { return new OBJ(resourceName); }); auto rm = m_ResourceManager; - m_ResourceManager->RegisterType("Model", [rm](std::string resourceName) { return new Model(rm, *rm->Load("OBJ", resourceName)); }); + m_ResourceManager->RegisterType("Model", [rm](std::string resourceName) { return new Model(rm, *rm->Load("OBJ", resourceName), false); }); + m_ResourceManager->RegisterType("AveragedModel", [rm](std::string resourceName) { return new Model(rm, *rm->Load("OBJ", resourceName), true); }); m_ResourceManager->RegisterType("Texture", [](std::string resourceName) { return new Texture(resourceName); }); m_FrameStack = new GUI::Frame(m_EventBroker, m_ResourceManager); diff --git a/src/GUI/GameFrame.h b/src/GUI/GameFrame.h index afa4fcf..69edcd3 100644 --- a/src/GUI/GameFrame.h +++ b/src/GUI/GameFrame.h @@ -42,10 +42,10 @@ public: m_FreeCamViewport = new Viewport(m_WorldFrame, "ViewportFreeCam", m_World); m_FreeCamViewport->Hide(); } - //m_WorldFrame->Hide(); - //m_MainMenuFrame = new MainMenuFrame(this, "MainMenu"); - + m_WorldFrame->Hide(); m_World->Initialize(); + + m_MainMenuFrame = new MainMenuFrame(this, "MainMenu"); } private: diff --git a/src/GUI/MainMenuFrame.h b/src/GUI/MainMenuFrame.h index ff43254..076d6f9 100644 --- a/src/GUI/MainMenuFrame.h +++ b/src/GUI/MainMenuFrame.h @@ -5,6 +5,7 @@ #include "GUI/HealthOverlay.h" #include "Events/GameStart.h" +#include "Events/PlayBGM.h" namespace GUI { @@ -27,6 +28,10 @@ public: m_TargetCoordinate = m_CurrentCoordinate; m_Buttons->X = m_CurrentCoordinate.x; m_Buttons->Y = m_CurrentCoordinate.y; + + Events::PlayBGM e; + e.Resource = "Sounds/BGM/DiesIrae.mp3"; + EventBroker->Publish(e); } void Update(double dt) override @@ -74,8 +79,11 @@ protected: if (m_CurrentSelection == 0) { Hide(); - Events::GameStart e; - EventBroker->Publish(e); + Events::GameStart e1; + EventBroker->Publish(e1); + Events::PlayBGM e2; + e2.Resource = "Sounds/BGM/FlightOfTheBumblebee.mp3"; + EventBroker->Publish(e2); } // Quit else if (m_CurrentSelection == 1) diff --git a/src/GUI/WorldFrame.h b/src/GUI/WorldFrame.h index ca69fb1..f0bc62e 100644 --- a/src/GUI/WorldFrame.h +++ b/src/GUI/WorldFrame.h @@ -55,7 +55,17 @@ public: auto modelComponent = m_World->GetComponent(entity); if (modelComponent) { - auto modelAsset = ResourceManager->Load("Model", modelComponent->ModelFile); + Model* modelAsset = nullptr; + if (modelComponent->AverageNormals) + { + modelAsset = ResourceManager->Load("AveragedModel", modelComponent->ModelFile); + } + else + { + modelAsset = ResourceManager->Load("Model", modelComponent->ModelFile); + } + + if (modelAsset) { Components::Transform absoluteTransform = m_TransformSystem->AbsoluteTransform(entity); diff --git a/src/GameWorld.cpp b/src/GameWorld.cpp index 0b17e0c..893039d 100755 --- a/src/GameWorld.cpp +++ b/src/GameWorld.cpp @@ -8,6 +8,13 @@ void GameWorld::Initialize() ResourceManager->Preload("Model", "Models/Placeholders/PhysicsTest/Plane.obj"); ResourceManager->Preload("Model", "Models/Placeholders/PhysicsTest/ArrowCube.obj"); + //Background Music + { + Events::PlayBGM e; + e.Resource = "Sounds/SFX/WUB.mp3"; + EventBroker->Publish(e); + } + // Interface BindKey(GLFW_KEY_A, "interface_horizontal", -1.f); BindKey(GLFW_KEY_D, "interface_horizontal", 1.f); @@ -296,8 +303,6 @@ void GameWorld::Initialize() - - //for (int i = 0; i < 500; i++) //{ // auto Light = CreateEntity(); @@ -415,6 +420,7 @@ void GameWorld::RegisterSystems() m_SystemFactory.Register([this]() { return new Systems::GarageSystem(this, EventBroker, ResourceManager); }); m_SystemFactory.Register([this]() { return new Systems::WallSystem(this, EventBroker, ResourceManager); }); m_SystemFactory.Register([this]() { return new Systems::FlagSystem(this, EventBroker, ResourceManager); }); + m_SystemFactory.Register([this]() { return new Systems::TowerSystem(this, EventBroker, ResourceManager); }); m_SystemFactory.Register([this]() { return new Systems::GameStateSystem(this, EventBroker, ResourceManager); }); m_SystemFactory.Register([this]() { return new Systems::RenderSystem(this, EventBroker, ResourceManager); }); } @@ -441,6 +447,7 @@ void GameWorld::AddSystems() AddSystem(); AddSystem(); AddSystem(); + AddSystem(); AddSystem(); AddSystem(); } @@ -607,6 +614,120 @@ void GameWorld::CreateGate(EntityID parent, glm::vec3 position, glm::quat orient } } +EntityID GameWorld::CreateTower(EntityID parent, glm::vec3 pos, int teamID) +{ + auto towerBase = CreateEntity(parent); + auto transform = AddComponent(towerBase); + transform->Position = pos; + + auto towerComponent = AddComponent(towerBase); + + auto physics = AddComponent(towerBase); + physics->Mass = 100.f; + physics->MotionType = Components::Physics::MotionTypeEnum::Fixed; + + auto model = AddComponent(towerBase); + model->ModelFile = "Models/Turret/Base/Base.obj"; + + auto health = AddComponent(towerBase); + health->Amount = 50.f; + + auto shape = CreateEntity(towerBase); + auto shapetransform = AddComponent(shape); + auto shapemesh = AddComponent(shape); + shapemesh->ResourceName = "Models/Turret/Base/Base.obj"; + + CommitEntity(shape); + { + auto towerGunRotation = CreateEntity(towerBase); + auto transform = AddComponent(towerGunRotation); + transform->Position = glm::vec3(0.f, 5.889f-0.92791f, 0.f); + + + auto towerGunBaseModel = CreateEntity(towerGunRotation); + { + auto transform = AddComponent(towerGunBaseModel); + transform->Orientation = glm::quat(glm::vec3(0, -glm::pi() / 2.f, 0)); + auto model = AddComponent(towerGunBaseModel); + model->ModelFile = "Models/Turret/GunRotation/GunRotation.obj"; + } + CommitEntity(towerGunBaseModel); + + auto health = AddComponent(towerGunRotation); + health->Amount = 50.f; + + { + auto towerGun = CreateEntity(towerGunRotation); + auto transform = AddComponent(towerGun); + transform->Position = glm::vec3(0.f, 4.12801f, 1.18125f); + //transform->Orientation = glm::quat(glm::vec3(0, -glm::pi() / 2.f, 0)); + +#pragma region Turret_Shot_Template + + { + auto shot = CreateEntity(towerGun); + auto transform = AddComponent(shot); + transform->Position = glm::vec3(0.f, 0.f, -4.37612f); + transform->Orientation = glm::angleAxis(-glm::pi() / 2.f, glm::vec3(1, 0, 0)); + transform->Scale = glm::vec3(2.f); + AddComponent(shot); + auto physics = AddComponent(shot); + physics->Mass = 25.f; + physics->MotionType = Components::Physics::MotionTypeEnum::Dynamic; + physics->CollisionEvent = true; + auto modelComponent = AddComponent(shot); + modelComponent->ModelFile = "Models/Placeholders/rocket/Rocket.obj"; + auto TurretShotComponent = AddComponent(shot); + TurretShotComponent->Damage = 20.f; + TurretShotComponent->ExplosionRadius = 30.f; + TurretShotComponent->ExplosionStrength = 300000.f; + { + auto shape = CreateEntity(shot); + auto transform = AddComponent(shape); + auto boxShape = AddComponent(shape); + boxShape->Width = 0.5f; + boxShape->Height = 0.5f; + boxShape->Depth = 0.5f; + CommitEntity(shape); + } + CommitEntity(shot); + m_ShotTemplate = shot; + } + +#pragma endregion + + auto towerGunModel = CreateEntity(towerGun); + { + auto transform = AddComponent(towerGunModel); + transform->Orientation = glm::quat(glm::vec3(0, -glm::pi() / 2.f, 0)); + auto model = AddComponent(towerGunModel); + model->ModelFile = "Models/Turret/Gun/Gun.obj"; + } + CommitEntity(towerGunModel); + + auto health = AddComponent(towerGun); + health->Amount = 50.f; + + CommitEntity(towerGun); + towerComponent->Gun = towerGun; + } + + CommitEntity(towerGunRotation); + towerComponent->GunBase = towerGunRotation; + } + + towerComponent->ID = teamID; + + auto turretComponent = AddComponent(towerBase); + turretComponent->ShotTemplate = m_ShotTemplate; + turretComponent->ShotSpeed = 40.f; + + CommitEntity(towerBase); + + return towerBase; + +} + EntityID GameWorld::CreateWall(EntityID parent, glm::vec3 pos, glm::quat orientation) { auto wall = CreateEntity(parent); @@ -696,6 +817,21 @@ void GameWorld::CreateTerrain() CommitEntity(groundshape); } CommitEntity(water);*/ + + { + auto water = CreateEntity(); + auto transform = AddComponent(water); + + { + auto waves = CreateEntity(water); + auto transform = AddComponent(water); + auto model = AddComponent(water); + model->ModelFile = "Models/Water/Waves.obj"; + CommitEntity(waves); + } + + CommitEntity(water); + } } { @@ -703,6 +839,7 @@ void GameWorld::CreateTerrain() auto transform = AddComponent(ground_middle); auto model = AddComponent(ground_middle); model->ModelFile = "Models/TerrainFiveIstles/Middle.obj"; + model->AverageNormals = true; auto blendmap = AddComponent(ground_middle); blendmap->TextureRed = "Textures/Ground/SoilBeach0087_11_S.jpg"; blendmap->TextureRedNormal = "Textures/Ground/SoilBeach0087_11_SNM.png"; @@ -727,6 +864,14 @@ void GameWorld::CreateTerrain() CommitEntity(ground_middle); } + { + auto decoration_middle = CreateEntity(); + auto transform = AddComponent(decoration_middle); + auto model = AddComponent(decoration_middle); + model->ModelFile = "Models/TerrainFiveIstles/Decoration/Middle.obj"; + CommitEntity(decoration_middle); + } + CreateBase(glm::quat(), 1); CreateBase(glm::quat(glm::vec3(0, glm::pi(), 0)), 2); @@ -803,11 +948,13 @@ void GameWorld::CreateBase(glm::quat orientation, int teamID) auto transform = AddComponent(base); transform->Orientation = orientation; #pragma region Terrain + { auto ground_small = CreateEntity(base); auto transform = AddComponent(ground_small); auto model = AddComponent(ground_small); model->ModelFile = "Models/TerrainFiveIstles/Small.obj"; + model->AverageNormals = true; auto blendmap = AddComponent(ground_small); blendmap->TextureRed = "Textures/Ground/SoilBeach0087_11_S.jpg"; blendmap->TextureRedNormal = "Textures/Ground/SoilBeach0087_11_SNM.png"; @@ -831,6 +978,14 @@ void GameWorld::CreateBase(glm::quat orientation, int teamID) CommitEntity(ground_small); } + { + auto decoration_small = CreateEntity(base); + auto transform = AddComponent(decoration_small); + auto model = AddComponent(decoration_small); + model->ModelFile = "Models/TerrainFiveIstles/Decoration/Small.obj"; + CommitEntity(decoration_small); + } + { auto road_small = CreateEntity(base); auto transform = AddComponent(road_small); @@ -856,6 +1011,7 @@ void GameWorld::CreateBase(glm::quat orientation, int teamID) auto transform = AddComponent(bridge_middle); auto model = AddComponent(bridge_middle); model->ModelFile = "Models/TerrainFiveIstles/Bridges/MiddleBridge.obj"; + model->AverageNormals = false; auto physics = AddComponent(bridge_middle); physics->Mass = 10; physics->MotionType = Components::Physics::MotionTypeEnum::Fixed; @@ -925,12 +1081,61 @@ void GameWorld::CreateBase(glm::quat orientation, int teamID) CommitEntity(bridge_middle); } + // Banners + std::string bannerModel = "Models/Banner/Blue/Blue.obj"; + if (teamID == 2) + { + bannerModel = "Models/Banner/Red/Red.obj"; + } + + { + auto banner = CreateEntity(base); + auto transform = AddComponent(banner); + transform->Position = glm::vec3(70.2f, 50.36f, -8.68f); + transform->Orientation = glm::quat(glm::vec3(0, glm::pi(), 0)); + auto model = AddComponent(banner); + model->ModelFile = bannerModel; + model->Transparent = true; + CommitEntity(banner); + } + { + auto banner = CreateEntity(base); + auto transform = AddComponent(banner); + transform->Position = glm::vec3(70.2f, 50.36f, 9.86f); + transform->Orientation = glm::quat(glm::vec3(0, glm::pi(), 0)); + auto model = AddComponent(banner); + model->ModelFile = bannerModel; + model->Transparent = true; + CommitEntity(banner); + } + { + auto banner = CreateEntity(base); + auto transform = AddComponent(banner); + transform->Position = glm::vec3(166.17f, 49.711f, -8.68f); + transform->Orientation = glm::quat(glm::vec3(0, glm::pi(), 0)); + auto model = AddComponent(banner); + model->ModelFile = bannerModel; + model->Transparent = true; + CommitEntity(banner); + } + { + auto banner = CreateEntity(base); + auto transform = AddComponent(banner); + auto model = AddComponent(banner); + transform->Position = glm::vec3(166.17f, 49.711f, 9.86f); + transform->Orientation = glm::quat(glm::vec3(0, glm::pi(), 0)); + model->ModelFile = bannerModel; + model->Transparent = true; + CommitEntity(banner); + } + { auto terrain_base = CreateEntity(base); auto transform = AddComponent(terrain_base); auto model = AddComponent(terrain_base); model->ModelFile = "Models/TerrainFiveIstles/Base.obj"; + model->AverageNormals = true; auto blendmap = AddComponent(terrain_base); blendmap->TextureRed = "Textures/Ground/SoilBeach0087_11_S.jpg"; blendmap->TextureRedNormal = "Textures/Ground/SoilBeach0087_11_SNM.png"; @@ -974,6 +1179,14 @@ void GameWorld::CreateBase(glm::quat orientation, int teamID) CommitEntity(ground_base); } + { + auto decoration_base = CreateEntity(base); + auto transform = AddComponent(decoration_base); + auto model = AddComponent(decoration_base); + model->ModelFile = "Models/TerrainFiveIstles/Decoration/Base.obj"; + CommitEntity(decoration_base); + } + { auto road_base = CreateEntity(base); auto transform = AddComponent(road_base); @@ -999,6 +1212,7 @@ void GameWorld::CreateBase(glm::quat orientation, int teamID) auto transform = AddComponent(bridge_base); auto model = AddComponent(bridge_base); model->ModelFile = "Models/TerrainFiveIstles/Bridges/BaseBridge.obj"; + model->AverageNormals = false; auto physics = AddComponent(bridge_base); physics->Mass = 10; physics->MotionType = Components::Physics::MotionTypeEnum::Fixed; @@ -1059,7 +1273,22 @@ void GameWorld::CreateBase(glm::quat orientation, int teamID) } #pragma endregion Terrain - CreateGate(base, glm::vec3(273.f, 40.185f, 0.06f), glm::quat(glm::vec3(0, glm::pi() / 2.f, 0)), teamID); + // Small island + CreateGate(base, glm::vec3(113.59f, 29.02f, 0.32f), glm::quat(glm::vec3(0, glm::pi() / 2.f, 0)), teamID); + // Z + glm::quat yawRot = glm::angleAxis(glm::pi() / 2.f, glm::vec3(0, 1, 0)); + CreateWall(base, glm::vec3(113.59f, 28.79635f, 15.26201f), yawRot); // glm::quat(glm::vec3(glm::radians(-9.21f), 0, 0))); + CreateWall(base, glm::vec3(113.60f, 28.05425f, 24.41458f), glm::angleAxis(glm::radians(9.21f), glm::vec3(1, 0, 0)) * yawRot); + CreateWall(base, glm::vec3(113.61f, 25.42271f, 32.34383f), glm::angleAxis(glm::radians(27.f), glm::vec3(1, 0, 0)) * yawRot); + CreateWall(base, glm::vec3(113.62f, 20.54767f, 38.68277f), glm::angleAxis(glm::radians(47.9f), glm::vec3(1, 0, 0)) * yawRot); + // -Z + CreateWall(base, glm::vec3(113.59f, 28.734f, -13.85581f), glm::angleAxis(glm::radians(-3.634f), glm::vec3(1, 0, 0)) * yawRot); + CreateWall(base, glm::vec3(113.60f, 27.166f, -22.438f), glm::angleAxis(glm::radians(-17.202f), glm::vec3(1, 0, 0)) * yawRot); + CreateWall(base, glm::vec3(113.61f, 23.5952f, -30.50557f), glm::angleAxis(glm::radians(-30.638f), glm::vec3(1, 0, 0)) * yawRot); + CreateWall(base, glm::vec3(113.62f, 18.30851f, -36.56623f), glm::angleAxis(glm::radians(-51.542f), glm::vec3(1, 0, 0)) * yawRot); + + // -X + CreateGate(base, glm::vec3(273.f, 40.185f, 0.f), glm::quat(glm::vec3(0, glm::pi() / 2.f, 0)), teamID); CreateWall(base, glm::vec3(273.f, 40.3f, -55.f), glm::quat(glm::vec3(0, glm::pi() / 2.f, 0))); CreateWall(base, glm::vec3(273.f, 40.3f, -45.f), glm::quat(glm::vec3(0, glm::pi() / 2.f, 0))); CreateWall(base, glm::vec3(273.f, 40.3f, -35.f), glm::quat(glm::vec3(0, glm::pi() / 2.f, 0))); @@ -1067,6 +1296,38 @@ void GameWorld::CreateBase(glm::quat orientation, int teamID) CreateWall(base, glm::vec3(273.f, 40.3f, -15.f), glm::quat(glm::vec3(0, glm::pi() / 2.f, 0))); CreateWall(base, glm::vec3(273.f, 40.3f, 15.f), glm::quat(glm::vec3(0, glm::pi() / 2.f, 0))); CreateWall(base, glm::vec3(273.f, 40.3f, 25.f), glm::quat(glm::vec3(0, glm::pi() / 2.f, 0))); + CreateTower(base, glm::vec3(290.f, 40.3f, 15.f), teamID); + + // -Z + CreateWall(base, glm::vec3(280.f, 40.3f, -62.f), glm::quat(glm::vec3(0, 0, 0))); + CreateWall(base, glm::vec3(290.f, 40.3f, -62.f), glm::quat(glm::vec3(0, 0, 0))); + CreateWall(base, glm::vec3(300.f, 40.3f, -62.f), glm::quat(glm::vec3(0, 0, 0))); + CreateWall(base, glm::vec3(310.f, 40.3f, -62.f), glm::quat(glm::vec3(0, 0, 0))); + CreateWall(base, glm::vec3(320.f, 40.3f, -62.f), glm::quat(glm::vec3(0, 0, 0))); + CreateWall(base, glm::vec3(330.f, 40.3f, -62.f), glm::quat(glm::vec3(0, 0, 0))); + CreateWall(base, glm::vec3(340.f, 40.3f, -62.f), glm::quat(glm::vec3(0, 0, 0))); + CreateWall(base, glm::vec3(350.f, 40.3f, -62.f), glm::quat(glm::vec3(0, 0, 0))); + + // X + CreateWall(base, glm::vec3(357.f, 40.3f, -55.f), glm::quat(glm::vec3(0, glm::pi() / 2.f, 0))); + CreateWall(base, glm::vec3(357.f, 40.3f, -45.f), glm::quat(glm::vec3(0, glm::pi() / 2.f, 0))); + CreateWall(base, glm::vec3(357.f, 40.3f, -35.f), glm::quat(glm::vec3(0, glm::pi() / 2.f, 0))); + CreateWall(base, glm::vec3(357.f, 40.3f, -25.f), glm::quat(glm::vec3(0, glm::pi() / 2.f, 0))); + CreateWall(base, glm::vec3(357.f, 40.3f, -15.f), glm::quat(glm::vec3(0, glm::pi() / 2.f, 0))); + CreateWall(base, glm::vec3(357.f, 40.3f, -5.f), glm::quat(glm::vec3(0, glm::pi() / 2.f, 0))); + CreateWall(base, glm::vec3(357.f, 40.3f, 5.f), glm::quat(glm::vec3(0, glm::pi() / 2.f, 0))); + CreateWall(base, glm::vec3(357.f, 40.3f, 15.f), glm::quat(glm::vec3(0, glm::pi() / 2.f, 0))); + CreateWall(base, glm::vec3(357.f, 40.3f, 25.f), glm::quat(glm::vec3(0, glm::pi() / 2.f, 0))); + + // Z + CreateWall(base, glm::vec3(280.f, 40.3f, 32.f), glm::quat(glm::vec3(0, 0, 0))); + CreateWall(base, glm::vec3(290.f, 40.3f, 32.f), glm::quat(glm::vec3(0, 0, 0))); + CreateWall(base, glm::vec3(300.f, 40.3f, 32.f), glm::quat(glm::vec3(0, 0, 0))); + CreateWall(base, glm::vec3(310.f, 40.3f, 32.f), glm::quat(glm::vec3(0, 0, 0))); + CreateWall(base, glm::vec3(320.f, 40.3f, 32.f), glm::quat(glm::vec3(0, 0, 0))); + CreateWall(base, glm::vec3(330.f, 40.3f, 32.f), glm::quat(glm::vec3(0, 0, 0))); + CreateWall(base, glm::vec3(340.f, 40.3f, 32.f), glm::quat(glm::vec3(0, 0, 0))); + CreateWall(base, glm::vec3(350.f, 40.3f, 32.f), glm::quat(glm::vec3(0, 0, 0))); CreateGarage(base, glm::vec3(323.2f, 41.4f, -10.2f), glm::quat(glm::vec3(0, glm::pi() / 2.f, 0)), teamID); diff --git a/src/GameWorld.h b/src/GameWorld.h index fc1d2bf..9a2ff76 100755 --- a/src/GameWorld.h +++ b/src/GameWorld.h @@ -23,6 +23,7 @@ #include "Systems/WheelPairSystem.h" #include "Systems/FollowSystem.h" #include "Systems/WallSystem.h" +#include "Systems/TowerSystem.h" #include "Systems/GarageSystem.h" #include "Systems/JeepSteeringSystem.h" #include "Systems/FlagSystem.h" @@ -87,11 +88,13 @@ private: void AddTankWheelPair(EntityID tankEntity, glm::vec3 position, int axleID, bool steering); EntityID CreateJeep(int playerID); EntityID CreateWall(EntityID parent, glm::vec3 pos, glm::quat orientation); + EntityID CreateTower(EntityID parent, glm::vec3 pos, int teamID); EntityID CreateGarage(EntityID parent, glm::vec3 Position, glm::quat orientation, int teamID); void CreateTerrain(); void CreateBase(glm::quat orientation, int playerID); void CreateFlag(EntityID parent, glm::vec3 position, glm::quat orientation, int TeamID); std::vector m_WallDebrisTemplates; + EntityID m_ShotTemplate; }; #endif // GameWorld_h__ diff --git a/src/InputManager.cpp b/src/InputManager.cpp index 01d61ba..97494c8 100644 --- a/src/InputManager.cpp +++ b/src/InputManager.cpp @@ -85,6 +85,28 @@ void InputManager::Update(double dt) EventBroker->Publish(e); } + + if(m_CurrentKeyState[GLFW_KEY_P]) + { + Events::StopSound e; + e.Emitter = 1; + EventBroker->Publish(e); + } + if(m_CurrentKeyState[GLFW_KEY_L]) + { + Events::PlayBGM e; + e.Resource = "Sounds/BGM/WilliamTellOverture.mp3"; + e.Loop = true; + EventBroker->Publish(e); + } + if(m_CurrentKeyState[GLFW_KEY_O]) + { + Events::PlayBGM e; + e.Resource = "Sounds/BGM/DiesIrae.mp3"; + e.Loop = true; + EventBroker->Publish(e); + } + // // Lock mouse while holding LMB // if (m_CurrentMouseState[GLFW_MOUSE_BUTTON_LEFT]) diff --git a/src/InputManager.h b/src/InputManager.h index 69827ba..bb30918 100644 --- a/src/InputManager.h +++ b/src/InputManager.h @@ -13,6 +13,9 @@ #include "Events/GamepadAxis.h" #include "Events/GamepadButton.h" +#include "Events/StopSound.h" +#include "Events/PlayBGM.h" + class InputManager { public: diff --git a/src/Model.cpp b/src/Model.cpp index eb689c0..c9d5790 100755 --- a/src/Model.cpp +++ b/src/Model.cpp @@ -1,7 +1,7 @@ #include "PrecompiledHeader.h" #include "Model.h" -Model::Model(std::shared_ptr rm, OBJ &obj) +Model::Model(std::shared_ptr rm, OBJ &obj, bool average) { OBJ::MaterialInfo* currentMaterial = nullptr; TextureGroup* currentTexGroup = nullptr; @@ -93,7 +93,10 @@ Model::Model(std::shared_ptr rm, OBJ &obj) if (Vertices.size() > 0) { CreateTangents(); - //getSimilarVertexIndex(); + if (average) + { + getSimilarVertexIndex(); + } CreateBuffers(Vertices, Normals, TangentNormals, BiTangentNormals, TextureCoords); } else diff --git a/src/Model.h b/src/Model.h index fc3e071..d7a8c8c 100755 --- a/src/Model.h +++ b/src/Model.h @@ -17,7 +17,7 @@ class Model : public Resource { public: - Model(std::shared_ptr resourceManager, OBJ &obj); + Model(std::shared_ptr resourceManager, OBJ &obj, bool average); struct TextureGroup { diff --git a/src/Renderer.cpp b/src/Renderer.cpp index ef8e67b..ed30987 100755 --- a/src/Renderer.cpp +++ b/src/Renderer.cpp @@ -169,7 +169,7 @@ void Renderer::LoadContent() FrameBufferTextures(); m_sphereModel = ResourceManager->Load("Model", "Models/Placeholders/PhysicsTest/Sphere.obj"); - m_Skybox = std::make_shared("Textures/Skybox/sunset", "jpg"); + m_Skybox = std::make_shared("Textures/Skybox/sky36", "jpg"); } void Renderer::Draw(double dt) @@ -271,7 +271,6 @@ void Renderer::Draw(double dt) void Renderer::DrawFrame(RenderQueuePair &rq) { - glBindFramebuffer(GL_FRAMEBUFFER, 0); glViewport(m_Viewport.X, m_Height - m_Viewport.Y - m_Viewport.Height, m_Viewport.Width, m_Viewport.Height); glScissor(m_Scissor.X, m_Height - m_Scissor.Y - m_Scissor.Height, m_Scissor.Width, m_Scissor.Height); @@ -376,6 +375,7 @@ void Renderer::DrawWorld(RenderQueuePair &rq) glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); glEnable(GL_SCISSOR_TEST); + glDepthRange(0.0, 0.999); //Sort forward rendering items by z value. for(auto job : rq.Forward) @@ -406,8 +406,7 @@ void Renderer::DrawWorld(RenderQueuePair &rq) glCullFace(GL_BACK); glEnable(GL_DEPTH_TEST); - //DrawSkybox(); - + DrawFBOScene(rq.Deferred); /* @@ -470,6 +469,16 @@ void Renderer::DrawWorld(RenderQueuePair &rq) void Renderer::ForwardRendering(RenderQueue &rq) { + /* + Skybochs + */ + glDisable(GL_BLEND); + glEnable(GL_DEPTH_TEST); + glDepthMask(GL_TRUE); + glDepthRange(0.999, 1.0); + DrawSkybox(); + glDepthRange(0.0, 0.999); + glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_DEPTH_TEST); @@ -479,7 +488,7 @@ void Renderer::ForwardRendering(RenderQueue &rq) //glBindFramebuffer(GL_FRAMEBUFFER, m_fbBasePass); glViewport(m_Viewport.X, m_Height - m_Viewport.Y - m_Viewport.Height, m_Viewport.Width, m_Viewport.Height); - glScissor(m_Viewport.X, m_Height - m_Viewport.Y - m_Viewport.Height, m_Viewport.Width, m_Viewport.Height); + glScissor(m_Scissor.X, m_Height - m_Scissor.Y - m_Scissor.Height, m_Scissor.Width, m_Scissor.Height); // Clear G-buffer //GLenum attachments[] = { GL_COLOR_ATTACHMENT0, GL_NONE , GL_NONE, GL_NONE }; @@ -550,7 +559,6 @@ void Renderer::ForwardRendering(RenderQueue &rq) } } //glDepthMask (GL_TRUE); - //glDisable (GL_BLEND); /* Final pass @@ -558,7 +566,7 @@ void Renderer::ForwardRendering(RenderQueue &rq) glBindFramebuffer(GL_FRAMEBUFFER, 0); glViewport(0, 0, m_Width, m_Height); - glScissor(0, 0, m_Width, m_Height); + glScissor(m_Scissor.X, m_Height - m_Scissor.Y - m_Scissor.Height, m_Scissor.Width, m_Scissor.Height); glDepthMask(GL_FALSE); glDisable(GL_DEPTH_TEST); @@ -613,6 +621,8 @@ void Renderer::Swap() void Renderer::DrawSkybox() { +// glEnable(GL_CULL_FACE); +// glCullFace(GL_BACK); //glBindFramebuffer(GL_FRAMEBUFFER, 0); glViewport(m_Viewport.X, m_Height - m_Viewport.Y - m_Viewport.Height, m_Viewport.Width, m_Viewport.Height); glScissor(m_Viewport.X, m_Height - m_Viewport.Y - m_Viewport.Height, m_Viewport.Width, m_Viewport.Height); @@ -623,8 +633,10 @@ void Renderer::DrawSkybox() //glm::mat4 cameraProjection = m_Camera->ProjectionMatrix((float)m_Viewport.Width / m_Viewport.Height); //glm::mat4 cameraMatrix = cameraProjection * m_Camera->ViewMatrix(); - glm::mat4 cameraMatrix = m_Camera->ProjectionMatrix((float)m_Viewport.Width / m_Viewport.Height) * glm::inverse(glm::toMat4(m_Camera->Orientation())); - glUniformMatrix4fv(glGetUniformLocation(m_ShaderProgramSkybox.GetHandle(), "MVP"), 1, GL_FALSE, glm::value_ptr(cameraMatrix)); + glm::mat4 cameraMatrix = m_Camera->ProjectionMatrix((float)m_Viewport.Width / m_Viewport.Height); + glm::mat4 cameraView = glm::inverse(glm::toMat4(m_Camera->Orientation())); + glUniformMatrix4fv(glGetUniformLocation(m_ShaderProgramSkybox.GetHandle(), "V"), 1, GL_FALSE, glm::value_ptr(cameraView)); + glUniformMatrix4fv(glGetUniformLocation(m_ShaderProgramSkybox.GetHandle(), "P"), 1, GL_FALSE, glm::value_ptr(cameraMatrix)); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); m_Skybox->Draw(); } diff --git a/src/Shaders/Skybox.vert.glsl b/src/Shaders/Skybox.vert.glsl index 548d93c..7d7d429 100755 --- a/src/Shaders/Skybox.vert.glsl +++ b/src/Shaders/Skybox.vert.glsl @@ -1,6 +1,7 @@ #version 430 -uniform mat4 MVP; +uniform mat4 V; +uniform mat4 P; layout(location = 0) in vec3 Position; @@ -11,6 +12,7 @@ out VertexData void main() { - gl_Position = MVP * vec4(Position, 1.0); + vec4 pos = V * vec4(Position, 1.0); + gl_Position = P * pos; Output.TextureCoord = Position; } \ No newline at end of file diff --git a/src/Systems/GameStateSystem.cpp b/src/Systems/GameStateSystem.cpp index d0ed866..8812bd1 100644 --- a/src/Systems/GameStateSystem.cpp +++ b/src/Systems/GameStateSystem.cpp @@ -11,9 +11,12 @@ bool Systems::GameStateSystem::OnFlagCaptured(const Events::FlagCaptured &event) { m_InGame = false; - Events::GameOver e; + Events::GameOver e1; e.Player = event.Player; - EventBroker->Publish(e); + EventBroker->Publish(e1); + Events::PlayBGM e2; + e2.Resource = "Sounds/BGM/WilliamTellOverture.mp3"; + EventBroker->Publish(e2); return true; } \ No newline at end of file diff --git a/src/Systems/GameStateSystem.h b/src/Systems/GameStateSystem.h index ac9d46e..d24f0a6 100644 --- a/src/Systems/GameStateSystem.h +++ b/src/Systems/GameStateSystem.h @@ -8,6 +8,7 @@ #include "Components/Player.h" #include "Events/FlagCaptured.h" #include "Events/GameOver.h" +#include "Events/PlayBGM.h" namespace Systems { diff --git a/src/Systems/PhysicsSystem.cpp b/src/Systems/PhysicsSystem.cpp index eb691a4..d87b1f6 100644 --- a/src/Systems/PhysicsSystem.cpp +++ b/src/Systems/PhysicsSystem.cpp @@ -255,7 +255,8 @@ void Systems::PhysicsSystem::UpdateEntity(double dt, EntityID entity, EntityID p } }*/ - + auto vehicleComponent = m_World->GetComponent(car); + vehicleComponent->currentRPM = m_Vehicles[car]->calcRPM(); m_Vehicles[car]->getChassis()->activate(); diff --git a/src/Systems/SoundSystem.cpp b/src/Systems/SoundSystem.cpp index 1617078..b0cb49e 100755 --- a/src/Systems/SoundSystem.cpp +++ b/src/Systems/SoundSystem.cpp @@ -2,13 +2,18 @@ #include "SoundSystem.h" #include "World.h" +Systems::SoundSystem::~SoundSystem() +{ + FMOD_System_Release(m_System); +} + void Systems::SoundSystem::Initialize() { EVENT_SUBSCRIBE_MEMBER(m_EComponentCreated, &SoundSystem::OnComponentCreated); EVENT_SUBSCRIBE_MEMBER(m_EPlaySFX, &SoundSystem::PlaySFX); EVENT_SUBSCRIBE_MEMBER(m_EPlayBGM, &SoundSystem::PlayBGM); EVENT_SUBSCRIBE_MEMBER(m_EStopSound, &SoundSystem::StopSound); - + m_isPlaying = false; m_TransformSystem = m_World->GetSystem(); FMOD_System_Create(&m_System); FMOD_RESULT result = FMOD_System_Init(m_System, 32, FMOD_INIT_3D_RIGHTHANDED | FMOD_INIT_ENABLE_PROFILE, 0); @@ -44,16 +49,15 @@ void Systems::SoundSystem::Update(double dt) std::map::iterator it; for(it = m_DeleteChannels.begin(); it != m_DeleteChannels.end();) { - FMOD_BOOL isPlaying = false; - FMOD_Channel_IsPlaying(it->second, &isPlaying); - if(isPlaying) + FMOD_Channel_IsPlaying(it->second, &m_isPlaying); + if(m_isPlaying) { it++; } else { // FMOD_Sound_Release(m_DeleteSounds[it->first]); -// m_DeleteSounds.erase(it->first); + m_DeleteSounds.erase(it->first); it = m_DeleteChannels.erase(it); } @@ -62,9 +66,8 @@ void Systems::SoundSystem::Update(double dt) for(it = m_Channels.begin(); it != m_Channels.end();) { - FMOD_BOOL isPlaying = false; - FMOD_Channel_IsPlaying(it->second, &isPlaying); - if(!isPlaying) + FMOD_Channel_IsPlaying(it->second, &m_isPlaying); + if(!m_isPlaying) { it = m_Channels.erase(it); } @@ -101,7 +104,7 @@ void Systems::SoundSystem::UpdateEntity(double dt, EntityID entity, EntityID par if(emitter) { FMOD_CHANNEL* channel = m_Channels[entity]; - //FMOD_SOUND* sound = m_Sounds[entity]; + FMOD_SOUND* sound = m_Sounds[entity]; auto eTransform = m_World->GetComponent(entity); glm::vec3 tPos = m_TransformSystem->AbsolutePosition(entity); @@ -134,9 +137,9 @@ bool Systems::SoundSystem::OnComponentCreated(const Events::ComponentCreated &ev float maxDist = emitter->MaxDistance; float minDist = emitter->MinDistance; float pitch = emitter->Pitch; - //LoadSound(sound, path, maxDist, minDist); + LoadSound(sound, path, maxDist, minDist); m_Channels.insert(std::make_pair(emitter->Entity, channel)); -// m_Sounds.insert(std::make_pair(emitter->Entity, sound)); + m_Sounds.insert(std::make_pair(emitter->Entity, sound)); } return true; } @@ -154,7 +157,7 @@ bool Systems::SoundSystem::PlaySFX(const Events::PlaySFX &event) eComponent->type = Components::SoundEmitter::SoundType::SOUND_3D; Sound* sound = ResourceManager->Load("Sound3D", event.Resource); - //m_Sounds[eEntity] = *sound; + m_Sounds[eEntity] = *sound; FMOD_Sound_Set3DMinMaxDistance(*sound, eComponent->MinDistance, eComponent->MaxDistance); PlaySound(&m_Channels[eEntity], *sound, 1.0, eComponent->Loop); @@ -163,21 +166,34 @@ bool Systems::SoundSystem::PlaySFX(const Events::PlaySFX &event) bool Systems::SoundSystem::PlayBGM(const Events::PlayBGM &event) { - auto emitter = m_World->CreateEntity(); - auto eTransform = m_World->AddComponent(emitter); - auto eComponent = m_World->AddComponent(emitter); - m_Channels[emitter] = m_BGMChannel; - eComponent->type = Components::SoundEmitter::SoundType::SOUND_3D; + FMOD_RESULT result; + result = FMOD_Channel_Stop(m_BGMChannel); + if(result != FMOD_OK) + LOG_INFO("FMOD error! (%d) %s\n", result, FMOD_ErrorString(result)); Sound* sound = ResourceManager->Load("Sound2D", event.Resource); - //m_Sounds[emitter] = *sound; - FMOD_System_PlaySound(m_System, FMOD_CHANNEL_FREE, *sound, false, &m_Channels[emitter]); + result = FMOD_System_PlaySound(m_System, FMOD_CHANNEL_FREE, *sound, false, &m_BGMChannel); + if(result != FMOD_OK) + LOG_INFO("FMOD error! (%d) %s\n", result, FMOD_ErrorString(result)); + FMOD_Channel_SetMode(m_BGMChannel, FMOD_LOOP_NORMAL); + FMOD_Sound_SetLoopCount(*sound, -1); + return true; } + + bool Systems::SoundSystem::StopSound(const Events::StopSound &event) { - FMOD_Channel_Stop(m_Channels[event.Emitter]); + auto eComp = m_World->GetComponent(event.Emitter); + if(eComp) + { + FMOD_Channel_Stop(m_Channels[event.Emitter]); + } + else + { + FMOD_Channel_Stop(m_BGMChannel); + } return true; } @@ -208,8 +224,8 @@ void Systems::SoundSystem::OnComponentRemoved(EntityID entity, std::string type, if(emitter) { m_DeleteChannels.insert(std::make_pair(entity, m_Channels[entity])); - //m_DeleteSounds.insert(std::make_pair(entity, m_Sounds[entity])); + m_DeleteSounds.insert(std::make_pair(entity, m_Sounds[entity])); m_Channels.erase(entity); - //m_Sounds.erase(entity); + m_Sounds.erase(entity); } } \ No newline at end of file diff --git a/src/Systems/SoundSystem.h b/src/Systems/SoundSystem.h index 66ef6bc..8803e0e 100755 --- a/src/Systems/SoundSystem.h +++ b/src/Systems/SoundSystem.h @@ -24,13 +24,12 @@ public: SoundSystem(World* world, std::shared_ptr<::EventBroker> eventBroker, std::shared_ptr<::ResourceManager> resourceManager) : System(world, eventBroker, resourceManager) { } - + ~SoundSystem(); void RegisterComponents(ComponentFactory* cf) override; void RegisterResourceTypes(std::shared_ptr<::ResourceManager> rm) override; void Initialize() override; void Update(double dt) override; void UpdateEntity(double dt, EntityID entity, EntityID parent) override; - //void OnComponentRemoved(std::string type, Component* component); void OnComponentRemoved(EntityID entity, std::string type, Component* component) override; FMOD_SYSTEM* GetFMODSystem() const { return m_System; } private: @@ -48,12 +47,13 @@ private: void PlaySound(FMOD_CHANNEL**, FMOD_SOUND*, float volume, bool loop); FMOD_SYSTEM* m_System; + FMOD_BOOL m_isPlaying; FMOD_CHANNEL* m_BGMChannel; std::vector m_Listeners; std::map m_Channels; std::map m_DeleteChannels; - //std::map m_Sounds; std::map m_DeleteSounds; + std::map m_Sounds; std::shared_ptr m_TransformSystem; }; diff --git a/src/Systems/TankSteeringSystem.cpp b/src/Systems/TankSteeringSystem.cpp index dbd7779..28a5a24 100644 --- a/src/Systems/TankSteeringSystem.cpp +++ b/src/Systems/TankSteeringSystem.cpp @@ -30,6 +30,32 @@ void Systems::TankSteeringSystem::Update(double dt) void Systems::TankSteeringSystem::UpdateEntity(double dt, EntityID entity, EntityID parent) { + auto pEmitter = m_World->GetComponent(entity); + if(pEmitter) + { + if(!m_World->GetComponent(parent)) + return; + auto tankTransform = m_World->GetComponent(parent); + glm::vec2 velXZ = glm::vec2(tankTransform->Velocity.x, tankTransform->Velocity.z); + float speedMPDT = glm::length(velXZ); + if(speedMPDT < 1) + { + pEmitter->Emitting = false; + return; + } + else + { + pEmitter->Emitting = true; + pEmitter->ScaleSpectrum.erase(pEmitter->ScaleSpectrum.begin()); + float scale = speedMPDT / 20; + scale = glm::clamp(scale, 0.3f, 20.f); + pEmitter->ScaleSpectrum.push_back(glm::vec3(speedMPDT / 20)); + float spawnFrequency = 1 / speedMPDT; + spawnFrequency = glm::clamp(spawnFrequency, 0.1f, 2.f); + pEmitter->SpawnFrequency = 1 / speedMPDT; + } + } + auto tankSteeringComponent = m_World->GetComponent(entity); if(!tankSteeringComponent) return; @@ -146,15 +172,6 @@ void Systems::TankSteeringSystem::UpdateEntity(double dt, EntityID entity, Entit m_TimeSinceLastShot[tankSteeringComponent->Barrel] += dt; } - -// auto shot = m_World->GetComponent(entity); -// if(shot) -// { -// if(inputController->Shoot && m_TimeSinceLastShot[tankSteeringComponent->Barrel] > 0.5) -// { -// -// } -// } } bool Systems::TankSteeringSystem::OnCollision(const Events::Collision &e) @@ -226,33 +243,63 @@ bool Systems::TankSteeringSystem::OnCollision(const Events::Collision &e) 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(180) / 4; - e.RelativeUpOrientation = glm::angleAxis(glm::radians(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); - + e.RelativeUpOrientation = glm::angleAxis(glm::pi() / 2, glm::vec3(1,0,0)); + e.Speed = 3; + e.SpreadAngle = glm::pi(); + e.spritePath = "Textures/Sprites/Smoke1.png"; + e.Color = glm::vec4(0.6,0.6,0.6,1); EventBroker->Publish(e); - e.LifeTime = 1.5; - e.ParticleScale.push_back(1); - e.ParticleScale.push_back(6); - e.ParticlesToSpawn = 20; + e.LifeTime = 0.7; + e.ParticleScale.push_back(12); + e.ParticlesToSpawn = 10; e.Position = shellTransform->Position; - e.SpreadAngle = glm::radians(180)/ 4; - e.RelativeUpOrientation = glm::angleAxis(glm::radians(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); + e.RelativeUpOrientation = glm::angleAxis(glm::pi() / 2, glm::vec3(1,0,0)); + e.Speed = 17; + e.SpreadAngle = glm::pi(); + e.spritePath = "Textures/Sprites/Fire.png"; + EventBroker->Publish(e); + e.LifeTime = 0.2; + e.ParticleScale.push_back(1); + e.ParticleScale.push_back(15); + e.ParticlesToSpawn = 5; + e.Position = shellTransform->Position; + e.RelativeUpOrientation = glm::angleAxis(glm::pi() / 2, glm::vec3(1,0,0)); + e.Speed = 6; + e.SpreadAngle = glm::pi(); + 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(180) / 4; +// e.RelativeUpOrientation = glm::angleAxis(glm::radians(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(180)/ 4; +// e.RelativeUpOrientation = glm::angleAxis(glm::radians(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; @@ -460,10 +507,14 @@ EntityID Systems::TankSteeringSystem::CreateTank(int playerID) player->ID = playerID; auto tankSteering = m_World->AddComponent(tank); m_World->AddComponent(tank); + m_World->AddComponent(tank); auto health = m_World->AddComponent(tank); health->Amount = 1.f; - m_World->AddComponent(tank); + + + + { auto shape = m_World->CreateEntity(tank); auto transform = m_World->AddComponent(shape); @@ -549,6 +600,8 @@ EntityID Systems::TankSteeringSystem::CreateTank(int playerID) transform->Orientation = glm::quat(glm::vec3(-glm::radians(5.f), 0.f, 0.f)); auto cameraComp = m_World->AddComponent(cameraTower); cameraComp->FarClip = 2000.f; + + /*auto follow = m_World->AddComponent(cameraTower); follow->Entity = barrel; follow->Distance = 15.f; @@ -597,31 +650,43 @@ EntityID Systems::TankSteeringSystem::CreateTank(int playerID) AddTankWheelPair(tank, glm::vec3(-1.68f, wheelOffset, 2.375), 1, false); #pragma endregion +#pragma region DustParticles + + std::vector ePos; + ePos.push_back(glm::vec3(-2, -1.7, 2.0)); + ePos.push_back(glm::vec3(2, -1.7, 2.0)); + ePos.push_back(glm::vec3(2, -1.7, -2.0)); + ePos.push_back(glm::vec3(-2, -1.7, -2.0)); + + for (int i = 0; i < 4; i++) { auto entity = m_World->CreateEntity(tank); auto transformComponent = m_World->AddComponent(entity); - transformComponent->Position = glm::vec3(-2, -1.7, 2.0); + transformComponent->Position = ePos[i]; transformComponent->Scale = glm::vec3(3, 3, 3); transformComponent->Orientation = glm::angleAxis(glm::pi() / 2, glm::vec3(1, 0, 0)); auto emitterComponent = m_World->AddComponent(entity); - emitterComponent->SpawnCount = 2; - emitterComponent->SpawnFrequency = 0.005; + emitterComponent->SpawnCount = 1; + emitterComponent->SpawnFrequency = 0.1; emitterComponent->SpreadAngle = glm::pi(); emitterComponent->UseGoalVelocity = false; - emitterComponent->LifeTime = 0.5; - //emitterComponent->AngularVelocitySpectrum.push_back(glm::pi() / 100); - emitterComponent->ScaleSpectrum.push_back(glm::vec3(0.05)); - m_World->CommitEntity(entity); - + emitterComponent->LifeTime = 0.3; + emitterComponent->Speed = 3; + emitterComponent->Emitting = true; + emitterComponent->Fade = true; + emitterComponent->ScaleSpectrum.push_back(glm::vec3(1)); + //emitterComponent->Color = glm::vec4(1); auto particleEntity = m_World->CreateEntity(entity); - auto TEMP = m_World->AddComponent(particleEntity); - TEMP->Scale = glm::vec3(0); + m_World->AddComponent(particleEntity); + m_World->AddComponent(particleEntity); auto spriteComponent = m_World->AddComponent(particleEntity); - spriteComponent->SpriteFile = "Models/Textures/Sprites/Dust.png"; - emitterComponent->ParticleTemplate = particleEntity; - + spriteComponent->SpriteFile = "Textures/Sprites/Dirt.png"; m_World->CommitEntity(particleEntity); + emitterComponent->ParticleTemplate = particleEntity; + m_World->CommitEntity(entity); } +#pragma endregion + m_World->CommitEntity(tank); diff --git a/src/Systems/TankSteeringSystem.h b/src/Systems/TankSteeringSystem.h index f83f3e7..61fb19a 100644 --- a/src/Systems/TankSteeringSystem.h +++ b/src/Systems/TankSteeringSystem.h @@ -1,5 +1,4 @@ #include - #include "System.h" #include "Events/TankSteer.h" #include "Events/SetVelocity.h" @@ -24,6 +23,7 @@ #include "Components/TankShell.h" #include "Components/SphereShape.h" #include "Components/Listener.h" +#include "Components/SoundEmitter.h" #include "Events/EnableCollisions.h" #include "Events/DisableCollisions.h" diff --git a/src/Systems/TowerSystem.cpp b/src/Systems/TowerSystem.cpp new file mode 100644 index 0000000..0c992e0 --- /dev/null +++ b/src/Systems/TowerSystem.cpp @@ -0,0 +1,328 @@ +#include "PrecompiledHeader.h" +#include "TowerSystem.h" +#include "World.h" + +void Systems::TowerSystem::RegisterComponents( ComponentFactory* cf ) +{ + cf->Register([]() { return new Components::Tower(); }); + cf->Register([]() { return new Components::Turret(); }); + cf->Register([]() {return new Components::TurretShot(); }); +} + +void Systems::TowerSystem::Initialize() +{ + //EVENT_SUBSCRIBE_MEMBER(m_eDamage, &Systems::TowerSystem::Damage); + EVENT_SUBSCRIBE_MEMBER(m_ECollision, &Systems::TowerSystem::OnCollision); + Temp_m_TimeSinceLastShot = 0; +} + +void Systems::TowerSystem::Update( double dt ) +{ + +} + +void Systems::TowerSystem::UpdateEntity( double dt, EntityID entity, EntityID parent ) +{ + auto towerComponent = m_World->GetComponent(entity); + if(!towerComponent) + return; + + Components::Transform absoluteTowerGunTransform = m_World->GetSystem()->AbsoluteTransform(towerComponent->Gun); + + auto towerGunTransformComponent = m_World->GetComponent(towerComponent->Gun); + if(!towerGunTransformComponent) + return; + + auto towerGunBaseTransformComponent = m_World->GetComponent(towerComponent->GunBase); + if(!towerGunBaseTransformComponent) + return; + + auto turretComponent = m_World->GetComponent(entity); + if(!turretComponent) + return; + + auto players = m_World->GetComponentsOfType(); + if (!players) + return; + + for(auto player : *players) + { + auto playerComponent = std::dynamic_pointer_cast(player); + if(towerComponent->ID != playerComponent->ID) //!= betyder att den bara targetar sitt eget lag, == fienden. + continue; + + auto playerTransform = m_World->GetComponent(player->Entity); + if(!playerTransform) + continue; + + Components::Transform absolutePlayerTransform = m_World->GetSystem()->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()->AbsoluteTransform(turretComponent->ShotTemplate); + auto cloneTransform = m_World->GetComponent(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() / 2, glm::vec3(1,0,0)); + e.Speed = 1.7; + e.SpreadAngle = glm::pi()/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(); + 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()->AbsoluteTransform(turretComponent->ShotTemplate); + auto cloneTransform = m_World->GetComponent(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() / 2, glm::vec3(1,0,0)); + e.Speed = 1.7; + e.SpreadAngle = glm::pi()/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(); + 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(e.Entity1); + auto tankShell2 = m_World->GetComponent(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(shellEntity)) + return false; + + //auto physicsComponents = m_World->GetComponentsOfType(); + auto shellTransform = m_World->GetComponent(shellEntity); + //auto otherTransform = m_World->GetComponent(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() / 2, glm::vec3(1, 0, 0)); + e.Speed = 3; + e.SpreadAngle = glm::pi(); + 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() / 2, glm::vec3(1, 0, 0)); + e.Speed = 17; + e.SpreadAngle = glm::pi(); + 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() / 2, glm::vec3(1, 0, 0)); + e.Speed = 6; + e.SpreadAngle = glm::pi(); + 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(180) / 4; + // e.RelativeUpOrientation = glm::angleAxis(glm::radians(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(180)/ 4; + // e.RelativeUpOrientation = glm::angleAxis(glm::radians(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(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()->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(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; +} + diff --git a/src/Systems/TowerSystem.h b/src/Systems/TowerSystem.h new file mode 100644 index 0000000..bf9b65d --- /dev/null +++ b/src/Systems/TowerSystem.h @@ -0,0 +1,49 @@ +#ifndef TowerSystem_h__ +#define TowerSystem_h__ + + +#include "System.h" +#include "Systems/TransformSystem.h" +#include "Components/Player.h" +#include "Components/Tower.h" +#include "Components/Turret.h" +#include "Components/TurretShot.h" +#include "Components/Health.h" +#include "Events/SetVelocity.h" +#include "Events/CreateExplosion.h" +#include "Events/Collision.h" +#include "Events/Damage.h" + + + + + +namespace Systems +{ + class TowerSystem : public System + { + public: + + TowerSystem(World* world, std::shared_ptr<::EventBroker> eventBroker, std::shared_ptr<::ResourceManager> resourceManager) + : System(world, eventBroker, resourceManager) { } + + + void Initialize() override; + void RegisterComponents(ComponentFactory* cf) override; + + virtual void Update(double dt); + virtual void UpdateEntity(double dt, EntityID entity, EntityID parent); + + + EventRelay m_ECollision; + bool OnCollision(const Events::Collision &e); + + + private: + std::map m_TimeSinceLastShot; + float Temp_m_TimeSinceLastShot; + + }; + +} +#endif // TowerSystem_h__ diff --git a/vs11/Returngeance/Returngeance.vcxproj b/vs11/Returngeance/Returngeance.vcxproj index f3f14ba..c4a2431 100755 --- a/vs11/Returngeance/Returngeance.vcxproj +++ b/vs11/Returngeance/Returngeance.vcxproj @@ -125,6 +125,7 @@ + @@ -149,6 +150,7 @@ + @@ -177,6 +179,8 @@ + + @@ -268,6 +272,7 @@ + diff --git a/vs11/Returngeance/Returngeance.vcxproj.filters b/vs11/Returngeance/Returngeance.vcxproj.filters index ba3e8ee..00ecabc 100755 --- a/vs11/Returngeance/Returngeance.vcxproj.filters +++ b/vs11/Returngeance/Returngeance.vcxproj.filters @@ -86,6 +86,12 @@ Physics\Systems + + Game\Systems + + + Game\Systems + Game\Systems @@ -582,6 +588,21 @@ Game\Components + + + Game\Systems + + + Game\Systems + + + Game\Components + + + Game\Components + + + Physics\Components Game\Components @@ -633,6 +654,8 @@ Game\Systems + +