Plant–herbivore coevolution + RimWorld-style health capacities
Adds the first plant↔animal coupling beyond "herbivore eats plant": a toxin/ thorns ↔ tolerance arms race built on the existing gene + hediff engines, plus the fuller RimWorld capacity set on the health scaffold. Coevolution C1 — plant defense → poisons/injures the eater: - Plant genes GeneToxicity/GeneThorns/GenePalatability (GenomeDef + PlantSet template + PlantPhenotype); animal gene GeneToxinTolerance. - Hediff Poisoned (non-progressing; grows from eating via HealthState.Intensify, immunity heals it, overdose is lethal). - AnimalActionSystem.ApplyPlantDefense on each bite: poison dose = toxicity × (1 − tolerance); thorns → ApplyInjury (reuses predator-cluster). - Cost of defense: PlantGrowthSystem growth ×= DefenseGrowthFactor() (1 − 0.4·toxicity − 0.3·thorns) — without a cost defense would max out and coevolution would stall. - Showcase: cactus thorns, poisonous mushroom; grass starts clean so toxicity can evolve on the staple. Deer/boar get small starting tolerance. Coevolution C2 — discrimination + the other half of the arms race: - Smart foraging (reuses A7 intelligence gating): herbivores with effective intelligence ≥ tier-4 weigh plants by palatability − perceived-toxin − distance; reflex grazers (or sick animals with dropped consciousness) eat the nearest plant and risk poison. - Cost of tolerance: detox raises metabolism (need decay ×= 1 + 0.5·tolerance), closing the arms race so tolerance doesn't fix at 1. - popstats reports mean toxinTolerance and a plants line (mean toxicity/thorns/ palatability) to watch the drift. Health capacities (RimWorld parity, user-requested): - New capacities BloodFiltration/Hearing/Talking/Eating; CapacityCalc rewritten to emit only capacities the body declares (a destroyed organ still shows 0%) with the full dependency chain (blood → pumping/breathing/filtration → consciousness → moving/sight/hearing/talking/eating, digestion). - Quadruped body gains kidneys + liver (filtration), ears (hearing), jaw/tongue (eating/talking). Inspector health tab lists all of a body's capacities. Localization (ru/en) for new genes' defense line, Poisoned, and the new capacity labels. Build + --check-content clean (11 def types, 40 genes, 39 traits). Not GUI-verified (headless can't render the world scene). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
97d83606ce
commit
8807045303
@@ -30,7 +30,8 @@
|
||||
"GeneBreedingSeason": 2,
|
||||
"GeneGestationDays": 30,
|
||||
"GeneLitterSize": 1,
|
||||
"GeneHerbivory": 1.0
|
||||
"GeneHerbivory": 1.0,
|
||||
"GeneToxinTolerance": 0.1
|
||||
}
|
||||
},
|
||||
|
||||
@@ -97,7 +98,8 @@
|
||||
"GeneLitterSize": 5,
|
||||
"GeneHerbivory": 0.4,
|
||||
"GeneCarnivory": 0.2,
|
||||
"GeneOmnivory": 0.85
|
||||
"GeneOmnivory": 0.85,
|
||||
"GeneToxinTolerance": 0.25
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -7,23 +7,36 @@
|
||||
{
|
||||
"defName": "Quadruped",
|
||||
"parts": [
|
||||
{ "name": "torso", "coverage": 0.32, "maxHp": 40, "vital": true },
|
||||
{ "name": "torso", "coverage": 0.3, "maxHp": 40, "vital": true },
|
||||
{ "name": "heart", "parent": "torso", "coverage": 0.02, "maxHp": 12, "vital": true,
|
||||
"capacities": { "BloodPumping": 1.0 } },
|
||||
{ "name": "lungLeft", "parent": "torso", "coverage": 0.03, "maxHp": 12,
|
||||
"capacities": { "Breathing": 0.5 } },
|
||||
{ "name": "lungRight", "parent": "torso", "coverage": 0.03, "maxHp": 12,
|
||||
"capacities": { "Breathing": 0.5 } },
|
||||
{ "name": "liver", "parent": "torso", "coverage": 0.03, "maxHp": 14, "vital": true },
|
||||
{ "name": "liver", "parent": "torso", "coverage": 0.03, "maxHp": 14, "vital": true,
|
||||
"capacities": { "BloodFiltration": 0.4 } },
|
||||
{ "name": "kidneyLeft", "parent": "torso", "coverage": 0.02, "maxHp": 10,
|
||||
"capacities": { "BloodFiltration": 0.3 } },
|
||||
{ "name": "kidneyRight", "parent": "torso", "coverage": 0.02, "maxHp": 10,
|
||||
"capacities": { "BloodFiltration": 0.3 } },
|
||||
{ "name": "stomach", "parent": "torso", "coverage": 0.03, "maxHp": 12,
|
||||
"capacities": { "Digestion": 1.0 } },
|
||||
{ "name": "head", "coverage": 0.1, "maxHp": 25 },
|
||||
{ "name": "head", "coverage": 0.08, "maxHp": 25 },
|
||||
{ "name": "brain", "parent": "head", "coverage": 0.02, "maxHp": 12, "vital": true,
|
||||
"capacities": { "Consciousness": 1.0 } },
|
||||
{ "name": "eyeLeft", "parent": "head", "coverage": 0.015, "maxHp": 8,
|
||||
"capacities": { "Sight": 0.5 } },
|
||||
{ "name": "eyeRight", "parent": "head", "coverage": 0.015, "maxHp": 8,
|
||||
"capacities": { "Sight": 0.5 } },
|
||||
{ "name": "earLeft", "parent": "head", "coverage": 0.01, "maxHp": 8,
|
||||
"capacities": { "Hearing": 0.5 } },
|
||||
{ "name": "earRight", "parent": "head", "coverage": 0.01, "maxHp": 8,
|
||||
"capacities": { "Hearing": 0.5 } },
|
||||
{ "name": "jaw", "parent": "head", "coverage": 0.02, "maxHp": 10,
|
||||
"capacities": { "Eating": 1.0, "Talking": 0.5 } },
|
||||
{ "name": "tongue", "parent": "head", "coverage": 0.01, "maxHp": 8,
|
||||
"capacities": { "Talking": 0.5 } },
|
||||
{ "name": "legFrontLeft", "coverage": 0.08, "maxHp": 15, "capacities": { "Moving": 0.25 } },
|
||||
{ "name": "legFrontRight", "coverage": 0.08, "maxHp": 15, "capacities": { "Moving": 0.25 } },
|
||||
{ "name": "legBackLeft", "coverage": 0.08, "maxHp": 15, "capacities": { "Moving": 0.25 } },
|
||||
|
||||
@@ -46,6 +46,13 @@
|
||||
"default": 0.0, "min": 0.0, "max": 1.0, "tags": ["animal", "diet"],
|
||||
"effects": { "omnivory": "value" } },
|
||||
|
||||
// Устойчивость к растительным ядам (коэволюция): снижает дозу отравления при поедании токсичных
|
||||
// растений (effectivePoison = toxicity × (1 − toxinTolerance), см. AnimalActionSystem). Растёт под
|
||||
// давлением ядовитого корма — другая сторона гонки вооружений с GeneToxicity растений.
|
||||
{ "defName": "GeneToxinTolerance", "parent": "BaseNumericGene", "label": "gene.toxinTolerance",
|
||||
"default": 0.0, "min": 0.0, "max": 1.0, "tags": ["animal", "diet"],
|
||||
"effects": { "toxinTolerance": "value" } },
|
||||
|
||||
// Пол как локус (фаза A3): аллели {X=0, Y=1}; самка XX, самец XY. Эффекта нет — пол читается из
|
||||
// самих аллелей (наличие Y), не из выраженного значения. mutationChance 0 (X не мутирует в Y).
|
||||
// Генерация особи-основателя задаёт пол явно (XX или XY), чтобы не возник невозможный YY.
|
||||
|
||||
@@ -15,6 +15,21 @@
|
||||
"default": 0.33, "min": 0, "max": 1, "spread": 0.04, "tags": ["morphology", "color"],
|
||||
"effects": { "leafHue": "value" } },
|
||||
|
||||
// --- Защита растения (коэволюция с травоядными) ---
|
||||
// Токсичность отравляет поедателя (hediff Poisoned, тем сильнее, чем ниже его устойчивость к яду);
|
||||
// шипы наносят поедателю лёгкую травму; вкусность (palatability) — обратная привлекательность для
|
||||
// умных травоядных (избегание появится в C2). У защиты ЕСТЬ ЦЕНА: токсичность/шипы тормозят рост
|
||||
// (см. PlantGrowthSystem), иначе все растения дошли бы до максимума и коэволюция бы встала.
|
||||
{ "defName": "GeneToxicity", "parent": "BaseNumericGene", "label": "gene.toxicity",
|
||||
"default": 0.0, "min": 0.0, "max": 1.0, "tags": ["defense"],
|
||||
"effects": { "toxicity": "value" } },
|
||||
{ "defName": "GeneThorns", "parent": "BaseNumericGene", "label": "gene.thorns",
|
||||
"default": 0.0, "min": 0.0, "max": 1.0, "tags": ["defense"],
|
||||
"effects": { "thorns": "value" } },
|
||||
{ "defName": "GenePalatability", "parent": "BaseNumericGene", "label": "gene.palatability",
|
||||
"default": 1.0, "min": 0.0, "max": 1.0, "tags": ["defense"],
|
||||
"effects": { "palatability": "value" } },
|
||||
|
||||
// Производный ген: признак собирается группировкой по регэкспу — сумма всех генов-толерантностей
|
||||
// (демонстрация gsom-функций фазы G5). Собственное значение гена не используется.
|
||||
{ "defName": "GeneHardiness", "parent": "BaseNumericGene", "label": "gene.hardiness",
|
||||
|
||||
@@ -22,6 +22,16 @@
|
||||
"defName": "Bleeding", "label": "hediff.bleeding",
|
||||
"initialSeverity": 0.3, "immunityPerDay": 0.5, "bloodLossPerDay": 0.8,
|
||||
"pain": 0.25, "capMods": { "Moving": 0.92, "Consciousness": 0.95 }
|
||||
},
|
||||
|
||||
// Отравление растительным ядом (коэволюция): сама не прогрессирует (severityPerDay 0) — тяжесть
|
||||
// копится при поедании токсичных растений (HealthState.Intensify в AnimalActionSystem). Иммунитет
|
||||
// её рассасывает (~1.5 дня), но если зверь ест яд быстрее, чем выводит, тяжесть доходит до 1 → смерть.
|
||||
// Это селективное давление: ядовитый корм опасен для травоядных с низкой устойчивостью.
|
||||
{
|
||||
"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 }
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -66,7 +66,8 @@
|
||||
"optimalFertility": 0.4, "fertilityTolerance": 0.5, "vigor": 0.5,
|
||||
"lifespan": 300, "dispersalRange": 2, "reproduceInterval": 25, "selfPollination": 0.6,
|
||||
"mutationRate": 0.05, "variantChance": 0.15, "spread": 0.08,
|
||||
"fruitYield": 3, "fruitSeason": 1, "harvestAmount": 3, "leafHue": 0.5 },
|
||||
"fruitYield": 3, "fruitSeason": 1, "harvestAmount": 3, "leafHue": 0.5,
|
||||
"thorns": 0.6, "palatability": 0.5 },
|
||||
"stages": [
|
||||
{ "texture": "things/plant/seed_default", "sizeCells": 0.5, "growDays": 5, "label": "plant.stage.sprout" },
|
||||
{ "label": "plant.stage.mature" }
|
||||
@@ -81,7 +82,8 @@
|
||||
"optimalFertility": 1.6, "fertilityTolerance": 1.1, "vigor": 1.2,
|
||||
"lifespan": 25, "dispersalRange": 3, "reproduceInterval": 4, "selfPollination": 0.9,
|
||||
"mutationRate": 0.06, "variantChance": 0.2, "spread": 0.1,
|
||||
"fruitYield": 0, "fruitSeason": 1, "harvestAmount": 3, "leafHue": 0.5 },
|
||||
"fruitYield": 0, "fruitSeason": 1, "harvestAmount": 3, "leafHue": 0.5,
|
||||
"toxicity": 0.5, "palatability": 0.4 },
|
||||
"stages": [
|
||||
{ "texture": "things/plant/seed_default", "sizeCells": 0.4, "growDays": 2, "label": "plant.stage.sprout" },
|
||||
{ "label": "plant.stage.mature" }
|
||||
|
||||
Reference in New Issue
Block a user