2 #include "LocateResourceGoal.hpp"
4 #include "Creature.hpp"
5 #include "../world/Planet.hpp"
6 #include "../world/TileType.hpp"
17 Goal::~Goal() noexcept {
21 LocateResourceGoal::LocateResourceGoal(int res)
25 LocateResourceGoal::~LocateResourceGoal() noexcept {
28 void LocateResourceGoal::Enable(Creature &c) {
31 void LocateResourceGoal::Tick(double dt) {
34 void LocateResourceGoal::Action(Creature &c) {
35 if (c.GetSituation().OnSurface()) {
36 const world::TileType &t = c.GetSituation().GetTileType();
37 auto yield = t.FindResource(res);
38 if (yield != t.resources.cend()) {
40 c.GetSteering().Halt();
43 // go find somewhere else
44 const world::Planet &planet = c.GetSituation().GetPlanet();
45 double side_length = planet.SideLength();
46 double offset = side_length * 0.5;
47 glm::ivec2 loc = glm::ivec2(c.GetSituation().Position() + offset);
48 glm::ivec2 seek_radius(2);
49 glm::ivec2 begin(glm::max(glm::ivec2(0), loc - seek_radius));
50 glm::ivec2 end(glm::min(glm::ivec2(side_length), loc + seek_radius));
51 const world::TileType::Yield *best = nullptr;
53 double best_distance = 2 * side_length * side_length;
54 for (int y = begin.y; y < end.y; ++y) {
55 for (int x = begin.x; x < end.x; ++x) {
56 const world::TileType &type = planet.TypeAt(c.GetSituation().Surface(), x, y);
57 auto yield = type.FindResource(res);
58 if (yield != type.resources.cend()) {
59 double dist = glm::length2(glm::dvec3(x - offset + 0.5, y - offset + 0.5, 0.0) - c.GetSituation().Position());
62 best_pos = glm::ivec2(x, y);
64 } else if (yield->ubiquity + (dist * 0.125) > best->ubiquity + (best_distance * 0.125)) {
66 best_pos = glm::ivec2(x, y);
73 c.GetSteering().GoTo(glm::dvec3(best_pos.x - offset + 0.5, best_pos.y - offset + 0.5, 0.0));