Compare commits

..
Author SHA1 Message Date
Sterrezo 5362995fbb Added checks for wing flap sound keyframes 2026-05-27 14:23:26 +02:00
Sterrezo 98a7240191 Lenient spellcheck 2026-05-27 02:08:11 +02:00
Sterrezo 84adc0e1cb Minor oopsie 2026-05-27 01:55:55 +02:00
Sterrezo 3ab2dfa0b3 Anti-optimizations 2026-05-27 01:47:28 +02:00
Sterrezo 86e8238230 Grammar 2026-05-26 20:16:31 +02:00
Sterrezo bdc7b5a504 Small correction 2026-05-26 20:10:07 +02:00
Sterrezo f3c165d282 Added geo and detailed locator parity checks 2026-05-26 20:04:04 +02:00
Sterrezo 9caf8376bc Made this thing easier to use 2026-05-26 17:53:17 +02:00
Sterrezo 9f998d92e6 Added a script to automatically find issues 2026-05-25 17:55:36 +02:00
Polymeta a91bf60ff8 pokemon that get fished now get marked as "seen" in pokedex
Closes #2015

Signed-off-by: Polymeta <4726322-polymeta@users.noreply.gitlab.com>
2026-05-22 18:05:49 +01:00
Polymeta 2d4c419216 remove unused override for chests
Closes #2016

Signed-off-by: Polymeta <4726322-polymeta@users.noreply.gitlab.com>
2026-05-22 18:01:10 +01:00
15 changed files with 1083 additions and 245 deletions

No files matched your search

+1
View File
@@ -24,6 +24,7 @@ eclipse
run
runClient
runServer
utilityscripts/implementation/*.txt
# Files from Forge MDK
forge*changelog.txt
+2
View File
@@ -335,6 +335,8 @@
- Fixed Exploit where you could take out the bait or drop your Pokérod with bait to avoid consuming bait, now the bobber will just disappear if you do so
- Fixed Apricorn and Saccharine boats incorrectly using chest boat models
- Fixed wild and trainer battle AI refusing to select moves with the `adjacentAlly` target type, even when it's their only option
- Fixed Guilded chests being more accessible than intended
- Fixed fished up Pokémon not being added as "seen" to the Pokedex
### Developer
- Added `PokeSnackSpawnerFactory` which allows influence registration on PokeSnack encounters
@@ -12,7 +12,6 @@ import com.cobblemon.mod.common.api.net.NetworkPacket
import com.mojang.brigadier.arguments.ArgumentType
import kotlin.reflect.KClass
import net.minecraft.commands.synchronization.ArgumentTypeInfo
import net.minecraft.core.HolderLookup
import net.minecraft.resources.ResourceKey
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.MinecraftServer
@@ -169,16 +168,12 @@ interface CobblemonImplementation {
* TODO
*
* @param identifier
* @param reloaderFactory
* @param reloader
* @param type
* @param dependencies
*/
fun registerResourceReloader(
identifier: ResourceLocation,
type: PackType,
dependencies: Collection<ResourceLocation>,
reloaderFactory: (HolderLookup.Provider) -> PreparableReloadListener
)
fun registerResourceReloader(identifier: ResourceLocation, reloader: PreparableReloadListener, type: PackType, dependencies: Collection<ResourceLocation>)
/**
* TODO
*
@@ -1,93 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.data
import com.cobblemon.mod.common.util.endsWith
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import net.minecraft.core.HolderLookup
import java.io.BufferedReader
import java.io.File
import java.util.concurrent.ExecutionException
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.packs.PackType
import net.minecraft.server.packs.resources.ResourceManager
/**
* A [DataRegistry] that consumes JSON files.
* Every deserialized instance is attached to an [Identifier].
* For example a file under data/mymod/[resourcePath]/entry.json would be backed by the identifier modid:entry.
*
* @param T The type of the data consumed by this registry.
*
* @author Licious
* @since August 5th, 2022
*/
interface ServerJsonDataRegistry<T> : DataRegistry {
/**
* The [TypeToken] of type [T].
*/
val typeToken: TypeToken<T>
/**
* The folder location for the data this registry will consume.
*/
val resourcePath: String
override val type: PackType
get() = PackType.SERVER_DATA
override fun reload(manager: ResourceManager) {
//NO-OP, handled by reload(manager, registry)
}
fun reload(manager: ResourceManager, registry: HolderLookup.Provider) {
val gson = setupParser(registry)
val data = hashMapOf<ResourceLocation, T>()
manager.listResources(resourcePath) { path -> path.endsWith(JSON_EXTENSION) }.forEach { (identifier, resource) ->
if (identifier.namespace == "pixelmon") {
return@forEach
}
resource.open().use { stream ->
stream.bufferedReader().use { reader ->
val resolvedIdentifier = ResourceLocation.fromNamespaceAndPath(identifier.namespace, File(identifier.path).nameWithoutExtension)
data[resolvedIdentifier] = parse(reader, resolvedIdentifier, gson)
}
}
}
reload(data, registry)
}
fun parse(reader: BufferedReader, identifier: ResourceLocation, gson: Gson): T {
return try {
gson.fromJson(reader, typeToken.type)
} catch (exception: Exception) {
throw ExecutionException("Error loading JSON for data: $identifier", exception)
}
}
/**
* Allows the creation of [Gson] instances which have adapters that are registry-aware, e.g. [com.cobblemon.mod.common.pokemon.evolution.adapters.LegacyItemConditionWrapperAdapter]
*/
fun setupParser(registry: HolderLookup.Provider): Gson
/**
* Reloads this registry from the deserialized data.
*
* @param data A map of the data associating an instance to the respective identifier from the [ResourceManager].
*/
fun reload(data: Map<ResourceLocation, T>, registry: HolderLookup.Provider)
companion object {
const val JSON_EXTENSION = ".json"
}
}
@@ -10,7 +10,7 @@ package com.cobblemon.mod.common.api.interaction
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.api.conditional.RegistryLikeCondition
import com.cobblemon.mod.common.api.data.ServerJsonDataRegistry
import com.cobblemon.mod.common.api.data.JsonDataRegistry
import com.cobblemon.mod.common.api.molang.ExpressionLike
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
import com.cobblemon.mod.common.api.pokemon.requirement.Requirement
@@ -26,7 +26,6 @@ import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.google.gson.reflect.TypeToken
import net.minecraft.advancements.critereon.ItemPredicate
import net.minecraft.core.HolderLookup
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerPlayer
import net.minecraft.server.packs.PackType
@@ -37,31 +36,28 @@ import net.minecraft.world.level.block.Block
import net.minecraft.world.level.levelgen.structure.Structure
import net.minecraft.world.level.material.Fluid
object PokemonInteractions : ServerJsonDataRegistry<PokemonInteractionSet> {
object PokemonInteractions : JsonDataRegistry<PokemonInteractionSet> {
override val id = cobblemonResource("pokemon_interactions")
override val type = PackType.SERVER_DATA
override fun setupParser(registry: HolderLookup.Provider): Gson {
return GsonBuilder()
.registerTypeAdapter(ResourceLocation::class.java, IdentifierAdapter)
.registerTypeAdapter(PokemonProperties::class.java, pokemonPropertiesShortAdapter)
.registerTypeAdapter(ItemPredicate::class.java, LegacyItemConditionWrapperAdapter(registry))
.registerTypeAdapter(Requirement::class.java, CobblemonRequirementAdapter)
.registerTypeAdapter(InteractionEffect::class.java, InteractionEffectAdapter)
.registerTypeAdapter(ExpressionLike::class.java, ExpressionLikeAdapter)
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Biome::class.java).type, BiomeLikeConditionAdapter)
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Block::class.java).type, BlockLikeConditionAdapter)
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Item::class.java).type, ItemLikeConditionAdapter)
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Structure::class.java).type, StructureLikeConditionAdapter)
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Fluid::class.java).type, FluidLikeConditionAdapter)
.registerTypeAdapter(IntRange::class.java, IntRangeAdapter)
.registerTypeAdapterFactory(LowerCaseEnumTypeAdapterFactory())
.setPrettyPrinting()
.create()
}
override val observable = SimpleObservable<PokemonInteractions>()
override val typeToken: TypeToken<PokemonInteractionSet> = TypeToken.get(PokemonInteractionSet::class.java)
override val resourcePath = "pokemon_interactions"
override val gson: Gson = GsonBuilder()
.registerTypeAdapter(ResourceLocation::class.java, IdentifierAdapter)
.registerTypeAdapter(PokemonProperties::class.java, pokemonPropertiesShortAdapter)
.registerTypeAdapter(ItemPredicate::class.java, LegacyItemConditionWrapperAdapter)
.registerTypeAdapter(Requirement::class.java, CobblemonRequirementAdapter)
.registerTypeAdapter(InteractionEffect::class.java, InteractionEffectAdapter)
.registerTypeAdapter(ExpressionLike::class.java, ExpressionLikeAdapter)
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Biome::class.java).type, BiomeLikeConditionAdapter)
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Block::class.java).type, BlockLikeConditionAdapter)
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Item::class.java).type, ItemLikeConditionAdapter)
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Structure::class.java).type, StructureLikeConditionAdapter)
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Fluid::class.java).type, FluidLikeConditionAdapter)
.registerTypeAdapter(IntRange::class.java, IntRangeAdapter)
.registerTypeAdapterFactory(LowerCaseEnumTypeAdapterFactory())
.setPrettyPrinting()
.create()
val interactions = mutableListOf<PokemonInteractionSet>()
@@ -69,7 +65,7 @@ object PokemonInteractions : ServerJsonDataRegistry<PokemonInteractionSet> {
PokemonInteractionsSyncPacket(interactions).sendToPlayer(player)
}
override fun reload(data: Map<ResourceLocation, PokemonInteractionSet>, registry: HolderLookup.Provider) {
override fun reload(data: Map<ResourceLocation, PokemonInteractionSet>) {
interactions.clear()
val split = data.entries
.partition {
@@ -91,4 +87,4 @@ object PokemonInteractions : ServerJsonDataRegistry<PokemonInteractionSet> {
.flatMap { it.interactions }
.firstOrNull(interactionCheck)
}
}
}
@@ -103,8 +103,6 @@ class GildedChestBlockEntity(pos: BlockPos, state: BlockState, val type: Type =
return dir == Direction.DOWN
}
override fun stillValid(player: Player) = !player.isSpectator
override fun setItems(inventory: NonNullList<ItemStack>) {
inventoryContents = inventory
}
@@ -15,7 +15,6 @@ import com.cobblemon.mod.common.api.berry.Berries
import com.cobblemon.mod.common.api.cooking.Seasonings
import com.cobblemon.mod.common.api.data.DataProvider
import com.cobblemon.mod.common.api.data.DataRegistry
import com.cobblemon.mod.common.api.data.ServerJsonDataRegistry
import com.cobblemon.mod.common.api.dialogue.Dialogues
import com.cobblemon.mod.common.api.events.CobblemonEvents
import com.cobblemon.mod.common.api.fishing.PokeRods
@@ -52,7 +51,6 @@ import com.cobblemon.mod.common.pokemon.properties.PropertiesCompletionProvider
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.ifClient
import com.cobblemon.mod.common.util.server
import net.minecraft.core.HolderLookup
import java.util.UUID
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerPlayer
@@ -121,9 +119,9 @@ object CobblemonDataProvider : DataProvider {
}
ifClient {
Cobblemon.implementation.registerResourceReloader(cobblemonResource("client_resources"), PackType.CLIENT_RESOURCES, emptyList()) { ClientResourceReloader() }
Cobblemon.implementation.registerResourceReloader(cobblemonResource("client_resources"), SimpleResourceReloader(PackType.CLIENT_RESOURCES), PackType.CLIENT_RESOURCES, emptyList())
}
Cobblemon.implementation.registerResourceReloader(cobblemonResource("data_resources"), PackType.SERVER_DATA, emptyList()) { ServerResourceReloader(it) }
Cobblemon.implementation.registerResourceReloader(cobblemonResource("data_resources"), SimpleResourceReloader(PackType.SERVER_DATA), PackType.SERVER_DATA, emptyList())
}
override fun <T : DataRegistry> register(registry: T, reloadable: Boolean): T {
@@ -162,22 +160,11 @@ object CobblemonDataProvider : DataProvider {
}
}
private class ClientResourceReloader : ResourceManagerReloadListener {
override fun onResourceManagerReload(manager: ResourceManager) {
registries.filter { it.type == PackType.CLIENT_RESOURCES }.forEach { it.reload(manager) }
}
}
private class ServerResourceReloader(private val registryAccess: HolderLookup.Provider) : ResourceManagerReloadListener {
private class SimpleResourceReloader(private val type: PackType) : ResourceManagerReloadListener {
override fun onResourceManagerReload(manager: ResourceManager) {
// Check for a server running, this is due to the create a world screen triggering datapack reloads, these are fine to happen as many times as needed as players may be in the process of adding their datapacks.
val reloadAllowed = server()?.isReady != true
registries
.filter { it.type == PackType.SERVER_DATA && (reloadAllowed || it in reloadableRegistries) }
.filterIsInstance<ServerJsonDataRegistry<*>>()
.forEach { it.reload(manager, registryAccess) }
registries
.filter { it.type == PackType.SERVER_DATA && (reloadAllowed || it in reloadableRegistries) }
registries.filter { it.type == this.type && (reloadAllowed || it in reloadableRegistries) }
.forEach { it.reload(manager) }
}
}
@@ -16,6 +16,7 @@ import com.cobblemon.mod.common.advancement.CobblemonCriteria
import com.cobblemon.mod.common.advancement.criterion.ReelInPokemonContext
import com.cobblemon.mod.common.api.events.CobblemonEvents
import com.cobblemon.mod.common.api.events.fishing.BobberSpawnPokemonEvent
import com.cobblemon.mod.common.api.events.pokemon.PokemonSeenEvent
import com.cobblemon.mod.common.api.fishing.SpawnBait
import com.cobblemon.mod.common.api.fishing.SpawnBaitEffects
import com.cobblemon.mod.common.api.scheduling.afterOnServer
@@ -875,7 +876,10 @@ class PokeRodFishingBobberEntity(type: EntityType<out PokeRodFishingBobberEntity
if (player !in player.level().players()) {
return@afterOnServer
}
spawnedPokemon?.forceBattle(player)
spawnedPokemon?.let {
it.forceBattle(player)
CobblemonEvents.POKEMON_SEEN.post(PokemonSeenEvent(uuid, it.pokemon))
}
}
return true
@@ -9,7 +9,6 @@
package com.cobblemon.mod.common.pokemon.evolution.adapters
import com.cobblemon.mod.common.util.adapters.CodecBackedAdapter
import com.cobblemon.mod.common.util.adapters.RegistryAccessResolver
import com.google.gson.JsonDeserializationContext
import com.google.gson.JsonDeserializer
import com.google.gson.JsonElement
@@ -20,7 +19,6 @@ import net.minecraft.advancements.critereon.ItemCustomDataPredicate
import net.minecraft.advancements.critereon.ItemPredicate
import net.minecraft.advancements.critereon.ItemSubPredicates
import net.minecraft.advancements.critereon.NbtPredicate
import net.minecraft.core.HolderLookup
import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.core.registries.Registries
import net.minecraft.resources.ResourceLocation
@@ -28,16 +26,13 @@ import net.minecraft.tags.TagKey
import java.lang.reflect.Type
// This is an ugly adapter because breaking changes are scary and people would ;(
class LegacyItemConditionWrapperAdapter(val registryAccess: HolderLookup.Provider = RegistryAccessResolver.getAccess())
: JsonDeserializer<ItemPredicate>, JsonSerializer<ItemPredicate> {
object LegacyItemConditionWrapperAdapter : JsonDeserializer<ItemPredicate>, JsonSerializer<ItemPredicate> {
companion object {
private const val TAG_PREFIX = "#"
private const val LEGACY_ITEM = "item"
private const val LEGACY_NBT = "nbt"
}
private const val TAG_PREFIX = "#"
private const val LEGACY_ITEM = "item"
private const val LEGACY_NBT = "nbt"
private val codecAdapter = CodecBackedAdapter(ItemPredicate.CODEC, registryAccess)
private val codecAdapter = CodecBackedAdapter(ItemPredicate.CODEC)
override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): ItemPredicate {
if (json.isJsonPrimitive) {
@@ -69,9 +64,7 @@ class LegacyItemConditionWrapperAdapter(val registryAccess: HolderLookup.Provide
{ id ->
if (isTag) {
val tag = TagKey.create(Registries.ITEM, id)
registryAccess.lookup(Registries.ITEM)
.map { builder.of(tag) }
.orElseGet { builder }
builder.of(tag)
} else {
BuiltInRegistries.ITEM.getOptional(id)
.map { builder.of(it) }
@@ -82,4 +75,4 @@ class LegacyItemConditionWrapperAdapter(val registryAccess: HolderLookup.Provide
)
}
}
}
@@ -10,19 +10,16 @@ package com.cobblemon.mod.common.util.adapters
import com.google.gson.*
import com.mojang.serialization.Codec
import com.mojang.serialization.JsonOps
import net.minecraft.core.HolderLookup
import net.minecraft.resources.RegistryOps
import java.lang.reflect.Type
class CodecBackedAdapter<T>(val codec: Codec<T>, val registryAccess: HolderLookup.Provider = RegistryAccessResolver.getAccess()) : JsonDeserializer<T>, JsonSerializer<T> {
class CodecBackedAdapter<T>(val codec: Codec<T>) : JsonDeserializer<T>, JsonSerializer<T> {
override fun deserialize(
jElement: JsonElement,
typeOfT: Type,
context: JsonDeserializationContext
): T {
val ops = RegistryOps.create(JsonOps.INSTANCE, registryAccess)
val ops = RegistryOpsProvider.getOpsWithDefaultFallback()
val result = ops.withDecoder(codec).apply(jElement)
return result.result().orElseThrow {
IllegalStateException("Failed to deserialize $jElement: ${result.error().orElse(null)}")
@@ -34,7 +31,7 @@ class CodecBackedAdapter<T>(val codec: Codec<T>, val registryAccess: HolderLooku
typeOfSrc: Type?,
context: JsonSerializationContext?
): JsonElement {
val ops = RegistryOps.create(JsonOps.INSTANCE, registryAccess)
val ops = RegistryOpsProvider.getOpsWithDefaultFallback()
val result = ops.withEncoder(codec).apply(src)
return result.result().orElseThrow {
IllegalStateException("Failed to serialize $src: ${result.error().orElse(null)}")
@@ -15,33 +15,27 @@ import com.google.gson.JsonElement
import com.mojang.serialization.DynamicOps
import com.mojang.serialization.JsonOps
import net.minecraft.client.Minecraft
import net.minecraft.core.RegistryAccess
import net.minecraft.resources.RegistryOps
/**
* Utility for getting RegistryAccess with the correct client/server registry access.
* Used when as a fallback when manually encoding/decoding registry-backed values (e.g., items, predicates).
* Utility for obtaining RegistryOps with the correct client/server registry access.
* Used when manually encoding/decoding registry-backed values (e.g., items, predicates).
*/
object RegistryAccessResolver {
fun getAccess(): RegistryAccess {
try {
Cobblemon.implementation
} catch (e: UninitializedPropertyAccessException) {
return RegistryAccess.EMPTY
}
object RegistryOpsProvider {
fun getOpsWithDefaultFallback(): DynamicOps<JsonElement> {
if (Cobblemon.implementation.environment() == Environment.CLIENT) {
val minecraft = Minecraft.getInstance()
if (minecraft != null && minecraft.level != null)
return minecraft.level!!.registryAccess()
return RegistryOps.create(JsonOps.INSTANCE, minecraft.level!!.registryAccess())
}
if (Cobblemon.implementation.environment() == Environment.SERVER) {
val server = server()
if (server != null)
return server.registryAccess()
return RegistryOps.create(JsonOps.INSTANCE, server.registryAccess())
}
return RegistryAccess.EMPTY
return JsonOps.INSTANCE
}
}
@@ -59,9 +59,7 @@ import net.fabricmc.fabric.impl.resource.loader.ResourceManagerHelperImpl
import net.fabricmc.loader.api.FabricLoader
import net.minecraft.client.Minecraft
import net.minecraft.commands.synchronization.ArgumentTypeInfo
import net.minecraft.core.HolderLookup
import net.minecraft.core.Registry
import net.minecraft.core.RegistryAccess
import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.network.syncher.EntityDataSerializers
import net.minecraft.resources.ResourceKey
@@ -347,52 +345,8 @@ object CobblemonFabric : CobblemonImplementation {
}
}
override fun registerResourceReloader(
identifier: ResourceLocation,
type: PackType,
dependencies: Collection<ResourceLocation>,
reloaderFactory: (HolderLookup.Provider) -> PreparableReloadListener
) {
if (type == PackType.SERVER_DATA) {
val resourceLoader = ResourceManagerHelper.get(PackType.CLIENT_RESOURCES)
resourceLoader.registerReloadListener(identifier, { object : IdentifiableResourceReloadListener {
override fun reload(
synchronizer: PreparableReloadListener.PreparationBarrier,
manager: ResourceManager,
prepareProfiler: ProfilerFiller,
applyProfiler: ProfilerFiller,
prepareExecutor: Executor,
applyExecutor: Executor
): CompletableFuture<Void> {
return reloaderFactory.invoke(it).reload(synchronizer,
manager, prepareProfiler, applyProfiler,
prepareExecutor, applyExecutor)
}
override fun getFabricId() = identifier
}})
}
else {
val resourceLoader = ResourceManagerHelper.get(PackType.CLIENT_RESOURCES)
resourceLoader.registerReloadListener(object : IdentifiableResourceReloadListener {
override fun reload(
synchronizer: PreparableReloadListener.PreparationBarrier,
manager: ResourceManager,
prepareProfiler: ProfilerFiller,
applyProfiler: ProfilerFiller,
prepareExecutor: Executor,
applyExecutor: Executor
): CompletableFuture<Void> {
return reloaderFactory.invoke(RegistryAccess.EMPTY).reload(synchronizer,
manager, prepareProfiler, applyProfiler,
prepareExecutor, applyExecutor)
}
override fun getFabricId() = identifier
})
}
override fun registerResourceReloader(identifier: ResourceLocation, reloader: PreparableReloadListener, type: PackType, dependencies: Collection<ResourceLocation>) {
ResourceManagerHelper.get(type).registerReloadListener(CobblemonReloadListener(identifier, reloader, dependencies))
}
override fun server(): MinecraftServer? = if (this.environment() == Environment.CLIENT) Minecraft.getInstance().singleplayerServer else this.server
@@ -38,8 +38,6 @@ import com.cobblemon.mod.neoforge.worldgen.CobblemonBiomeModifiers
import com.mojang.brigadier.arguments.ArgumentType
import net.minecraft.commands.synchronization.ArgumentTypeInfo
import net.minecraft.commands.synchronization.ArgumentTypeInfos
import net.minecraft.core.HolderLookup
import net.minecraft.core.RegistryAccess
import net.minecraft.core.registries.Registries
import net.minecraft.resources.ResourceKey
import net.minecraft.resources.ResourceLocation
@@ -94,16 +92,11 @@ import kotlin.reflect.KClass
@Mod(Cobblemon.MODID)
class CobblemonNeoForge : CobblemonImplementation {
private data class QueuedReloadListener(
val identifier: ResourceLocation,
val listener: (HolderLookup.Provider) -> PreparableReloadListener,
val dependencies: Collection<ResourceLocation>
)
override val modAPI = ModAPI.NEOFORGE
private val hasBeenSynced = hashSetOf<UUID>()
private val commandArgumentTypes = DeferredRegister.create(Registries.COMMAND_ARGUMENT_TYPE, Cobblemon.MODID)
private val reloadableResources = arrayListOf<QueuedReloadListener>()
private val reloadableResources = arrayListOf<PreparableReloadListener>()
private val queuedWork = arrayListOf<() -> Unit>()
override val networkManager = CobblemonNeoForgeNetworkManager
@@ -445,24 +438,17 @@ class CobblemonNeoForge : CobblemonImplementation {
}
}
override fun registerResourceReloader(
identifier: ResourceLocation,
type: PackType,
dependencies: Collection<ResourceLocation>,
reloaderFactory: (HolderLookup.Provider) -> PreparableReloadListener
) {
override fun registerResourceReloader(identifier: ResourceLocation, reloader: PreparableReloadListener, type: PackType, dependencies: Collection<ResourceLocation>) {
if (type == PackType.SERVER_DATA) {
this.reloadableResources += QueuedReloadListener(identifier, reloaderFactory, dependencies)
this.reloadableResources += reloader
}
else {
CobblemonNeoForgeClient.registerResourceReloader(reloaderFactory.invoke(RegistryAccess.EMPTY)) // client resources dont need access
CobblemonNeoForgeClient.registerResourceReloader(reloader)
}
}
private fun onReload(e: AddReloadListenerEvent) {
this.reloadableResources.forEach { queued ->
e.addListener(queued.listener.invoke(e.serverResources.registryLookup))
}
this.reloadableResources.forEach(e::addListener)
}
override fun server(): MinecraftServer? = ServerLifecycleHooks.getCurrentServer()
+16
View File
@@ -0,0 +1,16 @@
Hello!
This is a script for checking asset implementation.
You will need Python. If you don't have it already, install it from here: https://www.python.org/downloads/
Then you will need external libraries, open the terminal (search for `cmd` on Windows) and type in the following: `pip install pandas soundfile`
If the terminal says "Requirement already satisfied," but the script doesn't work, try this instead:
- Type in `py -0p`, this will show installed versions and highlight your default with `*`
- Type in `py -3.14 -m pip install pandas soundfile`, replace `-3.14` with your default version
The script assumes `cobblemon-assets` is in the same directory as `cobblemon`, the main mod where you're running this script from.
If not, create "assets_directory.txt" and paste in the path to where your assets repository is cloned.
For example `D:\Dev\Cobblemon\Repository\cobblemon-assets`
This text file will be ignored by Git.
If there are any issues, or you need help with anything, poke Sterr on Discord.
File diff suppressed because it is too large. Load diff