From d105f6757d8d4064bbfd81e2d72ef39a2e77ce5e Mon Sep 17 00:00:00 2001 From: claude Date: Fri, 30 Oct 2026 01:46:16 +0100 Subject: [PATCH] Phase 3: the Mangrove Mire poisons anyone without Mire Waders - Companion mod zone hazards (zone/ZoneHazards.kt, data in data/cobblesurvival/zone_hazards/): in the Mire a player without an item from #cobblesurvival:mire_protection gets Poison every 5 seconds, with a one-time warning. Potions, milk and golden apples still help. - Mire Waders: KubeJS leather boots, dropped by the Westmarch and Verdant Jungle guardians (the zones before the Mire), per Adrian's boss rule. - Self-test mire_poisons_without_waders. - Allow-list Cobblemon's misspelt jigsaw state in habitats/parched_peat_bog7.nbt, which test players now reach. Co-Authored-By: Claude Opus 5.5 --- .../cobblesurvival/guardians/frostpeak.json | 2 +- .../data/cobblesurvival/guardians/jungle.json | 6 +- .../cobblesurvival/guardians/westmarch.json | 8 +- .../tags/item/mire_protection.json | 6 ++ .../cobblesurvival/zone_hazards/mire.json | 10 ++ docs/balance.md | 3 +- docs/checklists/phase-3.md | 5 +- docs/design.md | 2 + docs/zone-species.md | 6 +- .../dev/cobblesurvival/CobbleSurvival.kt | 2 + .../cobblesurvival/selftest/HazardTests.kt | 36 ++++++- .../dev/cobblesurvival/zone/ZoneHazards.kt | 97 ++++++++++++++++++ .../assets/cobblesurvival/lang/en_us.json | 3 +- pack/index.toml | 8 ++ .../textures/item/mire_waders.png | Bin 0 -> 159 bytes pack/kubejs/startup_scripts/mire_waders.js | 9 ++ pack/pack.toml | 2 +- tools/smoke_allowlist.txt | 3 + world/zones.json | 4 +- 19 files changed, 197 insertions(+), 15 deletions(-) create mode 100644 datapacks/core/data/cobblesurvival/tags/item/mire_protection.json create mode 100644 datapacks/core/data/cobblesurvival/zone_hazards/mire.json create mode 100644 mod/src/main/kotlin/dev/cobblesurvival/zone/ZoneHazards.kt create mode 100644 pack/kubejs/assets/cobblesurvival/textures/item/mire_waders.png create mode 100644 pack/kubejs/startup_scripts/mire_waders.js diff --git a/datapacks/core/data/cobblesurvival/guardians/frostpeak.json b/datapacks/core/data/cobblesurvival/guardians/frostpeak.json index 8628a18..bc01504 100644 --- a/datapacks/core/data/cobblesurvival/guardians/frostpeak.json +++ b/datapacks/core/data/cobblesurvival/guardians/frostpeak.json @@ -1,7 +1,7 @@ { "_comment": "Generated by tools/zone_spawns.py from world/zones.json; do not edit by hand.", "zone": "frostpeak", - "pokemon": "tyranitar level=60 uncatchable=yes", + "pokemon": "archaludon level=60 uncatchable=yes", "scale": 1.5, "drops": [ { diff --git a/datapacks/core/data/cobblesurvival/guardians/jungle.json b/datapacks/core/data/cobblesurvival/guardians/jungle.json index ae1baf9..844a949 100644 --- a/datapacks/core/data/cobblesurvival/guardians/jungle.json +++ b/datapacks/core/data/cobblesurvival/guardians/jungle.json @@ -4,9 +4,13 @@ "pokemon": "tangrowth level=35 uncatchable=yes", "scale": 1.5, "drops": [ + { + "item": "cobblesurvival:mire_waders", + "count": 1 + }, { "item": "cobblemon:pecha_berry", - "count": 8 + "count": 4 }, { "item": "cobblemon:exp_candy_m", diff --git a/datapacks/core/data/cobblesurvival/guardians/westmarch.json b/datapacks/core/data/cobblesurvival/guardians/westmarch.json index 51759b0..aa71c6f 100644 --- a/datapacks/core/data/cobblesurvival/guardians/westmarch.json +++ b/datapacks/core/data/cobblesurvival/guardians/westmarch.json @@ -1,12 +1,16 @@ { "_comment": "Generated by tools/zone_spawns.py from world/zones.json; do not edit by hand.", "zone": "westmarch", - "pokemon": "carbink level=30 uncatchable=yes", + "pokemon": "pinsir level=30 uncatchable=yes", "scale": 1.5, "drops": [ + { + "item": "cobblesurvival:mire_waders", + "count": 1 + }, { "item": "cobblemon:pecha_berry", - "count": 8 + "count": 4 }, { "item": "cobblemon:exp_candy_m", diff --git a/datapacks/core/data/cobblesurvival/tags/item/mire_protection.json b/datapacks/core/data/cobblesurvival/tags/item/mire_protection.json new file mode 100644 index 0000000..a33b10c --- /dev/null +++ b/datapacks/core/data/cobblesurvival/tags/item/mire_protection.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "cobblesurvival:mire_waders" + ] +} diff --git a/datapacks/core/data/cobblesurvival/zone_hazards/mire.json b/datapacks/core/data/cobblesurvival/zone_hazards/mire.json new file mode 100644 index 0000000..76274bc --- /dev/null +++ b/datapacks/core/data/cobblesurvival/zone_hazards/mire.json @@ -0,0 +1,10 @@ +{ + "_comment": "Phase 3 hazard: in the Mangrove Mire a player keeps getting Poison unless they wear an item from the protection tag (Mire Waders). Placeholder values, docs/balance.md.", + "zone": "mire", + "effect": "minecraft:poison", + "amplifier": 0, + "duration_ticks": 140, + "every_ticks": 100, + "protection": "cobblesurvival:mire_protection", + "warning": "message.cobblesurvival.hazard.mire" +} diff --git a/docs/balance.md b/docs/balance.md index 256a078..9a1782d 100644 --- a/docs/balance.md +++ b/docs/balance.md @@ -25,7 +25,8 @@ Every tunable lives in a config file or in this table. **Placeholder** means gue | Goat Fur / Hoglin Hide recipes | 8 wool + 1 Heat Rock → 8 Goat Fur; 8 leather + 1 Icy Rock → 8 Hoglin Hide (a set takes 24) | Placeholder | `kubejs/server_scripts/insulation.js` | Heat and Icy Rocks come from the guardians before Frostpeak and Sunscorch (archaeology finds too) | | Guardian respawn | 5 hours of game time after being beaten | Decided (Adrian, 2026-10-29) | `world/zones.json` → `guardian_respawn_hours` | Fixed spots | | Guardian strength | strongest Pokémon spawning in the zone, band top + 5 levels, 1.5× size, uncatchable | Placeholder | `tools/zone_spawns.py` (`GUARDIAN_*`), `world/zones.json` → `guardian.species` | | -| Guardian drops | Button Isle 10 Poké Balls + 4 Potions; Southwold 6 Great Balls + 4 Exp. Candy S; Westmarch and Jungle 8 Pecha Berries + 2 Exp. Candy M; Mire and Highlands 3 Icy Rocks + 4 Super Potions; Sunscorch 3 Heat Rocks + 2 Exp. Candy L; Frostpeak and Deep Dark 3 Icy Rocks + 2 Exp. Candy L; Deep Sea Mystic Water + 3 Exp. Candy M | Placeholder | `world/zones.json` → `guardian.drops` | 3 rocks make one full fur or hide set | +| Guardian drops | Button Isle 10 Poké Balls + 4 Potions; Southwold 6 Great Balls + 4 Exp. Candy S; Westmarch and Jungle Mire Waders + 4 Pecha Berries + 2 Exp. Candy M; Mire and Highlands 3 Icy Rocks + 4 Super Potions; Sunscorch 3 Heat Rocks + 2 Exp. Candy L; Frostpeak and Deep Dark 3 Icy Rocks + 2 Exp. Candy L; Deep Sea Mystic Water + 3 Exp. Candy M | Placeholder | `world/zones.json` → `guardian.drops` | 3 rocks make one full fur or hide set | +| Mire poison | Poison I for 7 s, renewed every 5 s while in the Mire without Mire Waders | Placeholder | `datapacks/core/data/cobblesurvival/zone_hazards/mire.json` | Vanilla Poison stops at half a heart | | Healing while sleeping | off (`healPercent` 0) | Decided (roadmap) | `config/cobblemon/main.json` | | | Loot container refresh | 1 hour (72,000 ticks of game time) after first opened, all containers | Decided (Adrian, 2026-10-29) | `config/lootr-common.toml` | Tiering by structure/biome later | | Gamerules in the template | `doMobSpawning false` | Decided (Adrian, 2026-10-28; may be reverted later) | `world/world.json` → `gamerules` | Pokémon spawning is Cobblemon's own `doPokemonSpawning` | diff --git a/docs/checklists/phase-3.md b/docs/checklists/phase-3.md index 8be01f5..c2b97f0 100644 --- a/docs/checklists/phase-3.md +++ b/docs/checklists/phase-3.md @@ -19,7 +19,9 @@ Open `build/zone-map.png` (the island coloured by zone) and read the draft in `d - **Alpha guardians** (step 4). One per zone at a fixed spot, back 5 hours after being beaten; drops help with the next zone (`docs/zone-species.md` lists them). Automated: `guardian_appears_and_returns`. -Still to come: the Mire's poison (and the wading gear the Westmarch and Jungle guardians should drop for it), soft level pressure, flyers. +- **The Mire's poison** (step 5). Mire Waders from the Westmarch and Jungle guardians keep it off. Automated: `mire_poisons_without_waders`. + +Still to come: soft level pressure, flyers. ## In-game @@ -30,3 +32,4 @@ Still to come: the Mire's poison (and the wading gear the Westmarch and Jungle g - [ ] **Sunscorch heat:** the desert at noon overheats you in a couple of minutes; at night it's fine. The hide set (Hoglin Hide from 8 leather + 1 Icy Rock) or a Fire Resistance potion keeps you going. - [ ] **Lowlands:** a night in Southwold or on Button Isle without gear never gets dangerous. - [ ] **Guardians:** `/cobblesurvival guardians` (operator) lists each zone's guardian and spot. Walk there: a big Pokémon appears, can't be caught, and beating it puts its drops in your inventory with a gold message. It's gone for 5 hours of play. +- [ ] **Mire:** walk into the Mangrove Mire: a green warning, then Poison keeps coming back. With Mire Waders on (from the Westmarch or Jungle guardian) nothing happens. diff --git a/docs/design.md b/docs/design.md index 73de5a1..9a5aec6 100644 --- a/docs/design.md +++ b/docs/design.md @@ -109,6 +109,8 @@ Order of play the bands suggest: Button Isle → Southwold → Westmarch or Jung - Basalt Furnace got Durant, Torkoal and Heatmor pinned to it: its own lines were all big (Charizard, Turtonator, Centiskorch, …) and Cobblemon only spawns a Pokémon where its body fits, so cramped basalt caves stayed empty. - Tested: `spawn_pools_are_zoned` (no Cobblemon default spawn is left; every entry has a zone and spawns within its band) and `spawn_survey` (a player at a point deep inside each zone is offered only that zone's spawns, and at least one), both in `tools/quick_check.py`. +**The Mire's poison** (Phase 3, step 5): while a player is in the Mangrove Mire without Mire Waders on, the companion mod gives them Poison every 5 seconds (`zone/ZoneHazards.kt`, data in `datapacks/core/data/cobblesurvival/zone_hazards/mire.json`, protection tag `#cobblesurvival:mire_protection`); the first time they walk in unprotected they get a warning. Vanilla Poison never kills, but it pins a player at half a heart, so a fall or a Pokémon's hit becomes deadly; milk, potions and golden apples still help. Mire Waders (leather boots, a KubeJS item) drop from the guardians of Westmarch and the Verdant Jungle, the zones before the Mire. Tested: `mire_poisons_without_waders`. + **Alpha guardians** (Phase 3, step 4; Adrian, 2026-10-29: fixed spots, back 5 hours after being beaten): - One per zone except the Shallows, Lush Caves and Dripstone; the Basalt Furnace gets its boss in Phase 7. Each stands at its zone's sample point (deep inside the zone; a cave floor for the Deep Dark) and only appears while a player is within 96 blocks; it wanders no further than 24 blocks. - The guardian is the strongest Pokémon that spawns walking (or, at sea, swimming) in its zone, five levels above the band, half again as big, and uncatchable: Pachirisu (Button Isle), Sigilyph (Southwold), Carbink (Westmarch), Tangrowth (Jungle), Arcanine (Mire), Cinderace (Highlands), Delphox (Sunscorch), Tyranitar (Frostpeak), Kingdra (Deep Sea), Dusknoir (Deep Dark). `world/zones.json` → `guardian.species` overrides the pick. diff --git a/docs/zone-species.md b/docs/zone-species.md index 0a8be2f..5f8dca3 100644 --- a/docs/zone-species.md +++ b/docs/zone-species.md @@ -65,12 +65,12 @@ One per zone at its sample point, uncatchable, five levels above the band; it re | Zone | Guardian | Level | Drops | | --- | --- | --- | --- | | Button Isle | Pachirisu | 15 | 10× poke_ball, 4× potion | -| Frostpeak Range | Tyranitar | 60 | 3× icy_rock, 2× exp_candy_l | +| Frostpeak Range | Archaludon | 60 | 3× icy_rock, 2× exp_candy_l | | Sunscorch | Delphox | 50 | 3× heat_rock, 2× exp_candy_l | | Mangrove Mire | Arcanine | 43 | 3× icy_rock, 4× super_potion | -| Verdant Jungle | Tangrowth | 35 | 8× pecha_berry, 2× exp_candy_m | +| Verdant Jungle | Tangrowth | 35 | 1× mire_waders, 4× pecha_berry, 2× exp_candy_m | | Highland Meadows | Cinderace | 40 | 3× icy_rock, 4× super_potion | -| Westmarch | Carbink | 30 | 8× pecha_berry, 2× exp_candy_m | +| Westmarch | Pinsir | 30 | 1× mire_waders, 4× pecha_berry, 2× exp_candy_m | | Southwold | Sigilyph | 23 | 6× great_ball, 4× exp_candy_s | | Deep Sea | Kingdra | 55 | 1× mystic_water, 3× exp_candy_m | | Deep Dark | Dusknoir | 65 | 3× icy_rock, 2× exp_candy_l | diff --git a/mod/src/main/kotlin/dev/cobblesurvival/CobbleSurvival.kt b/mod/src/main/kotlin/dev/cobblesurvival/CobbleSurvival.kt index d977c20..9ccafd8 100644 --- a/mod/src/main/kotlin/dev/cobblesurvival/CobbleSurvival.kt +++ b/mod/src/main/kotlin/dev/cobblesurvival/CobbleSurvival.kt @@ -9,6 +9,7 @@ import dev.cobblesurvival.selftest.SelfTest import dev.cobblesurvival.world.OnlyPokemon import dev.cobblesurvival.zone.Guardians import dev.cobblesurvival.zone.ZoneCondition +import dev.cobblesurvival.zone.ZoneHazards import dev.cobblesurvival.zone.Zones import net.minecraft.commands.Commands import net.minecraft.core.BlockPos @@ -57,6 +58,7 @@ class CobbleSurvival { ZoneCondition.register() NeoForge.EVENT_BUS.addListener(Zones::onAddReloadListeners) Guardians.register() + ZoneHazards.register() SelfTest.register() } diff --git a/mod/src/main/kotlin/dev/cobblesurvival/selftest/HazardTests.kt b/mod/src/main/kotlin/dev/cobblesurvival/selftest/HazardTests.kt index a775cb6..568e58f 100644 --- a/mod/src/main/kotlin/dev/cobblesurvival/selftest/HazardTests.kt +++ b/mod/src/main/kotlin/dev/cobblesurvival/selftest/HazardTests.kt @@ -3,20 +3,22 @@ package dev.cobblesurvival.selftest import dev.cobblesurvival.CobbleSurvival import dev.cobblesurvival.zone.ZoneSample import dev.cobblesurvival.zone.Zones -import net.minecraft.gametest.framework.GameTestAssertException import net.minecraft.core.registries.BuiltInRegistries +import net.minecraft.gametest.framework.GameTestAssertException import net.minecraft.resources.ResourceLocation import net.minecraft.server.level.ServerPlayer +import net.minecraft.world.effect.MobEffects import net.minecraft.world.entity.EquipmentSlot import net.minecraft.world.entity.LivingEntity import net.minecraft.world.item.ItemStack +import net.minecraft.world.item.Items import net.minecraft.world.level.levelgen.Heightmap /** * Roadmap Phase 3, hazards as gates, on the island itself (real biomes, real altitude): in Frostpeak and Sunscorch * a player without the right gear freezes or overheats within a minute or two, while the fur (cold) or hide (heat) * set holds them off for many minutes; leather armour alone doesn't help. The zones without a hazard are livable - * without gear by day and by night. + * without gear by day and by night. The Mangrove Mire poisons anyone without Mire Waders. * * Cold Sweat's insulation doesn't change what counts as too cold or too hot; it slows how fast the body drifts * there. So the tests reset each player's core temperature to 0, wait, and turn the drift into minutes until the @@ -42,6 +44,7 @@ object HazardTests { SelfTestCase("cold_needs_fur", 600, ::cold, islandOnly = true, batch = "hazard_cold"), SelfTestCase("heat_needs_hide", 600, ::heat, islandOnly = true, batch = "hazard_heat"), SelfTestCase("lowlands_are_mild", 4000, ::lowlands, islandOnly = true, batch = "hazard_lowlands"), + SelfTestCase("mire_poisons_without_waders", 400, ::mire), ) /** Frostpeak at noon, its warmest hour. */ @@ -120,6 +123,35 @@ object HazardTests { }.thenSucceed() } + /** The Mire's fumes (companion mod zone hazard) poison a player without Mire Waders, and nobody outside it. */ + private fun mire(s: Scenario) { + val level = s.level + val mire = Zones.samples["mire"] ?: throw GameTestAssertException("no sample point for the Mire") + val elsewhere = Zones.samples["button_isle"] ?: throw GameTestAssertException("no sample point for Button Isle") + val waders = BuiltInRegistries.ITEM.get(ResourceLocation.fromNamespaceAndPath("cobblesurvival", "mire_waders")) + s.check(waders != Items.AIR) { "the Mire Waders item does not exist" } + val bare = s.player() + val wading = s.player().also { it.setItemSlot(EquipmentSlot.FEET, ItemStack(waders)) } + val outside = s.player() + fun surface(sample: ZoneSample): Double { + level.getChunk(sample.x shr 4, sample.z shr 4) + return level.getHeight(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, sample.x, sample.z).toDouble() + } + s.helper.startSequence() + .thenExecute { + for (player in listOf(bare, wading)) s.moveTo(player, mire.x + 0.5, surface(mire), mire.z + 0.5) + s.moveTo(outside, elsewhere.x + 0.5, surface(elsewhere), elsewhere.z + 0.5) + } + .thenIdle(220) + .thenExecute { + val poison = MobEffects.POISON + s.check(bare.hasEffect(poison)) { "a player without waders in the Mire isn't poisoned" } + s.check(!wading.hasEffect(poison)) { "a player in Mire Waders got poisoned" } + s.check(!outside.hasEffect(poison)) { "a player on Button Isle got poisoned" } + } + .thenSucceed() + } + private fun dress(player: ServerPlayer, namespace: String, pieces: List) { val slots = listOf(EquipmentSlot.HEAD, EquipmentSlot.CHEST, EquipmentSlot.LEGS, EquipmentSlot.FEET) for ((slot, piece) in slots.zip(pieces)) { diff --git a/mod/src/main/kotlin/dev/cobblesurvival/zone/ZoneHazards.kt b/mod/src/main/kotlin/dev/cobblesurvival/zone/ZoneHazards.kt new file mode 100644 index 0000000..085cc7e --- /dev/null +++ b/mod/src/main/kotlin/dev/cobblesurvival/zone/ZoneHazards.kt @@ -0,0 +1,97 @@ +package dev.cobblesurvival.zone + +import com.google.gson.Gson +import com.google.gson.JsonElement +import dev.cobblesurvival.CobbleSurvival +import net.minecraft.ChatFormatting +import net.minecraft.core.Holder +import net.minecraft.core.registries.BuiltInRegistries +import net.minecraft.core.registries.Registries +import net.minecraft.network.chat.Component +import net.minecraft.resources.ResourceLocation +import net.minecraft.server.level.ServerPlayer +import net.minecraft.server.packs.resources.ResourceManager +import net.minecraft.server.packs.resources.SimpleJsonResourceReloadListener +import net.minecraft.tags.TagKey +import net.minecraft.util.profiling.ProfilerFiller +import net.minecraft.world.effect.MobEffect +import net.minecraft.world.effect.MobEffectInstance +import net.minecraft.world.entity.EquipmentSlot +import net.minecraft.world.item.Item +import net.neoforged.neoforge.common.NeoForge +import net.neoforged.neoforge.event.AddReloadListenerEvent +import net.neoforged.neoforge.event.tick.ServerTickEvent +import java.util.UUID + +/** + * Zone hazards that Cold Sweat doesn't cover (roadmap Phase 3: "a poison swamp ... as area effects"): while a player + * is in the zone and wears nothing from the protection tag, they keep getting the effect. Potions, milk and golden + * apples still work against it. Definitions: `data/cobblesurvival/zone_hazards/.json`. + */ +object ZoneHazards : SimpleJsonResourceReloadListener(Gson(), "zone_hazards") { + class Hazard( + val zone: String, + val effect: Holder, + val amplifier: Int, + val durationTicks: Int, + val everyTicks: Int, + val protection: TagKey, + val warning: String?, + ) + + var hazards: List = emptyList() + private set + private val warned = HashMap() + + fun register() { + NeoForge.EVENT_BUS.addListener { it.addListener(this) } + NeoForge.EVENT_BUS.addListener(::onServerTick) + } + + override fun apply(files: Map, resources: ResourceManager, profiler: ProfilerFiller) { + hazards = files.mapNotNull { (id, element) -> + val json = element.asJsonObject + val effectId = ResourceLocation.parse(json.get("effect").asString) + val effect = BuiltInRegistries.MOB_EFFECT.getHolder(effectId).orElse(null) + if (effect == null) { + CobbleSurvival.LOGGER.error("Zone hazard {}: unknown effect {}", id, effectId) + return@mapNotNull null + } + Hazard( + zone = json.get("zone").asString, + effect = effect, + amplifier = json.get("amplifier")?.asInt ?: 0, + durationTicks = json.get("duration_ticks").asInt, + everyTicks = json.get("every_ticks").asInt, + protection = TagKey.create(Registries.ITEM, ResourceLocation.parse(json.get("protection").asString)), + warning = json.get("warning")?.asString, + ) + } + CobbleSurvival.LOGGER.info("Loaded {} zone hazards", hazards.size) + } + + private fun onServerTick(event: ServerTickEvent.Post) { + if (hazards.isEmpty()) return + val tick = event.server.tickCount + for (player in event.server.playerList.players) { + if (player.isCreative || player.isSpectator) continue + val zone = Zones.at(player.serverLevel(), player.blockPosition())?.id + if (zone == null || hazards.none { it.zone == zone }) { + warned.remove(player.uuid) + continue + } + for (hazard in hazards) { + if (hazard.zone != zone || tick % hazard.everyTicks != 0 || isProtected(player, hazard)) continue + player.addEffect(MobEffectInstance(hazard.effect, hazard.durationTicks, hazard.amplifier)) + if (hazard.warning != null && warned[player.uuid] != zone) { + warned[player.uuid] = zone + player.displayClientMessage(Component.translatable(hazard.warning).withStyle(ChatFormatting.DARK_GREEN), true) + } + } + } + } + + fun isProtected(player: ServerPlayer, hazard: Hazard) = + listOf(EquipmentSlot.HEAD, EquipmentSlot.CHEST, EquipmentSlot.LEGS, EquipmentSlot.FEET) + .any { player.getItemBySlot(it).`is`(hazard.protection) } +} diff --git a/mod/src/main/resources/assets/cobblesurvival/lang/en_us.json b/mod/src/main/resources/assets/cobblesurvival/lang/en_us.json index 053d43c..8c0ccab 100644 --- a/mod/src/main/resources/assets/cobblesurvival/lang/en_us.json +++ b/mod/src/main/resources/assets/cobblesurvival/lang/en_us.json @@ -2,5 +2,6 @@ "generator.cobblesurvival.island": "Cobblemon Survival Island", "message.cobblesurvival.permadeath.lost": "%s fainted and is gone for good.", "message.cobblesurvival.permadeath.saved": "%s's Revival Charm saved it and crumbled to dust.", - "message.cobblesurvival.guardian.beaten": "The guardian of %s is beaten! It returns in %s hours." + "message.cobblesurvival.guardian.beaten": "The guardian of %s is beaten! It returns in %s hours.", + "message.cobblesurvival.hazard.mire": "The Mire's fumes are poisoning you. Mire Waders would keep them off." } diff --git a/pack/index.toml b/pack/index.toml index 7910732..e49c30d 100644 --- a/pack/index.toml +++ b/pack/index.toml @@ -40,6 +40,10 @@ hash = "ff92c8b83a303441c81835a1ab22dfc42599fd58d43a920452257bb1c6b39d9d" file = "defaultconfigs/cobblehardcoremon/server.toml" hash = "5e68c4bc93fcc06f85cabc6c587c1b70cb2a22da01ad9653d678ac9131c0003b" +[[files]] +file = "kubejs/assets/cobblesurvival/textures/item/mire_waders.png" +hash = "37f7469789d281cbd2ab40f483914eec29f5c82e2c3575854cd276f3296ebb24" + [[files]] file = "kubejs/assets/cobblesurvival/textures/item/revival_charm.png" hash = "084c0a7b17bb429c317843a7c45096dc8cb1ab61c748293475c1f3d6a5984086" @@ -56,6 +60,10 @@ hash = "026dc5ab98cb13c906d5b6974ea7624014e804c58141f01ec57e077e1e8bb339" file = "kubejs/server_scripts/revival_charm.js" hash = "68c23da4ab4daa0687f0c367c4cf837a9c26c18c4034bd3fbdedbcc6d3b716f6" +[[files]] +file = "kubejs/startup_scripts/mire_waders.js" +hash = "946be2db734646167fe55ba83b57c6f310ba40313a18a959b84c0952e2302112" + [[files]] file = "kubejs/startup_scripts/revival_charm.js" hash = "a93eb4401ca303c9aab15ef8cd1edcb34cc7242cbb3501e6703f32e9b3f57e2b" diff --git a/pack/kubejs/assets/cobblesurvival/textures/item/mire_waders.png b/pack/kubejs/assets/cobblesurvival/textures/item/mire_waders.png new file mode 100644 index 0000000000000000000000000000000000000000..b51d351cf54fd56c9b11f31472933263f211c191 GIT binary patch literal 159 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s7(mY)pLn`JZCrD%*;7FGE zvGT9`v>h8>iUk(woDd4~QsQvs*)GvBG1)0BBz5V5fYhZ8S6A+M5)gBt> { + event.create('cobblesurvival:mire_waders', 'boots') + .material('minecraft:leather') + .displayName('Mire Waders') + .tooltip("Keeps the Mangrove Mire's poison off while worn.") +}) diff --git a/pack/pack.toml b/pack/pack.toml index 0352427..9de39d2 100644 --- a/pack/pack.toml +++ b/pack/pack.toml @@ -6,7 +6,7 @@ pack-format = "packwiz:1.1.0" [index] file = "index.toml" hash-format = "sha256" -hash = "090cc213fdd22bcaf74234d279c438a3aff08b9eb87b169802f66ae33b9b672f" +hash = "bdca52cbc4ab217c9ced202856d5be6a5af4fb4f21c07ac5ae2516d4b44ed037" [versions] minecraft = "1.21.1" diff --git a/tools/smoke_allowlist.txt b/tools/smoke_allowlist.txt index 4757bd1..5b22b5d 100644 --- a/tools/smoke_allowlist.txt +++ b/tools/smoke_allowlist.txt @@ -7,3 +7,6 @@ Failed to parse jigsaw replacement state 'minecraft:dirt_block' # Cobblemon 1.8.4 logs this at ERROR on every player's first join (no save files yet, so the # backup is missing too) and starts them with empty data. The self-tests join fresh players. \.old File \S+ for [0-9a-f-]+ is corrupt or missing\. Data is lost +# Cobblemon 1.8.4 bug: habitats/parched_peat_bog7.nbt has a jigsaw block whose final state is the misspelt +# "minecraft:strucutre_void". Logged at worldgen; the piece still generates (as air there). +Failed to parse jigsaw replacement state 'minecraft:strucutre_void' diff --git a/world/zones.json b/world/zones.json index 25e8303..a4027ff 100644 --- a/world/zones.json +++ b/world/zones.json @@ -22,7 +22,7 @@ "rule": {"biomes": ["minecraft:mangrove_swamp"]} }, { - "id": "jungle", "guardian": {"drops": [["cobblemon:pecha_berry", 8], ["cobblemon:exp_candy_m", 2]]}, "lines": 30, "name": "Verdant Jungle", "levels": [18, 30], "hazard": "none (warm and humid, below Cold Sweat's damage)", "color": "#5a8f1e", + "id": "jungle", "guardian": {"drops": [["cobblesurvival:mire_waders", 1], ["cobblemon:pecha_berry", 4], ["cobblemon:exp_candy_m", 2]]}, "lines": 30, "name": "Verdant Jungle", "levels": [18, 30], "hazard": "none (warm and humid, below Cold Sweat's damage)", "color": "#5a8f1e", "rule": {"biomes": ["minecraft:jungle"]} }, { @@ -30,7 +30,7 @@ "rule": {"region": {"z_max": 0, "x_min": -250}} }, { - "id": "westmarch", "guardian": {"drops": [["cobblemon:pecha_berry", 8], ["cobblemon:exp_candy_m", 2]]}, "lines": 35, "name": "Westmarch", "levels": [15, 25], "hazard": "none", "color": "#2f8f4e", + "id": "westmarch", "guardian": {"drops": [["cobblesurvival:mire_waders", 1], ["cobblemon:pecha_berry", 4], ["cobblemon:exp_candy_m", 2]]}, "lines": 35, "name": "Westmarch", "levels": [15, 25], "hazard": "none", "color": "#2f8f4e", "rule": {"region": {"z_max": 0, "x_max": -250}} }, {