forked from Dzejrou/tdt
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCombatSystem.hpp
More file actions
211 lines (189 loc) · 6.9 KB
/
Copy pathCombatSystem.hpp
File metadata and controls
211 lines (189 loc) · 6.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
#pragma once
#include <Ogre.h>
#include <tuple>
#include <cstdlib>
#include <bitset>
#include <map>
#include <string>
#include "System.hpp"
#include "Components.hpp"
#include "EntitySystem.hpp"
#include "HealthHelper.hpp"
#include "CombatHelper.hpp"
#include "GraphicsHelper.hpp"
#include "GridSystem.hpp"
#include "Util.hpp"
#include "RayCaster.hpp"
/**
* Used for entity container filtering, this represents the entity
* component list. (Allows to iterate over all entities in the get entity
* methods.)
*/
using ALL_COMPONENTS = std::bitset<Component::count>;
/**
* Manages auto attack melee and ranged combat, special melee and ranged attacks will be
* both handled by the spellcasting system.
*/
class CombatSystem : public System
{
public:
/**
* Constructor.
* Param: Reference to the game's entity system (component retrieval).
* Param: Reference to the main scene manager (ray casting).
* Param: Reference to the game's grid system (accessibility).
*/
CombatSystem(EntitySystem&, Ogre::SceneManager&, GridSystem&);
/**
* Destructor.
*/
~CombatSystem() {}
/**
* Brief: Updates all auto attack combat in the game currently in progress.
* Param: Time since the last frame.
*/
void update(Ogre::Real) override;
/**
* Brief: Returns true if two given entities can see each other,
* false otherwise. Tests polygons.
* Param: ID of the first entity.
* Param: ID of the second entity.
* NOTE: Tests only if entities that have query flags of WALL or BUILDING
* are in the way, allows to see through other friendly/enemy/neutral
* entities.
*/
bool in_sight(std::size_t, std::size_t) const;
/**
* Brief: Returns true if two given entities can see each other,
* false otherwise. Tests only bounding boxes.
* Param: ID of the first entity.
* Param: ID of the second entity.
* NOTE: Tests only if entities that have query flags of WALL or BUILDING
* are in the way, allows to see through other friendly/enemy/neutral
* entities.
*/
bool in_sight_wrt_BB(std::size_t, std::size_t) const;
/**
* Brief: Returns the ID of the closest entity (from a given entity's
* position), Component::NO_ENTITY otherwise.
* Param: ID of the entity from whose position the search is performed.
* Param: If true, will return only entities in sight.
* Param: If true, will return only friendly entities (enemies otherwise).
*/
std::size_t get_closest_entity(std::size_t,bool = true, bool = false) const;
/**
* Brief: Returns the ID of the closest gold deposit (entity with both structure
* and gold components).
* Param: ID of the entity that looks for the gold deposit.
* Param: If true, only deposits in sight will be checked.
*/
std::size_t get_closest_gold_deposit(std::size_t, bool = false) const;
/**
* Brief: Returns the ID of the closest gold vault that can store player's gold.
* Param: ID of the entity that looks for the gold vault.
* Param: If true, only vaults in sight will be checked.
* Param: If true, only vaults that have free space for more gold will be checked.
*/
std::size_t get_closest_gold_vault(std::size_t, bool = false, bool = false) const;
/**
* Brief: Returns the ID of the closest entity that has a given component, meets
* a given condition and is accessible.
* Param: ID of the entity that is searching.
* Param: Functor representing the condition.
* Param: If true, only entities in sight get checked.
* Note: The explicit template specialization determines over which component container
* this method will iterate, use a component name for a specific components only
* or ALL_COMPONENTS for the component bitset map (which allows to iterate over
* all entitites regardless of their components).
*/
template<typename CONT, typename COND>
std::size_t get_closest_entity(std::size_t id, COND& condition, bool only_sight = true) const
{
auto phys_comp = entities_.get_component<PhysicsComponent>(id);
std::size_t closest_id = Component::NO_ENTITY;
Ogre::Real min_distance = std::numeric_limits<Ogre::Real>::max();
if(phys_comp)
{
for(auto& ent : get_container<CONT>())
{
if(ent.first == id || !condition(ent.first))
continue;
auto enemy_phys_comp = entities_.get_component<PhysicsComponent>(ent.first);
if(enemy_phys_comp)
{
auto dist = phys_comp->position.squaredDistance(enemy_phys_comp->position);
if(enemy_phys_comp && dist < min_distance && (!only_sight || in_sight(id, ent.first))
&& util::pathfind(entities_, id, ent.first, util::heuristic::MANHATTAN_DISTANCE{entities_}, false))
{
min_distance = dist;
closest_id = ent.first;
}
}
}
}
return closest_id;
}
/**
* Brief: Tries to find a path used by an entity to run away from another entity.
* Param: ID of the entity running away.
* Param: ID of the entity that is ran away from.
* Param: Minimal amount of nodes the path has to have (will be ignored if the amount
* of attempts surpasses the maximum amount).
*/
void run_away_from(std::size_t, std::size_t, std::size_t);
/**
* Brief: Sets the maximum amount of pathfinding attempts for running away.
* Param: The new maximum amount.
*/
void set_max_run_away_attempts(std::size_t);
/**
* Brief: Returns the maximum amount of pathfinding attempts for running away.
*/
std::size_t get_max_run_away_attempts();
private:
/**
* Brief: Retuns a map containing pairs of IDs and components of a given type, use
* the type ALL_COMPONENTS to get the <ID, component bitset> container.
*/
template<typename COMP>
const std::map<std::size_t, COMP>& get_container() const
{
return entities_.get_component_container<COMP>();
}
/**
* Brief: Creates a new homing projectile at the position of a given entity
* homing at the entity's current target.
* Param: ID of the caster entity.
* Param: Reference to the caster entity's combat component.
*/
void create_homing_projectile(std::size_t, CombatComponent&);
/**
* Reference to the game's entity system (component retrieval).
*/
EntitySystem& entities_;
/**
* Reference to the ray cast used to check if two entities can see each other.
*/
Ogre::RaySceneQuery& ray_query_;
/**
* Used to check if an entity is accessible.
*/
GridSystem& grid_;
/**
* Used for polygon precise line of sight checking.
*/
RayCaster ray_caster_;
/**
* Maximum amount of pathfindings performed when running away from an enemy.
*/
std::size_t max_run_away_attempts_{10};
};
/**
* Brief: Specific case of the get_container method, which returns the map containing
* <ID, component bitset> map containing all entities.
*/
template<>
inline const std::map<std::size_t, ALL_COMPONENTS>& CombatSystem::get_container() const
{
return entities_.get_component_list();
}