X-Git-Url: http://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fcreature%2Fgoal.cpp;h=9000bc2dc10a61ba59776c033bd24a6a1ca3083d;hb=8370e531bf7d0ec860a69591ead1e0833e65998f;hp=95a3426d986419b8e0e1459fca9cc5d442c083ca;hpb=da5e275f10252813b4de3af5e58f0c7975468962;p=blobs.git diff --git a/src/creature/goal.cpp b/src/creature/goal.cpp index 95a3426..9000bc2 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" @@ -9,6 +10,7 @@ #include "../world/Simulation.hpp" #include "../world/TileType.hpp" +#include #include #include @@ -16,6 +18,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 +155,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()); - } } @@ -147,6 +207,7 @@ void LocateResourceGoal::Action() { } else { GetSteering().GoTo(target_pos); } + GetSteering().Haste(Urgency()); } void LocateResourceGoal::LocateResource() { @@ -180,7 +241,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) { @@ -190,7 +252,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; } } @@ -233,6 +295,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); } }