mirror of
https://github.com/Nimac0/SDL_Minigame
synced 2026-01-12 15:53:42 +00:00
Merge 39ccdf4138cc425978469667a9aed64ad25b94d4 into 7c50c8d1fb622cfa37ba91b42e65c5afe5512443
This commit is contained in:
commit
3aebec86e2
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -17,3 +17,6 @@
|
||||
path = docs/doxygen-awesome-css
|
||||
url = https://github.com/jothepro/doxygen-awesome-css.git
|
||||
|
||||
[submodule "external/tmxlite"]
|
||||
path = external/tmxlite
|
||||
url = https://github.com/fallahn/tmxlite.git
|
||||
|
||||
73
include/InteractionComponent.h
Normal file
73
include/InteractionComponent.h
Normal file
@ -0,0 +1,73 @@
|
||||
#pragma once
|
||||
|
||||
#include "Component.h"
|
||||
#include "Entity.h"
|
||||
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
|
||||
class InteractionComponent : public Component
|
||||
{
|
||||
public:
|
||||
InteractionComponent(bool canInteract, bool isInteractable, int reach);
|
||||
~InteractionComponent();
|
||||
|
||||
void init() override;
|
||||
void update();
|
||||
|
||||
/*!
|
||||
* \brief Checks if two entities can interact with each other
|
||||
* \param interactor The source of the interaction
|
||||
* \param interactee The target of the interaction
|
||||
* \return A boolean if an interaction is possible
|
||||
*/
|
||||
bool interact(Entity* interactor, Entity* interactee);
|
||||
|
||||
/*!
|
||||
* \brief Find the closest entity the interactor could interact with
|
||||
* \param direction The direction in which the interactor is facing, the interactor can only interact with entities in the direction it is facing
|
||||
* \param interactor The initiator of the interaction
|
||||
* \param entities A list of entities
|
||||
* \return The interactable entity closest to the interactor
|
||||
*/
|
||||
Entity* getClosestInteractableEntity(Direction direction, Entity* interactor, std::vector<Entity*> entities);
|
||||
|
||||
private:
|
||||
bool canInteract;
|
||||
bool isInteractable;
|
||||
|
||||
int reach;
|
||||
|
||||
/*!
|
||||
* \brief Find the entity closest to the interactor
|
||||
* \param entities A list of entities
|
||||
* \param interactorT TransformComponent of the interactor (contains the coordinates)
|
||||
* \param direction The direction the interactor is facing
|
||||
* \return The closest entity
|
||||
*/
|
||||
Entity* findClosestEntity(std::vector<Entity*>& entities, TransformComponent& interactorT, Direction direction);
|
||||
|
||||
/*!
|
||||
* \brief Checks if an entity is in the direction the interactor faces
|
||||
* \param direction The direction the interactor is facing
|
||||
* \param interactorT TransformComponent of the interactor (contains the coordinates)
|
||||
*/
|
||||
std::function<bool(const TransformComponent&)> getDirectionalCheck(Direction direction, const TransformComponent& interactorT);
|
||||
|
||||
/*!
|
||||
* \brief Checks if entity is within reach of the interactor
|
||||
* \param interactorT TransformComponent of the interactor (contains the coordinates)
|
||||
* \param entityT TransformComponent of the entity (contains the coordinates)
|
||||
* @param direction The direction the interactor is facing
|
||||
* @return
|
||||
*/
|
||||
bool isEntityCloseEnough(const TransformComponent& interactorT, const TransformComponent& entityT, Direction direction);
|
||||
|
||||
/*!
|
||||
* \brief Calculates distance between entity and interactor
|
||||
* \param iPos Coordinates of the interactor
|
||||
* \param ePos Coordinates of the entity
|
||||
* \return The distance between interactor and entity
|
||||
*/
|
||||
float calculateDistance(Vector2D iPos, Vector2D ePos);
|
||||
};
|
||||
113
src/InteractionComponent.cpp
Normal file
113
src/InteractionComponent.cpp
Normal file
@ -0,0 +1,113 @@
|
||||
#include "InteractionComponent.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
|
||||
InteractionComponent::InteractionComponent(bool canInteract, bool isInteractable, int reach)
|
||||
: canInteract(canInteract), isInteractable(isInteractable), reach(reach) {}
|
||||
|
||||
InteractionComponent::~InteractionComponent() = default;
|
||||
|
||||
void InteractionComponent::init() {}
|
||||
|
||||
void InteractionComponent::update() {}
|
||||
|
||||
bool InteractionComponent::interact(Entity* interactor, Entity* interactee)
|
||||
{
|
||||
if(interactee == nullptr)
|
||||
return false;
|
||||
|
||||
if(!interactor->hasComponent<InteractionComponent>() || !interactor->getComponent<InteractionComponent>().canInteract)
|
||||
throw std::logic_error("Interactor entity cannot interact");
|
||||
|
||||
if(!interactee->hasComponent<InteractionComponent>() || !interactee->getComponent<InteractionComponent>().isInteractable)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Entity* InteractionComponent::getClosestInteractableEntity(Direction direction, Entity* interactor, std::vector<Entity*> entities)
|
||||
{
|
||||
entities.erase(std::remove_if(entities.begin(), entities.end(), [](Entity* e) {
|
||||
return !e->hasComponent<InteractionComponent>() || !e->getComponent<InteractionComponent>().isInteractable;
|
||||
}), entities.end());
|
||||
|
||||
if(entities.empty())
|
||||
return nullptr;
|
||||
|
||||
auto& interactorT = interactor->getComponent<TransformComponent>();
|
||||
return findClosestEntity(entities, interactorT, direction);
|
||||
}
|
||||
|
||||
Entity* InteractionComponent::findClosestEntity(std::vector<Entity*>& entities, TransformComponent& interactorT, Direction direction)
|
||||
{
|
||||
Entity* closestEntity = nullptr;
|
||||
float closestDistance = std::numeric_limits<float>::max();
|
||||
|
||||
auto isInDirection = getDirectionalCheck(direction, interactorT);
|
||||
|
||||
entities.erase(std::remove_if(entities.begin(), entities.end(), [&](Entity* e){
|
||||
auto& entityT = e->getComponent<TransformComponent>();
|
||||
return !isInDirection(entityT) || !isEntityCloseEnough(interactorT, entityT, direction);
|
||||
}), entities.end());
|
||||
|
||||
for(auto e : entities)
|
||||
{
|
||||
auto& entityT = e->getComponent<TransformComponent>();
|
||||
float distance = calculateDistance(interactorT.position, entityT.position);
|
||||
|
||||
if (distance < closestDistance) {
|
||||
closestDistance = distance;
|
||||
closestEntity = e;
|
||||
}
|
||||
}
|
||||
|
||||
return closestEntity;
|
||||
}
|
||||
|
||||
std::function<bool(const TransformComponent&)> InteractionComponent::getDirectionalCheck(Direction direction, const TransformComponent& interactorT)
|
||||
{
|
||||
switch(direction)
|
||||
{
|
||||
case Direction::LEFT:
|
||||
return[&interactorT](const TransformComponent& entityT) {
|
||||
return entityT.position.x < interactorT.position.x;
|
||||
};
|
||||
case Direction::RIGHT:
|
||||
return[&interactorT](const TransformComponent& entityT) {
|
||||
return entityT.position.x > interactorT.position.x;
|
||||
};
|
||||
case Direction::UP:
|
||||
return[&interactorT](const TransformComponent& entityT) {
|
||||
return entityT.position.y < interactorT.position.y;
|
||||
};
|
||||
case Direction::DOWN:
|
||||
return[&interactorT](const TransformComponent& entityT) {
|
||||
return entityT.position.y > interactorT.position.y;
|
||||
};
|
||||
default:
|
||||
return [](const TransformComponent&) { return false; };
|
||||
}
|
||||
}
|
||||
|
||||
bool InteractionComponent::isEntityCloseEnough(const TransformComponent& interactorT, const TransformComponent& entityT, Direction direction)
|
||||
{
|
||||
switch (direction)
|
||||
{
|
||||
case Direction::LEFT:
|
||||
return (entityT.position.x >= (interactorT.position.x - reach));
|
||||
case Direction::RIGHT:
|
||||
return (entityT.position.x <= (interactorT.position.x + reach));
|
||||
case Direction::UP:
|
||||
return (entityT.position.y >= (interactorT.position.y - reach));
|
||||
case Direction::DOWN:
|
||||
return (entityT.position.y <= (interactorT.position.y + reach));
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
float InteractionComponent::calculateDistance(Vector2D iPos, Vector2D ePos)
|
||||
{
|
||||
return std::abs(ePos.x - iPos.x) + std::abs(ePos.y - iPos.y);
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user