Cobblemon Survival Pack: phases 0-2 and Phase 3 zones and hazards
Free NeoForge 1.21.1 modpack on Cobblemon 1.8.4 built with packwiz, plus the Kotlin companion mod (cobblesurvival) and its built-in data pack. - Phase 0: packwiz pack with Modrinth/CurseForge cross-links, build and export tooling, Prism instance sync, test server with smoke checks. - Phase 1: Poke Ball shaped island (WorldGen Editor preset, seed isle-26), Adrian's biome list, no natural ore, structures without ore or vanilla mobs, no Nether portals, world template builder and world report. - Phase 2: permadeath (CobbleHardcoreMon plus the companion mod's gap fixes), Revival Charm, expensive Healing Machine, Lootr refreshing loot, in-game self-tests on Minecraft's GameTest framework. - Phase 3 so far: 14 zones with their own spawn pools and level bands (tools/zone_layout.py, tools/zone_spawns.py, "zone" spawn condition), Cold Sweat heat and cold as gates with boss-drop insulation recipes, spawn survey and hazard self-tests in tools/quick_check.py. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
commit
398301f0be
232 files changed
+72665
No files matched your search
@@ -0,0 +1,103 @@
|
||||
package dev.cobblesurvival
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies
|
||||
import com.mojang.logging.LogUtils
|
||||
import dev.cobblesurvival.dev.BiomePreview
|
||||
import dev.cobblesurvival.permadeath.Permadeath
|
||||
import dev.cobblesurvival.selftest.SelfTest
|
||||
import dev.cobblesurvival.world.OnlyPokemon
|
||||
import dev.cobblesurvival.zone.ZoneCondition
|
||||
import dev.cobblesurvival.zone.Zones
|
||||
import net.minecraft.commands.Commands
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.server.packs.PackType
|
||||
import net.minecraft.server.packs.repository.Pack
|
||||
import net.minecraft.server.packs.repository.PackSource
|
||||
import net.minecraft.world.level.Level
|
||||
import net.neoforged.fml.ModList
|
||||
import net.neoforged.fml.common.Mod
|
||||
import net.neoforged.neoforge.common.NeoForge
|
||||
import net.neoforged.neoforge.event.AddPackFindersEvent
|
||||
import net.neoforged.neoforge.event.RegisterCommandsEvent
|
||||
import net.neoforged.neoforge.event.level.BlockEvent
|
||||
import net.neoforged.neoforge.event.server.ServerStartedEvent
|
||||
import org.slf4j.Logger
|
||||
import thedarkcolour.kotlinforforge.neoforge.forge.MOD_BUS
|
||||
|
||||
@Mod(CobbleSurvival.MOD_ID)
|
||||
class CobbleSurvival {
|
||||
companion object {
|
||||
const val MOD_ID = "cobblesurvival"
|
||||
val LOGGER: Logger = LogUtils.getLogger()
|
||||
|
||||
val version: String
|
||||
get() = ModList.get().getModContainerById(MOD_ID)
|
||||
.map { it.modInfo.version.toString() }
|
||||
.orElse("unknown")
|
||||
|
||||
/** One line the server smoke test reads over RCON to confirm the mod is live. */
|
||||
fun statusLine() =
|
||||
"$MOD_ID $version ok; cobblemon ${Cobblemon.VERSION}; species ${PokemonSpecies.count()}"
|
||||
}
|
||||
|
||||
init {
|
||||
LOGGER.info("Cobblemon Survival companion {} loaded (Cobblemon {})", version, Cobblemon.VERSION)
|
||||
MOD_BUS.addListener(::onAddPackFinders)
|
||||
NeoForge.EVENT_BUS.addListener(::onRegisterCommands)
|
||||
NeoForge.EVENT_BUS.addListener(::onServerStarted)
|
||||
NeoForge.EVENT_BUS.addListener(::onPortalSpawn)
|
||||
NeoForge.EVENT_BUS.addListener(OnlyPokemon::onChunkLoad)
|
||||
NeoForge.EVENT_BUS.addListener(OnlyPokemon::onEntityJoin)
|
||||
Permadeath.register()
|
||||
ZoneCondition.register()
|
||||
NeoForge.EVENT_BUS.addListener(Zones::onAddReloadListeners)
|
||||
SelfTest.register()
|
||||
}
|
||||
|
||||
/** The island world type has no Nether, so a lit obsidian frame must not turn into a dead portal. */
|
||||
private fun onPortalSpawn(event: BlockEvent.PortalSpawnEvent) {
|
||||
val level = event.level as? ServerLevel ?: return
|
||||
if (level.server.getLevel(Level.NETHER) == null) {
|
||||
event.isCanceled = true
|
||||
}
|
||||
}
|
||||
|
||||
/** Ships datapacks/core from the repo as a built-in data pack that is always on, in every world. */
|
||||
private fun onAddPackFinders(event: AddPackFindersEvent) {
|
||||
event.addPackFinders(
|
||||
ResourceLocation.fromNamespaceAndPath(MOD_ID, "datapacks/core"),
|
||||
PackType.SERVER_DATA,
|
||||
Component.literal("Cobblemon Survival core data"),
|
||||
PackSource.BUILT_IN,
|
||||
true,
|
||||
Pack.Position.TOP,
|
||||
)
|
||||
}
|
||||
|
||||
private fun onRegisterCommands(event: RegisterCommandsEvent) {
|
||||
val root = Commands.literal(MOD_ID)
|
||||
.requires { it.hasPermission(2) }
|
||||
.then(Commands.literal("status").executes { context ->
|
||||
context.source.sendSuccess({ Component.literal(statusLine()) }, false)
|
||||
1
|
||||
})
|
||||
.then(BiomePreview.command())
|
||||
.then(Commands.literal("zone").executes { context ->
|
||||
val source = context.source
|
||||
val zone = Zones.at(source.level, BlockPos.containing(source.position))
|
||||
val text = zone?.let { "${it.name} (${it.id}), Lv ${it.minLevel}-${it.maxLevel}" } ?: "no zone"
|
||||
source.sendSuccess({ Component.literal(text) }, false)
|
||||
1
|
||||
})
|
||||
if (SelfTest.enabled) root.then(SelfTest.command())
|
||||
event.dispatcher.register(root)
|
||||
}
|
||||
|
||||
private fun onServerStarted(event: ServerStartedEvent) {
|
||||
LOGGER.info("Cobblemon Survival companion ready: {}", statusLine())
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user