Animal thermoregulation (insulation) + wound infection
Two health threads finished, both via the existing hediff engine in AnimalHealthSystem (now also takes Climate + the new hediff defs): - Thermoregulation revives the dead GeneInsulation. A comfort band is derived per animal: fur (insulation) widens cold tolerance but worsens heat tolerance, larger body resists cold. Outside it, Hypothermia/Heatstroke severity builds (Poisoned-pattern: Intensify zeroes immunity so it can't recover while still exposed), capacities drop, severity 1 = death; back in comfort it heals. Seasonal/climate mortality and a real cold↔heat adaptation tradeoff. - Wound infection marries the injury and disease systems: while bleeding, a chance (∝ wound severity) to contract Infection, a progressing disease fought by immunity × blood filtration — weak kidneys/liver or many wounds = worse. New hediffs Hypothermia/Heatstroke/Infection (+ru/en). Build + --check-content clean. Not GUI-verified. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
5b0cf1dd4a
commit
562e365be1
@@ -32,6 +32,29 @@
|
||||
"defName": "Poisoned", "label": "hediff.poisoned",
|
||||
"initialSeverity": 0.0, "immunityPerDay": 0.65, "lethalSeverity": 1.0, "pain": 0.2,
|
||||
"capMods": { "Moving": 0.85, "Consciousness": 0.9, "Digestion": 0.7 }
|
||||
},
|
||||
|
||||
// Терморегуляция (как Poisoned-паттерн): сами не прогрессируют — тяжесть копится, пока зверю
|
||||
// холодно/жарко (см. AnimalHealthSystem, зависит от GeneInsulation + размера тела), а в комфорте
|
||||
// immunityPerDay их рассасывает. Тяжесть 1 = смерть от переохлаждения/перегрева.
|
||||
{
|
||||
"defName": "Hypothermia", "label": "hediff.hypothermia",
|
||||
"initialSeverity": 0.0, "immunityPerDay": 0.5, "lethalSeverity": 1.0, "pain": 0.15,
|
||||
"capMods": { "Moving": 0.7, "Consciousness": 0.8 }
|
||||
},
|
||||
{
|
||||
"defName": "Heatstroke", "label": "hediff.heatstroke",
|
||||
"initialSeverity": 0.0, "immunityPerDay": 0.5, "lethalSeverity": 1.0, "pain": 0.15,
|
||||
"capMods": { "Moving": 0.75, "Consciousness": 0.8 }
|
||||
},
|
||||
|
||||
// Заражение раны (предатор/шипы → кровотечение → инфекция): прогрессирует, иммунитет (× фильтрация
|
||||
// крови) душит. Слабая фильтрация/много ран → выше риск и хуже исход.
|
||||
{
|
||||
"defName": "Infection", "label": "hediff.infection",
|
||||
"initialSeverity": 0.08, "severityPerDay": 0.2, "immunityPerDay": 0.28,
|
||||
"lethalSeverity": 1.0, "pain": 0.25,
|
||||
"capMods": { "Moving": 0.8, "Consciousness": 0.85, "BloodFiltration": 0.8 }
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -73,6 +73,9 @@
|
||||
"hediff.fever": "fever",
|
||||
"hediff.bleeding": "bleeding",
|
||||
"hediff.poisoned": "poisoned",
|
||||
"hediff.hypothermia": "hypothermia",
|
||||
"hediff.heatstroke": "heatstroke",
|
||||
"hediff.infection": "infection",
|
||||
"inspect.hint": "LMB — select · RMB/Esc — clear",
|
||||
"hud.paused": "PAUSED",
|
||||
"menu.title": "LittleSim",
|
||||
|
||||
@@ -73,6 +73,9 @@
|
||||
"hediff.fever": "лихорадка",
|
||||
"hediff.bleeding": "кровотечение",
|
||||
"hediff.poisoned": "отравление",
|
||||
"hediff.hypothermia": "переохлаждение",
|
||||
"hediff.heatstroke": "тепловой удар",
|
||||
"hediff.infection": "заражение",
|
||||
"inspect.hint": "ЛКМ — выбрать · ПКМ/Esc — снять",
|
||||
"hud.paused": "ПАУЗА",
|
||||
"menu.title": "LittleSim",
|
||||
|
||||
@@ -242,7 +242,11 @@ public sealed class WorldScene : Scene
|
||||
CellSize,
|
||||
Context.Clock,
|
||||
SecondsPerDay,
|
||||
climate,
|
||||
content.Defs.All<HediffDef>().Where(h => h.AmbientPerDay > 0f).ToArray(),
|
||||
content.Defs.TryGet<HediffDef>("Hypothermia", out var hypo) ? hypo : null,
|
||||
content.Defs.TryGet<HediffDef>("Heatstroke", out var heat) ? heat : null,
|
||||
content.Defs.TryGet<HediffDef>("Infection", out var infe) ? infe : null,
|
||||
_config.Seed + 0x3EAD
|
||||
)
|
||||
);
|
||||
|
||||
@@ -1833,7 +1833,11 @@ public sealed class AnimalHealthSystem : BaseSystem
|
||||
private readonly int _cellSize;
|
||||
private readonly GameClock _clock;
|
||||
private readonly float _secondsPerDay;
|
||||
private readonly Climate _climate;
|
||||
private readonly HediffDef[] _ambient;
|
||||
private readonly HediffDef? _hypothermia;
|
||||
private readonly HediffDef? _heatstroke;
|
||||
private readonly HediffDef? _infection;
|
||||
private readonly Random _rng;
|
||||
private readonly ArchetypeQuery<Health, AnimalOrganism, AnimalGrowth> _query;
|
||||
private readonly List<Entity> _deaths = [];
|
||||
@@ -1844,13 +1848,28 @@ public sealed class AnimalHealthSystem : BaseSystem
|
||||
private const float SenescenceStart = 0.6f;
|
||||
private const float SenescenceMax = 0.45f;
|
||||
|
||||
// Термокомфорт (°C) при теплоизоляции 0.5 и размере тела 1; границы сдвигаются мехом и размером тела.
|
||||
private const float ColdComfort = 2f; // ниже — мёрзнет
|
||||
private const float HeatComfort = 30f; // выше — перегревается
|
||||
private const float ColdInsulationBonus = 30f; // мех (insulation 0..1) расширяет холодоустойчивость
|
||||
private const float HeatInsulationPenalty = 14f; // тот же мех ухудшает жароустойчивость
|
||||
private const float ColdBodyBonus = 8f; // крупное тело (тепловая инерция) держит холод лучше
|
||||
private const float ThermalRatePerDegree = 0.06f; // прирост тяжести за °C за пределом комфорта в день
|
||||
|
||||
// Заражение раны: шанс в день при кровотечении тяжести 1 подхватить инфекцию.
|
||||
private const float InfectionChancePerDay = 0.25f;
|
||||
|
||||
public AnimalHealthSystem(
|
||||
EntityStore store,
|
||||
AnimalSet animals,
|
||||
int cellSize,
|
||||
GameClock clock,
|
||||
float secondsPerDay,
|
||||
Climate climate,
|
||||
HediffDef[] ambient,
|
||||
HediffDef? hypothermia,
|
||||
HediffDef? heatstroke,
|
||||
HediffDef? infection,
|
||||
int seed
|
||||
)
|
||||
{
|
||||
@@ -1859,7 +1878,11 @@ public sealed class AnimalHealthSystem : BaseSystem
|
||||
_cellSize = cellSize;
|
||||
_clock = clock;
|
||||
_secondsPerDay = secondsPerDay;
|
||||
_climate = climate;
|
||||
_ambient = ambient;
|
||||
_hypothermia = hypothermia;
|
||||
_heatstroke = heatstroke;
|
||||
_infection = infection;
|
||||
_rng = new Random(seed);
|
||||
_query = store.Query<Health, AnimalOrganism, AnimalGrowth>();
|
||||
}
|
||||
@@ -1912,8 +1935,48 @@ public sealed class AnimalHealthSystem : BaseSystem
|
||||
}
|
||||
}
|
||||
|
||||
// Терморегуляция: вне комфорта (зависит от GeneInsulation + размера тела) копится тяжесть
|
||||
// гипотермии/теплового удара; в комфорте immunityPerDay их рассасывает. Мех расширяет
|
||||
// холодоустойчивость, но ухудшает жароустойчивость; крупное тело держит холод.
|
||||
var insul = Math.Clamp(o[i].Traits.Insulation, 0f, 1f);
|
||||
var coldLimit =
|
||||
ColdComfort
|
||||
- ColdInsulationBonus * insul
|
||||
- ColdBodyBonus * MathF.Max(0f, o[i].Traits.BodySize - 1f);
|
||||
var heatLimit = HeatComfort - HeatInsulationPenalty * insul;
|
||||
var temp = _climate.Temperature;
|
||||
if (temp < coldLimit && _hypothermia is not null)
|
||||
{
|
||||
state.Intensify(_hypothermia, (coldLimit - temp) * ThermalRatePerDegree * days);
|
||||
}
|
||||
else if (temp > heatLimit && _heatstroke is not null)
|
||||
{
|
||||
state.Intensify(_heatstroke, (temp - heatLimit) * ThermalRatePerDegree * days);
|
||||
}
|
||||
|
||||
// Заражение раны: пока есть кровотечение, шанс (∝ его тяжести) подхватить инфекцию.
|
||||
if (_infection is not null && !state.Has(_infection.DefName))
|
||||
{
|
||||
var bleedSeverity = 0f;
|
||||
foreach (var hd in state.Hediffs)
|
||||
{
|
||||
if (hd.Def.BloodLossPerDay > 0f && hd.Severity > bleedSeverity)
|
||||
{
|
||||
bleedSeverity = hd.Severity;
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
bleedSeverity > 0f
|
||||
&& _rng.NextSingle() < InfectionChancePerDay * bleedSeverity * days
|
||||
)
|
||||
{
|
||||
state.Add(_infection);
|
||||
}
|
||||
}
|
||||
|
||||
// Фильтрация крови (почки/печень) ускоряет вывод токсинов и набор иммунитета: повреждённый
|
||||
// орган → медленнее выздоровление от яда/болезни (для тела без неё Capacity вернёт 1).
|
||||
// орган → медленнее выздоровление от яда/болезни/инфекции (для тела без неё Capacity вернёт 1).
|
||||
var lethal = state.AdvanceHediffs(
|
||||
days,
|
||||
state.Capacity(AnimalCapacities.BloodFiltration)
|
||||
|
||||
Reference in New Issue
Block a user