Compare commits
11
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5362995fbb | ||
|
|
98a7240191 | ||
|
|
84adc0e1cb | ||
|
|
3ab2dfa0b3 | ||
|
|
86e8238230 | ||
|
|
bdc7b5a504 | ||
|
|
f3c165d282 | ||
|
|
9caf8376bc | ||
|
|
9f998d92e6 | ||
|
|
a91bf60ff8 | ||
|
|
2d4c419216 |
No files matched your search
@@ -24,6 +24,7 @@ eclipse
|
||||
run
|
||||
runClient
|
||||
runServer
|
||||
utilityscripts/implementation/*.txt
|
||||
|
||||
# Files from Forge MDK
|
||||
forge*changelog.txt
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
+20
-24
@@ -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) }
|
||||
}
|
||||
}
|
||||
|
||||
+5
-1
@@ -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
|
||||
|
||||
+7
-14
@@ -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)}")
|
||||
|
||||
+7
-13
@@ -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()
|
||||
|
||||
@@ -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
Reference in new issue
Block a user