#include #include "FleeNode.h" #include "Pathfinder.h" #include "BehaviourTree.h" #include "Actor.h" #include "Tilemap.h" #include "FieldOfView.h" FleeNode::FleeNode(BehaviourTreeNode* parent) : BehaviourTreeNode(parent) {} FleeNode::~FleeNode() = default; BehaviourTreeStatus FleeNode::tick(BTTick * tick) { Pathfinder::DijkstraMap dijkstra; Tilemap * map = tick->map; std::vector enemyPos; bool ishero = tick->target->is_type_of(ACT_HERO); vec2i targetpos = tick->target->get_position(); auto actors = map->get_actors(targetpos.x, targetpos.y, 6); for (Actor* actor : actors) { if (actor->is_type_of(ACT_HERO) != ishero) { vec2i pos = actor->get_position(); if (line_of_sight(map, tick->target->get_position(), pos)) { enemyPos.push_back(pos); } } } if (enemyPos.empty()) { return BT_FAILED; } Pathfinder::calc_dijkstra_map(*map, enemyPos, dijkstra, 16); dijkstra.add(-16); dijkstra.mult(-1); std::vector safety; for (int x = 0; x < dijkstra.width; x++) { for (int y = 0; y < dijkstra.height; y++) { if (dijkstra.get_value(x,y) <= 0 && dijkstra.get_value(x, y) >= -10) { safety.emplace_back(x, y); } } } Pathfinder::calc_dijkstra_map(*map, safety, dijkstra); vec2i pos = tick->target->get_position(); std::vector neigh = map->get_neighbours(pos.x, pos.y); std::vector options; float lowestval = 999999; for (vec2i npos : neigh) { float val = dijkstra.get_value(npos.x, npos.y); 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; } while (!options.empty()) { int i = rand() % options.size(); vec2i next = options[i]; vec2i dp = next - pos; if (tick->target->move(dp.x, dp.y, map)) { //printf("FLEEING val:%f\t(%i,%i)\n", lowestval, next.x, next.y); return BT_RUNNING; } options.erase(options.begin() + i); if (options.empty()) { return BT_FAILED; } } return BT_FAILED; }