From 70e79a5c30553d6fcd9df16b1f41d1b7ed9b3d54 Mon Sep 17 00:00:00 2001 From: Leonid Pershin Date: Sun, 14 Jun 2026 23:55:56 +0300 Subject: [PATCH] Senses stage 1: smell/touch capacities, organs, acuity + detectability genes Foundation for the perception system. Adds Smell and Touch capacities (CapacityCalc dependency chain x consciousness) with organs on the Quadruped body (nose->Smell, skin->Touch; eyes/ears already give Sight/Hearing) so hediffs and organ damage reduce them for free. New genes: acuity GeneHearing/GeneSmell/GeneTouch (radius multipliers, default 1 if a species omits them) and detectability GeneCamouflage (lower sight), GeneScent (raise smell), GeneNoise (raise hearing) on AnimalPhenotype. Deer/wolf/boar/chicken get sensible values (wolf smells well, deer is alert + dappled). cap.smell/cap.touch localized. Build + --check-content clean (48 genes, 47 traits). Multi-sense detection + memory come next. Co-Authored-By: Claude Opus 4.8 --- Mods/Core/Defs/Animals/Animals.json | 24 ++++++++++++++++++++++++ Mods/Core/Defs/Bodies/Bodies.json | 4 ++++ Mods/Core/Defs/Genes/Animal.json | 23 +++++++++++++++++++++++ Mods/Core/Languages/en/ui.json | 2 ++ Mods/Core/Languages/ru/ui.json | 2 ++ src/LittleSim/Sim/AnimalOrganism.cs | 26 ++++++++++++++++++++++++++ src/LittleSim/Sim/CapacityCalc.cs | 6 ++++++ 7 files changed, 87 insertions(+) diff --git a/Mods/Core/Defs/Animals/Animals.json b/Mods/Core/Defs/Animals/Animals.json index c2ce0ed..f6323d8 100644 --- a/Mods/Core/Defs/Animals/Animals.json +++ b/Mods/Core/Defs/Animals/Animals.json @@ -23,6 +23,12 @@ "GeneMoveSpeed": 1.2, "GeneBloodVolume": 1.4, "GeneVision": 1.3, + "GeneHearing": 1.4, + "GeneSmell": 1.2, + "GeneTouch": 1.0, + "GeneCamouflage": 0.35, + "GeneScent": 0.5, + "GeneNoise": 0.4, "GeneBrainSize": 0.45, "GeneInsulation": 0.55, "GeneFurColor": 0.45, @@ -59,6 +65,12 @@ "GeneMoveSpeed": 1.4, "GeneBloodVolume": 1.3, "GeneVision": 1.5, + "GeneHearing": 1.5, + "GeneSmell": 1.8, + "GeneTouch": 1.0, + "GeneCamouflage": 0.2, + "GeneScent": 0.6, + "GeneNoise": 0.5, "GeneBrainSize": 0.5, "GeneInsulation": 0.6, "GeneFurColor": 0.7, @@ -93,6 +105,12 @@ "GeneMoveSpeed": 1.0, "GeneBloodVolume": 1.2, "GeneVision": 1.0, + "GeneHearing": 1.2, + "GeneSmell": 1.6, + "GeneTouch": 1.0, + "GeneCamouflage": 0.2, + "GeneScent": 0.7, + "GeneNoise": 0.7, "GeneBrainSize": 0.42, "GeneInsulation": 0.5, "GeneFurColor": 0.85, @@ -126,6 +144,12 @@ "GeneMoveSpeed": 0.9, "GeneBloodVolume": 0.7, "GeneVision": 1.1, + "GeneHearing": 1.0, + "GeneSmell": 0.6, + "GeneTouch": 1.0, + "GeneCamouflage": 0.2, + "GeneScent": 0.4, + "GeneNoise": 0.6, "GeneBrainSize": 0.3, "GeneInsulation": 0.45, "GeneFurColor": 0.6, diff --git a/Mods/Core/Defs/Bodies/Bodies.json b/Mods/Core/Defs/Bodies/Bodies.json index c688659..ab1d939 100644 --- a/Mods/Core/Defs/Bodies/Bodies.json +++ b/Mods/Core/Defs/Bodies/Bodies.json @@ -33,6 +33,10 @@ "capacities": { "Hearing": 0.5 } }, { "name": "earRight", "parent": "head", "coverage": 0.01, "maxHp": 8, "capacities": { "Hearing": 0.5 } }, + { "name": "nose", "parent": "head", "coverage": 0.01, "maxHp": 8, + "capacities": { "Smell": 1.0 } }, + { "name": "skin", "coverage": 0.05, "maxHp": 20, + "capacities": { "Touch": 1.0 } }, { "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, diff --git a/Mods/Core/Defs/Genes/Animal.json b/Mods/Core/Defs/Genes/Animal.json index 31dc673..869122d 100644 --- a/Mods/Core/Defs/Genes/Animal.json +++ b/Mods/Core/Defs/Genes/Animal.json @@ -18,6 +18,29 @@ { "defName": "GeneVision", "parent": "BaseNumericGene", "label": "gene.vision", "default": 1.0, "min": 0.2, "max": 3.0, "tags": ["animal", "senses"], "effects": { "vision": "value" } }, + + // --- Чувства (острота = множитель радиуса восприятия) и заметность (как видят/слышат/чуют ЭТУ особь) --- + // Острота работает вместе со способностью органа (глаза/уши/нос/кожа): ген × capacity × радиус чувства. + { "defName": "GeneHearing", "parent": "BaseNumericGene", "label": "gene.hearing", + "default": 1.0, "min": 0.2, "max": 3.0, "tags": ["animal", "senses"], + "effects": { "hearing": "value" } }, + { "defName": "GeneSmell", "parent": "BaseNumericGene", "label": "gene.smell", + "default": 1.0, "min": 0.2, "max": 3.0, "tags": ["animal", "senses"], + "effects": { "smell": "value" } }, + { "defName": "GeneTouch", "parent": "BaseNumericGene", "label": "gene.touch", + "default": 1.0, "min": 0.2, "max": 3.0, "tags": ["animal", "senses"], + "effects": { "touch": "value" } }, + // Заметность цели: камуфляж снижает обнаружение зрением (1−camouflage), запах повышает обонянием, + // шум при движении повышает обнаружение слухом. См. формулу радиуса в системе восприятия. + { "defName": "GeneCamouflage", "parent": "BaseNumericGene", "label": "gene.camouflage", + "default": 0.0, "min": 0.0, "max": 1.0, "tags": ["animal", "stealth"], + "effects": { "camouflage": "value" } }, + { "defName": "GeneScent", "parent": "BaseNumericGene", "label": "gene.scent", + "default": 0.5, "min": 0.0, "max": 1.0, "tags": ["animal", "stealth"], + "effects": { "scent": "value" } }, + { "defName": "GeneNoise", "parent": "BaseNumericGene", "label": "gene.noise", + "default": 0.5, "min": 0.0, "max": 1.0, "tags": ["animal", "stealth"], + "effects": { "noise": "value" } }, { "defName": "GeneBrainSize", "parent": "BaseNumericGene", "label": "gene.brainSize", "default": 0.45, "min": 0.0, "max": 1.0, "spread": 0.03, "tags": ["animal", "brain"], "effects": { "brainSize": "value" } }, diff --git a/Mods/Core/Languages/en/ui.json b/Mods/Core/Languages/en/ui.json index 85fe1ce..80d01bd 100644 --- a/Mods/Core/Languages/en/ui.json +++ b/Mods/Core/Languages/en/ui.json @@ -70,6 +70,8 @@ "cap.moving": "moving", "cap.sight": "sight", "cap.hearing": "hearing", + "cap.smell": "smell", + "cap.touch": "touch", "cap.talking": "talking", "cap.eating": "eating", "cap.breathing": "breathing", diff --git a/Mods/Core/Languages/ru/ui.json b/Mods/Core/Languages/ru/ui.json index fbe410d..6e4652e 100644 --- a/Mods/Core/Languages/ru/ui.json +++ b/Mods/Core/Languages/ru/ui.json @@ -70,6 +70,8 @@ "cap.moving": "движение", "cap.sight": "зрение", "cap.hearing": "слух", + "cap.smell": "обоняние", + "cap.touch": "осязание", "cap.talking": "речь", "cap.eating": "питание", "cap.breathing": "дыхание", diff --git a/src/LittleSim/Sim/AnimalOrganism.cs b/src/LittleSim/Sim/AnimalOrganism.cs index 2a53ad3..065d5fb 100644 --- a/src/LittleSim/Sim/AnimalOrganism.cs +++ b/src/LittleSim/Sim/AnimalOrganism.cs @@ -27,6 +27,24 @@ public struct AnimalPhenotype /// Дальность зрения (множитель радиуса поиска). public float Vision; + /// Острота слуха (множитель радиуса). + public float Hearing; + + /// Острота обоняния (множитель радиуса). + public float Smell; + + /// Острота осязания (множитель радиуса; чувство ближнего контакта). + public float Touch; + + /// Камуфляж [0..1] — снижает обнаружение этой особи зрением (заметность = 1−camouflage). + public float Camouflage; + + /// Запах [0..1] — повышает обнаружение этой особи обонянием. + public float Scent; + + /// Шумность [0..1] — повышает обнаружение этой особи слухом при движении. + public float Noise; + /// Размер мозга (0..1) — основа интеллекта. public float BrainSize; @@ -76,6 +94,8 @@ public struct AnimalPhenotype public static AnimalPhenotype FromTraits(IReadOnlyDictionary traits) { float T(string name) => traits.GetValueOrDefault(name); + // Острота чувств по умолчанию 1 (вид без гена не «слепнет»); заметность — мягкие дефолты. + float Acuity(string name) => traits.TryGetValue(name, out var v) ? v : 1f; return new AnimalPhenotype { BodySize = T("bodySize"), @@ -83,6 +103,12 @@ public struct AnimalPhenotype MoveSpeed = T("moveSpeed"), BloodVolume = T("bloodVolume"), Vision = T("vision"), + Hearing = Acuity("hearing"), + Smell = Acuity("smell"), + Touch = Acuity("touch"), + Camouflage = T("camouflage"), + Scent = traits.GetValueOrDefault("scent", 0.5f), + Noise = traits.GetValueOrDefault("noise", 0.5f), BrainSize = T("brainSize"), Insulation = T("insulation"), FurHue = T("furHue"), diff --git a/src/LittleSim/Sim/CapacityCalc.cs b/src/LittleSim/Sim/CapacityCalc.cs index ea120d5..5d87cea 100644 --- a/src/LittleSim/Sim/CapacityCalc.cs +++ b/src/LittleSim/Sim/CapacityCalc.cs @@ -12,6 +12,8 @@ public static class AnimalCapacities public const string BloodFiltration = "BloodFiltration"; public const string Sight = "Sight"; public const string Hearing = "Hearing"; + public const string Smell = "Smell"; + public const string Touch = "Touch"; public const string Talking = "Talking"; public const string Eating = "Eating"; public const string Digestion = "Digestion"; @@ -23,6 +25,8 @@ public static class AnimalCapacities Moving, Sight, Hearing, + Smell, + Touch, Talking, Eating, Breathing, @@ -99,6 +103,8 @@ public static class CapacityCalc [AnimalCapacities.Moving] = Raw(AnimalCapacities.Moving) * cons * pump, [AnimalCapacities.Sight] = Raw(AnimalCapacities.Sight) * cons, [AnimalCapacities.Hearing] = Raw(AnimalCapacities.Hearing) * cons, + [AnimalCapacities.Smell] = Raw(AnimalCapacities.Smell) * cons, + [AnimalCapacities.Touch] = Raw(AnimalCapacities.Touch) * cons, [AnimalCapacities.Talking] = Raw(AnimalCapacities.Talking) * cons, [AnimalCapacities.Eating] = Raw(AnimalCapacities.Eating) * cons, [AnimalCapacities.Digestion] = Raw(AnimalCapacities.Digestion) * pump,