From c37df5c178d601934f07e99ef4ddf1d5272d2fd4 Mon Sep 17 00:00:00 2001 From: ViktorLjung Date: Tue, 27 May 2014 07:04:29 +0200 Subject: [PATCH] Damage and Spashdamage working, phantomShapes not really working --- assets | 2 +- src/Components/FrameTimer.h | 17 ++ src/Components/TankShell.h | 2 + src/Components/Timer.h | 17 ++ src/Components/Trigger.h | 17 ++ src/Components/TriggerExplosion.h | 22 ++ src/Events/Damage.h | 17 ++ src/Events/EnterTrigger.h | 17 ++ src/GameWorld.cpp | 67 ++--- src/GameWorld.h | 4 + src/System.h | 2 +- src/Systems/DamageSystem.cpp | 22 ++ src/Systems/DamageSystem.h | 32 +++ src/Systems/PhysicsSystem.cpp | 246 ++++++++++++------ src/Systems/PhysicsSystem.h | 29 ++- src/Systems/SoundSystem.cpp | 2 +- src/Systems/SoundSystem.h | 2 +- src/Systems/TankSteeringSystem.cpp | 176 ++++++++----- src/Systems/TankSteeringSystem.h | 6 + src/Systems/TimerSystem.cpp | 38 +++ src/Systems/TimerSystem.h | 28 ++ src/Systems/TriggerSystem.cpp | 91 +++++++ src/Systems/TriggerSystem.h | 43 +++ src/World.cpp | 9 +- src/World.h | 40 ++- vs11/Returngeance/Returngeance.vcxproj | 13 +- .../Returngeance/Returngeance.vcxproj.filters | 45 +++- 27 files changed, 804 insertions(+), 202 deletions(-) create mode 100644 src/Components/FrameTimer.h create mode 100644 src/Components/Timer.h create mode 100644 src/Components/Trigger.h create mode 100644 src/Components/TriggerExplosion.h create mode 100644 src/Events/Damage.h create mode 100644 src/Events/EnterTrigger.h create mode 100644 src/Systems/DamageSystem.cpp create mode 100644 src/Systems/DamageSystem.h create mode 100644 src/Systems/TimerSystem.cpp create mode 100644 src/Systems/TimerSystem.h create mode 100644 src/Systems/TriggerSystem.cpp create mode 100644 src/Systems/TriggerSystem.h diff --git a/assets b/assets index c231d53..72b93d5 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit c231d531a7050fb5ff7b2df12b614ca5452d7254 +Subproject commit 72b93d5750283864f244241e65a38436d05c5f96 diff --git a/src/Components/FrameTimer.h b/src/Components/FrameTimer.h new file mode 100644 index 0000000..60f8dd4 --- /dev/null +++ b/src/Components/FrameTimer.h @@ -0,0 +1,17 @@ +#ifndef Components_FrameTimer_h__ +#define Components_FrameTimer_h__ + +#include "Component.h" + +namespace Components +{ + + struct FrameTimer : public Component + { + int Frames; + virtual FrameTimer* Clone() const override { return new FrameTimer(*this); } + }; + +} + +#endif // Components_FrameTimer_h__ diff --git a/src/Components/TankShell.h b/src/Components/TankShell.h index 6ac7630..b055c83 100644 --- a/src/Components/TankShell.h +++ b/src/Components/TankShell.h @@ -12,6 +12,8 @@ : Damage(1.0f){ } float Damage; + float ExplosionRadius; + float ExplosionStrength; virtual TankShell* Clone() const override { return new TankShell(*this); } }; diff --git a/src/Components/Timer.h b/src/Components/Timer.h new file mode 100644 index 0000000..ccac0aa --- /dev/null +++ b/src/Components/Timer.h @@ -0,0 +1,17 @@ +#ifndef Components_Timer_h__ +#define Components_Timer_h__ + +#include "Component.h" + +namespace Components +{ + + struct Timer : public Component + { + double Time; + virtual Timer* Clone() const override { return new Timer(*this); } + }; + +} + +#endif // Components_Timer_h__ diff --git a/src/Components/Trigger.h b/src/Components/Trigger.h new file mode 100644 index 0000000..ec7cfc4 --- /dev/null +++ b/src/Components/Trigger.h @@ -0,0 +1,17 @@ +#ifndef Trigger_h__ +#define Trigger_h__ + +#include "Component.h" + +namespace Components +{ + + struct Trigger : Component + { + bool TriggerOnce; + virtual Trigger* Clone() const override { return new Trigger(*this); } + }; + +} + +#endif // Trigger_h__ \ No newline at end of file diff --git a/src/Components/TriggerExplosion.h b/src/Components/TriggerExplosion.h new file mode 100644 index 0000000..b036d2e --- /dev/null +++ b/src/Components/TriggerExplosion.h @@ -0,0 +1,22 @@ +#ifndef TriggerExplosion_h__ +#define TriggerExplosion_h__ + +#include "Component.h" + +namespace Components +{ + + struct TriggerExplosion : Component + { + TriggerExplosion() + : MaxVelocity(1.f), Radius(1.f){ } + + // Velocity = (1 - (distance / radius)^2) * Strength; + float MaxVelocity; + float Radius; //HACK: Radius should only be in the SphereShapeComponent + virtual TriggerExplosion* Clone() const override { return new TriggerExplosion(*this); } + }; + +} + +#endif // TriggerExplosion_h__ \ No newline at end of file diff --git a/src/Events/Damage.h b/src/Events/Damage.h new file mode 100644 index 0000000..5f46f3e --- /dev/null +++ b/src/Events/Damage.h @@ -0,0 +1,17 @@ +#ifndef Events_Damage_h__ +#define Events_Damage_h__ +#include "Entity.h" +#include "EventBroker.h" + +namespace Events +{ + + struct Damage : Event + { + EntityID Entity; + float damage; + }; + +} + +#endif // Events_Damage_h__ \ No newline at end of file diff --git a/src/Events/EnterTrigger.h b/src/Events/EnterTrigger.h new file mode 100644 index 0000000..117b306 --- /dev/null +++ b/src/Events/EnterTrigger.h @@ -0,0 +1,17 @@ +#ifndef Events_EnterTrigger_h__ +#define Events_EnterTrigger_h__ +#include "Entity.h" +#include "EventBroker.h" + +namespace Events +{ + + struct EnterTrigger : Event + { + EntityID Entity1; + EntityID Entity2; + }; + +} + +#endif // Events_EnterTrigger_h__ \ No newline at end of file diff --git a/src/GameWorld.cpp b/src/GameWorld.cpp index 342e559..3984e9e 100755 --- a/src/GameWorld.cpp +++ b/src/GameWorld.cpp @@ -264,7 +264,7 @@ void GameWorld::Initialize() tankSteering->Player = player1; AddComponent(tank); auto health = AddComponent(tank); - health->health = 1; + health->health = 100; { auto shape = CreateEntity(tank); auto transform = AddComponent(shape); @@ -321,6 +321,8 @@ void GameWorld::Initialize() modelComponent->ModelFile = "Models/Placeholders/rocket/Rocket.obj"; auto tankShellComponent = AddComponent(shot); tankShellComponent->Damage = 20.f; + tankShellComponent->ExplosionRadius = 30.f; + tankShellComponent->ExplosionStrength = 300000.f; { auto shape = CreateEntity(shot); auto transform = AddComponent(shape); @@ -688,7 +690,7 @@ void GameWorld::Initialize() tankSteering->Player = player2; AddComponent(tank); auto health = AddComponent(tank); - health->health = 1; + health->health = 100; { auto shape = CreateEntity(tank); auto transform = AddComponent(shape); @@ -745,6 +747,8 @@ void GameWorld::Initialize() modelComponent->ModelFile = "Models/Placeholders/rocket/Rocket.obj"; auto tankShellComponent = AddComponent(shot); tankShellComponent->Damage = 20.f; + tankShellComponent->ExplosionRadius = 30.f; + tankShellComponent->ExplosionStrength = 300000.f; { auto shape = CreateEntity(shot); auto transform = AddComponent(shape); @@ -1118,44 +1122,12 @@ void GameWorld::Initialize() CommitEntity(entity); }*/ - for(int i = 0; i < 0; i++) - { - for (int y = 0; y < 15; y++) - { - for (int x = -5; x < 5; x++) - { - auto brick = CreateEntity(); - auto transform = AddComponent(brick); - transform->Position = glm::vec3(x + 0.01f, y * 0.3f + 0.01f, -20); - transform->Position.x += (y % 2)*0.5f; - transform->Scale = glm::vec3(1, 0.3f, 0.4f); - transform->Orientation = glm::quat(glm::vec3(0.0f, 0.0f, 0.0f)); - auto model = AddComponent(brick); - model->ModelFile = "Models/Placeholders/PhysicsTest/Cube2.obj"; - auto physics = AddComponent(brick); - physics->Mass = 3; - - - - auto shape = CreateEntity(brick); - auto transformshape = AddComponent(shape); - auto box = AddComponent(shape); - box->Width = 0.5f; - box->Height = 0.15f; - box->Depth = 0.3f; - CommitEntity(shape); - CommitEntity(brick); - } - } - } - - /*for (int x = 0; x < 5; x++) for (int y = 0; y < 5; y++) { auto cube = CreateEntity(); auto transform = AddComponent(cube); - transform->Position = glm::vec3(3 * x + 0.1f + -20.f, 3 * y + 0.1f + 1.f, 0); + transform->Position = glm::vec3(0, 10*y, 50); transform->Scale = glm::vec3(3); transform->Orientation = glm::quat(glm::vec3(0.0f, 0.0f, 0.0f)); auto model = AddComponent(cube); @@ -1163,13 +1135,19 @@ void GameWorld::Initialize() auto physics = AddComponent(cube); physics->Mass = 100; - auto box = AddComponent(cube); - box->Width = 1.5f; - box->Height = 1.5f; - box->Depth = 1.5f; + + { + auto shape = CreateEntity(cube); + auto transform = AddComponent(shape); + auto box = AddComponent(shape); + box->Width = 1.5f; + box->Height = 1.5f; + box->Depth = 1.5f; + CommitEntity(shape); + } CommitEntity(cube); } -*/ + /*{ @@ -1193,12 +1171,13 @@ void GameWorld::RegisterComponents() { m_ComponentFactory.Register([]() { return new Components::Transform(); }); m_ComponentFactory.Register([]() { return new Components::Template(); }); - m_ComponentFactory.Register([]() { return new Components::Player(); }); - m_ComponentFactory.Register([]() { return new Components::Health(); }); + m_ComponentFactory.Register([]() { return new Components::Player(); }); } void GameWorld::RegisterSystems() { + m_SystemFactory.Register([this]() { return new Systems::TimerSystem(this, m_EventBroker); }); + m_SystemFactory.Register([this]() { return new Systems::DamageSystem(this, m_EventBroker); }); m_SystemFactory.Register([this]() { return new Systems::TransformSystem(this, m_EventBroker); }); //m_SystemFactory.Register([this]() { return new Systems::LevelGenerationSystem(this); }); m_SystemFactory.Register([this]() { return new Systems::InputSystem(this, m_EventBroker); }); @@ -1210,11 +1189,14 @@ void GameWorld::RegisterSystems() m_SystemFactory.Register([this]() { return new Systems::TankSteeringSystem(this, m_EventBroker); }); m_SystemFactory.Register([this]() { return new Systems::SoundSystem(this, m_EventBroker); }); m_SystemFactory.Register([this]() { return new Systems::PhysicsSystem(this, m_EventBroker); }); + m_SystemFactory.Register([this]() { return new Systems::TriggerSystem(this, m_EventBroker); }); m_SystemFactory.Register([this]() { return new Systems::RenderSystem(this, m_EventBroker, m_Renderer); }); } void GameWorld::AddSystems() { + AddSystem(); + AddSystem(); AddSystem(); //AddSystem(); AddSystem(); @@ -1226,6 +1208,7 @@ void GameWorld::AddSystems() AddSystem(); AddSystem(); AddSystem(); + AddSystem(); AddSystem(); } diff --git a/src/GameWorld.h b/src/GameWorld.h index d90e67e..a5746d8 100755 --- a/src/GameWorld.h +++ b/src/GameWorld.h @@ -17,6 +17,9 @@ #include "Systems/RenderSystem.h" #include "Systems/SoundSystem.h" #include "Systems/PhysicsSystem.h" +#include "Systems/TriggerSystem.h" +#include "Systems/TimerSystem.h" +#include "Systems/DamageSystem.h" #include "Components/Camera.h" #include "Components/DirectionalLight.h" @@ -42,6 +45,7 @@ #include "Components/BarrelSteering.h" #include "Components/Player.h" #include "Components/Health.h" +#include "Components/Trigger.h" class GameWorld : public World { diff --git a/src/System.h b/src/System.h index f795d5e..f29aeb5 100755 --- a/src/System.h +++ b/src/System.h @@ -30,7 +30,7 @@ public: // Called when a component is created virtual void OnComponentCreated(std::string type, std::shared_ptr component) { } // Called when a component is removed - virtual void OnComponentRemoved(std::string type, Component* component) { } + virtual void OnComponentRemoved(EntityID entity, std::string type, Component* component) { } // Called when components are committed to an entity virtual void OnEntityCommit(EntityID entity) { } virtual void OnEntityRemoved(EntityID entity) { } diff --git a/src/Systems/DamageSystem.cpp b/src/Systems/DamageSystem.cpp new file mode 100644 index 0000000..9ba2b82 --- /dev/null +++ b/src/Systems/DamageSystem.cpp @@ -0,0 +1,22 @@ +#include "PrecompiledHeader.h" +#include "DamageSystem.h" +#include "World.h" + +void Systems::DamageSystem::RegisterComponents( ComponentFactory* cf ) +{ + cf->Register([]() { return new Components::Health(); }); +} + +void Systems::DamageSystem::Initialize() +{ + + EVENT_SUBSCRIBE_MEMBER(m_EDamage, &Systems::DamageSystem::OnDamage); +} + +bool Systems::DamageSystem::OnDamage( const Events::Damage &event ) +{ + auto health = m_World->GetComponent(event.Entity); + health->health -= event.damage; + LOG_INFO("Damaged entity %i, Health left: %f", event.Entity, health->health); + return true; +} \ No newline at end of file diff --git a/src/Systems/DamageSystem.h b/src/Systems/DamageSystem.h new file mode 100644 index 0000000..215b9df --- /dev/null +++ b/src/Systems/DamageSystem.h @@ -0,0 +1,32 @@ +#ifndef DamageSystem_h__ +#define DamageSystem_h__ + + +#include "System.h" +#include "Components/Health.h" +#include "Events/Damage.h" + +namespace Systems +{ + class DamageSystem : public System + { + public: + + DamageSystem(World* world, std::shared_ptr<::EventBroker> eventBroker) + : System(world, eventBroker) { } + + + void Initialize() override; + void RegisterComponents(ComponentFactory* cf) override; + + + + EventRelay m_EDamage; + bool OnDamage(const Events::Damage &event); + + private: + + }; + +} +#endif // DamageSystem_h__ diff --git a/src/Systems/PhysicsSystem.cpp b/src/Systems/PhysicsSystem.cpp index 35b78f3..89d7693 100644 --- a/src/Systems/PhysicsSystem.cpp +++ b/src/Systems/PhysicsSystem.cpp @@ -39,7 +39,7 @@ void Systems::PhysicsSystem::Initialize() EVENT_SUBSCRIBE_MEMBER(m_EEnableCollisions, &Systems::PhysicsSystem::OnEnableCollisions); EVENT_SUBSCRIBE_MEMBER(m_EDisableCollisions, &Systems::PhysicsSystem::OnDisableCollisions); - hkMemorySystem::FrameInfo finfo(6000 * 1024); // Allocate 6MB of Physics solver buffer + hkMemorySystem::FrameInfo finfo(10000 * 1024); // Allocate 10MB of Physics solver buffer hkMemoryRouter* memoryRouter = hkMemoryInitUtil::initDefault(hkMallocAllocator::m_defaultMallocAllocator, finfo); hkBaseSystem::init(memoryRouter, HavokErrorReport); @@ -77,7 +77,7 @@ void Systems::PhysicsSystem::Initialize() worldInfo.setupSolverInfo(hkpWorldCinfo::SOLVER_TYPE_4ITERS_MEDIUM); worldInfo.m_gravity = hkVector4(0.0f, -9.82f, 0.0f); - worldInfo.m_broadPhaseBorderBehaviour = hkpWorldCinfo::BROADPHASE_BORDER_DO_NOTHING; + worldInfo.m_broadPhaseBorderBehaviour = hkpWorldCinfo::BROADPHASE_BORDER_FIX_ENTITY; // You must specify the size of the broad phase - objects should not be simulated outside this region worldInfo.setBroadPhaseWorldSize(1500.0f); @@ -110,34 +110,6 @@ void Systems::PhysicsSystem::Initialize() m_PhysicsWorld->unmarkForWrite(); m_collisionResolution = new MyCollisionResolution(this); - - hkpBoxShape* shape = new hkpBoxShape(hkVector4(5, 5, 5), 0); - - PhantomCallbackShape* phantom = new PhantomCallbackShape(this); - hkpBvShape* phantomShape = new hkpBvShape(shape, phantom); - - hkMassProperties massProperties; - hkpInertiaTensorComputer::computeBoxVolumeMassProperties(hkVector4(5, 5, 5),1, massProperties); - - hkpRigidBodyCinfo rigidBodyInfo; - { - rigidBodyInfo.m_shape = shape; - rigidBodyInfo.m_motionType = hkpMotion::MOTION_FIXED; - rigidBodyInfo.m_position = hkVector4(0, 0, 0); - - rigidBodyInfo.m_inertiaTensor = massProperties.m_inertiaTensor; - rigidBodyInfo.m_centerOfMass = massProperties.m_centerOfMass; - rigidBodyInfo.m_mass = massProperties.m_mass; - } - // Create RigidBody - - hkpRigidBody* rigidBody = new hkpRigidBody(rigidBodyInfo); - m_PhysicsWorld->markForWrite(); - m_PhysicsWorld->addEntity(rigidBody); - m_PhysicsWorld->unmarkForWrite(); - - shape->removeReference(); - rigidBody->removeReference(); } enum @@ -147,12 +119,13 @@ void Systems::PhysicsSystem::Initialize() VEHICLE2_LAYER = 3, EXPLOSION_LAYER = 4, }; +/* { Events::DisableCollisions e; e.Layer1 = GROUND_LAYER; e.Layer2 = EXPLOSION_LAYER; EventBroker->Publish(e); - } + }*/ /*{ Events::DisableCollisions e; e.Layer1 = VEHICLE1_LAYER; @@ -285,6 +258,10 @@ void Systems::PhysicsSystem::UpdateEntity(double dt, EntityID entity, EntityID p void Systems::PhysicsSystem::OnEntityCommit( EntityID entity ) { + auto tempalteComponent = m_World->GetComponent(entity); + if(tempalteComponent) + return; + auto transformComponent = m_World->GetComponent(entity); if (!transformComponent) return; @@ -310,15 +287,14 @@ void Systems::PhysicsSystem::OnEntityCommit( EntityID entity ) } auto physicsComponent = m_World->GetComponent(entity); - if (physicsComponent) + if (physicsComponent && m_Shapes[entity].size() > 0) { - hkpShape* shape; if(entityParent != entity) { LOG_ERROR("Entity: %i , Only the baseparent can have a PhysicsComponent", entity); return; } - + hkpShape* shape; if(! physicsComponent->Static) // Not static { hkArray shapeArray; @@ -332,12 +308,15 @@ void Systems::PhysicsSystem::OnEntityCommit( EntityID entity ) hkQsTransform transform( GLMVEC3_TO_HKVECTOR4(childTransformComponent->Position), GLMQUAT_TO_HKQUATERNION(childTransformComponent->Orientation), GLMVEC3_TO_HKVECTOR4(childTransformComponent->Scale)); hkpConvexTransformShape* transformedBoxShape = new hkpConvexTransformShape( shapeData.ConvexShape, transform ); shapeArray.pushBack(transformedBoxShape); + } if(shapeData.Shape != nullptr) { shapeArray.pushBack(shapeData.Shape); + } + } @@ -346,20 +325,22 @@ void Systems::PhysicsSystem::OnEntityCommit( EntityID entity ) // Save the listShape for further use m_ListShapes[entity] = listShape; hkMassProperties massProperties; - if(physicsComponent->Phantom) - { - PhantomCallbackShape* phantom = new PhantomCallbackShape(this); - shape = new hkpBvShape(listShape, phantom); - hkpInertiaTensorComputer::computeSphereVolumeMassProperties(1, physicsComponent->Mass, massProperties); - } - else - { - hkpBoxShape* box = new hkpBoxShape(listShape->m_aabbHalfExtents, 0.0f); - shape = new hkpBvShape(listShape, box); - hkpInertiaTensorComputer::computeShapeVolumeMassProperties(shape, physicsComponent->Mass, massProperties); - } + hkpBoxShape* box = new hkpBoxShape(listShape->m_aabbHalfExtents, 0.0f); + shape = new hkpBvShape(listShape, box); + hkpInertiaTensorComputer::computeShapeVolumeMassProperties(shape, physicsComponent->Mass, massProperties); - + + for (auto &shapeData : m_Shapes[entity]) + { + if(shapeData.ConvexShape != nullptr) + { + shapeData.ConvexShape->removeReference(); + } + if(shapeData.Shape != nullptr) + { + shapeData.Shape->removeReference(); + } + } // Clean up for less memory usage m_Shapes.erase(entity); @@ -392,6 +373,7 @@ void Systems::PhysicsSystem::OnEntityCommit( EntityID entity ) rigidBodyInfo.m_maxLinearVelocity = physicsComponent->MaxLinearVelocity; rigidBodyInfo.m_maxAngularVelocity = physicsComponent->MaxAngularVelocity; rigidBodyInfo.m_collisionFilterInfo = hkpGroupFilter::calcFilterInfo(physicsComponent->CollisionLayer, physicsComponent->CollisionSystemGroup, physicsComponent->CollisionSubSystemId, physicsComponent->CollisionSubSystemDontCollideWith); + rigidBodyInfo.m_enableDeactivation = false; } // Create RigidBody hkpRigidBody* rigidBody = new hkpRigidBody(rigidBodyInfo); @@ -480,17 +462,20 @@ void Systems::PhysicsSystem::OnEntityCommit( EntityID entity ) staticCompoundShape->bake(); shape = staticCompoundShape; hkMassProperties massProperties; - if(physicsComponent->Phantom) + hkpInertiaTensorComputer::computeShapeVolumeMassProperties(shape, physicsComponent->Mass, massProperties); + + + for (auto &shapeData : m_Shapes[entity]) { - PhantomCallbackShape* phantom = new PhantomCallbackShape(this); - shape = new hkpBvShape(shape, phantom); - hkpInertiaTensorComputer::computeSphereVolumeMassProperties(1, physicsComponent->Mass, massProperties); + if(shapeData.ConvexShape != nullptr) + { + shapeData.ConvexShape->removeReference(); + } + if(shapeData.Shape != nullptr) + { + shapeData.Shape->removeReference(); + } } - else - { - hkpInertiaTensorComputer::computeShapeVolumeMassProperties(shape, physicsComponent->Mass, massProperties); - } - m_Shapes.erase(entity); @@ -521,6 +506,7 @@ void Systems::PhysicsSystem::OnEntityCommit( EntityID entity ) rigidBodyInfo.m_maxLinearVelocity = physicsComponent->MaxLinearVelocity; rigidBodyInfo.m_maxAngularVelocity = physicsComponent->MaxAngularVelocity; rigidBodyInfo.m_collisionFilterInfo = hkpGroupFilter::calcFilterInfo(physicsComponent->CollisionLayer, physicsComponent->CollisionSystemGroup, physicsComponent->CollisionSubSystemId, physicsComponent->CollisionSubSystemDontCollideWith); + rigidBodyInfo.m_enableDeactivation = false; } // Create RigidBody hkpRigidBody* rigidBody = new hkpRigidBody(rigidBodyInfo); @@ -538,22 +524,91 @@ void Systems::PhysicsSystem::OnEntityCommit( EntityID entity ) } else { - - //TODO: COMMENT THIS SECTION if(sphereComponent) { hkpSphereShape* sphereShape = new hkpSphereShape(sphereComponent->Radius); - m_Shapes[entityParent].push_back(ShapeArrayData(entity, sphereShape, nullptr)); - //sphereShape->removeReference(); + + auto triggerComponent = m_World->GetComponent(entityParent); + if(triggerComponent) + { + auto parentTransformComponent = m_World->GetComponent(entityParent); + + PhantomCallbackShape* phantom = new PhantomCallbackShape(this); + hkpBvShape* phantomShape = new hkpBvShape(sphereShape, phantom); + + hkpRigidBodyCinfo rigidBodyInfo; + { + rigidBodyInfo.m_shape = phantomShape; + rigidBodyInfo.m_motionType = hkpMotion::MOTION_FIXED; + rigidBodyInfo.m_position = GLMVEC3_TO_HKVECTOR4(parentTransformComponent->Position); + + rigidBodyInfo.m_mass = 1; + rigidBodyInfo.m_collisionFilterInfo = hkpGroupFilter::calcFilterInfo(4, 0, 0, 0); + } + // Create RigidBody + + hkpRigidBody* rigidBody = new hkpRigidBody(rigidBodyInfo); + m_PhysicsWorld->markForWrite(); + m_PhysicsWorld->addEntity(rigidBody); + m_PhysicsWorld->unmarkForWrite(); + + m_RigidBodies[entityParent] = rigidBody; + m_RigidBodyEntities[rigidBody] = entityParent; + + phantomShape->removeReference(); + phantom->removeReference(); + sphereShape->removeReference(); + rigidBody->removeReference(); + } + else + { + m_Shapes[entityParent].push_back(ShapeArrayData(entity, sphereShape, nullptr)); + } } //TODO: COMMENT THIS SECTION else if(boxComponent) { hkReal thickness = 0.05; hkpBoxShape* boxShape = new hkpBoxShape(hkVector4(boxComponent->Width- thickness, boxComponent->Height -thickness, boxComponent->Depth - thickness), thickness); - m_Shapes[entityParent].push_back(ShapeArrayData(entity, boxShape, nullptr)); - //boxShape->removeReference(); + + auto triggerComponent = m_World->GetComponent(entityParent); + if(triggerComponent) + { + auto parentTransformComponent = m_World->GetComponent(entityParent); + + PhantomCallbackShape* phantom = new PhantomCallbackShape(this); + hkpBvShape* phantomShape = new hkpBvShape(boxShape, phantom); + + hkpRigidBodyCinfo rigidBodyInfo; + { + rigidBodyInfo.m_shape = phantomShape; + rigidBodyInfo.m_motionType = hkpMotion::MOTION_FIXED; + rigidBodyInfo.m_position = GLMVEC3_TO_HKVECTOR4(parentTransformComponent->Position); + + rigidBodyInfo.m_mass = 1; + rigidBodyInfo.m_collisionFilterInfo = hkpGroupFilter::calcFilterInfo(4, 0, 0, 0); // HACK: + } + // Create RigidBody + + hkpRigidBody* rigidBody = new hkpRigidBody(rigidBodyInfo); + m_PhysicsWorld->markForWrite(); + m_PhysicsWorld->addEntity(rigidBody); + m_PhysicsWorld->unmarkForWrite(); + + m_RigidBodies[entityParent] = rigidBody; + m_RigidBodyEntities[rigidBody] = entityParent; + + phantomShape->removeReference(); + boxShape->removeReference(); + phantom->removeReference(); + rigidBody->removeReference(); + } + else + { + m_Shapes[entityParent].push_back(ShapeArrayData(entity, boxShape, nullptr)); + } + } else if(meshShapeComponent) { @@ -605,9 +660,6 @@ void Systems::PhysicsSystem::OnEntityCommit( EntityID entity ) m_Shapes[entityParent].push_back(ShapeArrayData(entity, nullptr, moppShape)); } } - - - } void Systems::PhysicsSystem::TearDownPhysicsState(EntityID entity, EntityID parent) @@ -620,12 +672,6 @@ void Systems::PhysicsSystem::OnComponentCreated(std::string type, std::shared_pt } -void Systems::PhysicsSystem::OnComponentRemoved(std::string type, Component* component) -{ - -} - - void Systems::PhysicsSystem::SetupVisualDebugger(hkpPhysicsContext* worlds) { // Setup the visual debugger @@ -678,37 +724,71 @@ bool Systems::PhysicsSystem::OnTankSteer(const Events::TankSteer &event) bool Systems::PhysicsSystem::OnSetVelocity( const Events::SetVelocity &event ) { - m_PhysicsWorld->markForWrite(); - m_RigidBodies[event.Entity]->setLinearVelocity(GLMVEC3_TO_HKVECTOR4(event.Velocity)); - m_PhysicsWorld->unmarkForWrite(); + if(m_RigidBodies.find(event.Entity) != m_RigidBodies.end()) + { + m_PhysicsWorld->markForWrite(); + m_RigidBodies[event.Entity]->setLinearVelocity(GLMVEC3_TO_HKVECTOR4(event.Velocity)); + m_PhysicsWorld->unmarkForWrite(); + } return true; } bool Systems::PhysicsSystem::OnApplyForce(const Events::ApplyForce &event) { - m_PhysicsWorld->markForWrite(); - m_RigidBodies[event.Entity]->applyForce(event.DeltaTime, GLMVEC3_TO_HKVECTOR4(event.Force)); - m_PhysicsWorld->unmarkForWrite(); + if(m_RigidBodies.find(event.Entity) != m_RigidBodies.end()) + { + m_PhysicsWorld->markForWrite(); + m_RigidBodies[event.Entity]->applyForce(event.DeltaTime, GLMVEC3_TO_HKVECTOR4(event.Force)); + m_PhysicsWorld->unmarkForWrite(); + } return true; } bool Systems::PhysicsSystem::OnApplyPointImpulse( const Events::ApplyPointImpulse &event ) { - m_PhysicsWorld->markForWrite(); - m_RigidBodies[event.Entity]->applyPointImpulse(GLMVEC3_TO_HKVECTOR4(event.Impulse), GLMVEC3_TO_HKVECTOR4(event.Position)); - m_PhysicsWorld->unmarkForWrite(); + if(m_RigidBodies.find(event.Entity) != m_RigidBodies.end()) + { + m_PhysicsWorld->markForWrite(); + m_RigidBodies[event.Entity]->applyPointImpulse(GLMVEC3_TO_HKVECTOR4(event.Impulse), GLMVEC3_TO_HKVECTOR4(event.Position)); + m_PhysicsWorld->unmarkForWrite(); + } return true; } + +void Systems::PhysicsSystem::OnComponentRemoved(EntityID entity, std::string type, Component* component) +{ + if(type == "Trigger") + { + if(m_RigidBodies.find(entity) != m_RigidBodies.end()) + { + LOG_INFO("Removed Trigger of entity %i", entity); + m_PhysicsWorld->markForWrite(); + m_RigidBodyEntities.erase(m_RigidBodies[entity]); + m_PhysicsWorld->removeEntity(m_RigidBodies[entity]); + m_RigidBodies.erase(entity); + m_PhysicsWorld->unmarkForWrite(); + } + } +} + + void Systems::PhysicsSystem::OnEntityRemoved( EntityID entity ) { - if(m_RigidBodies.find(entity) != m_RigidBodies.end()) + if(m_RigidBodies.find(entity) != m_RigidBodies.end()) { - m_RigidBodyEntities.erase(m_RigidBodies[entity]); + LOG_INFO("Removed rigid body of entity %i", entity); m_PhysicsWorld->markForWrite(); + m_RigidBodyEntities.erase(m_RigidBodies[entity]); + if(m_ListShapes.find(entity) != m_ListShapes.end()) + { + m_ListShapes[entity]->removeReference(); + m_ListShapes.erase(entity); + } + m_PhysicsWorld->removeEntity(m_RigidBodies[entity]); - m_PhysicsWorld->unmarkForWrite(); m_RigidBodies.erase(entity); + m_PhysicsWorld->unmarkForWrite(); } if(m_Vehicles.find(entity) != m_Vehicles.end()) { diff --git a/src/Systems/PhysicsSystem.h b/src/Systems/PhysicsSystem.h index ed6bde4..1aae3ec 100644 --- a/src/Systems/PhysicsSystem.h +++ b/src/Systems/PhysicsSystem.h @@ -82,6 +82,10 @@ #include #include "Events/EnableCollisions.h" #include "Events/DisableCollisions.h" +#include "Components/Trigger.h" +#include "Components/Template.h" + +#include "Events/EnterTrigger.h" namespace Systems { @@ -104,6 +108,7 @@ public: e.Entity1 = entity1; e.Entity2 = entity2; m_PhysicsSystem->EventBroker->Publish(e); + LOG_INFO("CollisionEvent!"); } private: @@ -120,14 +125,26 @@ public: virtual void phantomEnterEvent( const hkpCollidable* collidableA, const hkpCollidable* collidableB, const hkpCollisionInput& env ) { - - LOG_INFO("AAAAAAAAAAAAAAAAAAAAAAAAAH!"); + EntityID entity1 = m_PhysicsSystem->m_RigidBodyEntities[hkpGetRigidBody(collidableA)]; + EntityID entity2 = m_PhysicsSystem->m_RigidBodyEntities[hkpGetRigidBody(collidableB)]; + + if(m_PhysicsSystem->m_World->ValidEntity(entity1) && m_PhysicsSystem->m_World->ValidEntity(entity2)) + { + auto trigger = m_PhysicsSystem->m_World->GetComponent(entity1); + if(trigger->TriggerOnce) + { + m_PhysicsSystem->m_World->RemoveComponent(entity1); + } + Events::EnterTrigger e; + e.Entity1 = entity1; + e.Entity2 = entity2; + m_PhysicsSystem->EventBroker->Publish(e); + } } virtual void phantomLeaveEvent( const hkpCollidable* collidableA, const hkpCollidable* collidableB ) { - - LOG_INFO("AAAAAAAAAAAAAAAAAAAAAAAAAH!"); + } private: @@ -144,10 +161,10 @@ public: void Update(double dt) override; void UpdateEntity(double dt, EntityID entity, EntityID parent) override; void OnComponentCreated(std::string type, std::shared_ptr component) override; - void OnComponentRemoved(std::string type, Component* component) override; + void OnComponentRemoved(EntityID entity, std::string type, Component* component) override; void OnEntityCommit(EntityID entity) override; void OnEntityRemoved(EntityID entity) override; - + private: double m_Accumulator; hkpWorld* m_PhysicsWorld; diff --git a/src/Systems/SoundSystem.cpp b/src/Systems/SoundSystem.cpp index b36bf47..ffb81b8 100755 --- a/src/Systems/SoundSystem.cpp +++ b/src/Systems/SoundSystem.cpp @@ -124,7 +124,7 @@ void Systems::SoundSystem::OnComponentCreated(std::string type, std::shared_ptr< } } -void Systems::SoundSystem::OnComponentRemoved(std::string type, Component* component) +void Systems::SoundSystem::OnComponentRemoved(EntityID entity, std::string type, Component* component) { if(type == "SoundEmitter") { diff --git a/src/Systems/SoundSystem.h b/src/Systems/SoundSystem.h index 00ae091..f885b60 100755 --- a/src/Systems/SoundSystem.h +++ b/src/Systems/SoundSystem.h @@ -26,7 +26,7 @@ public: void Update(double dt) override; void UpdateEntity(double dt, EntityID entity, EntityID parent) override; void OnComponentCreated(std::string type, std::shared_ptr component) override; - void OnComponentRemoved(std::string type, Component* component) override; + void OnComponentRemoved(EntityID entity, std::string type, Component* component) override; void PlaySound(Components::SoundEmitter* emitter, std::string path); // Use if you want to play a temporary .wav file not from component void PlaySound(std::shared_ptr emitter); // Use if you want to play .wav file from component // imon no hate plx T.T void StopSound(std::shared_ptr emitter); diff --git a/src/Systems/TankSteeringSystem.cpp b/src/Systems/TankSteeringSystem.cpp index 281e03a..5b5e34d 100644 --- a/src/Systems/TankSteeringSystem.cpp +++ b/src/Systems/TankSteeringSystem.cpp @@ -97,80 +97,140 @@ void Systems::TankSteeringSystem::UpdateEntity(double dt, EntityID entity, Entit bool Systems::TankSteeringSystem::OnCollision( const Events::Collision &e ) { - if(m_World->ValidEntity(e.Entity1) && m_World->ValidEntity(e.Entity1)) + 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); - - if(tankShell1) + EntityID shellEntity = 0; + Components::TankShell* shellComponent; + EntityID otherEntity = 0; + + if (tankShell1) { - auto transform = m_World->GetComponent(e.Entity1); - m_World->GetSystem()->CreateExplosion(transform->Position, 1, 60, "Textures/Sprites/NewtonTreeDeleteASAPPlease.png", glm::angleAxis(glm::pi()/2, glm::vec3(1,0,0)), 40, glm::pi(), 0.5f); - - auto health2 = m_World->GetComponent(e.Entity2); - if(health2) - { - health2->health -= tankShell1->Damage; - } - - { - auto hitSphere = m_World->CreateEntity(); - auto transformHit = m_World->AddComponent(hitSphere); - transformHit->Position = transform->Position; - - auto physics = m_World->AddComponent(hitSphere); - physics->Static = true; - physics->Phantom = false; - physics->CollisionLayer = 4; - - { - auto shape = m_World->CreateEntity(hitSphere); - auto transformHit = m_World->AddComponent(shape); - auto sphereShape = m_World->AddComponent(shape); - sphereShape->Radius = 40.f*0.5f; //HACK: - m_World->CommitEntity(shape); - } - m_World->CommitEntity(hitSphere); - } - - m_World->RemoveEntity(e.Entity1); + shellEntity = e.Entity1; + otherEntity = e.Entity2; + shellComponent = tankShell1; + } + else if (tankShell2) + { + shellEntity = e.Entity2; + otherEntity = e.Entity1; + shellComponent = tankShell2; + } + else + { + return false; } - if(tankShell2) + auto physicsComponents = m_World->GetComponentsOfType(); + auto shellTransform = m_World->GetComponent(shellEntity); + //auto otherTransform = m_World->GetComponent(otherEntity); + for (auto &physComponent : *physicsComponents) { - auto transform = m_World->GetComponent(e.Entity2); - m_World->GetSystem()->CreateExplosion(transform->Position, 1, 60, "Textures/Sprites/NewtonTreeDeleteASAPPlease.png", glm::angleAxis(glm::pi()/2, glm::vec3(1,0,0)), 40, glm::pi(), 0.5f); + EntityID physicsEntity = std::dynamic_pointer_cast(physComponent)->Entity; + auto physEntityTransform = m_World->GetComponent(physicsEntity); - auto health1 = m_World->GetComponent(e.Entity2); - if(health1) + float distance = glm::distance(physEntityTransform->Position, shellTransform->Position); + if (distance <= shellComponent->ExplosionRadius) { - health1->health -= tankShell1->Damage; - } - - { - auto hitSphere = m_World->CreateEntity(); - auto transformHit = m_World->AddComponent(hitSphere); - transformHit->Position = transform->Position; + // 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); - auto physics = m_World->AddComponent(hitSphere); - physics->Static = true; - physics->Phantom = false; - physics->CollisionLayer = 4; + 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) { - auto shape = m_World->CreateEntity(hitSphere); - auto transformHit = m_World->AddComponent(shape); - auto sphereShape = m_World->AddComponent(shape); - sphereShape->Radius = 40.f*0.5f; //HACK: - m_World->CommitEntity(shape); + Events::Damage d; + d.Entity = physicsEntity; + d.damage = (1.f - pow(distance / radius, 2)) * shellComponent->Damage; + EventBroker->Publish(d); } - m_World->CommitEntity(hitSphere); + + + + m_World->RemoveEntity(shellEntity); } - - - m_World->RemoveEntity(e.Entity2); } + + //if(tankShell1) + //{ + // LOG_DEBUG("%i collided with %i", e.Entity1, e.Entity2); + // auto transform = m_World->GetComponent(e.Entity1); + // //m_World->GetSystem()->CreateExplosion(transform->Position, 1, 60, "Textures/Sprites/NewtonTreeDeleteASAPPlease.png", glm::angleAxis(glm::pi()/2, glm::vec3(1,0,0)), 40, glm::pi(), 0.5f); + + // glm::vec3 pointOfImpact = transform->Position; + + + // { + // auto ent = m_World->CreateEntity(); + // LOG_DEBUG("Created trigger entity %i", ent); + // auto transform = m_World->AddComponent(ent); + // transform->Position = pointOfImpact; + + // auto trigger = m_World->AddComponent(ent); + // trigger->TriggerOnce = true; + // auto frameTimer = m_World->AddComponent(ent); + // frameTimer->Frames = 100; + // auto explosion = m_World->AddComponent(ent); + // explosion->MaxVelocity = 50.f; + // explosion->Radius = 30.f; + // { + // auto shape = m_World->CreateEntity(ent); + // auto transformshape = m_World->AddComponent(shape); + // auto sphere = m_World->AddComponent(shape); + // sphere->Radius = 30.f; + // m_World->CommitEntity(shape); + + // } + // m_World->CommitEntity(ent); + // } + // + // m_World->RemoveEntity(e.Entity1); + //} + + //if(tankShell2) + //{ + // LOG_DEBUG("%i collided with %i", e.Entity1, e.Entity2); + // auto transform = m_World->GetComponent(e.Entity2); + // //m_World->GetSystem()->CreateExplosion(transform->Position, 1, 60, "Textures/Sprites/NewtonTreeDeleteASAPPlease.png", glm::angleAxis(glm::pi()/2, glm::vec3(1,0,0)), 40, glm::pi(), 0.5f); + + // glm::vec3 pointOfImpact = transform->Position; + + + // { + // auto ent = m_World->CreateEntity(); + // LOG_DEBUG("Created trigger entity %i", ent); + // auto transform = m_World->AddComponent(ent); + // transform->Position = pointOfImpact; + + // auto trigger = m_World->AddComponent(ent); + // trigger->TriggerOnce = true; + // auto frameTimer = m_World->AddComponent(ent); + // frameTimer->Frames = 100; + // auto explosion = m_World->AddComponent(ent); + // explosion->MaxVelocity = 50.f; + // explosion->Radius = 30.f; + // { + // auto shape = m_World->CreateEntity(ent); + // auto transformshape = m_World->AddComponent(shape); + // auto sphere = m_World->AddComponent(shape); + // sphere->Radius = 30.f; + // m_World->CommitEntity(shape); + + // } + // m_World->CommitEntity(ent); + // } + + // m_World->RemoveEntity(e.Entity2); + //} } return true; diff --git a/src/Systems/TankSteeringSystem.h b/src/Systems/TankSteeringSystem.h index 1b38fe1..aba3047 100644 --- a/src/Systems/TankSteeringSystem.h +++ b/src/Systems/TankSteeringSystem.h @@ -24,6 +24,12 @@ #include "Events/EnableCollisions.h" #include "Events/DisableCollisions.h" +#include "Components/Trigger.h" +#include "Components/TriggerExplosion.h" +#include "Components/FrameTimer.h" + +#include "Events/Damage.h" + namespace Systems { diff --git a/src/Systems/TimerSystem.cpp b/src/Systems/TimerSystem.cpp new file mode 100644 index 0000000..dc9c6d3 --- /dev/null +++ b/src/Systems/TimerSystem.cpp @@ -0,0 +1,38 @@ +#include "PrecompiledHeader.h" +#include "TimerSystem.h" +#include "World.h" + +void Systems::TimerSystem::RegisterComponents( ComponentFactory* cf ) +{ + cf->Register([]() { return new Components::Timer(); }); + cf->Register([]() { return new Components::FrameTimer(); }); +} + +void Systems::TimerSystem::UpdateEntity( double dt, EntityID entity, EntityID parent ) +{ + auto timer = m_World->GetComponent(entity); + if(timer) + { + timer->Time -= dt; + + if(timer->Time <= 0) + { + m_World->RemoveEntity(entity); + } + } + + auto frameTimer = m_World->GetComponent(entity); + if(frameTimer) + { + frameTimer->Frames -= 1; + + if(frameTimer->Frames <= 0) + { + m_World->RemoveEntity(entity); + } + } + + +} + + diff --git a/src/Systems/TimerSystem.h b/src/Systems/TimerSystem.h new file mode 100644 index 0000000..1e73c96 --- /dev/null +++ b/src/Systems/TimerSystem.h @@ -0,0 +1,28 @@ +#ifndef TimerSystem_h__ +#define TimerSystem_h__ + + +#include "System.h" +#include "Components/Transform.h" +#include "Components/Timer.h" +#include "Components/FrameTimer.h" + +namespace Systems +{ + class TimerSystem : public System + { + public: + + TimerSystem(World* world, std::shared_ptr<::EventBroker> eventBroker) + : System(world, eventBroker) { } + + void RegisterComponents(ComponentFactory* cf) override; + void UpdateEntity(double dt, EntityID entity, EntityID parent) override; + + private: + + + }; + +} +#endif // TimerSystem_h__ diff --git a/src/Systems/TriggerSystem.cpp b/src/Systems/TriggerSystem.cpp new file mode 100644 index 0000000..9a4d548 --- /dev/null +++ b/src/Systems/TriggerSystem.cpp @@ -0,0 +1,91 @@ +#include "PrecompiledHeader.h" +#include "TriggerSystem.h" +#include "World.h" + +void Systems::TriggerSystem::RegisterComponents( ComponentFactory* cf ) +{ + cf->Register([]() { return new Components::Trigger(); }); + cf->Register([]() { return new Components::TriggerExplosion(); }); +} + +void Systems::TriggerSystem::Initialize() +{ + EVENT_SUBSCRIBE_MEMBER(m_EEnterTrigger, &Systems::TriggerSystem::OnEnterTrigger); +} + +void Systems::TriggerSystem::Update( double dt ) +{ + +} + +void Systems::TriggerSystem::UpdateEntity( double dt, EntityID entity, EntityID parent ) +{ + +} + +void Systems::TriggerSystem::OnComponentCreated( std::string type, std::shared_ptr component ) +{ + +} + +void Systems::TriggerSystem::OnComponentRemoved(EntityID entity, std::string type, Component* component ) +{ + +} + +void Systems::TriggerSystem::OnEntityCommit( EntityID entity ) +{ + +} + +void Systems::TriggerSystem::OnEntityRemoved( EntityID entity ) +{ + +} + +bool Systems::TriggerSystem::OnEnterTrigger( const Events::EnterTrigger &event ) +{ + auto explosionComponent1 = m_World->GetComponent(event.Entity1); + auto explosionComponent2 = m_World->GetComponent(event.Entity2); + + if(explosionComponent1) + { + Explosion(event.Entity2, event.Entity1); + } + else if (explosionComponent2) + { + Explosion(event.Entity1, event.Entity2); + } + + return true; +} + +void Systems::TriggerSystem::Explosion( EntityID entity, EntityID phantomEntity ) +{ + auto transformComponent = m_World->GetComponent(entity); + auto PhantomTransformComponent = m_World->GetComponent(phantomEntity); + auto explosionComponent = m_World->GetComponent(phantomEntity); + + if(transformComponent && PhantomTransformComponent) + { + // Velocity = (1 - (distance / radius)^2) * Strength; + glm::vec3 vect = transformComponent->Position - PhantomTransformComponent->Position; + float distance = glm::length(vect); + float radius = explosionComponent->Radius; + float velocity = (1.f - pow(distance / radius, 2)) * explosionComponent->MaxVelocity; + + glm::vec3 direction = glm::normalize(transformComponent->Position - PhantomTransformComponent->Position); + + Events::SetVelocity e; + e.Entity = entity; + e.Velocity = direction*velocity; + EventBroker->Publish(e); + + m_World->RemoveEntity(phantomEntity); + } + + +} + + + diff --git a/src/Systems/TriggerSystem.h b/src/Systems/TriggerSystem.h new file mode 100644 index 0000000..d073433 --- /dev/null +++ b/src/Systems/TriggerSystem.h @@ -0,0 +1,43 @@ +#ifndef TriggerSystem_h__ +#define TriggerSystem_h__ + + +#include "System.h" +#include "Components/Transform.h" +#include "Events/SetVelocity.h" +#include "Events/ApplyForce.h" +#include "Events/ApplyPointImpulse.h" + +#include + +#include "Components/Trigger.h" +#include "Components/TriggerExplosion.h" +#include "Events/EnterTrigger.h" +#include +namespace Systems +{ + class TriggerSystem : public System + { + public: + + TriggerSystem(World* world, std::shared_ptr<::EventBroker> eventBroker) + : System(world, eventBroker) { } + + void Initialize() override; + void RegisterComponents(ComponentFactory* cf) override; + void Update(double dt) override; + void UpdateEntity(double dt, EntityID entity, EntityID parent) override; + void OnComponentCreated(std::string type, std::shared_ptr component) override; + void OnComponentRemoved(EntityID entity, std::string type, Component* component) override; + void OnEntityCommit(EntityID entity) override; + void OnEntityRemoved(EntityID entity) override; + + EventRelay m_EEnterTrigger; + bool OnEnterTrigger(const Events::EnterTrigger &event); + private: + void Explosion(EntityID entity, EntityID phantomEntity); + + }; + +} +#endif // TriggerSystem_h__ diff --git a/src/World.cpp b/src/World.cpp index 699811e..309f36d 100755 --- a/src/World.cpp +++ b/src/World.cpp @@ -72,17 +72,18 @@ EntityID World::GetEntityBaseParent(EntityID entity) bool World::ValidEntity(EntityID entity) { - return m_EntityParents.find(entity) != m_EntityParents.end(); + return m_EntityParents.find(entity) != m_EntityParents.end() + && m_EntitiesToRemove.find(entity) == m_EntitiesToRemove.end(); } void World::RemoveEntity(EntityID entity) { - m_EntitiesToRemove.push_back(entity); + m_EntitiesToRemove.insert(entity); for (auto pair : m_EntityParents) { if (pair.second == entity) { - m_EntitiesToRemove.push_back(pair.first); + m_EntitiesToRemove.insert(pair.first); } } } @@ -102,7 +103,7 @@ void World::ProcessEntityRemovals() for (auto pair : m_Systems) { auto system = pair.second; - system->OnComponentRemoved(type, component.get()); + system->OnComponentRemoved(entity, type, component.get()); } m_ComponentsOfType[type].remove(component); } diff --git a/src/World.h b/src/World.h index 87bfecf..7c085b4 100755 --- a/src/World.h +++ b/src/World.h @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -76,10 +77,15 @@ public: template std::shared_ptr AddComponent(EntityID entity); template + void RemoveComponent(EntityID entity); + template T* GetComponent(EntityID entity); // Triggers commit events in systems void CommitEntity(EntityID entity); + template + std::list>* GetComponentsOfType(); + /*std::vector GetEntityChildren(EntityID entity);*/ virtual void Update(double dt); @@ -111,7 +117,7 @@ protected: // Internal: Add a component to an entity void AddComponent(EntityID entity, std::string componentType, std::shared_ptr component); - std::list m_EntitiesToRemove; + std::set m_EntitiesToRemove; void ProcessEntityRemovals(); EntityID GenerateEntityID(); @@ -120,6 +126,18 @@ protected: }; +template +std::list>* World::GetComponentsOfType() +{ + const char* componentType = typeid(T).name(); + + auto it = m_ComponentsOfType.find(componentType); + if (it == m_ComponentsOfType.end()) + return nullptr; + + return &it->second; +} + template std::shared_ptr World::GetSystem() { @@ -151,6 +169,26 @@ std::shared_ptr World::AddComponent(EntityID entity) return component; } +template +void World::RemoveComponent(EntityID entity) +{ + const char* componentType = typeid(T).name(); + + auto it = m_EntityComponents[entity].find(componentType); + if (it == m_EntityComponents[entity].end()) + return; + + auto component = it->second; + + component->Entity = 0; + m_ComponentsOfType[componentType].remove(component); + m_EntityComponents[entity].erase(it); + for (auto pair : m_Systems) + { + auto system = pair.second; + system->OnComponentRemoved(entity, componentType, component.get()); + } +} template T* World::GetComponent(EntityID entity) diff --git a/vs11/Returngeance/Returngeance.vcxproj b/vs11/Returngeance/Returngeance.vcxproj index b9ad781..2026fd0 100755 --- a/vs11/Returngeance/Returngeance.vcxproj +++ b/vs11/Returngeance/Returngeance.vcxproj @@ -109,6 +109,7 @@ + @@ -118,7 +119,9 @@ + + @@ -129,8 +132,10 @@ - + + + @@ -152,6 +157,7 @@ + @@ -166,6 +172,7 @@ + @@ -180,6 +187,7 @@ + @@ -198,6 +206,7 @@ + @@ -207,7 +216,9 @@ + + diff --git a/vs11/Returngeance/Returngeance.vcxproj.filters b/vs11/Returngeance/Returngeance.vcxproj.filters index 3619c2d..0448d88 100755 --- a/vs11/Returngeance/Returngeance.vcxproj.filters +++ b/vs11/Returngeance/Returngeance.vcxproj.filters @@ -66,6 +66,15 @@ Gameplay\Vehicles\Helicopter\Systems + + Physics\Systems + + + Base\Systems + + + Gameplay\Systems + @@ -158,6 +167,12 @@ {cb06b441-90b8-46ed-b347-4190dac7185b} + + {3c2ea0e5-41a1-4b11-a891-1d59ead7223c} + + + {9702064a-02a2-4b3c-a2ab-47c23a9cf49c} + @@ -400,9 +415,6 @@ Gameplay\Components - - Gameplay\Components - Physics\Components @@ -412,6 +424,33 @@ Physics\Events + + Physics\Components + + + Physics\Systems + + + Physics\Components + + + Physics\Events + + + Base\Systems + + + Base\Components + + + Base\Components + + + Gameplay\Systems + + + Gameplay\Events +