SetComplete();
return;
}
- const glm::dvec3 diff(GetCreature().GetSituation().Position() - target.GetSituation().Position());
+ const glm::dvec3 diff(GetSituation().Position() - target.GetSituation().Position());
const double hit_range = GetCreature().Size() * 0.5 * GetCreature().DexertyFactor();
const double hit_dist = hit_range + (0.5 * GetCreature().Size()) + 0.5 * (target.Size());
- if (GetCreature().GetStats().Damage().Critical()) {
+ if (GetStats().Damage().Critical()) {
// flee
- GetCreature().GetSteering().Pass(diff * 5.0);
- GetCreature().GetSteering().DontSeparate();
- GetCreature().GetSteering().Haste(1.0);
+ GetSteering().Pass(diff * 5.0);
+ GetSteering().DontSeparate();
+ GetSteering().Haste(1.0);
} else if (glm::length2(diff) > hit_dist * hit_dist) {
// full throttle chase
- GetCreature().GetSteering().Pass(target.GetSituation().Position());
- GetCreature().GetSteering().DontSeparate();
- GetCreature().GetSteering().Haste(1.0);
+ GetSteering().Pass(target.GetSituation().Position());
+ GetSteering().DontSeparate();
+ GetSteering().Haste(1.0);
} else {
// attack
- GetCreature().GetSteering().Halt();
- GetCreature().GetSteering().DontSeparate();
- GetCreature().GetSteering().Haste(1.0);
+ GetSteering().Halt();
+ GetSteering().DontSeparate();
+ GetSteering().Haste(1.0);
if (cooldown <= 0.0) {
constexpr double impulse = 0.05;
const double force = GetCreature().Strength();
// TODO: derive breathing ability
int gas = Assets().data.resources["air"].id;
// TODO: check if in compatible atmosphere
- double amount = GetCreature().GetStats().Breath().gain * -(1.0 + GetCreature().ExhaustionFactor());
- GetCreature().GetStats().Breath().Add(amount * dt);
+ double amount = GetStats().Breath().gain * -(1.0 + GetCreature().ExhaustionFactor());
+ GetStats().Breath().Add(amount * dt);
// maintain ~1% gas composition
double gas_amount = GetCreature().GetComposition().Get(gas);
if (gas_amount < GetCreature().GetComposition().TotalMass() * 0.01) {
double add = std::min(GetCreature().GetComposition().TotalMass() * 0.025 - gas_amount, -amount * dt);
GetCreature().Ingest(gas, add);
}
- if (GetCreature().GetStats().Breath().Empty()) {
+ if (GetStats().Breath().Empty()) {
breathing = false;
}
}
}
void BlobBackgroundTask::CheckStats() {
- Creature::Stats &stats = GetCreature().GetStats();
+ Creature::Stats &stats = GetStats();
if (!breathing && stats.Breath().Bad()) {
breathing = true;
eat_subtask->WhenComplete([&](Goal &) { eat_subtask = nullptr; });
GetCreature().AddGoal(std::unique_ptr<Goal>(eat_subtask));
}
-
- // when in bad shape, don't make much effort
- if (stats.Damage().Bad() || stats.Exhaustion().Bad() || stats.Fatigue().Critical()) {
- GetCreature().GetSteering().DontSeparate();
- } else {
- GetCreature().GetSteering().ResumeSeparate();
- }
}
void BlobBackgroundTask::CheckSplit() {
Goal::~Goal() noexcept {
}
-Situation &Goal::GetSituation() noexcept {
- return c.GetSituation();
-}
-
-const Situation &Goal::GetSituation() const noexcept {
- return c.GetSituation();
-}
-
-Steering &Goal::GetSteering() noexcept {
- return c.GetSteering();
-}
-
-const Steering &Goal::GetSteering() const noexcept {
- return c.GetSteering();
-}
-
app::Assets &Goal::Assets() noexcept {
return c.GetSimulation().Assets();
}
}
void IdleGoal::Action() {
- // use boredom as chance per minute
- if (Random().UNorm() < GetCreature().GetStats().Boredom().value * (1.0 / 3600.0)) {
+ // when in bad shape, don't make much effort
+ if (GetStats().Damage().Bad() || GetStats().Exhaustion().Bad() || GetStats().Fatigue().Critical()) {
+ GetSteering().DontSeparate();
+ } else {
+ GetSteering().ResumeSeparate();
+ }
+
+ // use boredom as chance per 30s
+ if (Random().UNorm() < GetStats().Boredom().value * (1.0 / 1800.0)) {
PickActivity();
}
}
}
if (ingesting) {
if (OnSuitableTile() && !GetSituation().Moving()) {
- GetCreature().Ingest(resource, yield * GetCreature().GetComposition().Compatibility(resource) * dt);
- stat.Add(-1.0 * yield * dt);
+ GetCreature().Ingest(resource, yield * dt);
+ stat.Add(-1.0 * yield * GetCreature().GetComposition().Compatibility(resource) * dt);
if (stat.Empty()) {
SetComplete();
}
if (!searching) {
LocateResource();
} else {
- double dist = glm::length2(GetSituation().Position() - target_pos);
- if (dist < 0.0001) {
+ if (OnTarget()) {
searching = false;
LocateResource();
} else {
GetSteering().GoTo(target_pos);
}
}
- } else if (NearTarget()) {
+ } else if (OnTarget()) {
GetSteering().Halt();
if (!GetSituation().Moving()) {
SetComplete();
const world::Planet &planet = GetSituation().GetPlanet();
const glm::dvec3 &pos = GetSituation().Position();
const glm::dvec3 normal(planet.NormalAt(pos));
- const glm::dvec3 step_x(glm::normalize(glm::cross(normal, glm::dvec3(normal.z, normal.x, normal.y))));
- const glm::dvec3 step_y(glm::normalize(glm::cross(step_x, normal)));
+ const glm::dvec3 step_x(glm::normalize(glm::cross(normal, glm::dvec3(normal.z, normal.x, normal.y))) * (GetCreature().PerceptionOmniRange() * 0.7));
+ const glm::dvec3 step_y(glm::normalize(glm::cross(step_x, normal)) * (GetCreature().PerceptionOmniRange() * 0.7));
- constexpr int search_radius = 2;
- double rating[2 * search_radius + 1][2 * search_radius + 1] = {0};
+ const int search_radius = int(GetCreature().PerceptionRange() / (GetCreature().PerceptionOmniRange() * 0.7));
+ double rating[2 * search_radius + 1][2 * search_radius + 1];
+ std::memset(rating, '\0', (2 * search_radius + 1) * (2 * search_radius + 1) * sizeof(double));
// find close and rich field
for (int y = -search_radius; y < search_radius + 1; ++y) {
const world::TileType &type = planet.TileTypeAt(tpos);
auto yield = type.FindBestResource(accept);
if (yield != type.resources.cend()) {
- // TODO: subtract minimum yield
rating[y + search_radius][x + search_radius] = yield->ubiquity * accept.Get(yield->resource);
// penalize distance
double dist = std::max(0.125, 0.25 * glm::length2(tpos - pos));
found = false;
searching = true;
target_pos = GetSituation().Position();
- target_pos += Random().SNorm() * step_x;
- target_pos += Random().SNorm() * step_y;
+ target_pos += Random().SNorm() * 3.0 * step_x;
+ target_pos += Random().SNorm() * 3.0 * step_y;
// bias towards current heading
target_pos += GetSituation().Heading() * 1.5;
target_pos = glm::normalize(target_pos) * planet.Radius();
GetSteering().GoTo(target_pos);
}
-bool LocateResourceGoal::NearTarget() const noexcept {
+bool LocateResourceGoal::OnTarget() const noexcept {
const Situation &s = GetSituation();
- return s.OnSurface() && glm::length2(s.Position() - target_pos) < 0.5;
+ return s.OnGround() && glm::length2(s.Position() - target_pos) < 0.0001;
}