Wire health capacities to behaviour: filtration→immunity, sight/hearing→perception

The expanded capacities were mostly display-only; make two of them affect the
simulation (Moving→speed and Consciousness→intelligence gating already existed):

- Blood filtration → toxin/disease clearance: AdvanceHediffs takes an immunity
  scale (default 1); AnimalHealthSystem passes the BloodFiltration capacity, so
  damaged kidneys/liver clear Poisoned and diseases slower (RimWorld model).
  Ties the new capacities to the coevolution work — weak filtration makes toxic
  plants deadlier.
- Sight/hearing → perception radius: foraging, hunting and mate search scale by
  Sight; threat detection (flee) scales by max(Sight, Hearing) — you see or hear
  a predator. Injured eyes/ears shrink awareness.

Eating/Talking/Digestion remain indicators for now. Build + --check-content
clean. Not GUI-verified.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Leonid Pershin
2026-06-14 14:18:35 +03:00
co-authored by Claude Opus 4.8
parent 8807045303
commit e105938a22
2 changed files with 24 additions and 13 deletions
+20 -11
View File
@@ -330,20 +330,24 @@ public sealed class AnimalDecisionSystem : BaseSystem
brain.DecideIn = Interval + _rng.NextSingle() * Interval; // джиттер — расфазировать скан
var pos = t[i].Position;
var adult = AnimalFactory.IsAdult(_animalSet[o[i].Species], gr[i].Stage);
var radius = VisionRadius(o[i].Species, o[i].Traits.Vision);
var self = entities.EntityAt(i);
var health = self.GetComponent<Health>().State;
// Эффективный интеллект (мозг × сознание) гейтит доступные нужды/действия (фаза A7):
// больной/раненый зверь с упавшим сознанием теряет высшие нужды (сон/секс) → рефлексы.
var intelligence = AnimalFactory.Intelligence(
o[i].Traits,
self.GetComponent<Health>().State
);
var intelligence = AnimalFactory.Intelligence(o[i].Traits, health);
// Радиус восприятия по способностям: зрение ищет корм/партнёра/добычу, угрозу замечаем
// зрением ИЛИ слухом (повреждённые глаза/уши сужают восприятие).
var baseRadius = VisionRadius(o[i].Species, o[i].Traits.Vision);
var sight = health?.Capacity(AnimalCapacities.Sight) ?? 1f;
var hearing = health?.Capacity(AnimalCapacities.Hearing) ?? 1f;
var seeRadius = baseRadius * MathF.Max(0.2f, sight);
var senseRadius = baseRadius * MathF.Max(0.2f, MathF.Max(sight, hearing));
// Настроение (A8): стресс/истощение (низкое настроение) подавляет тягу к спариванию.
var mood = self.GetComponent<Mood>();
// Бегство (предатор-кластер): жертва, заметившая рядом хищника, спасается — это важнее
// любых нужд (инстинкт выживания). Сам хищник от добычи не бежит (см. IsThreatTo).
if (TryFindThreat(pos, radius, o[i].Species, o[i].Traits, out var threatPos))
if (TryFindThreat(pos, senseRadius, o[i].Species, o[i].Traits, out var threatPos))
{
brain.Action = AnimalActions.Flee;
brain.TargetPlant = -1;
@@ -352,7 +356,7 @@ public sealed class AnimalDecisionSystem : BaseSystem
var len = away.Length();
brain.Target =
len > 0.001f
? pos + away / len * (radius + _cellSize)
? pos + away / len * (senseRadius + _cellSize)
: pos + new Vector2(_cellSize, 0f);
continue;
}
@@ -372,7 +376,7 @@ public sealed class AnimalDecisionSystem : BaseSystem
when eatsMeat
&& TryFindKill(
pos,
radius,
seeRadius,
o[i].Species,
o[i].Traits,
self.Id,
@@ -390,7 +394,7 @@ public sealed class AnimalDecisionSystem : BaseSystem
when eatsPlants
&& TryFindForage(
pos,
radius,
seeRadius,
intelligence,
o[i].Traits.ToxinTolerance,
out var plant,
@@ -415,7 +419,7 @@ public sealed class AnimalDecisionSystem : BaseSystem
&& TryFindMate(
pos,
o[i].IsMale,
radius,
seeRadius,
out var mateId,
out var matePos
):
@@ -1760,7 +1764,12 @@ public sealed class AnimalHealthSystem : BaseSystem
}
}
var lethal = state.AdvanceHediffs(days);
// Фильтрация крови (почки/печень) ускоряет вывод токсинов и набор иммунитета: повреждённый
// орган → медленнее выздоровление от яда/болезни (для тела без неё Capacity вернёт 1).
var lethal = state.AdvanceHediffs(
days,
state.Capacity(AnimalCapacities.BloodFiltration)
);
// Кровопотеря от ран (кровотечения), иначе — постепенное восстановление крови в покое.
var bleed = 0f;
foreach (var hd in state.Hediffs)