Commit 032b9727 authored by Pierre TESSIER's avatar Pierre TESSIER

Added health/damage system, bug when a character dies

parent c17fbc6e
......@@ -14,5 +14,6 @@
#include "components/animation.hpp"
#include "components/ai_player.hpp"
#include "components/player_component.hpp"
#include "components/character_design.hpp"
#endif // !COMPONENTS_HPP_INCLUDED
#ifndef COMPONENTS_AI_PLAYER_HPP_INCLUDED
#define COMPONENTS_AI_PLAYER_HPP_INCLUDED
#include "vcl/vcl.hpp"
#include "ECS/Component.hpp"
struct AIPlayer
......
#ifndef COMPONENTS_CHARACTER_DESIGN_COMPONENT_HPP_INCLUDED
#define COMPONENTS_CHARACTER_DESIGN_COMPONENT_HPP_INCLUDED
#include "ECS/Component.hpp"
struct CharacterDesign
{
CharacterDesign(float maxHealth_, float damage_) : maxHealth{ maxHealth_ }, damage{ damage_ } {currentHealth = maxHealth; };
float maxHealth;
float damage;
float currentHealth;
};
using CharacterDesignComponent = ecs::Component<CharacterDesign>;
#endif // !COMPONENTS_CHARACTER_DESIGN_COMPONENT_HPP_INCLUDED
......@@ -7,14 +7,19 @@
struct Ray
{
Ray(vcl::vec3 const& shootOrigin, vcl::vec3 const& shootDirection, float const& m_speed, ecs::Entity const& shooter, vcl::vec3 const& end) : position{ shootOrigin }, direction{ shootDirection }, speed{ m_speed }, srcEntity{ shooter }, endTrajectory{ end }{};
Ray(vcl::vec3 const& shootOrigin, vcl::vec3 const& shootDirection, float const& m_speed, ecs::Entity const& shooter) : position{ shootOrigin }, direction{ shootDirection }, speed{ m_speed }, srcEntity{ shooter }{};
Ray(vcl::vec3 const& shootOrigin, vcl::vec3 const& shootDirection, float const& m_speed, ecs::Entity const& shooter, vcl::vec3 const& end) : position{ shootOrigin }, direction{ shootDirection }, speed{ m_speed }, srcEntity{ shooter }, endTrajectory{ end }, damage{}{};
Ray(vcl::vec3 const& shootOrigin, vcl::vec3 const& shootDirection, float const& m_speed, ecs::Entity const& shooter, float damage_) : position{ shootOrigin }, direction{ shootDirection }, speed{ m_speed }, srcEntity{ shooter }, damage{ damage_ }{};
Ray(vcl::vec3 const& shootOrigin, vcl::vec3 const& shootDirection, float const& m_speed, ecs::Entity const& shooter) : position{ shootOrigin }, direction{ shootDirection }, speed{ m_speed }, srcEntity{ shooter }, damage{}{};
Ray() = default;
vcl::vec3 position;
vcl::vec3 direction;
float speed;
ecs::Entity srcEntity;
std::optional<ecs::Entity> endEntity;
std::optional<vcl::vec3> endTrajectory{ std::nullopt };
float damage;
};
using RayComponent = ecs::Component<Ray>;
......
......@@ -138,6 +138,8 @@ void scene_model::logicLoop(std::map<std::string,GLuint>& shaders, scene_structu
m_ecs.update<BillboardOrientationSystem>(scene.camera.orientation);
m_ecs.update<HierarchyPositionUpdater::Transform2Collision>();
m_ecs.update<LockdownSystem>();
m_ecs.update<HealthSystem>(m_ecs);
m_ecs.getSystem<HealthSystem>().destroyDeadCharacter(m_ecs);
}
void scene_model::renderLoop(std::map<std::string,GLuint>& shaders, scene_structure& scene)
......
......@@ -6,7 +6,7 @@
#include "components.hpp"
#include "systems.hpp"
struct MyEcs : ecs::ecs<ecs::Components<HierarchyCollisionBoxComponent, TransformComponent, DerivedTransformComponent, RenderComponent, ArticulatedHierarchyComponent, CollisionComponent, ForceComponent, PhysicsComponent, PlayerControlComponent, RayComponent, AnimationComponent, AIPlayerComponent, PlayerComponent>
struct MyEcs : ecs::ecs<ecs::Components<HierarchyCollisionBoxComponent, TransformComponent, DerivedTransformComponent, RenderComponent, ArticulatedHierarchyComponent, CollisionComponent, ForceComponent, PhysicsComponent, PlayerControlComponent, RayComponent, AnimationComponent, AIPlayerComponent, PlayerComponent, CharacterDesignComponent>
, ecs::Systems<RayRender, RayTrajectory,
GravitySystem, PhysicsSystem, DeadEntityCollector,
PositionUpdater::Collision2Transform, PositionUpdater::Transform2Collision, HierarchyPositionUpdater::Collision2Transform, HierarchyPositionUpdater::Transform2Collision,
......@@ -14,7 +14,7 @@ struct MyEcs : ecs::ecs<ecs::Components<HierarchyCollisionBoxComponent, Transfor
BillboardOrientationSystem, RenderSystem, HierarchyRenderSystem, CollisionBoxesRenderer,
AnimationInterpolator, AnimationApplier, AnimationChooser,
ControlHandlingSystem, AIHandlingSystem,
CameraHandlingSystem, LockdownSystem>>
CameraHandlingSystem, LockdownSystem, HealthSystem>>
{};
#endif // !MY_ECS_HPP_INCLUDED
\ No newline at end of file
......@@ -88,6 +88,7 @@ ecs::Entity EntityBuilder::buildPlayer(vcl::vec3 const& position, std::map<std::
{
auto& hierarchy = m_resources.AIHierarchyPool.getFreeElement().first;
auto playerEntity = buildCharacter(m_resources.standardCharacter, hierarchy, position, shaders);
m_ecs.add<CharacterDesignComponent>(playerEntity, 10.0f, 1.0f);
m_ecs.add<PlayerComponent>(playerEntity);
return playerEntity;
}
......@@ -95,8 +96,8 @@ ecs::Entity EntityBuilder::buildPlayer(vcl::vec3 const& position, std::map<std::
ecs::Entity EntityBuilder::buildAICharacter(ecs::Entity const target, vcl::vec3 const& position, std::map<std::string,GLuint>& shaders)
{
auto& hierarchy = m_resources.AIHierarchyPool.getFreeElement().first;
ecs::Entity ai = buildCharacter(m_resources.standardCharacter, hierarchy, position, shaders);
m_ecs.add<CharacterDesignComponent>(ai, 3.0f, 1.0f);
m_ecs.add<AIPlayerComponent>(ai, target);
return ai;
}
......@@ -27,5 +27,6 @@
#include "systems/camera_handling.hpp"
#include "systems/ai_handling.hpp"
#include "systems/lockdown_system.hpp"
#include "systems/health_system.hpp"
#endif // !SYSTEMS_HPP_INCLUDED
......@@ -30,13 +30,13 @@ void AIHandlingSystem::update(const MyEcs& m_ecs, const bool AIEvent, PlayerCont
const float shoot = static_cast <float> (rand()) / static_cast <float> (RAND_MAX);
const float jump = static_cast <float> (rand()) / static_cast <float> (RAND_MAX);
if (changeDirection < changeDirectionProba)
if (changeDirection < m_changeDirectionProba)
NewDirection(controls);
if (shoot < shootProba)
if (shoot < m_shootProba)
controls.currentControls[PlayerControlComponent::Control::Shoot] = true;
if (jump < jumpProba)
if (jump < m_jumpProba)
controls.currentControls[PlayerControlComponent::Control::Jump] = true;
}
......@@ -44,5 +44,7 @@ void AIHandlingSystem::update(const MyEcs& m_ecs, const bool AIEvent, PlayerCont
const vec3 verticalAxis = vec3(0, 0, 1);
vec3 targetDirection = normalize(m_ecs.get<TransformComponent>(player.target).position - transform.position);
targetDirection = normalize(targetDirection - dot(verticalAxis, targetDirection) * verticalAxis);
transform.rotation = transform.rotation * rotation_between_vector_mat3(currentAxis, targetDirection);
mat3 rot = rotation_between_vector_mat3(currentAxis, targetDirection);
rot.zz = 1.0f;
transform.rotation = transform.rotation * rot;
}
\ No newline at end of file
......@@ -17,8 +17,8 @@ public :
using UpdatePolicy = ecs::OncePerEntity;
private :
const float changeDirectionProba = .2f;
const float shootProba = 0.1f;
const float jumpProba = 0.1f;
const float m_changeDirectionProba = .2f;
const float m_shootProba = 0.1f;
const float m_jumpProba = 0.1f;
};
#endif // !SYSTEMS_AI_HANDLING_HPP_INCLUDED
......@@ -33,7 +33,7 @@ void CameraHandlingSystem::createRay(MyEcs& m_ecs, ecs::Entity const& playerEnti
{
auto toolRayEntity = m_ecs.createEntity();
vcl::ray const shootInfos = vcl::picking_ray(camera, m_cursorPosition);
auto& toolRay = m_ecs.add<RayComponent>(toolRayEntity, shootInfos.p + shootInfos.u*camera.scale ,shootInfos.u, 0.0f, playerEntity);
auto& toolRay = m_ecs.add<RayComponent>(toolRayEntity, shootInfos.p + shootInfos.u * camera.scale, shootInfos.u, 0.0f, playerEntity);// , 0.0f);
m_ecs.getSystem<RayTrajectory>().computeRayTrajectory(toolRay, m_ecs);
m_ecs.getSystem<RayTrajectory>().addDeadRay(toolRay);
......@@ -44,6 +44,6 @@ void CameraHandlingSystem::createRay(MyEcs& m_ecs, ecs::Entity const& playerEnti
float const speed = 50.0f;
vec3 const position = playerTransform.position + vec3(0, 0, 1) * 0.4;
vec3 const direction = (*toolRay.endTrajectory - position) / norm(*toolRay.endTrajectory - position);
auto& realRay = m_ecs.add<RayComponent>(realRayEntity, position, direction, speed, playerEntity);
auto& realRay = m_ecs.add<RayComponent>(realRayEntity, position, direction, speed, playerEntity, m_ecs.get<CharacterDesignComponent>(playerEntity).damage);
m_ecs.getSystem<RayTrajectory>().computeRayTrajectory(realRay, m_ecs);
}
\ No newline at end of file
......@@ -37,7 +37,6 @@ void CollisionResolver::handleOneCollision(CollisionRateMap const& collisionRate
auto aCanMove = dTransforms.has(a.entity);
auto bCanMove = dTransforms.has(b.entity);
std::cout << collisionComponentA.material << collisionComponentB.material << std::endl;
auto collisionRates = collisionRateMap.find({ collisionComponentA.material, collisionComponentB.material });
assert(collisionRates != std::end(collisionRateMap));
auto slowdownRate = collisionRates->second.bounceSlowdown;
......
#include "health_system.hpp"
#include "../my_ecs.hpp"
void HealthSystem::update(MyEcs& myEcs, RayComponent& ray)
{
if (ray.endEntity.has_value() && myEcs.has<CharacterDesignComponent>(*ray.endEntity))
{
auto& target = myEcs.get<CharacterDesignComponent>(*ray.endEntity);
target.currentHealth -= ray.damage;
ray.damage = 0;
std::cout << "Ray endEntityHealth = " << target.currentHealth << std::endl;
if (target.currentHealth <= 0)
m_deadCharacters.push_back(*ray.endEntity);
}
}
void HealthSystem::destroyDeadCharacter(MyEcs& myEcs)
{
for (auto entity = m_deadCharacters.begin(); entity != m_deadCharacters.end(); entity++)
{
myEcs.destroy(*entity);
}
m_deadCharacters.clear();
}
#ifndef SYSTEMS_HEALTH_SYSTEM_HPP_INCLUDED
#define SYSTEMS_HEALTH_SYSTEM_HPP_INCLUDED
#include "ECS.hpp"
#include "../components.hpp"
struct MyEcs;
struct HealthSystem
{
public:
void update(MyEcs& myEcs, RayComponent& ray);
void destroyDeadCharacter(MyEcs& myEcs);
using Requirements = ecs::Requirements<ecs::Auto>;
using UpdatePolicy = ecs::OncePerEntity;
private:
std::vector<ecs::Entity> m_deadCharacters;
};
#endif // !SYSTEMS_HEALTH_SYSTEM_HPP_INCLUDED
......@@ -37,7 +37,7 @@ static std::optional<vcl::vec3> getBulletImpact(RayComponent const& ray, Collisi
//Check if the ray is intersecting with the cylinder
if (std::max(z1, cylinder.center.z) > std::min(z2, cylinder.center.z + cylinder.height))
return {};
//std::cout << ray.direction << cylinder.center << ray.position << cylinder.radius << " "<< lambdaMoins << std::endl;
//Different scenarios to get the intersection point
vec3 res;
if (lambdaMoins > 0 && cylinder.center.z <= intersect1.z && intersect1.z <= cylinder.center.z + cylinder.height)
......@@ -57,10 +57,11 @@ static std::optional<vcl::vec3> getBulletImpact(RayComponent const& ray, Collisi
return res;
}
static std::optional<vcl::vec3> bulletCollisionInCell(CollisionGrid::Cell const& cell, RayComponent& ray, MyEcs const& m_ecs)
static std::pair<std::optional<vcl::vec3>,std::optional<ecs::Entity>> bulletCollisionInCell(CollisionGrid::Cell const& cell, RayComponent& ray, MyEcs const& m_ecs)
{
float distanceMin = infinity;
std::optional<vcl::vec3> rayEnd{ std::nullopt };
std::optional<ecs::Entity> endEntity{ std::nullopt };
for (auto entity = cell.begin(); entity != cell.end(); entity++)
for(size_t cylIdx = 0; cylIdx<m_ecs.get<CollisionComponent>(*entity).shape.cylinders.size(); cylIdx++)
{
......@@ -68,35 +69,37 @@ static std::optional<vcl::vec3> bulletCollisionInCell(CollisionGrid::Cell const&
auto collisionPoint = getBulletImpact(ray, cylinder);
if (*entity != ray.srcEntity && collisionPoint && norm(ray.position - collisionPoint.value()) < distanceMin)
{
//std::cout << "Shooter entity = " << ray.srcEntity << ", colliding entity = " << *entity << std::endl;
distanceMin = norm(ray.position - collisionPoint.value());
rayEnd = collisionPoint;
endEntity = *entity;
}
}
return rayEnd;
return { rayEnd, endEntity };
}
static std::optional<vcl::vec3> getBulletFirstCollision(CollisionGrid const& collisionGrid, RayComponent& ray, MyEcs const& m_ecs)
static std::pair<std::optional<vcl::vec3>, std::optional<ecs::Entity>> getBulletFirstCollision(CollisionGrid const& collisionGrid, RayComponent& ray, MyEcs const& m_ecs)
{
vec2 const positionPlan{ ray.position.x,ray.position.y };
vec2 const directionPlan{ ray.direction.x, ray.direction.y };
float distanceMin = infinity;
std::optional< vcl::vec3 > rayEnd{ std::nullopt };
std::optional<ecs::Entity> endEntity{ std::nullopt };
for(size_t xIdx=0; xIdx<collisionGrid.xSize(); xIdx++)
for (size_t yIdx = 0; yIdx < collisionGrid.ySize(); yIdx++)
{
if (collisionGrid.getBoundingBox(xIdx, yIdx).intersect(positionPlan, directionPlan))
{
auto end = bulletCollisionInCell(collisionGrid.at(xIdx * collisionGrid.ySize() + yIdx), ray, m_ecs);
if (end && norm(ray.position-end.value())<distanceMin)
auto endInfo = bulletCollisionInCell(collisionGrid.at(xIdx * collisionGrid.ySize() + yIdx), ray, m_ecs);
if (endInfo.first && norm(ray.position- endInfo.first.value())<distanceMin)
{
distanceMin = norm(ray.position - end.value());
rayEnd = end;
distanceMin = norm(ray.position - endInfo.first.value());
rayEnd = endInfo.first;
endEntity = endInfo.second;
}
}
}
return rayEnd;
return { rayEnd, endEntity };
}
static vcl::vec3 collisionByDichotomy(TerrainGeometry const& terrainGeometry, vec3 const& position, vec3 const& direction, float const step)
......@@ -148,20 +151,25 @@ void RayTrajectory::computeRayTrajectory(RayComponent& ray, MyEcs const& m_ecs)
{
auto firstEntityCollision = getBulletFirstCollision(*collisionGrid, ray, m_ecs);
auto firstGroundCollision = getBulletGroundCollision(*terrainGeometry, ray);
if (firstEntityCollision.has_value() && firstGroundCollision.has_value())
if (firstEntityCollision.first.has_value() && firstGroundCollision.has_value())
{
if (norm(*firstEntityCollision - ray.position) < norm(*firstGroundCollision - ray.position))
ray.endTrajectory = *firstEntityCollision;
if (norm(*firstEntityCollision.first - ray.position) < norm(*firstGroundCollision - ray.position))
{
ray.endTrajectory = *firstEntityCollision.first;
ray.endEntity = firstEntityCollision.second;
}
else
ray.endTrajectory = *firstGroundCollision;
}
else if (firstEntityCollision.has_value())
ray.endTrajectory = *firstEntityCollision;
else if (firstEntityCollision.first.has_value())
{
ray.endTrajectory = *firstEntityCollision.first;
ray.endEntity = firstEntityCollision.second;
}
else if (firstGroundCollision.has_value())
ray.endTrajectory = *firstGroundCollision;
else
ray.endTrajectory = ray.position + infinity * ray.direction;
std::cout << "Rayon cree, start = " << ray.position << ", end = " << *ray.endTrajectory << std::endl;
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment