diff --git a/Mods/Core/Defs/plants.json b/Mods/Core/Defs/plants.json index 0791e14..6d078c2 100644 --- a/Mods/Core/Defs/plants.json +++ b/Mods/Core/Defs/plants.json @@ -19,7 +19,7 @@ { "defName": "TreeBirchA", "parent": "BaseTree", "label": "plant.birch", "texture": "things/plant/treebirch/TreeBirchA" }, { "defName": "TreeGrayPineA", "parent": "BaseTree", "label": "plant.pine", "texture": "things/plant/treegraypine/TreeGrayPineA" }, - { "defName": "GrassA", "label": "plant.grass", "texture": "things/plant/grass/grassa", "sizeCells": 1.2, + { "defName": "GrassA", "label": "plant.grass", "texture": "things/plant/grass/grassa", "sizeCells": 1.5, "harvestProduct": "ProductGrass", "genome": { "optimalLight": 0.85, "lightTolerance": 0.35, "optimalTemperature": 19, "temperatureTolerance": 8, "coldHardiness": 9, "heatHardiness": 6, @@ -29,7 +29,7 @@ "harvestAmount": 2, "leafHue": 0.36 }, "stages": [ { "texture": "things/plant/seed_default", "sizeCells": 0.5, "growDays": 2, "label": "plant.stage.sprout" }, - { "sizeCells": 1.2, "label": "plant.stage.mature" } + { "sizeCells": 1.5, "label": "plant.stage.mature" } ] }, { "defName": "BaseBush", "abstract": true, "label": "plant.bush", "sizeCells": 1.4, @@ -46,6 +46,119 @@ ] }, { "defName": "BushA", "parent": "BaseBush", "texture": "things/plant/bush/BushA" }, { "defName": "BushB", "parent": "BaseBush", "texture": "things/plant/bush/BushB" }, - { "defName": "BushC", "parent": "BaseBush", "texture": "things/plant/bush/BushC" } + { "defName": "BushC", "parent": "BaseBush", "texture": "things/plant/bush/BushC" }, + + // --- Деревья+: тёплая и холодная температурные ниши (showcase температурных генов) --- + { "defName": "BaseWarmTree", "abstract": true, "sizeCells": 2.0, "trunkRadiusCells": 0.28, + "harvestProduct": "ProductWood", "fruitProduct": "ProductAcorn", + "genome": { "optimalLight": 0.65, "lightTolerance": 0.5, "optimalTemperature": 23, "temperatureTolerance": 9, + "coldHardiness": 8, "heatHardiness": 16, + "optimalFertility": 1.5, "fertilityTolerance": 0.9, "vigor": 1.1, + "lifespan": 150, "dispersalRange": 2, "reproduceInterval": 14, "selfPollination": 0.2, + "mutationRate": 0.05, "variantChance": 0.15, "spread": 0.08, + "fruitYield": 5, "fruitSeason": 2, "harvestAmount": 10, "leafHue": 0.22 }, + "stages": [ + { "texture": "things/plant/seed_default", "sizeCells": 0.6, "growDays": 4, "label": "plant.stage.seedling" }, + { "sizeCells": 1.2, "growDays": 9, "label": "plant.stage.sapling" }, + { "sizeCells": 2.0, "label": "plant.stage.mature" } + ] }, + { "defName": "BaseColdTree", "abstract": true, "sizeCells": 2.0, "trunkRadiusCells": 0.26, + "harvestProduct": "ProductWood", "fruitProduct": "ProductAcorn", + "genome": { "optimalLight": 0.55, "lightTolerance": 0.5, "optimalTemperature": 8, "temperatureTolerance": 12, + "coldHardiness": 18, "heatHardiness": 8, + "optimalFertility": 1.2, "fertilityTolerance": 1.0, "vigor": 0.9, + "lifespan": 220, "dispersalRange": 2, "reproduceInterval": 16, "selfPollination": 0.2, + "mutationRate": 0.05, "variantChance": 0.12, "spread": 0.08, + "fruitYield": 4, "fruitSeason": 2, "harvestAmount": 12, "leafHue": 0.45 }, + "stages": [ + { "texture": "things/plant/seed_default", "sizeCells": 0.6, "growDays": 4, "label": "plant.stage.seedling" }, + { "sizeCells": 1.2, "growDays": 9, "label": "plant.stage.sapling" }, + { "sizeCells": 2.0, "label": "plant.stage.mature" } + ] }, + { "defName": "TreeMapleA", "parent": "BaseTree", "label": "plant.maple", "texture": "things/plant/treemaple/TreeMapleA" }, + { "defName": "TreeMapleB", "parent": "BaseTree", "label": "plant.maple", "texture": "things/plant/treemaple/TreeMapleB" }, + { "defName": "TreePoplarA", "parent": "BaseTree", "label": "plant.poplar", "texture": "things/plant/treepoplar/TreePoplarA" }, + { "defName": "TreeTeakA", "parent": "BaseWarmTree", "label": "plant.teak", "texture": "things/plant/treeteak/TreeTeakA" }, + { "defName": "TreeTeakB", "parent": "BaseWarmTree", "label": "plant.teak", "texture": "things/plant/treeteak/TreeTeakB" }, + { "defName": "TreeCypressA", "parent": "BaseColdTree", "label": "plant.cypress", "texture": "things/plant/treecypress/TreeCypressA" }, + { "defName": "TreeCypressB", "parent": "BaseColdTree", "label": "plant.cypress", "texture": "things/plant/treecypress/TreeCypressB" }, + + // --- Пустыня: кактусы и агава на песке. Жаролюбивы, засухоустойчивы (низкий оптимум почвы), + // морозо-нестойки (tMin ≈ -2°C → гибнут в морозы). Большинство без плодов; сагуаро/агава плодоносят. --- + { "defName": "BaseCactus", "abstract": true, "label": "plant.cactus", "sizeCells": 1.2, "trunkRadiusCells": 0, + "harvestProduct": "ProductFiber", + "genome": { "optimalLight": 0.95, "lightTolerance": 0.35, "optimalTemperature": 26, "temperatureTolerance": 8, + "coldHardiness": 20, "heatHardiness": 18, + "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 }, + "stages": [ + { "texture": "things/plant/seed_default", "sizeCells": 0.5, "growDays": 5, "label": "plant.stage.sprout" }, + { "label": "plant.stage.mature" } + ] }, + { "defName": "SaguaroCactusA", "parent": "BaseCactus", "label": "plant.saguaro", "sizeCells": 2.2, "trunkRadiusCells": 0.18, + "fruitProduct": "ProductBerry", "texture": "things/plant/saguarocactus/SaguaroCactusA" }, + { "defName": "SaguaroCactusB", "parent": "BaseCactus", "label": "plant.saguaro", "sizeCells": 2.2, "trunkRadiusCells": 0.18, + "fruitProduct": "ProductBerry", "texture": "things/plant/saguarocactus/SaguaroCactusB" }, + { "defName": "PebbleCactusA", "parent": "BaseCactus", "sizeCells": 1.0, "texture": "things/plant/pebblecactus/PebbleCactusA" }, + { "defName": "PebbleCactusB", "parent": "BaseCactus", "sizeCells": 1.0, "texture": "things/plant/pebblecactus/PebbleCactusB" }, + { "defName": "PincushionCactusA", "parent": "BaseCactus", "sizeCells": 0.9, "texture": "things/plant/pincushioncactus/PincushionCactusA" }, + { "defName": "AgaveA", "parent": "BaseCactus", "label": "plant.agave", "sizeCells": 1.3, "fruitProduct": "ProductBerry", "texture": "things/plant/agave/AgaveA" }, + { "defName": "AgaveB", "parent": "BaseCactus", "label": "plant.agave", "sizeCells": 1.3, "fruitProduct": "ProductBerry", "texture": "things/plant/agave/AgaveB" }, + + // --- Грибы: подлесок леса. Низкий оптимум света (0.15) → растут в тени крон, где другим темно + // (showcase световой пригодности). Богатая почва, короткая жизнь, быстрое спороношение. --- + { "defName": "BaseMushroom", "abstract": true, "label": "plant.mushroom", "sizeCells": 0.9, "trunkRadiusCells": 0, + "harvestProduct": "ProductMushroom", + "genome": { "optimalLight": 0.15, "lightTolerance": 0.22, "optimalTemperature": 14, "temperatureTolerance": 11, + "coldHardiness": 12, "heatHardiness": 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 }, + "stages": [ + { "texture": "things/plant/seed_default", "sizeCells": 0.4, "growDays": 2, "label": "plant.stage.sprout" }, + { "label": "plant.stage.mature" } + ] }, + { "defName": "GlowstoolA", "parent": "BaseMushroom", "sizeCells": 0.9, "texture": "things/plant/glowstool/GlowstoolA" }, + { "defName": "GlowstoolB", "parent": "BaseMushroom", "sizeCells": 0.9, "texture": "things/plant/glowstool/GlowstoolB" }, + { "defName": "TimbershroomA", "parent": "BaseMushroom", "sizeCells": 1.1, "texture": "things/plant/timbershroom/TimbershroomA" }, + { "defName": "TimbershroomB", "parent": "BaseMushroom", "sizeCells": 1.1, "texture": "things/plant/timbershroom/TimbershroomB" }, + { "defName": "NutrifungusA", "parent": "BaseMushroom", "sizeCells": 0.9, "texture": "things/plant/nutrifungus/NutrifungusA" }, + + // --- Луг: цветы (декоративные, быстрое расселение) и ягодный почвопокров (еда). --- + { "defName": "BaseFlower", "abstract": true, "label": "plant.flower", "sizeCells": 1.0, "trunkRadiusCells": 0, + "genome": { "optimalLight": 0.9, "lightTolerance": 0.35, "optimalTemperature": 20, "temperatureTolerance": 9, + "coldHardiness": 8, "heatHardiness": 8, + "optimalFertility": 1.0, "fertilityTolerance": 1.1, "vigor": 1.4, + "lifespan": 18, "dispersalRange": 4, "reproduceInterval": 3, "selfPollination": 0.85, + "mutationRate": 0.08, "variantChance": 0.3, "spread": 0.1, + "fruitYield": 0, "fruitSeason": 0, "harvestAmount": 0, "leafHue": 0.2 }, + "stages": [ + { "texture": "things/plant/seed_default", "sizeCells": 0.4, "growDays": 2, "label": "plant.stage.sprout" }, + { "label": "plant.stage.mature" } + ] }, + { "defName": "DandelionA", "parent": "BaseFlower", "label": "plant.dandelion", "texture": "things/plant/dandelion/Dandelion" }, + { "defName": "DandelionB", "parent": "BaseFlower", "label": "plant.dandelion", "texture": "things/plant/dandelion/DandelionB" }, + { "defName": "DandelionC", "parent": "BaseFlower", "label": "plant.dandelion", "texture": "things/plant/dandelion/DandelionC" }, + { "defName": "DaylilyA", "parent": "BaseFlower", "label": "plant.daylily", "texture": "things/plant/daylily/DaylilyA" }, + { "defName": "DaylilyB", "parent": "BaseFlower", "label": "plant.daylily", "texture": "things/plant/daylily/DaylilyB" }, + { "defName": "RoseA", "parent": "BaseFlower", "label": "plant.rose", "sizeCells": 1.1, "texture": "things/plant/rose/RoseA" }, + + { "defName": "BaseBerryBush", "abstract": true, "label": "plant.berrybush", "sizeCells": 1.2, "trunkRadiusCells": 0, + "fruitProduct": "ProductBerry", + "genome": { "optimalLight": 0.8, "lightTolerance": 0.4, "optimalTemperature": 18, "temperatureTolerance": 9, + "coldHardiness": 10, "heatHardiness": 7, + "optimalFertility": 1.2, "fertilityTolerance": 1.0, "vigor": 1.1, + "lifespan": 40, "dispersalRange": 2, "reproduceInterval": 6, "selfPollination": 0.6, + "mutationRate": 0.05, "variantChance": 0.18, "spread": 0.1, + "fruitYield": 4, "fruitSeason": 2, "harvestAmount": 0, "leafHue": 0.33 }, + "stages": [ + { "texture": "things/plant/seed_default", "sizeCells": 0.5, "growDays": 3, "label": "plant.stage.sprout" }, + { "label": "plant.stage.mature" } + ] }, + { "defName": "Strawberry", "parent": "BaseBerryBush", "label": "plant.strawberry", "sizeCells": 1.0, "texture": "things/plant/strawberryplant/StrawberryPlant" }, + { "defName": "Raspberry", "parent": "BaseBerryBush", "label": "plant.raspberry", "texture": "things/plant/raspberryplant/raspberrybusha" } ] } diff --git a/Mods/Core/Defs/products.json b/Mods/Core/Defs/products.json index f43d352..eec749f 100644 --- a/Mods/Core/Defs/products.json +++ b/Mods/Core/Defs/products.json @@ -5,7 +5,9 @@ "defs": [ { "defName": "ProductWood", "label": "product.wood", "kind": "material" }, { "defName": "ProductGrass", "label": "product.grass", "kind": "material" }, + { "defName": "ProductFiber", "label": "product.fiber", "kind": "material" }, { "defName": "ProductBerry", "label": "product.berry", "kind": "food" }, - { "defName": "ProductAcorn", "label": "product.acorn", "kind": "food" } + { "defName": "ProductAcorn", "label": "product.acorn", "kind": "food" }, + { "defName": "ProductMushroom", "label": "product.mushroom", "kind": "food" } ] } diff --git a/Mods/Core/Defs/terrain.json b/Mods/Core/Defs/terrain.json index d86cb5b..36fb0fb 100644 --- a/Mods/Core/Defs/terrain.json +++ b/Mods/Core/Defs/terrain.json @@ -3,19 +3,31 @@ "defs": [ { "defName": "DeepWater", "label": "terrain.deepwater", "maxHeight": 0.30, "color": [23, 63, 95] }, { "defName": "Water", "label": "terrain.water", "maxHeight": 0.42, "color": [32, 99, 155] }, - { "defName": "Sand", "label": "terrain.sand", "maxHeight": 0.48, "color": [237, 201, 120], - "isLand": true, "surface": "terrain/surfaces/sand", "fertility": 0.4 }, - { "defName": "Grass", "label": "terrain.grass", "maxHeight": 0.68, "color": [90, 160, 70], + { "defName": "Sand", "label": "terrain.sand", "maxHeight": 0.46, "color": [237, 201, 120], + "isLand": true, "surface": "terrain/surfaces/sand", "fertility": 0.4, + "scatter": [ + { "chance": 0.05, "options": ["SaguaroCactusA", "SaguaroCactusB"] }, + { "chance": 0.10, "options": ["PebbleCactusA", "PebbleCactusB", "PincushionCactusA"] }, + { "chance": 0.04, "options": ["AgaveA", "AgaveB"] } + ] }, + { "defName": "Grass", "label": "terrain.grass", "maxHeight": 0.72, "color": [90, 160, 70], "isLand": true, "surface": "terrain/surfaces/mossy", "fertility": 1.0, "scatter": [ - { "chance": 0.6, "options": ["GrassA"] }, - { "chance": 0.07, "options": ["BushA", "BushB", "BushC"] } + { "chance": 1.0, "options": ["GrassA"] }, + { "chance": 0.5, "options": ["GrassA"] }, + { "chance": 0.22, "options": ["BushA", "BushB", "BushC"] }, + { "chance": 0.20, "options": ["Strawberry", "Raspberry"] }, + { "chance": 0.14, "options": ["DandelionA", "DandelionB", "DandelionC", "DaylilyA", "DaylilyB", "RoseA"] } ] }, { "defName": "Forest", "label": "terrain.forest", "maxHeight": 0.85, "color": [44, 110, 50], "isLand": true, "surface": "terrain/surfaces/soil", "fertility": 1.6, "scatter": [ - { "chance": 0.35, "options": ["TreeOakA", "TreeOakB", "TreeBirchA", "TreeGrayPineA"] }, - { "chance": 0.3, "options": ["GrassA"] } + { "chance": 0.35, "options": ["TreeOakA", "TreeOakB", "TreeBirchA", "TreeGrayPineA", + "TreeMapleA", "TreeMapleB", "TreePoplarA", "TreeCypressA", "TreeCypressB", "TreeTeakA", "TreeTeakB"] }, + { "chance": 0.6, "options": ["GrassA"] }, + { "chance": 0.16, "options": ["BushA", "BushB", "BushC"] }, + { "chance": 0.14, "options": ["Strawberry", "Raspberry"] }, + { "chance": 0.16, "options": ["GlowstoolA", "GlowstoolB", "TimbershroomA", "TimbershroomB", "NutrifungusA"] } ] }, { "defName": "Mountain", "label": "terrain.mountain", "maxHeight": 1.01, "color": [136, 132, 128], "surface": "terrain/surfaces/roughhewnrock", "fertility": 0.2, "blocksLight": true } diff --git a/Mods/Core/Languages/en/ui.json b/Mods/Core/Languages/en/ui.json index 916cab9..5c4464f 100644 --- a/Mods/Core/Languages/en/ui.json +++ b/Mods/Core/Languages/en/ui.json @@ -89,14 +89,31 @@ "plant.pine": "pine", "plant.grass": "grass tuft", "plant.bush": "bush", + "plant.maple": "maple", + "plant.poplar": "poplar", + "plant.teak": "teak", + "plant.cypress": "cypress", + "plant.cactus": "cactus", + "plant.saguaro": "saguaro", + "plant.agave": "agave", + "plant.mushroom": "mushroom", + "plant.flower": "flower", + "plant.dandelion": "dandelion", + "plant.daylily": "daylily", + "plant.rose": "rose", + "plant.berrybush": "berry bush", + "plant.strawberry": "strawberry", + "plant.raspberry": "raspberry", "plant.stage.seedling": "seedling", "plant.stage.sprout": "sprout", "plant.stage.sapling": "sapling", "plant.stage.mature": "mature", "product.wood": "wood", "product.grass": "grass", + "product.fiber": "fiber", "product.berry": "berries", "product.acorn": "acorn", + "product.mushroom": "mushrooms", "pawn.being": "being", "pawn.bear": "bear", "pawn.deer": "deer", diff --git a/Mods/Core/Languages/ru/ui.json b/Mods/Core/Languages/ru/ui.json index d41562d..f576f95 100644 --- a/Mods/Core/Languages/ru/ui.json +++ b/Mods/Core/Languages/ru/ui.json @@ -89,14 +89,31 @@ "plant.pine": "сосна", "plant.grass": "пучок травы", "plant.bush": "куст", + "plant.maple": "клён", + "plant.poplar": "тополь", + "plant.teak": "тик", + "plant.cypress": "кипарис", + "plant.cactus": "кактус", + "plant.saguaro": "сагуаро", + "plant.agave": "агава", + "plant.mushroom": "гриб", + "plant.flower": "цветок", + "plant.dandelion": "одуванчик", + "plant.daylily": "лилейник", + "plant.rose": "роза", + "plant.berrybush": "ягодный куст", + "plant.strawberry": "земляника", + "plant.raspberry": "малина", "plant.stage.seedling": "росток", "plant.stage.sprout": "всходы", "plant.stage.sapling": "саженец", "plant.stage.mature": "взрослое", "product.wood": "древесина", "product.grass": "трава", + "product.fiber": "волокно", "product.berry": "ягоды", "product.acorn": "жёлудь", + "product.mushroom": "грибы", "pawn.being": "житель", "pawn.bear": "медведь", "pawn.deer": "олень", diff --git a/engine b/engine index 0838170..38bdfbb 160000 --- a/engine +++ b/engine @@ -1 +1 @@ -Subproject commit 08381703f79377a5bc48fc0745620f8815695b05 +Subproject commit 38bdfbbb81fa7e283d2908e097c94d16853bc0de diff --git a/src/LittleSim/Scenes/WorldScene.cs b/src/LittleSim/Scenes/WorldScene.cs index f5a0dd3..5b56a1b 100644 --- a/src/LittleSim/Scenes/WorldScene.cs +++ b/src/LittleSim/Scenes/WorldScene.cs @@ -45,6 +45,15 @@ public sealed class WorldScene : Scene /// Максимум растений на клетку — потолок плотности для размножения. public const int DensityCap = 4; + /// + /// День года, с которого начинается мир — тёплая весна (~16 °C), а не холодный рубеж года. + /// Сдвигает сезонную фазу климата, давая длинный тёплый сезон роста до первой зимы. + /// + public const int StartDayOfYear = 10; + + /// Час суток на старте мира — утро (07:00), а не полночь. + public const int StartHour = 7; + private readonly WorldConfig _config; private readonly WorldSave? _save; private readonly RectF _bounds; @@ -89,8 +98,13 @@ public sealed class WorldScene : Scene GameLayers.EnsureRegistered(renderer); this.UseTilemaps(); - var calendar = Context.UseCalendar(SecondsPerDay); - var climate = Context.UseClimate(ClimateSettings.Default); + var calendar = Context.UseCalendar(SecondsPerDay, StartHour / 24.0); + var climate = Context.UseClimate( + ClimateSettings.Default with + { + StartDayOfYear = StartDayOfYear, + } + ); var dayNight = new DayNight(calendar, DayNightSettings.Default); // Рельеф детерминирован сидом. Растения: новый мир — скаттер из сида; загрузка — из сейва.