Wire Eating + Digestion capacities to feeding (option 1)

Eating (jaw) scales graze bite and Digestion×Eating scales satiety gained from
food (plant grazing and corpse scavenging via Refill efficiency). A damaged jaw
or sick gut means less nutrition per feeding, so the animal must eat more often.
Completes wiring the new health capacities to behaviour; Talking remains an
indicator (no social system yet). Build clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Leonid Pershin
2026-06-14 14:58:10 +03:00
co-authored by Claude Opus 4.8
parent e105938a22
commit 249b603497
+22 -8
View File
@@ -877,6 +877,10 @@ public sealed class AnimalActionSystem : BaseSystem
// Способность Moving (падает от ран/болезней) — множитель к скорости: больные медленнее.
var moving = hh[i].State.Capacity(AnimalCapacities.Moving);
var speed = def.BaseSpeed * MathF.Max(0.2f, o[i].Traits.MoveSpeed) * moving;
// Питание (челюсть) масштабирует укус, пищеварение (желудок) — усвоение: их произведение
// даёт сытость с корма; раненая челюсть/больной желудок → зверь голоднее (опция 1).
var eating = hh[i].State.Capacity(AnimalCapacities.Eating);
var foodEff = eating * hh[i].State.Capacity(AnimalCapacities.Digestion);
switch (brain.Action)
{
@@ -887,8 +891,12 @@ public sealed class AnimalActionSystem : BaseSystem
case AnimalActions.Eat:
if (MoveTo(ref pos, brain.Target, speed * seconds))
{
Refill(values, AnimalActions.Eat, days);
Graze(brain.TargetPlant, days, def.ForageBiteDays);
Refill(values, AnimalActions.Eat, days, foodEff);
Graze(
brain.TargetPlant,
days,
def.ForageBiteDays * MathF.Max(0.2f, eating)
);
// Коэволюция: защита растения бьёт по поедателю (яд/шипы).
ApplyPlantDefense(
brain.TargetPlant,
@@ -940,7 +948,7 @@ public sealed class AnimalActionSystem : BaseSystem
break;
case AnimalActions.Hunt:
Hunt(ref brain, ref pos, values, def, speed * seconds, days);
Hunt(ref brain, ref pos, values, def, speed * seconds, days, foodEff);
break;
case AnimalActions.Flee:
@@ -987,7 +995,8 @@ public sealed class AnimalActionSystem : BaseSystem
float[] values,
AnimalDef def,
float step,
float days
float days,
float foodEff
)
{
if (
@@ -1018,7 +1027,7 @@ public sealed class AnimalActionSystem : BaseSystem
}
ref var corpse = ref target.GetComponent<Corpse>();
Refill(values, AnimalActions.Eat, days);
Refill(values, AnimalActions.Eat, days, foodEff);
corpse.Meat -= def.ForageBiteDays * days; // расход мяса той же «силой укуса», что и выедание
if (corpse.Meat <= 0f && !_consumed.Contains(target))
{
@@ -1065,8 +1074,9 @@ public sealed class AnimalActionSystem : BaseSystem
}
}
// Восполняет нужду, которую утоляет действие (по NeedSet), на её FeedPerDay.
private void Refill(float[] values, string action, float days)
// Восполняет нужду, которую утоляет действие (по NeedSet), на её FeedPerDay × эффективность
// (питание/пищеварение для еды — слабая челюсть/больной желудок дают меньше сытости с того же корма).
private void Refill(float[] values, string action, float days, float efficiency = 1f)
{
var index = _needs.NeedForAction(action);
if (index < 0 || values is null || index >= values.Length)
@@ -1074,7 +1084,11 @@ public sealed class AnimalActionSystem : BaseSystem
return;
}
values[index] = Math.Clamp(values[index] + _needs[index].FeedPerDay * days, 0f, 1f);
values[index] = Math.Clamp(
values[index] + _needs[index].FeedPerDay * days * efficiency,
0f,
1f
);
}
// Двигает позицию к цели на step; возвращает true, если уже у цели (можно исполнять действие).