X-Git-Url: http://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fcreature%2Fgoal.cpp;h=e65a4dbf484ad743c23624c5fea28f225b9595ae;hb=628b6dfe0b4bd98bd8438f70ec686fe2df464550;hp=d72c3015be1ddbfddcc2d4936d7404154bf9828d;hpb=806a118a907a5391c135983e7d57e27def521e5b;p=blobs.git diff --git a/src/creature/goal.cpp b/src/creature/goal.cpp index d72c301..e65a4db 100644 --- a/src/creature/goal.cpp +++ b/src/creature/goal.cpp @@ -1,3 +1,4 @@ +#include "BlobBackgroundTask.hpp" #include "Goal.hpp" #include "IdleGoal.hpp" #include "LocateResourceGoal.hpp" @@ -16,6 +17,71 @@ namespace blobs { namespace creature { +BlobBackgroundTask::BlobBackgroundTask(Creature &c) +: Goal(c) { +} + +BlobBackgroundTask::~BlobBackgroundTask() { +} + +std::string BlobBackgroundTask::Describe() const { + return "being a blob"; +} + +void BlobBackgroundTask::Tick(double dt) { +} + +void BlobBackgroundTask::Action() { + // check if eligible to split + if (GetCreature().Mass() > GetCreature().GetProperties().Birth().mass * 1.8) { + double fert = GetCreature().Fertility(); + double rand = Assets().random.UNorm(); + if (fert > rand) { + std::cout << "[" << int(GetCreature().GetSimulation().Time()) + << "s] " << GetCreature().Name() << " split" << std::endl; + Split(GetCreature()); + return; + } + } + // check for random property mutation + if (GetCreature().Mutability() > Assets().random.UNorm()) { + double amount = 1.0 + (Assets().random.SNorm() * 0.05); + auto &props = GetCreature().GetGenome().properties; + double r = Assets().random.UNorm(); + math::Distribution *d = nullptr; + if (Assets().random.UNorm() < 0.5) { + auto &set = props.props[(int(Assets().random.UNorm() * 4.0) % 4) + 1]; + if (r < 0.25) { + d = &set.age; + } else if (r < 0.5) { + d = &set.mass; + } else if (r < 0.75) { + d = &set.fertility; + } else { + d = &set.highlight; + } + } else { + if (r < 0.2) { + d = &props.strength; + } else if (r < 0.4) { + d = &props.stamina; + } else if (r < 0.6) { + d = &props.dexerty; + } else if (r < 0.8) { + d = &props.intelligence; + } else { + d = &props.mutability; + } + } + if (Assets().random.UNorm() < 0.5) { + d->Mean(d->Mean() * amount); + } else { + d->StandardDeviation(d->StandardDeviation() * amount); + } + } +} + + Goal::Goal(Creature &c) : c(c) , on_complete() @@ -88,13 +154,6 @@ void IdleGoal::Tick(double dt) { } void IdleGoal::Action() { - double fert = GetCreature().Fertility(); - double rand = Assets().random.UNorm(); - if (fert > rand) { - std::cout << "[" << int(GetCreature().GetSimulation().Time()) - << "s] " << GetCreature().Name() << " split" << std::endl; - Split(GetCreature()); - } } @@ -105,7 +164,8 @@ LocateResourceGoal::LocateResourceGoal(Creature &c, int res) , target_pos(0.0) , target_srf(0) , target_tile(0) -, searching(false) { +, searching(false) +, reevaluate(0.0) { } LocateResourceGoal::~LocateResourceGoal() noexcept { @@ -116,14 +176,18 @@ std::string LocateResourceGoal::Describe() const { } void LocateResourceGoal::Enable() { - LocateResource(); + } void LocateResourceGoal::Tick(double dt) { + reevaluate -= dt; } void LocateResourceGoal::Action() { - if (!found) { + if (reevaluate < 0.0) { + LocateResource(); + reevaluate = 3.0; + } else if (!found) { if (!searching) { LocateResource(); } else { @@ -142,6 +206,7 @@ void LocateResourceGoal::Action() { } else { GetSteering().GoTo(target_pos); } + GetSteering().Haste(Urgency()); } void LocateResourceGoal::LocateResource() { @@ -175,7 +240,8 @@ void LocateResourceGoal::SearchVicinity() { glm::ivec2 begin(glm::max(glm::ivec2(0), loc - seek_radius)); glm::ivec2 end(glm::min(glm::ivec2(planet.SideLength()), loc + seek_radius + glm::ivec2(1))); - double rating[end.y - begin.y][end.x - begin.x] { 0.0 }; + double rating[end.y - begin.y][end.x - begin.x]; + std::memset(rating, 0, sizeof(double) * (end.y - begin.y) * (end.x - begin.x)) // find close and rich field for (int y = begin.y; y < end.y; ++y) { @@ -185,7 +251,7 @@ void LocateResourceGoal::SearchVicinity() { if (yield != type.resources.cend()) { // TODO: subtract minimum yield rating[y - begin.y][x - begin.x] = yield->ubiquity; - double dist = 1.0 - 0.25 * glm::length2(planet.TileCenter(srf, x, y) - pos); + double dist = std::max(0.125, 0.25 * glm::length(planet.TileCenter(srf, x, y) - pos)); rating[y - begin.y][x - begin.x] /= dist; } } @@ -228,6 +294,7 @@ void LocateResourceGoal::SearchVicinity() { target_pos[(srf + 1) % 3] += Assets().random.SNorm(); // bias towards current direction target_pos += glm::normalize(GetSituation().Velocity()) * 0.5; + target_pos = clamp(target_pos, -planet.Radius(), planet.Radius()); GetSteering().GoTo(target_pos); } }