dungeon/src/FleeNode.cpp

84 lines
2.2 KiB
C++
Raw Normal View History

2017-09-17 20:07:38 +02:00
#include <cstdlib>
2017-09-17 13:43:13 +02:00
#include "FleeNode.h"
#include "Pathfinder.h"
#include "BehaviourTree.h"
#include "Actor.h"
#include "Tilemap.h"
#include "FieldOfView.h"
2017-09-17 13:43:13 +02:00
FleeNode::FleeNode(BehaviourTreeNode* parent) : BehaviourTreeNode(parent) {}
2017-09-26 15:49:11 +02:00
FleeNode::~FleeNode() = default;
2017-09-17 13:43:13 +02:00
BehaviourTreeStatus FleeNode::tick(BTTick * tick) {
Pathfinder::DijkstraMap dijkstra;
2018-01-09 21:59:05 +01:00
Tilemap * map = tick->map;
2017-09-17 13:43:13 +02:00
std::vector<vec2i> enemyPos;
2017-09-26 15:49:11 +02:00
bool ishero = tick->target->is_type_of(ACT_HERO);
vec2i targetpos = tick->target->get_position();
2018-01-09 21:59:05 +01:00
auto actors = map->get_actors(targetpos.x, targetpos.y, 6);
for (Actor* actor : actors) {
2017-09-26 15:49:11 +02:00
if (actor->is_type_of(ACT_HERO) != ishero) {
2017-09-21 22:44:05 +02:00
vec2i pos = actor->get_position();
2018-01-09 21:59:05 +01:00
if (line_of_sight(map, tick->target->get_position(), pos)) {
2017-09-17 13:43:13 +02:00
enemyPos.push_back(pos);
}
}
}
2017-09-26 15:49:11 +02:00
if (enemyPos.empty()) {
2017-09-17 13:43:13 +02:00
return BT_FAILED;
}
2018-01-09 21:59:05 +01:00
Pathfinder::calc_dijkstra_map(*map, enemyPos, dijkstra, 16);
2017-09-17 13:43:13 +02:00
dijkstra.add(-16);
dijkstra.mult(-1);
std::vector<vec2i> safety;
for (int x = 0; x < dijkstra.width; x++) {
for (int y = 0; y < dijkstra.height; y++) {
2018-01-09 21:59:05 +01:00
if (dijkstra.get_value(x,y) <= 0 && dijkstra.get_value(x, y) >= -10) {
2017-09-26 15:49:11 +02:00
safety.emplace_back(x, y);
2017-09-17 13:43:13 +02:00
}
}
}
2018-01-09 21:59:05 +01:00
Pathfinder::calc_dijkstra_map(*map, safety, dijkstra);
2017-09-17 13:43:13 +02:00
2017-09-21 22:44:05 +02:00
vec2i pos = tick->target->get_position();
2017-09-17 13:43:13 +02:00
std::vector<vec2i> neigh = map->get_neighbours(pos.x, pos.y);
2017-09-17 13:43:13 +02:00
std::vector<vec2i> options;
float lowestval = 999999;
2017-09-17 20:07:38 +02:00
for (vec2i npos : neigh) {
2018-01-09 21:59:05 +01:00
float val = dijkstra.get_value(npos.x, npos.y);
2017-09-17 13:43:13 +02:00
if (val < lowestval) {
lowestval = val;
options.clear();
options.push_back(npos);
}
else if (val == lowestval) {
options.push_back(npos);
}
}
if (options.size() >= 8) {
//printf("FLEEING SUCCESS\n");
return BT_FAILED;
}
2017-09-26 15:49:11 +02:00
while (!options.empty()) {
2017-09-17 13:43:13 +02:00
int i = rand() % options.size();
vec2i next = options[i];
vec2i dp = next - pos;
2018-01-09 21:59:05 +01:00
if (tick->target->move(dp.x, dp.y, map)) {
2017-09-17 13:43:13 +02:00
//printf("FLEEING val:%f\t(%i,%i)\n", lowestval, next.x, next.y);
return BT_RUNNING;
}
options.erase(options.begin() + i);
2017-09-26 15:49:11 +02:00
if (options.empty()) {
2017-09-17 13:43:13 +02:00
return BT_FAILED;
}
}
return BT_FAILED;
}