diff --git a/.github/workflows/build_artifacts.yml b/.github/workflows/build_artifacts.yml index 6c1c10e..4c66dbb 100644 --- a/.github/workflows/build_artifacts.yml +++ b/.github/workflows/build_artifacts.yml @@ -54,4 +54,4 @@ jobs: uses: actions/upload-artifact@v4 with: name: Artifacts - path: build/libs/ + path: ./loader/*/*/build/libs/ diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml deleted file mode 100644 index 5df68ad..0000000 --- a/.github/workflows/docs.yml +++ /dev/null @@ -1,60 +0,0 @@ -name: Publish docs - -on: - push: - branches: - - "*" - release: - types: [published] - - -jobs: - publish-docs: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Set url prefix - run: | - if [[ "${{ github.event_name }}" == "push" ]]; then - echo "url_prefix=staging-" >> "$GITHUB_ENV" - echo "seelf_env=staging" >> "$GITHUB_ENV" - else - echo "url_prefix=" >> "$GITHUB_ENV" - echo "seelf_env=production" >> "$GITHUB_ENV" - fi - - - name: Store short commit hash - run: echo "short_commit_hash=$(git rev-parse --short "$GITHUB_SHA")" >> "$GITHUB_ENV" - - - uses: danielr1996/envsubst-action@1.1.0 - env: - URL_PREFIX: ${{ env.url_prefix }} - SHORT_COMMIT_HASH: ${{ env.short_commit_hash }} - with: - input: docker-compose-template.yml - output: docker-compose.yml - - - name: Login to container registry - uses: docker/login-action@v3 - with: - registry: registry.oracle.offsetmonkey538.top - username: ${{ secrets.REGISTRY_USER }} - password: ${{ secrets.REGISTRY_PASSWORD }} - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Build and push - uses: docker/build-push-action@v6 - with: - context: . - push: true - tags: registry.oracle.offsetmonkey538.top/loot-table-modifier/docs:${{ env.short_commit_hash }} - - - run: | - tar -czf archive.tar.gz docker-compose.yml && curl -i -X POST -H "Authorization: Bearer $SEELF_TOKEN" -F environment=$SEELF_ENVIRONMENT -F archive=@archive.tar.gz $SEELF_APPLICATION_URL - env: - SEELF_TOKEN: ${{ secrets.SEELF_TOKEN }} - SEELF_ENVIRONMENT: ${{ env.seelf_env }} - SEELF_APPLICATION_URL: https://seelf.oracle.offsetmonkey538.top/api/v1/apps/300qBnG3t1dOFrUGfw1EeWYwKYA/deployments diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index c9d030d..fd37e9b 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -26,14 +26,12 @@ jobs: with: cache-read-only: false - - name: Store short commit hash - run: echo "short_commit_hash=$(git rev-parse --short "$GITHUB_SHA")" >> "$GITHUB_ENV" - - name: Generate resources with Gradle run: ./gradlew runDatagenClient env: IS_RELEASE: true DISABLE_PROPERTIES_UPDATE: true + VERSION_SUFFIX: "" - name: Build with Gradle @@ -41,12 +39,14 @@ jobs: env: IS_RELEASE: true DISABLE_PROPERTIES_UPDATE: true + VERSION_SUFFIX: "" - name: Upload to Modrinth run: ./gradlew modrinth env: IS_RELEASE: true DISABLE_PROPERTIES_UPDATE: true + VERSION_SUFFIX: "" MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }} VERSION_NAME: ${{ github.event.release.name }} VERSION_IS_PRERELEASE: ${{ github.event.release.prerelease }} @@ -57,10 +57,11 @@ jobs: env: IS_RELEASE: true DISABLE_PROPERTIES_UPDATE: true + VERSION_SUFFIX: "" MAVEN_USERNAME: ${{ secrets.MAVEN_USERNAME }} MAVEN_PASSWORD: ${{ secrets.MAVEN_PASSWORD }} - name: Upload to GitHub uses: softprops/action-gh-release@v2 with: - files: build/libs/*.jar + files: ./loader/*/*/build/libs/ diff --git a/.gitignore b/.gitignore index 8a8d2c7..1e457fe 100644 --- a/.gitignore +++ b/.gitignore @@ -5,11 +5,36 @@ out classes # Fabric -run/ -src/main/generated/* +**/run/ +**/src/main/generated/* # Java hs_err_*.log replay_*.log *.hprof *.jfr + + + +## Docs related stuff. Docs is on separate branch, but checking out between them will leave docs stuff at the root level +# build output +dist/ +# generated types +.astro/ + +# dependencies +node_modules/ + +# logs +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* + + +# environment variables +.env +.env.production + +# macOS-specific files +.DS_Store diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 93abdf3..0000000 --- a/Dockerfile +++ /dev/null @@ -1,40 +0,0 @@ -#FROM nginx:alpine AS runtime -#COPY ./nginx.conf /etc/nginx/nginx.conf -#COPY ./dist /usr/share/nginx/html -#CMD ["nginx", "-g", "daemon off;"] - -#FROM httpd:latest AS runtime -#COPY ./dist /usr/local/apache2/htdocs/ - -FROM node:lts-slim AS base -ENV PNPM_HOME="/pnpm" -ENV PATH="$PATH:$PNPM_HOME" -RUN corepack enable -COPY /docs /docs -WORKDIR /docs - -FROM base AS build -RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile -RUN pnpm run build - -FROM httpd:alpine -COPY --from=build /docs/dist /usr/local/apache2/htdocs/ -EXPOSE 80 - - -#FROM base -#COPY --from=prod-deps -#COPY package.json pnpm-lock.yaml -#RUN npm install -g pnpm - - - -#FROM node:lts AS setup -#WORKDIR /docs -#COPY ./docs . -#RUN npm install -g pnpm -#RUN pnpm i -#RUN pnpm run build - -#FROM httpd:2.4 AS runtime -#COPY --from=build /docs/dist /usr/local/apache2/htdocs/ diff --git a/README.md b/README.md index ef44504..ace2386 100644 --- a/README.md +++ b/README.md @@ -1,84 +1,31 @@ # Loot Table Modifier -[![discord-singular](https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/cozy/social/discord-singular_vector.svg)](https://discord.offsetmonkey538.top/) -[![modrinth](https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/cozy/available/modrinth_vector.svg)](https://modrinth.com/mod/loot-table-modifier) +[![Chat with me on Discord](https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/cozy/social/discord-singular_vector.svg)](https://discord.offsetmonkey538.top/) +[![Available on Modrinth](https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/cozy/available/modrinth_vector.svg)](https://modrinth.com/mod/loot-table-modifier) +[![Requires MonkeyLib538](https://raw.githubusercontent.com/OffsetMods538/MonkeyLib538/master/images/requires_monkeylib538.png)](https://modrinth.com/mod/monkeylib538) [![Requires Fabric API](https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/cozy/requires/fabric-api_vector.svg)](https://modrinth.com/mod/fabric-api) -todo: good readme for alpha version +## Why? +Vanilla datapacks can only replace existing loot tables, which is not good for being compatible with other datapacks that also try to replace the same table. +This mod fixes that by implementing a system of *loot modifiers*, which do just that, modify loot (tables)! -Allows datapacks to modify loot tables, instead of just overwriting them. -Version 2 of the mod is currently in alpha. v2 adds more ways to modify loot tables than just adding to them -v2 will be backwards-compatible with v1 modifiers, so no need to worry about them breaking. +Unlike some other mods (*ahem* KubeJS) which work by running code at runtime to intercept and change drops, Loot Table Modifier modifies the loot tables as they're loaded from datapacks. +This means that the mod will only hurt performance during data loading, but has no performance impact during gameplay!¹ -If you want to use v1, then see the original description below. -If you do decide to try out the alpha version of v2 (please do), then please go ahead and read the documentation [here](https://loot-table-modifier.docs.offsetmonkey538.top/) and if you encounter any problems, have suggestions for new actions/predicates or just want to say literally anything about the mod, please please please join my discord and tell me about it. I want to make this as good as I can and any sort of feedback really helps. +###### ¹ Except when you make zombies drop a bajillion stacks of diamonds or something crazy like that, but that's really not the mod's fault 😅 +## Usage +### Players +This mod does *nothing* when installed on its own. There needs to be some sort of datapack present that uses loot modifiers. +If you are using some mod or datapack which depends on Loot Table Modifier, just download the latest version for the Minecraft version you use from the versions page and add it to your mods folder. +List of projects utilizing Loot Table Modifier: +- I don't know of any yet 😅 Please do hit me up on discord or something if you wanna add your project here :D -## Original Description +### Mod, Modpack or Datapack developers +Follow the documentation available [here](https://loot-table-modifier.docs.offsetmonkey538.top). -Allows datapacks (and thus mods as well) to add to loot tables, instead of just overwriting them. +This mod is allowed to be used in Modrinth modpacks. +I don't think I can legally prevent redistribution when using the MIT license, but I'd really appreciate if the mod wouldn't be redistributed as part of a modpack on other platforms. -This mod shouldn't impact performance while playing the game, but only when datapacks are reloading (joining a world, starting a server, `/reload` command, whatever else). -Performance impact during pack reloading varies depending on the datapacks. -The mod writes how long applying modifiers took in the console. -Also provides a datagen provider for creating loot table modifiers in mods. - -A modifier json file includes two components: -1. `"modifies"` - string or array, which defines the loot tables to modify. For example `"minecraft:entities/creeper"` or `"minecraft:chests/abandoned_mineshaft"` -2. `"pools"` - array of loot pools. This works exactly the same as the `"pools"` in a vanilla loot table, thus you can generate a loot table online with a tool like [misode.github.io](https://misode.github.io/loot-table/) and copy over the `"pools"` from the generated json. (I may fork it and add a generator for specifically this mod in the future™) -An example json file: -```json5 -// example_pack/data/example/loot-table-modifier/loot_modifier/drop_tnt.json -{ - // Can also be a single identifier without an array - // "modifies": "minecraft:entities/creeper", - "modifies": [ - "minecraft:entities/creeper", - "minecraft:entities/zombie" - ], - "pools": [ - { - "bonus_rolls": 0.0, - "entries": [ - { - "type": "minecraft:item", - "functions": [ - { - "add": false, - "count": { - "type": "minecraft:uniform", - "max": 1.0, - "min": 0.0 - }, - "function": "minecraft:set_count" - } - ], - "name": "minecraft:tnt" - } - ], - "rolls": 1.0 - } - ] -} -``` - -Depend on inside mod: -```groovy -repositories { - // ... - maven { - name = "OffsetMods538" - url = "https://maven.offsetmonkey538.top/releases" - content { - includeGroup "top.offsetmonkey538.loottablemodifier" - } - } -} - - -dependencies { - // ... - modImplementation "top.offsetmonkey538.loottablemodifier:loot-table-modifier:1.0.1+1.21.1" -} -``` +###### This mod collects anonymous usage statistics, read more about what's collected [here](https://github.com/OffsetMods538/MonkeyMetrics-Server). No personal data is collected. This can be disabled by modifying the config at `config/monkeylib538/telemetry.json` or by running the `/monkeylib538 telemetry set isEnabled false` command. diff --git a/build.gradle b/build.gradle index 2a84be7..4697179 100644 --- a/build.gradle +++ b/build.gradle @@ -1,12 +1,14 @@ -import dex.plugins.outlet.v2.util.ReleaseType +import org.codehaus.groovy.runtime.GStringImpl import java.nio.file.Files plugins { - id 'fabric-loom' version '1.11-SNAPSHOT' - id 'io.github.dexman545.outlet' version '1.6.1' - id 'com.modrinth.minotaur' version '2.+' - id 'maven-publish' + id 'java' + id 'java-library' + id 'net.neoforged.moddev' version '2.0.+' apply false + id 'fabric-loom' version '1.14-SNAPSHOT' apply false + id 'io.github.dexman545.outlet' version '1.6.1' apply false + id 'com.modrinth.minotaur' version '2.+' apply false } ext { @@ -22,224 +24,36 @@ ext { var separator = "-" if (versionPrefix.contains("-")) separator = "." - versionPrefix = "${versionPrefix}${separator}${preReleaseVersion}" + versionPrefix = "${versionPrefix}${separator}${preReleaseVersion}" as GStringImpl } final String versionSuffix = System.getenv("VERSION_SUFFIX") - if (versionSuffix != null && !versionSuffix.isEmpty()) { - versionPrefix = "${versionPrefix}+${versionSuffix}" - } + versionPrefix = "${versionPrefix}${versionSuffix == null ? "+local" : versionSuffix.isEmpty() ? "" : "+${versionSuffix}"}" as GStringImpl System.out.println("Version Prefix: " + versionPrefix) } allprojects { - group = "top.offsetmonkey538.loottablemodifier" - base.archivesName = "mesh-lib" // todo: move to subprojects and give em different suffixes - version = "${rootProject.versionPrefix}+${project.property("minecraft_version")}" // todo: again, move to subprojects -} - -outlet { - maintainPropertiesFile = System.getenv("DISABLE_PROPERTIES_UPDATE") == null - mcVersionRange = project.supported_minecraft_versions - allowedReleaseTypes = [ReleaseType.RELEASE] - propertiesData = [ - 'fapi_version': outlet.fapiVersion(project.minecraft_version), - 'yarn_version': outlet.yarnVersion(project.minecraft_version), - 'loader_version': outlet.loaderVersion() - ] -} - - -loom { - splitEnvironmentSourceSets() - - mods { - modid { - sourceSet sourceSets.main - sourceSet sourceSets.client - } - } - - accessWidenerPath = file("src/main/resources/loot-table-modifier.accesswidener") - - runs { - server { - runDir "run/server" - } - client { - runDir "run/client" - } - datagenClient { - inherit client - name "Data Generation" - vmArg "-Dfabric-api.datagen" - vmArg "-Dfabric-api.datagen.output-dir=${file("src/main/generated")}" - vmArg "-Dfabric-api.datagen.modid=loot-table-modifier" - - runDir "build/datagen" - } - } -} - -// https://gist.github.com/maityyy/3dbcd558d58a6412c3a2a38c72706e8e -afterEvaluate { - loom.runs.configureEach { - vmArg "-javaagent:${configurations.compileClasspath.find{ it.name.contains("sponge-mixin") }}" - if (System.getenv("DISABLE_PROPERTIES_UPDATE") == null) vmArg "-Ddevauth.enabled=true" - } -} -sourceSets { - main { - resources { - srcDirs += [ - "src/main/generated" - ] - } - } -} - -configurations { - includeModImplementation - - include.extendsFrom includeModImplementation - modImplementation.extendsFrom includeModImplementation - - - includeImplementation - - include.extendsFrom includeImplementation - implementation.extendsFrom includeImplementation - - - includeApi - - include.extendsFrom includeApi - api.extendsFrom includeApi -} - -repositories { - mavenCentral() - mavenLocal() - maven { - name = "DevAuth" - url = "https://pkgs.dev.azure.com/djtheredstoner/DevAuth/_packaging/public/maven/v1" - content { - includeGroup "me.djtheredstoner" - } - } -} - -dependencies { - minecraft "com.mojang:minecraft:${project.minecraft_version}" - mappings "net.fabricmc:yarn:${project.yarn_version}:v2" - modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" - - // DevAuth - modLocalRuntime "me.djtheredstoner:DevAuth-fabric:${devauth_version}" - // Fabric API - modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fapi_version}" - - // Uncomment for including a module of fabric api - // includeModImplementation fabricApi.module("fabric-api-base", project.fapi_version) -} - -processResources { - final Map properties = Map.of( - "modVersion", project.mod_version, - "supportedMinecraftVersions", project.supported_minecraft_versions - ) - - inputs.properties(properties) - - filesMatching("fabric.mod.json") { - expand(properties) - } - - exclude ".cache/**" -} - -tasks.withType(JavaCompile).configureEach { - it.options.release = 17 -} - -java { - withSourcesJar() - withJavadocJar() -} -tasks.named("javadoc", Javadoc) { - options.addFileOption('-add-stylesheet', project.file("javadoc-stylesheet.css")) - - options { - links( - "https://maven.fabricmc.net/docs/fabric-api-${project.fapi_version}/", - "https://maven.fabricmc.net/docs/yarn-${project.yarn_version}/" - ) - } -} - -jar { - from("${rootProject.projectDir}/LICENSE") { - rename { "${it}" } - } -} - -modrinth { - // Main properties - token = System.getenv("MODRINTH_TOKEN") - projectId = "loot-table-modifier" - gameVersions = outlet.mcVersions() - loaders = ["fabric"] - - // Version stuff - def customVersionName = System.getenv("VERSION_NAME") - if (customVersionName != null) versionName = customVersionName - - versionNumber = "${project.version}" - - versionType = Boolean.parseBoolean(System.getenv("VERSION_IS_PRERELEASE")) ? "beta" : "release" - - if (rootProject.mod_version.contains("beta")) versionType = "beta" - if (rootProject.mod_version.contains("alpha")) versionType = "alpha" - - - // Files - uploadFile = remapJar.archiveFile - additionalFiles = [sourcesJar.archiveFile] - - - // Project info - syncBodyFrom = rootProject.file("README.md").text - def changelogEnv = System.getenv("VERSION_CHANGELOG") - if (changelogEnv != null) changelog = changelogEnv - - - dependencies { - required.project "fabric-api" - } -} - -tasks.modrinth.dependsOn(tasks.modrinthSyncBody) - - -publishing { - repositories { - maven { - name = "OffsetMonkey538" - url = "https://maven.offsetmonkey538.top/releases" - credentials { - username = providers.gradleProperty("OffsetMonkey538Username").getOrElse(System.getenv("MAVEN_USERNAME")) - password = providers.gradleProperty("OffsetMonkey538Password").getOrElse(System.getenv("MAVEN_PASSWORD")) - } - authentication { - basic(BasicAuthentication) - } - } - } - publications { - maven(MavenPublication) { - artifactId = base.archivesName.get() + apply plugin: "java-library" + + repositories { + mavenCentral() + mavenLocal() + exclusiveContent { + forRepositories( + maven { + name = "OffsetMods538" + url = "https://maven.offsetmonkey538.top/releases" + }, + mavenLocal() + ) + filter { + includeGroupAndSubgroups "top.offsetmonkey538" + } + } + } - from(components["java"]) - } - } + dependencies { + // TODO: jspecify: compileOnlyApi "org.jspecify:jspecify:${rootProject.jspecify_version}" + compileOnlyApi "org.jetbrains:annotations:${rootProject.jetbrainsannotations_version}" + } } diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle new file mode 100644 index 0000000..1957c33 --- /dev/null +++ b/buildSrc/build.gradle @@ -0,0 +1,3 @@ +plugins { + id 'groovy-gradle-plugin' +} \ No newline at end of file diff --git a/buildSrc/src/main/groovy/multiloader-base.gradle b/buildSrc/src/main/groovy/multiloader-base.gradle new file mode 100644 index 0000000..d03fe6d --- /dev/null +++ b/buildSrc/src/main/groovy/multiloader-base.gradle @@ -0,0 +1,97 @@ +plugins { + id 'java-library' + id 'maven-publish' +} + +base.archivesName = "loot-table-modifier-${project.project_name}" +version = project.project_name == project.name ? "${rootProject.versionPrefix}+${project.project_name}" : "${rootProject.versionPrefix}+${project.getParent().project_name}+${project.minecraft_version}" + +configurations { + commonJava { + canBeResolved = true + canBeConsumed = true + } + commonResources { + canBeResolved = true + canBeConsumed = true + } +} + +java { + withSourcesJar() + withJavadocJar() + + toolchain.languageVersion = JavaLanguageVersion.of(21) + sourceCompatibility = JavaVersion.VERSION_21 + targetCompatibility = JavaVersion.VERSION_21 +} + + +tasks.withType(JavaCompile).configureEach { + it.options.release = 21 +} + +tasks.named("javadoc", Javadoc) { + dependsOn configurations.commonJava + source configurations.commonJava + + options.addFileOption('-add-stylesheet', rootProject.file("javadoc-stylesheet.css")) +} + +tasks.named("sourcesJar", Jar) { + dependsOn configurations.commonJava + from configurations.commonJava + dependsOn configurations.commonResources + from configurations.commonResources + + from(rootProject.file("LICENSE")) { + rename { "${it}" } + } +} + +jar { + from(rootProject.file("LICENSE")) { + rename { "${it}" } + } + manifest { + attributes("Fabric-Loom-Remap": project.name == "common" ? "false" : "true") + } +} + +tasks.named("compileJava", JavaCompile) { + dependsOn configurations.commonJava + source configurations.commonJava +} + +processResources { + dependsOn configurations.commonResources + from configurations.commonResources +} + +artifacts { + commonJava sourceSets.main.java.sourceDirectories.singleFile + commonResources sourceSets.main.resources.sourceDirectories.singleFile +} + +publishing { + repositories { + maven { + name = "OffsetMonkey538" + url = "https://maven.offsetmonkey538.top/releases" + credentials { + username = providers.gradleProperty("OffsetMonkey538Username").getOrElse(System.getenv("MAVEN_USERNAME")) + password = providers.gradleProperty("OffsetMonkey538Password").getOrElse(System.getenv("MAVEN_PASSWORD")) + } + authentication { + basic(BasicAuthentication) + } + } + } + publications { + register("maven", MavenPublication) { + artifactId base.archivesName.get() + groupId "top.offsetmonkey538.loottablemodifier" + from components.java + } + } +} diff --git a/buildSrc/src/main/groovy/multiloader-modded.gradle b/buildSrc/src/main/groovy/multiloader-modded.gradle new file mode 100644 index 0000000..3c85049 --- /dev/null +++ b/buildSrc/src/main/groovy/multiloader-modded.gradle @@ -0,0 +1,19 @@ +plugins { + id 'multiloader-base' +} + +processResources { + final Map properties = [ + "modVersion" : project.version, + "fabricSupportedMinecraftVersions" : project.hasProperty("supported_minecraft_versions") ? project.findProperty("supported_minecraft_versions") : "", + "neoforgeSupportedMinecraftVersions": project.hasProperty("minecraft_version_range") ? project.findProperty("minecraft_version_range") : "", + "fabricDatagenEntrypoint" : project.hasProperty("fabricDatagenEntrypoint") ? project.findProperty("fabricDatagenEntrypoint") : "", + ] + inputs.properties(properties) + + filesMatching(["fabric.mod.json", "META-INF/neoforge.mods.toml", "META-INF/mods.toml"]) { + expand(properties) + } +} + + diff --git a/common/build.gradle b/common/build.gradle new file mode 100644 index 0000000..b0ba47a --- /dev/null +++ b/common/build.gradle @@ -0,0 +1,20 @@ +plugins { + id 'multiloader-base' +} + +repositories { + maven { + name = "Mojang Libraries" + url = "https://libraries.minecraft.net" + content { + includeGroup "com.mojang" + } + } +} + +dependencies { + compileOnlyApi "top.offsetmonkey538.monkeylib538:monkeylib538-common:${rootProject.monkeylib538_version}+common" + compileOnly "com.mojang:datafixerupper:${rootProject.datafixerupper_version}" + compileOnly "com.mojang:brigadier:${rootProject.brigadier_version}" + compileOnly "commons-io:commons-io:${rootProject.commonsio_version}" +} diff --git a/common/gradle.properties b/common/gradle.properties new file mode 100644 index 0000000..e99725d --- /dev/null +++ b/common/gradle.properties @@ -0,0 +1 @@ +project_name = common diff --git a/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/LootTableModifierCommon.java b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/LootTableModifierCommon.java new file mode 100644 index 0000000..77fe44a --- /dev/null +++ b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/LootTableModifierCommon.java @@ -0,0 +1,238 @@ +package top.offsetmonkey538.loottablemodifier.common; + +import com.google.common.base.Stopwatch; +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; +import com.google.gson.stream.JsonWriter; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.serialization.DataResult; +import com.mojang.serialization.DynamicOps; +import it.unimi.dsi.fastutil.Pair; +import org.apache.commons.io.file.PathUtils; +import org.jetbrains.annotations.Unmodifiable; +import top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierAction; +import top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierActionTypes; +import top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicateTypes; +import top.offsetmonkey538.loottablemodifier.common.api.resource.LootModifier; +import top.offsetmonkey538.loottablemodifier.common.api.resource.util.LootModifierContext; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.Identifier; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.ResourceManager; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootPool; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootTable; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.entry.LootPoolEntry; +import top.offsetmonkey538.loottablemodifier.common.platform.PlatformCommandUtils; +import top.offsetmonkey538.loottablemodifier.common.platform.PlatformMain; +import top.offsetmonkey538.monkeylib538.common.api.command.CommandRegistrationApi; +import top.offsetmonkey538.monkeylib538.common.api.log.MonkeyLibLogger; +import top.offsetmonkey538.monkeylib538.common.api.platform.LoaderUtil; +import top.offsetmonkey538.monkeylib538.common.api.telemetry.TelemetryRegistry; +import top.offsetmonkey538.monkeylib538.common.api.text.MonkeyLibStyle; +import top.offsetmonkey538.monkeylib538.common.api.text.MonkeyLibText; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.*; +import java.util.stream.Stream; + +import static top.offsetmonkey538.monkeylib538.common.api.command.CommandAbstractionApi.*; + +public final class LootTableModifierCommon { + public static final String MOD_ID = "loot-table-modifier"; + public static final MonkeyLibLogger LOGGER = MonkeyLibLogger.create(MOD_ID); + + public static final boolean IS_DEV; + static { + final String isDev = System.getProperty("lootTableModifierDev", ""); + if (isDev.equalsIgnoreCase("true")) IS_DEV = true; + else if (isDev.equalsIgnoreCase("false")) IS_DEV = false; // This way it can be disabled in devenv too. + else IS_DEV = LoaderUtil.isDevelopmentEnvironment(); + } + + // Only used when IS_DEV is true + private static final List MODIFIED_TABLE_IDs; + static { + if (IS_DEV) MODIFIED_TABLE_IDs = Collections.synchronizedList(new ArrayList<>(0)); + else MODIFIED_TABLE_IDs = null; + } + + public static void initialize() { + TelemetryRegistry.register(MOD_ID); + + LootModifierActionTypes.register(); + LootModifierPredicateTypes.register(); + + if (IS_DEV) enableDebug(); + } + + public static void runModification(ResourceManager resourceManager, Stream> lootRegistry, DynamicOps registryOps) { + LOGGER.info("Gathering loot tables..."); + final Stopwatch stopwatch = Stopwatch.createStarted(); + + // Streams are lazy so calling toList here means all the intermediary steps will only now be executed and counted between the stopwatch. + final List> tables = lootRegistry.toList(); + + LOGGER.info("Gathered %s loot tables in %s", tables.size(), stopwatch.stop()); + + LootTableModifierCommon.runModification(loadModifiers(resourceManager, registryOps), tables); + } + + private static Map loadModifiers(ResourceManager resourceManager, DynamicOps registryOps) { + LOGGER.info("Loading loot table modifiers..."); + final Stopwatch stopwatch = Stopwatch.createStarted(); + + final Map result = new HashMap<>(); + + resourceManager.listResources(MOD_ID + "/loot_modifier", path -> path.endsWith(".json")).forEach(resource -> { + final Identifier id = resource.left(); + + try { + LOGGER.debug("Loading load loot table modifier from '%s'", id); + result.put( + id, + // Can't just use orElseThrow cause 1.20.1 don't have that + LootModifier.CODEC.decode(registryOps, JsonParser.parseReader(resource.right().get())).map(com.mojang.datafixers.util.Pair::getFirst).resultOrPartial(error -> {throw new RuntimeException(error);}).orElseThrow() + ); + } catch (Exception e) { + LOGGER.error("Failed to load loot table modifier from '%s'!", e, id); + } + }); + + LOGGER.info("Loaded %s loot modifiers in %s!", result.size(), stopwatch.stop()); + + return result; + } + + //public static void runModification(ResourceManager resourceManager, Registry lootRegistry, RegistryOps registryOps) { + private static void runModification(Map modifiers, @Unmodifiable List> tables) { + final List modifiedTableIds = new ArrayList<>(); // Used for exporting modified ones + int poolsModified = 0, entriesModified = 0; + boolean tableModified, poolModified; + + LOGGER.info("Modifying loot tables..."); + final Stopwatch stopwatch = Stopwatch.createStarted(); + + for (Pair tableEntry : tables) { + final Identifier tableId = tableEntry.left(); + final LootTable table = tableEntry.right(); + + tableModified = false; + + final LootPool[] poolsCopy = table.getPools().toArray(LootPool[]::new); + int poolsSize = Math.max(1, poolsCopy.length); // Run loop at least once + for (int i = 0; i < poolsSize; i++) { + final LootPool pool = poolsCopy.length == 0 ? null : poolsCopy[i]; + poolModified = false; + + final LootPoolEntry[] entriesCopy = pool == null ? new LootPoolEntry[]{} : pool.getEntries().toArray(LootPoolEntry[]::new); + int entriesSize = Math.max(1, entriesCopy.length); // Run loop at least once + for (int j = 0; j < entriesSize; j++) { + final LootPoolEntry entry = entriesCopy.length == 0 ? null : entriesCopy[j]; + + for (Map.Entry modifierEntry : modifiers.entrySet()) { + final LootModifierContext context = new LootModifierContext(table, tableId, pool, entry, tableModified, poolModified); + + final LootModifier modifier = modifierEntry.getValue(); + if (!modifier.test(context)) continue; + + if (IS_DEV) LOGGER.warn("Modifier %s can modify table %s", modifierEntry.getKey(), tableId); + + + int result = modifier.apply(context); + + if (IS_DEV && result != LootModifierAction.MODIFIED_NONE) LOGGER.warn("Modifier %s modified table %s with modified mask %s", modifierEntry.getKey(), tableId, Integer.toUnsignedString(result, 2)); + + if ((result & LootModifierAction.MODIFIED_TABLE) == LootModifierAction.MODIFIED_TABLE) tableModified = true; + if ((result & LootModifierAction.MODIFIED_POOL) == LootModifierAction.MODIFIED_POOL) poolModified = true; + if ((result & LootModifierAction.MODIFIED_ENTRY) == LootModifierAction.MODIFIED_ENTRY) entriesModified++; + } + } + + poolsModified += poolModified ? 1 : 0; + } + if (tableModified) modifiedTableIds.add(tableId); + } + + + LOGGER.info("Applied %s modifiers and modified %s entries, %s pools and %s loot tables in %s!", modifiers.size(), entriesModified, poolsModified, modifiedTableIds.size(), stopwatch.stop()); + + if (!IS_DEV) return; + + LOGGER.warn("Dev mode enabled, modified loot tables can be exported using the '/loot-table-modifier debug export' command"); + synchronized (MODIFIED_TABLE_IDs) { + MODIFIED_TABLE_IDs.clear(); + MODIFIED_TABLE_IDs.addAll(modifiedTableIds); + } + } + + private static void enableDebug() { + CommandRegistrationApi.registerCommand( + literal(MOD_ID) + .then( + literal("debug") + .then( + literal("export") + .executes( + LootTableModifierCommon::executeExportCommand + ) + ) + ) + ); + } + + private static int executeExportCommand(CommandContext context) { + synchronized (MODIFIED_TABLE_IDs) { + final DynamicOps ops = PlatformCommandUtils.getRegistryOps(context); + + try { + final Path exportDir = LoaderUtil.getGameDir().resolve(".loot-table-modifier").resolve("export"); + if (Files.exists(exportDir)) PathUtils.deleteDirectory(exportDir); + + sendText( + context, + MonkeyLibText + .of("Exporting modified tables to ") + .append(MonkeyLibText.of(exportDir.toString()).setStyle( + MonkeyLibStyle.empty() + .withUnderline(true) + .withColor(MonkeyLibStyle.Color.WHITE) + .withShowText(MonkeyLibText.of("Click to copy")) + .withCopyToClipboard(exportDir.toAbsolutePath().toString()) + )) + ); + final Stopwatch stopwatch = Stopwatch.createStarted(); + + for (Identifier id : MODIFIED_TABLE_IDs) { + final LootTable table = PlatformCommandUtils.getTableForId(context, id); + final Path file = exportDir.resolve(id.getNamespace()).resolve(id.getPath() + ".json"); + Files.createDirectories(file.getParent()); + + LOGGER.warn("Exporting loot table to %s", file); + DataResult dataResult = LootTable.CODEC_PROVIDER.get().encodeStart(ops, table); + final Optional optionalResult = dataResult.resultOrPartial(LOGGER::error); + final JsonElement result = optionalResult.orElseThrow(); + + LOGGER.warn("Writing loot table to %s", file); + + try (JsonWriter jsonWriter = new JsonWriter(Files.newBufferedWriter(file, StandardCharsets.UTF_8))) { + jsonWriter.setSerializeNulls(false); + jsonWriter.setIndent(" "); + PlatformMain.writeSorted(jsonWriter, result); + } + } + sendMessage(context, "Exported %s modified tables in %s".formatted(MODIFIED_TABLE_IDs.size(), stopwatch.stop())); + } catch (IOException e) { + throw new RuntimeException("Failed to export modified tables!", e); + } + + return 1; + } + } + + public static T load(Class clazz) { + return java.util.ServiceLoader.load(clazz, LootTableModifierCommon.class.getClassLoader()) + .findFirst() + .orElseThrow(() -> new RuntimeException("Failed to load service for " + clazz.getName())); + } +} diff --git a/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/LootModifier.java b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/LootModifier.java similarity index 81% rename from src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/LootModifier.java rename to common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/LootModifier.java index d3a3647..1831dbd 100644 --- a/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/LootModifier.java +++ b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/LootModifier.java @@ -1,40 +1,37 @@ -package top.offsetmonkey538.loottablemodifier.api.resource; +package top.offsetmonkey538.loottablemodifier.common.api.resource; import com.google.common.collect.ImmutableList; import com.mojang.datafixers.util.Either; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import net.minecraft.loot.LootPool; -import net.minecraft.util.Identifier; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.UnmodifiableView; -import top.offsetmonkey538.loottablemodifier.api.datagen.LootModifierProvider; -import top.offsetmonkey538.loottablemodifier.api.resource.action.pool.PoolAddAction; -import top.offsetmonkey538.loottablemodifier.api.resource.action.LootModifierAction; -import top.offsetmonkey538.loottablemodifier.api.resource.predicate.LootModifierPredicate; -import top.offsetmonkey538.loottablemodifier.api.resource.predicate.table.TablePredicate; -import top.offsetmonkey538.loottablemodifier.api.resource.util.LootModifierContext; +import top.offsetmonkey538.loottablemodifier.common.api.resource.action.pool.PoolAddAction; +import top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierAction; +import top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicate; +import top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.table.TablePredicate; +import top.offsetmonkey538.loottablemodifier.common.api.resource.util.LootModifierContext; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.Identifier; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootPool; import java.util.*; import java.util.function.Predicate; -import static top.offsetmonkey538.loottablemodifier.LootTableModifier.LOGGER; -import static top.offsetmonkey538.loottablemodifier.api.resource.action.LootModifierAction.MODIFIED_NONE; +import static top.offsetmonkey538.loottablemodifier.common.LootTableModifierCommon.LOGGER; +import static top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierAction.MODIFIED_NONE; /** - * A loot modifier. Use the {@link LootModifier.Builder} for building it and the {@link LootModifierProvider} for generating the files. - * * @param actions a list of actions to apply * @param predicate the predicate */ public record LootModifier(@NotNull @UnmodifiableView List actions, @NotNull LootModifierPredicate predicate) implements Predicate { private static final Codec LEGACY_CODEC = RecordCodecBuilder.create(instance -> instance.group( - Codec.either(Identifier.CODEC, Identifier.CODEC.listOf()).fieldOf("modifies").forGetter(modifier -> { + Codec.either(Identifier.CODEC_PROVIDER.get(), Identifier.CODEC_PROVIDER.get().listOf()).fieldOf("modifies").forGetter(modifier -> { throw new IllegalStateException("Tried using legacy loot table modifier codec for serialization for some reason!"); }), - LootPool.CODEC.listOf().optionalFieldOf("pools").forGetter(lootModifier -> Optional.empty()), - LootPool.CODEC.listOf().optionalFieldOf("loot_pools").forGetter(lootModifier -> Optional.empty()) + LootPool.CODEC_PROVIDER.get().listOf().optionalFieldOf("pools").forGetter(lootModifier -> Optional.empty()), + LootPool.CODEC_PROVIDER.get().listOf().optionalFieldOf("loot_pools").forGetter(lootModifier -> Optional.empty()) ).apply(instance, (modifiesEither, pools, lootPools) -> new LootModifier(getActionsFromLegacyCodec(pools, lootPools), getPredicateFromLegacyCodec(modifiesEither)))); private static final Codec CURRENT_CODEC = RecordCodecBuilder.create(instance -> instance.group( @@ -63,7 +60,7 @@ public record LootModifier(@NotNull @UnmodifiableView List a private static @NotNull LootModifierPredicate getPredicateFromLegacyCodec(@NotNull Either> modifiesEither) { final TablePredicate.Builder predicateBuilder = TablePredicate.builder(); for (final Identifier currentId : modifiesEither.map(List::of, it -> it)) { - predicateBuilder.name(currentId); + predicateBuilder.name(currentId.asString()); } return predicateBuilder.build(); } diff --git a/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/action/LootModifierAction.java b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/action/LootModifierAction.java similarity index 82% rename from src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/action/LootModifierAction.java rename to common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/action/LootModifierAction.java index bdf74ab..5a64a0a 100644 --- a/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/action/LootModifierAction.java +++ b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/action/LootModifierAction.java @@ -1,8 +1,8 @@ -package top.offsetmonkey538.loottablemodifier.api.resource.action; +package top.offsetmonkey538.loottablemodifier.common.api.resource.action; import com.mojang.serialization.Codec; import org.jetbrains.annotations.NotNull; -import top.offsetmonkey538.loottablemodifier.api.resource.util.LootModifierContext; +import top.offsetmonkey538.loottablemodifier.common.api.resource.util.LootModifierContext; /** * A loot modifier action @@ -11,7 +11,7 @@ public interface LootModifierAction { /** * Codec containing the type id */ - Codec CODEC = LootModifierActionType.REGISTRY.getCodec().dispatch(LootModifierAction::getType, LootModifierActionType::codec); + Codec CODEC = LootModifierActionType.CODEC_PROVIDER.get(); /** * Bitmask specifying that the action modified nothing diff --git a/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/action/LootModifierActionType.java b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/action/LootModifierActionType.java new file mode 100644 index 0000000..067adfe --- /dev/null +++ b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/action/LootModifierActionType.java @@ -0,0 +1,46 @@ +package top.offsetmonkey538.loottablemodifier.common.api.resource.action; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.Identifier; + +import java.util.function.Supplier; + +import static top.offsetmonkey538.loottablemodifier.common.LootTableModifierCommon.load; + +/** + * The type of a {@link LootModifierAction}, holds the codec. + * + * @param codec the codec for this action. + */ +public record LootModifierActionType(@NotNull MapCodec codec) { + /** + * Provides codec for {@link LootModifierActionType} + */ + public static final Supplier> CODEC_PROVIDER = load(CodecProvider.class); + + /** + * Register method + * + * @param id the identifier to register as + * @param codec the codec for the loot modifier action type + * @return a loot modifier action type for the provided codec + */ + public static LootModifierActionType register(final @NotNull Identifier id, final @NotNull MapCodec codec) { + return Registry.INSTANCE.register(id, new LootModifierActionType(codec)); + } + + @ApiStatus.Internal + public interface Registry { + Registry INSTANCE = load(Registry.class); + + LootModifierActionType register(final @NotNull Identifier id, final @NotNull LootModifierActionType type); + } + + @ApiStatus.Internal + public interface CodecProvider extends Supplier> { + + } +} diff --git a/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/action/LootModifierActionTypes.java b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/action/LootModifierActionTypes.java new file mode 100644 index 0000000..6a0302e --- /dev/null +++ b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/action/LootModifierActionTypes.java @@ -0,0 +1,60 @@ +package top.offsetmonkey538.loottablemodifier.common.api.resource.action; + +import org.jetbrains.annotations.ApiStatus; +import top.offsetmonkey538.loottablemodifier.common.api.resource.action.condition.ConditionAddAction; +import top.offsetmonkey538.loottablemodifier.common.api.resource.action.entry.EntryAddAction; +import top.offsetmonkey538.loottablemodifier.common.api.resource.action.entry.EntryRemoveAction; +import top.offsetmonkey538.loottablemodifier.common.api.resource.action.pool.PoolAddAction; +import top.offsetmonkey538.loottablemodifier.common.api.resource.action.entry.EntryItemSetAction; +import top.offsetmonkey538.loottablemodifier.common.api.resource.action.pool.PoolRemoveAction; + +import static top.offsetmonkey538.loottablemodifier.common.platform.PlatformMain.id; + +/** + * Contains all {@link LootModifierAction} types available in Loot Table Modifier. + *
+ * Use their builders to create them. + */ +public final class LootModifierActionTypes { + private LootModifierActionTypes() { + + } + + /** + * Type of {@link PoolAddAction} + */ + public static final LootModifierActionType POOL_ADD = LootModifierActionType.register(id("pool_add"), PoolAddAction.CODEC); + /** + * Type of {@link PoolRemoveAction} + */ + public static final LootModifierActionType POOL_REMOVE = LootModifierActionType.register(id("pool_remove"), PoolRemoveAction.CODEC); + + /** + * Type of {@link EntryAddAction} + */ + public static final LootModifierActionType ENTRY_ADD = LootModifierActionType.register(id("entry_add"), EntryAddAction.CODEC); + /** + * Type of {@link EntryRemoveAction} + */ + public static final LootModifierActionType ENTRY_REMOVE = LootModifierActionType.register(id("entry_remove"), EntryRemoveAction.CODEC); + /** + * Type of {@link EntryItemSetAction} + */ + public static final LootModifierActionType ENTRY_ITEM_SET = LootModifierActionType.register(id("entry_item_set"), EntryItemSetAction.CODEC); + + /** + * Type of {@link ConditionAddAction} + */ + public static final LootModifierActionType CONDITION_ADD = LootModifierActionType.register(id("condition_add"), ConditionAddAction.CODEC); + + + /** + * Registers action types by loading the class. + *
+ * Only for the loot table modifier initializer to call, NO TOUCHY >:( + */ + @ApiStatus.Internal + public static void register() { + // Registers action types by loading the class + } +} diff --git a/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/action/condition/ConditionAddAction.java b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/action/condition/ConditionAddAction.java similarity index 69% rename from src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/action/condition/ConditionAddAction.java rename to common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/action/condition/ConditionAddAction.java index b7e765b..596dd89 100644 --- a/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/action/condition/ConditionAddAction.java +++ b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/action/condition/ConditionAddAction.java @@ -1,20 +1,20 @@ -package top.offsetmonkey538.loottablemodifier.api.resource.action.condition; +package top.offsetmonkey538.loottablemodifier.common.api.resource.action.condition; import com.google.common.collect.ImmutableList; import com.mojang.serialization.Codec; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import net.minecraft.loot.LootPool; -import net.minecraft.loot.condition.LootCondition; -import net.minecraft.loot.entry.LootPoolEntry; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; -import top.offsetmonkey538.loottablemodifier.api.resource.action.LootModifierAction; -import top.offsetmonkey538.loottablemodifier.api.resource.action.LootModifierActionType; -import top.offsetmonkey538.loottablemodifier.api.resource.action.LootModifierActionTypes; -import top.offsetmonkey538.loottablemodifier.api.resource.util.LootModifierContext; -import top.offsetmonkey538.loottablemodifier.duck.LootElementWithConditions; - +import top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierAction; +import top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierActionType; +import top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierActionTypes; +import top.offsetmonkey538.loottablemodifier.common.api.resource.util.LootModifierContext; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootCondition; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootPool; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.entry.LootPoolEntry; + +import java.util.ArrayList; import java.util.List; /** @@ -26,7 +26,7 @@ */ public record ConditionAddAction(List conditions, boolean includePools, boolean includeEntries) implements LootModifierAction { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - LootCondition.CODEC.listOf().fieldOf("conditions").forGetter(ConditionAddAction::conditions), + LootCondition.CODEC_PROVIDER.get().listOf().fieldOf("conditions").forGetter(ConditionAddAction::conditions), Codec.BOOL.optionalFieldOf("includePools", true).forGetter(ConditionAddAction::includePools), Codec.BOOL.optionalFieldOf("includeEntries", true).forGetter(ConditionAddAction::includeEntries) ).apply(instance, ConditionAddAction::new)); @@ -44,12 +44,10 @@ public int apply(@NotNull LootModifierContext context) { int returnValue = MODIFIED_NONE; if (includePools && !context.poolAlreadyModified()) { - final List newConditions = ImmutableList.builder() - .addAll(pool.conditions) - .addAll(conditions) - .build(); + final ArrayList poolConditions = pool.getConditions(); + poolConditions.addAll(conditions); + pool.setConditions(poolConditions); - ((LootElementWithConditions) pool).loot_table_modifier$setConditions(newConditions); returnValue |= MODIFIED_POOL; } @@ -59,12 +57,9 @@ public int apply(@NotNull LootModifierContext context) { final LootPoolEntry entry = context.entry(); if (entry == null) return returnValue | MODIFIED_NONE; - final List newConditions = ImmutableList.builder() - .addAll(entry.conditions) - .addAll(conditions) - .build(); - - ((LootElementWithConditions) entry).loot_table_modifier$setConditions(newConditions); + final ArrayList entryConditions = entry.getConditions(); + entryConditions.addAll(conditions); + entry.setConditions(entryConditions); return MODIFIED_ENTRY; } @@ -93,12 +88,12 @@ private Builder() { /** * Adds a condition * - * @param conditionBuilder The condition to add + * @param condition The condition to add * @return this */ @Contract("_->this") - public ConditionAddAction.Builder condition(LootCondition.Builder conditionBuilder) { - this.conditions.add(conditionBuilder.build()); + public ConditionAddAction.Builder condition(LootCondition condition) { + this.conditions.add(condition); return this; } diff --git a/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/action/entry/EntryAddAction.java b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/action/entry/EntryAddAction.java similarity index 60% rename from src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/action/entry/EntryAddAction.java rename to common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/action/entry/EntryAddAction.java index 0a9ceab..9d49f6c 100644 --- a/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/action/entry/EntryAddAction.java +++ b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/action/entry/EntryAddAction.java @@ -1,19 +1,18 @@ -package top.offsetmonkey538.loottablemodifier.api.resource.action.entry; +package top.offsetmonkey538.loottablemodifier.common.api.resource.action.entry; import com.google.common.collect.ImmutableList; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import net.minecraft.loot.LootPool; -import net.minecraft.loot.entry.LootPoolEntry; -import net.minecraft.loot.entry.LootPoolEntryTypes; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; -import top.offsetmonkey538.loottablemodifier.api.resource.action.LootModifierAction; -import top.offsetmonkey538.loottablemodifier.api.resource.action.LootModifierActionType; -import top.offsetmonkey538.loottablemodifier.api.resource.action.LootModifierActionTypes; -import top.offsetmonkey538.loottablemodifier.api.resource.util.LootModifierContext; -import top.offsetmonkey538.loottablemodifier.mixin.LootPoolAccessor; +import top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierAction; +import top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierActionType; +import top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierActionTypes; +import top.offsetmonkey538.loottablemodifier.common.api.resource.util.LootModifierContext; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootPool; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.entry.LootPoolEntry; +import java.util.ArrayList; import java.util.List; /** @@ -23,7 +22,7 @@ */ public record EntryAddAction(List entries) implements LootModifierAction { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - LootPoolEntryTypes.CODEC.listOf().fieldOf("entries").forGetter(EntryAddAction::entries) + LootPoolEntry.CODEC_PROVIDER.get().listOf().fieldOf("entries").forGetter(EntryAddAction::entries) ).apply(instance, EntryAddAction::new)); @Override @@ -38,12 +37,9 @@ public int apply(@NotNull LootModifierContext context) { final LootPool pool = context.pool(); if (pool == null) return MODIFIED_NONE; - final List newEntries = ImmutableList.builder() - .addAll(pool.entries) - .addAll(this.entries) - .build(); - - ((LootPoolAccessor) pool).setEntries(newEntries); + final ArrayList poolEntries = pool.getEntries(); + poolEntries.addAll(this.entries); + pool.setEntries(poolEntries); return MODIFIED_ENTRY; } @@ -71,12 +67,12 @@ private Builder() { /** * Adds an entry * - * @param entryBuilder The entry to add + * @param entry The entry to add * @return this */ @Contract("_->this") - public EntryAddAction.Builder entry(LootPoolEntry.Builder entryBuilder) { - this.entries.add(entryBuilder.build()); + public EntryAddAction.Builder entry(LootPoolEntry entry) { + this.entries.add(entry); return this; } diff --git a/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/action/entry/EntryItemSetAction.java b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/action/entry/EntryItemSetAction.java new file mode 100644 index 0000000..4db0b9b --- /dev/null +++ b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/action/entry/EntryItemSetAction.java @@ -0,0 +1,60 @@ +package top.offsetmonkey538.loottablemodifier.common.api.resource.action.entry; + +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierActionTypes; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.Item; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.entry.ItemEntry; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.entry.LootPoolEntry; +import top.offsetmonkey538.loottablemodifier.common.api.resource.util.LootModifierContext; +import top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierAction; +import top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierActionType; + +import static top.offsetmonkey538.loottablemodifier.common.LootTableModifierCommon.IS_DEV; +import static top.offsetmonkey538.loottablemodifier.common.LootTableModifierCommon.LOGGER; + +/** + * Sets the item in matched item entries + * + * @param item the new item to replace the existing one with + */ +public record EntryItemSetAction(Item item) implements LootModifierAction { + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( + Item.CODEC_PROVIDER.get().fieldOf("name").forGetter(EntryItemSetAction::item) + ).apply(instance, EntryItemSetAction::new)); + + @Override + public LootModifierActionType getType() { + return LootModifierActionTypes.ENTRY_ITEM_SET; + } + + @Override + public int apply(@NotNull LootModifierContext context) { + final LootPoolEntry entry = context.entry(); + if (entry == null) return MODIFIED_NONE; + + if (entry instanceof ItemEntry itemEntry) { + itemEntry.setItem(item); + return MODIFIED_ENTRY; + } + + // Matched entry is not an ItemEntry + LOGGER.error("loot-table-modifier:entry_item_set action matched for non-item entry!"); + if (IS_DEV) throw new IllegalStateException("loot-table-modifier:entry_item_set action matched for non-item entry!"); + + return MODIFIED_NONE; + } + + /** + * Creates a builder for {@link EntryItemSetAction} + * + * @param item the new item to replace the existing one with + * @return a new {@link EntryItemSetAction.Builder} + */ + @Contract("_->new") + public static EntryItemSetAction.Builder builder(@NotNull Item item) { + return () -> new EntryItemSetAction(item); + } +} diff --git a/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/action/entry/EntryRemoveAction.java b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/action/entry/EntryRemoveAction.java similarity index 54% rename from src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/action/entry/EntryRemoveAction.java rename to common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/action/entry/EntryRemoveAction.java index d07f05e..5a46c4c 100644 --- a/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/action/entry/EntryRemoveAction.java +++ b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/action/entry/EntryRemoveAction.java @@ -1,19 +1,19 @@ -package top.offsetmonkey538.loottablemodifier.api.resource.action.entry; +package top.offsetmonkey538.loottablemodifier.common.api.resource.action.entry; -import com.google.common.collect.ImmutableList; import com.mojang.serialization.Codec; import com.mojang.serialization.Decoder; import com.mojang.serialization.Encoder; import com.mojang.serialization.MapCodec; -import net.minecraft.loot.LootPool; -import net.minecraft.loot.entry.LootPoolEntry; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; -import top.offsetmonkey538.loottablemodifier.api.resource.action.LootModifierAction; -import top.offsetmonkey538.loottablemodifier.api.resource.action.LootModifierActionType; -import top.offsetmonkey538.loottablemodifier.api.resource.action.LootModifierActionTypes; -import top.offsetmonkey538.loottablemodifier.api.resource.util.LootModifierContext; -import top.offsetmonkey538.loottablemodifier.mixin.LootPoolAccessor; +import top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierAction; +import top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierActionType; +import top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierActionTypes; +import top.offsetmonkey538.loottablemodifier.common.api.resource.util.LootModifierContext; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootPool; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.entry.LootPoolEntry; + +import java.util.ArrayList; /** * Removes the matched entries from their pools @@ -32,14 +32,9 @@ public int apply(@NotNull LootModifierContext context) { final LootPoolEntry entry = context.entry(); if (pool == null || entry == null) return MODIFIED_NONE; - final ImmutableList.Builder newEntriesBuilder = ImmutableList.builder(); - - for (final LootPoolEntry originalEntry : pool.entries) { - if (originalEntry == entry) continue; - newEntriesBuilder.add(originalEntry); - } - - ((LootPoolAccessor) pool).setEntries(newEntriesBuilder.build()); + final ArrayList poolEntries = pool.getEntries(); + poolEntries.remove(entry); + pool.setEntries(poolEntries); return MODIFIED_ENTRY; } diff --git a/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/action/pool/PoolAddAction.java b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/action/pool/PoolAddAction.java similarity index 63% rename from src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/action/pool/PoolAddAction.java rename to common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/action/pool/PoolAddAction.java index f750d17..8965cb6 100644 --- a/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/action/pool/PoolAddAction.java +++ b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/action/pool/PoolAddAction.java @@ -1,17 +1,17 @@ -package top.offsetmonkey538.loottablemodifier.api.resource.action.pool; +package top.offsetmonkey538.loottablemodifier.common.api.resource.action.pool; import com.google.common.collect.ImmutableList; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import net.minecraft.loot.LootPool; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; -import top.offsetmonkey538.loottablemodifier.api.resource.action.LootModifierActionTypes; -import top.offsetmonkey538.loottablemodifier.mixin.LootTableAccessor; -import top.offsetmonkey538.loottablemodifier.api.resource.util.LootModifierContext; -import top.offsetmonkey538.loottablemodifier.api.resource.action.LootModifierAction; -import top.offsetmonkey538.loottablemodifier.api.resource.action.LootModifierActionType; +import top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierActionTypes; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootPool; +import top.offsetmonkey538.loottablemodifier.common.api.resource.util.LootModifierContext; +import top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierAction; +import top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierActionType; +import java.util.ArrayList; import java.util.List; /** @@ -21,7 +21,7 @@ */ public record PoolAddAction(List pools) implements LootModifierAction { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - LootPool.CODEC.listOf().fieldOf("pools").forGetter(PoolAddAction::pools) + LootPool.CODEC_PROVIDER.get().listOf().fieldOf("pools").forGetter(PoolAddAction::pools) ).apply(instance, PoolAddAction::new)); @Override @@ -33,12 +33,9 @@ public LootModifierActionType getType() { public int apply(@NotNull LootModifierContext context) { if (context.tableAlreadyModified()) return MODIFIED_NONE; - final List newPools = ImmutableList.builder() - .addAll(context.table().pools) - .addAll(this.pools) - .build(); - - ((LootTableAccessor) context.table()).setPools(newPools); + final ArrayList tablePools = context.table().getPools(); + tablePools.addAll(pools); + context.table().setPools(tablePools); return MODIFIED_POOL; } @@ -70,8 +67,8 @@ private Builder() { * @return this */ @Contract("_->this") - public PoolAddAction.Builder pool(LootPool.Builder poolBuilder) { - this.pools.add(poolBuilder.build()); + public PoolAddAction.Builder pool(LootPool poolBuilder) { + this.pools.add(poolBuilder); return this; } diff --git a/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/action/pool/PoolRemoveAction.java b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/action/pool/PoolRemoveAction.java similarity index 53% rename from src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/action/pool/PoolRemoveAction.java rename to common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/action/pool/PoolRemoveAction.java index e1debda..a5875fa 100644 --- a/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/action/pool/PoolRemoveAction.java +++ b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/action/pool/PoolRemoveAction.java @@ -1,19 +1,19 @@ -package top.offsetmonkey538.loottablemodifier.api.resource.action.pool; +package top.offsetmonkey538.loottablemodifier.common.api.resource.action.pool; -import com.google.common.collect.ImmutableList; import com.mojang.serialization.Codec; import com.mojang.serialization.Decoder; import com.mojang.serialization.Encoder; import com.mojang.serialization.MapCodec; -import net.minecraft.loot.LootPool; -import net.minecraft.loot.LootTable; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; -import top.offsetmonkey538.loottablemodifier.api.resource.action.LootModifierActionTypes; -import top.offsetmonkey538.loottablemodifier.mixin.LootTableAccessor; -import top.offsetmonkey538.loottablemodifier.api.resource.util.LootModifierContext; -import top.offsetmonkey538.loottablemodifier.api.resource.action.LootModifierAction; -import top.offsetmonkey538.loottablemodifier.api.resource.action.LootModifierActionType; +import top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierActionTypes; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootPool; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootTable; +import top.offsetmonkey538.loottablemodifier.common.api.resource.util.LootModifierContext; +import top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierAction; +import top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierActionType; + +import java.util.ArrayList; /** * Removes the matched pools from their tables @@ -32,14 +32,9 @@ public int apply(@NotNull LootModifierContext context) { final LootPool pool = context.pool(); if (pool == null) return MODIFIED_NONE; - final ImmutableList.Builder newPoolsBuilder = ImmutableList.builder(); - - for (LootPool originalPool : table.pools) { - if (originalPool == pool) continue; // I think we do want '==' here as the references should be the same? - newPoolsBuilder.add(originalPool); - } - - ((LootTableAccessor) table).setPools(newPoolsBuilder.build()); + final ArrayList tablePools = table.getPools(); + tablePools.remove(pool); + table.setPools(tablePools); return MODIFIED_POOL; } diff --git a/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/predicate/LootModifierPredicate.java b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/predicate/LootModifierPredicate.java similarity index 83% rename from src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/predicate/LootModifierPredicate.java rename to common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/predicate/LootModifierPredicate.java index a8eb983..d288ee2 100644 --- a/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/predicate/LootModifierPredicate.java +++ b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/predicate/LootModifierPredicate.java @@ -1,12 +1,12 @@ -package top.offsetmonkey538.loottablemodifier.api.resource.predicate; +package top.offsetmonkey538.loottablemodifier.common.api.resource.predicate; import com.mojang.serialization.Codec; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; -import top.offsetmonkey538.loottablemodifier.api.resource.util.LootModifierContext; -import top.offsetmonkey538.loottablemodifier.api.resource.predicate.op.AllOfPredicate; -import top.offsetmonkey538.loottablemodifier.api.resource.predicate.op.AnyOfPredicate; -import top.offsetmonkey538.loottablemodifier.api.resource.predicate.op.InvertedPredicate; +import top.offsetmonkey538.loottablemodifier.common.api.resource.util.LootModifierContext; +import top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.op.AllOfPredicate; +import top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.op.AnyOfPredicate; +import top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.op.InvertedPredicate; import java.util.function.Predicate; @@ -17,7 +17,7 @@ public interface LootModifierPredicate extends Predicate { /** * Codec containing the type id */ - Codec CODEC = LootModifierPredicateType.REGISTRY.getCodec().dispatch(LootModifierPredicate::getType, LootModifierPredicateType::codec); + Codec CODEC = LootModifierPredicateType.CODEC_PROVIDER.get(); /** * Returns the type of this action. diff --git a/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/predicate/LootModifierPredicateType.java b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/predicate/LootModifierPredicateType.java new file mode 100644 index 0000000..b2be014 --- /dev/null +++ b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/predicate/LootModifierPredicateType.java @@ -0,0 +1,46 @@ +package top.offsetmonkey538.loottablemodifier.common.api.resource.predicate; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.Identifier; + +import java.util.function.Supplier; + +import static top.offsetmonkey538.loottablemodifier.common.LootTableModifierCommon.load; + +/** + * They type of a {@link LootModifierPredicate}, holds the codec. + * + * @param codec the codec for this predicate + */ +public record LootModifierPredicateType(@NotNull MapCodec codec) { + /** + * Provides codec for {@link LootModifierPredicate} + */ + public static final Supplier> CODEC_PROVIDER = load(CodecProvider.class); + + /** + * Register method + * + * @param id the identifier to register as + * @param codec the codec for the loot modifier predicate type + * @return a loot modifier predicate type for the provided codec + */ + public static LootModifierPredicateType register(final @NotNull Identifier id, final @NotNull MapCodec codec) { + return Registry.INSTANCE.register(id, new LootModifierPredicateType(codec)); + } + + @ApiStatus.Internal + public interface Registry { + Registry INSTANCE = load(Registry.class); + + LootModifierPredicateType register(final @NotNull Identifier id, final @NotNull LootModifierPredicateType type); + } + + @ApiStatus.Internal + public interface CodecProvider extends Supplier> { + + } +} diff --git a/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/predicate/LootModifierPredicateTypes.java b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/predicate/LootModifierPredicateTypes.java new file mode 100644 index 0000000..fefa084 --- /dev/null +++ b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/predicate/LootModifierPredicateTypes.java @@ -0,0 +1,54 @@ +package top.offsetmonkey538.loottablemodifier.common.api.resource.predicate; + +import org.jetbrains.annotations.ApiStatus; +import top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.entry.EntryItemPredicate; +import top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.op.AllOfPredicate; +import top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.op.AnyOfPredicate; +import top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.op.InvertedPredicate; +import top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.table.TablePredicate; + +import static top.offsetmonkey538.loottablemodifier.common.platform.PlatformMain.id; + +/** + * Contains all {@link LootModifierPredicate} types available in Loot Table Modifier + *
+ * Use their builders to create them. + */ +public final class LootModifierPredicateTypes { + private LootModifierPredicateTypes() { + + } + + /** + * Type of {@link InvertedPredicate} + */ + public static final LootModifierPredicateType INVERTED = LootModifierPredicateType.register(id("inverted"), InvertedPredicate.CODEC); + /** + * Type of {@link AnyOfPredicate} + */ + public static final LootModifierPredicateType ANY_OF = LootModifierPredicateType.register(id("any_of"), AnyOfPredicate.CODEC); + /** + * Type of {@link AllOfPredicate} + */ + public static final LootModifierPredicateType ALL_OF = LootModifierPredicateType.register(id("all_of"), AllOfPredicate.CODEC); + + /** + * Type of {@link EntryItemPredicate} + */ + public static final LootModifierPredicateType ENTRY_ITEM = LootModifierPredicateType.register(id("entry_item"), EntryItemPredicate.CODEC); + + /** + * Type of {@link TablePredicate} + */ + public static final LootModifierPredicateType TABLE = LootModifierPredicateType.register(id("table"), TablePredicate.CODEC); + + /** + * Registers predicate types by loading the class. + *
+ * Only for the loot table modifier initializer to call, NO TOUCHY >:( + */ + @ApiStatus.Internal + public static void register() { + // Registers predicate types by loading the class + } +} diff --git a/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/predicate/entry/EntryItemPredicate.java b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/predicate/entry/EntryItemPredicate.java similarity index 67% rename from src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/predicate/entry/EntryItemPredicate.java rename to common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/predicate/entry/EntryItemPredicate.java index 72d4710..7f7c951 100644 --- a/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/predicate/entry/EntryItemPredicate.java +++ b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/predicate/entry/EntryItemPredicate.java @@ -1,18 +1,16 @@ -package top.offsetmonkey538.loottablemodifier.api.resource.predicate.entry; +package top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.entry; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import net.minecraft.item.ItemConvertible; -import net.minecraft.loot.entry.ItemEntry; -import net.minecraft.registry.Registries; -import net.minecraft.util.Identifier; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; -import top.offsetmonkey538.loottablemodifier.api.resource.predicate.LootModifierPredicateTypes; -import top.offsetmonkey538.loottablemodifier.api.resource.util.LootModifierContext; -import top.offsetmonkey538.loottablemodifier.api.resource.util.RegexPattern; -import top.offsetmonkey538.loottablemodifier.api.resource.predicate.LootModifierPredicate; -import top.offsetmonkey538.loottablemodifier.api.resource.predicate.LootModifierPredicateType; +import top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicateTypes; +import top.offsetmonkey538.loottablemodifier.common.api.resource.util.LootModifierContext; +import top.offsetmonkey538.loottablemodifier.common.api.resource.util.RegexPattern; +import top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicate; +import top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicateType; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.Item; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.entry.ItemEntry; /** * Matches an item entry based on its item @@ -34,7 +32,7 @@ public boolean test(@NotNull LootModifierContext context) { // No need for a separate null check of entry as null isn't an instance of ItemEntry if (!(context.entry() instanceof ItemEntry itemEntry)) return false; - return name.matches(itemEntry.item.getIdAsString()); + return name.matches(itemEntry.getId()); } /** @@ -44,8 +42,8 @@ public boolean test(@NotNull LootModifierContext context) { * @return a new {@link EntryItemPredicate.Builder} */ @Contract("_->new") - public static EntryItemPredicate.Builder builder(ItemConvertible name) { - return builder(Registries.ITEM.getId(name.asItem())); + public static EntryItemPredicate.Builder builder(Item name) { + return builder(name.getId()); } /** * Creates a builder for {@link EntryItemPredicate} matching the item based on the provided identifier @@ -54,7 +52,7 @@ public static EntryItemPredicate.Builder builder(ItemConvertible name) { * @return a new {@link EntryItemPredicate.Builder} */ @Contract("_->new") - public static EntryItemPredicate.Builder builder(Identifier name) { + public static EntryItemPredicate.Builder builder(String name) { return builder(RegexPattern.literal(name)); } /** diff --git a/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/predicate/op/AllOfPredicate.java b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/predicate/op/AllOfPredicate.java similarity index 72% rename from src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/predicate/op/AllOfPredicate.java rename to common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/predicate/op/AllOfPredicate.java index 7ae03ab..a77bc65 100644 --- a/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/predicate/op/AllOfPredicate.java +++ b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/predicate/op/AllOfPredicate.java @@ -1,12 +1,12 @@ -package top.offsetmonkey538.loottablemodifier.api.resource.predicate.op; +package top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.op; import com.mojang.serialization.MapCodec; -import net.minecraft.util.Util; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; -import top.offsetmonkey538.loottablemodifier.api.resource.predicate.LootModifierPredicateTypes; -import top.offsetmonkey538.loottablemodifier.api.resource.predicate.LootModifierPredicate; -import top.offsetmonkey538.loottablemodifier.api.resource.predicate.LootModifierPredicateType; +import top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicateTypes; +import top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicate; +import top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicateType; +import top.offsetmonkey538.loottablemodifier.common.util.PredicateUtils; import java.util.List; @@ -20,7 +20,7 @@ public class AllOfPredicate extends TermsPredicate { public static final MapCodec CODEC = createCodec(AllOfPredicate::new); private AllOfPredicate(final List terms) { - super(terms, Util.allOf(terms)); + super(terms, PredicateUtils.allOf(terms)); } @Override diff --git a/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/predicate/op/AnyOfPredicate.java b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/predicate/op/AnyOfPredicate.java similarity index 72% rename from src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/predicate/op/AnyOfPredicate.java rename to common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/predicate/op/AnyOfPredicate.java index a754d55..43f1b04 100644 --- a/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/predicate/op/AnyOfPredicate.java +++ b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/predicate/op/AnyOfPredicate.java @@ -1,12 +1,12 @@ -package top.offsetmonkey538.loottablemodifier.api.resource.predicate.op; +package top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.op; import com.mojang.serialization.MapCodec; -import net.minecraft.util.Util; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; -import top.offsetmonkey538.loottablemodifier.api.resource.predicate.LootModifierPredicateTypes; -import top.offsetmonkey538.loottablemodifier.api.resource.predicate.LootModifierPredicate; -import top.offsetmonkey538.loottablemodifier.api.resource.predicate.LootModifierPredicateType; +import top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicateTypes; +import top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicate; +import top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicateType; +import top.offsetmonkey538.loottablemodifier.common.util.PredicateUtils; import java.util.List; @@ -20,7 +20,7 @@ public class AnyOfPredicate extends TermsPredicate { public static final MapCodec CODEC = createCodec(AnyOfPredicate::new); private AnyOfPredicate(final List terms) { - super(terms, Util.anyOf(terms)); + super(terms, PredicateUtils.anyOf(terms)); } @Override diff --git a/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/predicate/op/InvertedPredicate.java b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/predicate/op/InvertedPredicate.java similarity index 71% rename from src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/predicate/op/InvertedPredicate.java rename to common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/predicate/op/InvertedPredicate.java index 727e12a..1cf7d88 100644 --- a/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/predicate/op/InvertedPredicate.java +++ b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/predicate/op/InvertedPredicate.java @@ -1,12 +1,12 @@ -package top.offsetmonkey538.loottablemodifier.api.resource.predicate.op; +package top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.op; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; import org.jetbrains.annotations.NotNull; -import top.offsetmonkey538.loottablemodifier.api.resource.predicate.LootModifierPredicateTypes; -import top.offsetmonkey538.loottablemodifier.api.resource.util.LootModifierContext; -import top.offsetmonkey538.loottablemodifier.api.resource.predicate.LootModifierPredicate; -import top.offsetmonkey538.loottablemodifier.api.resource.predicate.LootModifierPredicateType; +import top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicateTypes; +import top.offsetmonkey538.loottablemodifier.common.api.resource.util.LootModifierContext; +import top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicate; +import top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicateType; /** * Matches when the provided predicate doesn't diff --git a/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/predicate/op/TermsPredicate.java b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/predicate/op/TermsPredicate.java similarity index 90% rename from src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/predicate/op/TermsPredicate.java rename to common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/predicate/op/TermsPredicate.java index a0c5c20..d4dc15a 100644 --- a/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/predicate/op/TermsPredicate.java +++ b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/predicate/op/TermsPredicate.java @@ -1,11 +1,11 @@ -package top.offsetmonkey538.loottablemodifier.api.resource.predicate.op; +package top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.op; import com.google.common.collect.ImmutableList; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; import org.jetbrains.annotations.NotNull; -import top.offsetmonkey538.loottablemodifier.api.resource.util.LootModifierContext; -import top.offsetmonkey538.loottablemodifier.api.resource.predicate.LootModifierPredicate; +import top.offsetmonkey538.loottablemodifier.common.api.resource.util.LootModifierContext; +import top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicate; import java.util.List; import java.util.function.Function; diff --git a/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/predicate/table/TablePredicate.java b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/predicate/table/TablePredicate.java similarity index 62% rename from src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/predicate/table/TablePredicate.java rename to common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/predicate/table/TablePredicate.java index 0cdc8f8..77df5a6 100644 --- a/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/predicate/table/TablePredicate.java +++ b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/predicate/table/TablePredicate.java @@ -1,24 +1,16 @@ -package top.offsetmonkey538.loottablemodifier.api.resource.predicate.table; +package top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.table; import com.google.common.collect.ImmutableList; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import net.minecraft.block.Block; -import net.minecraft.entity.EntityType; -import net.minecraft.loot.LootTable; -import net.minecraft.loot.context.LootContextTypes; -import net.minecraft.registry.RegistryKey; -import net.minecraft.util.Identifier; -import net.minecraft.util.context.ContextType; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import top.offsetmonkey538.loottablemodifier.api.resource.predicate.LootModifierPredicateTypes; -import top.offsetmonkey538.loottablemodifier.api.resource.util.LootModifierContext; -import top.offsetmonkey538.loottablemodifier.api.resource.util.LootTableIdGetter; -import top.offsetmonkey538.loottablemodifier.api.resource.util.RegexPattern; -import top.offsetmonkey538.loottablemodifier.api.resource.predicate.LootModifierPredicate; -import top.offsetmonkey538.loottablemodifier.api.resource.predicate.LootModifierPredicateType; +import top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicateTypes; +import top.offsetmonkey538.loottablemodifier.common.api.resource.util.LootModifierContext; +import top.offsetmonkey538.loottablemodifier.common.api.resource.util.RegexPattern; +import top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicate; +import top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicateType; import java.util.List; import java.util.Optional; @@ -72,7 +64,7 @@ public boolean test(@NotNull LootModifierContext context) { if (types != null && !types.isEmpty()) { boolean typeResult = false; - final String tableTypeString = LootContextTypes.MAP.inverse().get(context.table().getType()).toString(); + final String tableTypeString = context.table().getType(); for (RegexPattern pattern : types) typeResult = typeResult || pattern.matches(tableTypeString); result = result && typeResult; } @@ -101,47 +93,14 @@ private Builder() { private final ImmutableList.Builder names = ImmutableList.builder(); private final ImmutableList.Builder types = ImmutableList.builder(); - /** - * Adds an entity type to match - * - * @param name the {@link EntityType} to match - * @return this - */ - @Contract("_->this") - public TablePredicate.Builder name(@NotNull EntityType name) { - name(LootTableIdGetter.INSTANCE.get(name)); - return this; - } - /** - * Adds a block to match - * - * @param name the {@link Block} to match - * @return this - */ - @Contract("_->this") - public TablePredicate.Builder name(@NotNull Block name) { - name(LootTableIdGetter.INSTANCE.get(name)); - return this; - } - /** - * Adds a loot table to match - * - * @param name the {@link RegistryKey} of the loot table to match - * @return this - */ - @Contract("_->this") - public TablePredicate.Builder name(@NotNull RegistryKey name) { - name(name.getValue()); - return this; - } /** * Adds a loot table to match * - * @param name the {@link Identifier} of the loot table to match + * @param name the identifier of the loot table to match * @return this */ - @Contract("_->this") - public TablePredicate.Builder name(@NotNull Identifier name) { + @Contract("_->this") //TODO: these methods shoulöd prolly also take identigfiers? + public TablePredicate.Builder name(@NotNull String name) { name(RegexPattern.literal(name)); return this; } @@ -157,25 +116,14 @@ public TablePredicate.Builder name(@NotNull RegexPattern name) { return this; } - /** - * Adds a {@link ContextType type} to match. - * - * @param type the {@link ContextType type} to match - * @return this - */ - @Contract("_->this") - public TablePredicate.Builder type(@NotNull ContextType type) { - type(LootContextTypes.MAP.inverse().get(type)); - return this; - } /** * Adds a type to match. * - * @param type the {@link Identifier} of the type to match + * @param type the identifier of the type to match * @return this */ @Contract("_->this") - public TablePredicate.Builder type(@NotNull Identifier type) { + public TablePredicate.Builder type(@NotNull String type) { type(RegexPattern.literal(type)); return this; } diff --git a/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/util/LootModifierContext.java b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/util/LootModifierContext.java similarity index 62% rename from src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/util/LootModifierContext.java rename to common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/util/LootModifierContext.java index aa764ae..e9cd989 100644 --- a/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/util/LootModifierContext.java +++ b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/util/LootModifierContext.java @@ -1,9 +1,9 @@ -package top.offsetmonkey538.loottablemodifier.api.resource.util; +package top.offsetmonkey538.loottablemodifier.common.api.resource.util; -import net.minecraft.loot.LootPool; -import net.minecraft.loot.LootTable; -import net.minecraft.loot.entry.LootPoolEntry; -import net.minecraft.util.Identifier; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.Identifier; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootPool; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootTable; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.entry.LootPoolEntry; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/util/RegexPattern.java b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/util/RegexPattern.java similarity index 78% rename from src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/util/RegexPattern.java rename to common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/util/RegexPattern.java index f0380e4..aa93e69 100644 --- a/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/util/RegexPattern.java +++ b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/resource/util/RegexPattern.java @@ -1,25 +1,25 @@ -package top.offsetmonkey538.loottablemodifier.api.resource.util; +package top.offsetmonkey538.loottablemodifier.common.api.resource.util; import com.mojang.datafixers.util.Either; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import net.minecraft.util.Identifier; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.Identifier; import java.util.regex.Pattern; /** * {@link RegexPattern}s allow either matching {@link Identifier}s directly or using regex to do so. *
- * Use {@link #literal(Identifier)} for creating literal patterns and {@link #compile(String)} for creating regex patterns. + * Use {@link #literal(String)} for creating literal patterns and {@link #compile(String)} for creating regex patterns. * * @param isRegex if this {@link RegexPattern} is using regex or not * @param patternString the pattern as a plain string * @param pattern the compiled pattern */ public record RegexPattern(boolean isRegex, @NotNull String patternString, @NotNull Pattern pattern) { - private static final Codec INLINE_CODEC = Identifier.CODEC.xmap(RegexPattern::literal, instance -> Identifier.of(instance.patternString())); + private static final Codec INLINE_CODEC = Identifier.CODEC_PROVIDER.get().xmap(identifier -> RegexPattern.literal(identifier.toString()), instance -> Identifier.of(instance.patternString())); private static final Codec FULL_CODEC = RecordCodecBuilder.create(instance -> instance.group( Codec.STRING.fieldOf("regexPattern").forGetter(RegexPattern::patternString) ).apply(instance, RegexPattern::compile)); @@ -32,17 +32,17 @@ public record RegexPattern(boolean isRegex, @NotNull String patternString, @NotN ); /** - * Creates a literal {@link RegexPattern} from the provided {@link Identifier}. + * Creates a literal {@link RegexPattern} from the provided string. * - * @param identifier the {@link Identifier} to match - * @return a new {@link RegexPattern} matching the provided {@link Identifier} + * @param literal the literal String to match + * @return a new {@link RegexPattern} matching the provided string */ @Contract("_->new") - public static RegexPattern literal(final Identifier identifier) { + public static RegexPattern literal(final String literal) { return new RegexPattern( false, - identifier.toString(), - Pattern.compile(Pattern.quote(identifier.toString())) + literal, + Pattern.compile(Pattern.quote(literal)) ); } diff --git a/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/wrapper/Identifier.java b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/wrapper/Identifier.java new file mode 100644 index 0000000..42f748b --- /dev/null +++ b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/wrapper/Identifier.java @@ -0,0 +1,33 @@ +package top.offsetmonkey538.loottablemodifier.common.api.wrapper; + +import com.mojang.serialization.Codec; +import org.jetbrains.annotations.ApiStatus; + +import java.util.function.Function; +import java.util.function.Supplier; + +import static top.offsetmonkey538.loottablemodifier.common.LootTableModifierCommon.load; + +public interface Identifier { + Supplier> CODEC_PROVIDER = load(CodecProvider.class); + @ApiStatus.Internal + Function INSTANTIATOR = load(Instantiator.class); + + static Identifier of(String path) { + return INSTANTIATOR.apply(path); + } + String asString(); + String getNamespace(); + String getPath(); + + @ApiStatus.Internal + interface CodecProvider extends Supplier> { + + } + + @ApiStatus.Internal + interface Instantiator extends Function { + + } +} + diff --git a/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/wrapper/Item.java b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/wrapper/Item.java new file mode 100644 index 0000000..fa3a0bc --- /dev/null +++ b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/wrapper/Item.java @@ -0,0 +1,20 @@ +package top.offsetmonkey538.loottablemodifier.common.api.wrapper; + +import com.mojang.serialization.Codec; +import org.jetbrains.annotations.ApiStatus; + +import java.util.function.Supplier; + +import static top.offsetmonkey538.loottablemodifier.common.LootTableModifierCommon.load; + +public interface Item { + Supplier> CODEC_PROVIDER = load(CodecProvider.class); + + String getId(); + + @ApiStatus.Internal + interface CodecProvider extends Supplier> { + + } +} + diff --git a/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/wrapper/ResourceManager.java b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/wrapper/ResourceManager.java new file mode 100644 index 0000000..304d3c4 --- /dev/null +++ b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/wrapper/ResourceManager.java @@ -0,0 +1,12 @@ +package top.offsetmonkey538.loottablemodifier.common.api.wrapper; + +import it.unimi.dsi.fastutil.Pair; + +import java.io.BufferedReader; +import java.util.function.Predicate; +import java.util.function.Supplier; +import java.util.stream.Stream; + +public interface ResourceManager { + Stream>> listResources(String string, Predicate predicate); +} diff --git a/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/wrapper/loot/LootCondition.java b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/wrapper/loot/LootCondition.java new file mode 100644 index 0000000..f1df58f --- /dev/null +++ b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/wrapper/loot/LootCondition.java @@ -0,0 +1,18 @@ +package top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot; + +import com.mojang.serialization.Codec; +import org.jetbrains.annotations.ApiStatus; + +import java.util.function.Supplier; + +import static top.offsetmonkey538.loottablemodifier.common.LootTableModifierCommon.load; + +public interface LootCondition { + Supplier> CODEC_PROVIDER = load(CodecProvider.class); + + @ApiStatus.Internal + interface CodecProvider extends Supplier> { + + } +} + diff --git a/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/wrapper/loot/LootFunction.java b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/wrapper/loot/LootFunction.java new file mode 100644 index 0000000..2aae37f --- /dev/null +++ b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/wrapper/loot/LootFunction.java @@ -0,0 +1,6 @@ +package top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot; + +public interface LootFunction { + +} + diff --git a/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/wrapper/loot/LootPool.java b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/wrapper/loot/LootPool.java new file mode 100644 index 0000000..8f6a252 --- /dev/null +++ b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/wrapper/loot/LootPool.java @@ -0,0 +1,30 @@ +package top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot; + +import com.mojang.serialization.Codec; +import org.jetbrains.annotations.ApiStatus; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.entry.LootPoolEntry; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Supplier; + +import static top.offsetmonkey538.loottablemodifier.common.LootTableModifierCommon.load; + +public interface LootPool { + Supplier> CODEC_PROVIDER = load(CodecProvider.class); + + ArrayList getEntries(); + void setEntries(List entries); + + ArrayList getConditions(); + void setConditions(List conditions); + + ArrayList getFunctions(); + void setFunctions(List functions); + + @ApiStatus.Internal + interface CodecProvider extends Supplier> { + + } +} + diff --git a/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/wrapper/loot/LootTable.java b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/wrapper/loot/LootTable.java new file mode 100644 index 0000000..f5885e4 --- /dev/null +++ b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/wrapper/loot/LootTable.java @@ -0,0 +1,27 @@ +package top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot; + +import com.mojang.serialization.Codec; +import org.jetbrains.annotations.ApiStatus; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Supplier; + +import static top.offsetmonkey538.loottablemodifier.common.LootTableModifierCommon.load; + +public interface LootTable { + Supplier> CODEC_PROVIDER = load(CodecProvider.class); + + String getType(); + + ArrayList getPools(); + void setPools(List entries); + + ArrayList getFunctions(); + void setFunctions(List functions); + + @ApiStatus.Internal + interface CodecProvider extends Supplier> { + + } +} diff --git a/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/wrapper/loot/entry/ItemEntry.java b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/wrapper/loot/entry/ItemEntry.java new file mode 100644 index 0000000..39aa754 --- /dev/null +++ b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/wrapper/loot/entry/ItemEntry.java @@ -0,0 +1,8 @@ +package top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.entry; + +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.Item; + +public interface ItemEntry extends LootPoolEntry { + void setItem(Item item); + String getId(); +} diff --git a/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/wrapper/loot/entry/LootPoolEntry.java b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/wrapper/loot/entry/LootPoolEntry.java new file mode 100644 index 0000000..2b4f7ef --- /dev/null +++ b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/api/wrapper/loot/entry/LootPoolEntry.java @@ -0,0 +1,24 @@ +package top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.entry; + +import com.mojang.serialization.Codec; +import org.jetbrains.annotations.ApiStatus; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootCondition; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Supplier; + +import static top.offsetmonkey538.loottablemodifier.common.LootTableModifierCommon.load; + +public interface LootPoolEntry { + Supplier> CODEC_PROVIDER = load(CodecProvider.class); + + ArrayList getConditions(); + void setConditions(List conditions); + + @ApiStatus.Internal + interface CodecProvider extends Supplier> { + + } +} + diff --git a/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/platform/PlatformCommandUtils.java b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/platform/PlatformCommandUtils.java new file mode 100644 index 0000000..38aacd4 --- /dev/null +++ b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/platform/PlatformCommandUtils.java @@ -0,0 +1,26 @@ +package top.offsetmonkey538.loottablemodifier.common.platform; + +import com.google.gson.JsonElement; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.serialization.DynamicOps; +import org.jetbrains.annotations.ApiStatus; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.Identifier; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootTable; + +import static top.offsetmonkey538.loottablemodifier.common.LootTableModifierCommon.load; + +public interface PlatformCommandUtils { + @ApiStatus.Internal + PlatformCommandUtils INSTANCE = load(PlatformCommandUtils.class); + + static DynamicOps getRegistryOps(CommandContext context) { + return INSTANCE.getRegistryOpsImpl(context); + } + + static LootTable getTableForId(CommandContext context, Identifier id) { + return INSTANCE.getTableForIdImpl(context, id); + } + + DynamicOps getRegistryOpsImpl(CommandContext context); + LootTable getTableForIdImpl(CommandContext context, Identifier id); +} diff --git a/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/platform/PlatformMain.java b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/platform/PlatformMain.java new file mode 100644 index 0000000..83299a7 --- /dev/null +++ b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/platform/PlatformMain.java @@ -0,0 +1,26 @@ +package top.offsetmonkey538.loottablemodifier.common.platform; + +import com.google.gson.JsonElement; +import com.google.gson.stream.JsonWriter; +import org.jetbrains.annotations.ApiStatus; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.Identifier; + +import java.io.IOException; + +import static top.offsetmonkey538.loottablemodifier.common.LootTableModifierCommon.load; + +public interface PlatformMain { + @ApiStatus.Internal + PlatformMain INSTANCE = load(PlatformMain.class); + + static void writeSorted(JsonWriter jsonWriter, JsonElement json) throws IOException { + INSTANCE.writeSortedImpl(jsonWriter, json); + } + + static Identifier id(String path) { + return INSTANCE.idImpl(path); + } + + void writeSortedImpl(JsonWriter jsonWriter, JsonElement json) throws IOException; + Identifier idImpl(String path); +} diff --git a/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/util/PredicateUtils.java b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/util/PredicateUtils.java new file mode 100644 index 0000000..a73c193 --- /dev/null +++ b/common/src/main/java/top/offsetmonkey538/loottablemodifier/common/util/PredicateUtils.java @@ -0,0 +1,125 @@ +package top.offsetmonkey538.loottablemodifier.common.util; + +import java.util.List; +import java.util.function.Predicate; + +public final class PredicateUtils { + private PredicateUtils() {} + + + @SuppressWarnings("DuplicatedCode") // Blame Mr GauntRecluse https://discord.com/channels/507304429255393322/807617284129423370/1457806051775877120 + public static Predicate allOf(List> predicates) { + return switch (predicates.size()) { + case 0 -> object -> true; + case 1 -> object -> predicates.getFirst().test(object); + case 2 -> object -> predicates.getFirst().test(object) && predicates.get(1).test(object); + case 3 -> object -> predicates.getFirst().test(object) && predicates.get(1).test(object) && predicates.get(2).test(object); + case 4 -> object -> predicates.getFirst().test(object) && predicates.get(1).test(object) && predicates.get(2).test(object) && predicates.get(3).test(object); + case 5 -> object -> predicates.getFirst().test(object) && predicates.get(1).test(object) && predicates.get(2).test(object) && predicates.get(3).test(object) && predicates.get(4).test(object); + case 6 -> object -> predicates.getFirst().test(object) && predicates.get(1).test(object) && predicates.get(2).test(object) && predicates.get(3).test(object) && predicates.get(4).test(object) && predicates.get(5).test(object); + case 7 -> object -> predicates.getFirst().test(object) && predicates.get(1).test(object) && predicates.get(2).test(object) && predicates.get(3).test(object) && predicates.get(4).test(object) && predicates.get(5).test(object) && predicates.get(6).test(object); + case 8 -> object -> predicates.getFirst().test(object) && predicates.get(1).test(object) && predicates.get(2).test(object) && predicates.get(3).test(object) && predicates.get(4).test(object) && predicates.get(5).test(object) && predicates.get(6).test(object) && predicates.get(7).test(object); + default -> allOf2(predicates); + }; + } + + private static Predicate allOf2(List> predicates) { + return object -> { + for (final Predicate predicate : predicates) { + if (!predicate.test(object)) return false; + } + return true; + }; + } + + @SuppressWarnings("DuplicatedCode") + /* + kr1v what have you done 😭😭😭😭😭😭 https://discord.com/channels/507304429255393322/807617284129423370/1457808463848538114 + Btw there should be no mistyped numbers here, blame kr1v again if there is https://discord.com/channels/507304429255393322/807617284129423370/1457816346082414835 + He is 100% certain there is no mistake (though I guess he didn't say anything about mistake*s*) https://discord.com/channels/507304429255393322/807617284129423370/1457816583442399284 + */ + public static Predicate anyOf(List> predicates) { + return switch (predicates.size()) { + case 0 -> object -> false; + case 1 -> object -> predicates.getFirst().test(object); + case 2 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object); + case 3 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object); + case 4 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object); + case 5 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object); + case 6 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object); + case 7 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object); + case 8 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object); + case 9 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object); + case 10 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object); + case 11 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object); + case 12 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object); + case 13 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object); + case 14 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object); + case 15 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object); + case 16 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object); + case 17 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object); + case 18 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object); + case 19 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object); + case 20 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object); + case 21 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object); + case 22 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object) || predicates.get(21).test(object); + case 23 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object) || predicates.get(21).test(object) || predicates.get(22).test(object); + case 24 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object) || predicates.get(21).test(object) || predicates.get(22).test(object) || predicates.get(23).test(object); + case 25 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object) || predicates.get(21).test(object) || predicates.get(22).test(object) || predicates.get(23).test(object) || predicates.get(24).test(object); + case 26 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object) || predicates.get(21).test(object) || predicates.get(22).test(object) || predicates.get(23).test(object) || predicates.get(24).test(object) || predicates.get(25).test(object); + case 27 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object) || predicates.get(21).test(object) || predicates.get(22).test(object) || predicates.get(23).test(object) || predicates.get(24).test(object) || predicates.get(25).test(object) || predicates.get(26).test(object); + case 28 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object) || predicates.get(21).test(object) || predicates.get(22).test(object) || predicates.get(23).test(object) || predicates.get(24).test(object) || predicates.get(25).test(object) || predicates.get(26).test(object) || predicates.get(27).test(object); + case 29 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object) || predicates.get(21).test(object) || predicates.get(22).test(object) || predicates.get(23).test(object) || predicates.get(24).test(object) || predicates.get(25).test(object) || predicates.get(26).test(object) || predicates.get(27).test(object) || predicates.get(28).test(object); + case 30 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object) || predicates.get(21).test(object) || predicates.get(22).test(object) || predicates.get(23).test(object) || predicates.get(24).test(object) || predicates.get(25).test(object) || predicates.get(26).test(object) || predicates.get(27).test(object) || predicates.get(28).test(object) || predicates.get(29).test(object); + case 31 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object) || predicates.get(21).test(object) || predicates.get(22).test(object) || predicates.get(23).test(object) || predicates.get(24).test(object) || predicates.get(25).test(object) || predicates.get(26).test(object) || predicates.get(27).test(object) || predicates.get(28).test(object) || predicates.get(29).test(object) || predicates.get(30).test(object); + case 32 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object) || predicates.get(21).test(object) || predicates.get(22).test(object) || predicates.get(23).test(object) || predicates.get(24).test(object) || predicates.get(25).test(object) || predicates.get(26).test(object) || predicates.get(27).test(object) || predicates.get(28).test(object) || predicates.get(29).test(object) || predicates.get(30).test(object) || predicates.get(31).test(object); + case 33 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object) || predicates.get(21).test(object) || predicates.get(22).test(object) || predicates.get(23).test(object) || predicates.get(24).test(object) || predicates.get(25).test(object) || predicates.get(26).test(object) || predicates.get(27).test(object) || predicates.get(28).test(object) || predicates.get(29).test(object) || predicates.get(30).test(object) || predicates.get(31).test(object) || predicates.get(32).test(object); + case 34 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object) || predicates.get(21).test(object) || predicates.get(22).test(object) || predicates.get(23).test(object) || predicates.get(24).test(object) || predicates.get(25).test(object) || predicates.get(26).test(object) || predicates.get(27).test(object) || predicates.get(28).test(object) || predicates.get(29).test(object) || predicates.get(30).test(object) || predicates.get(31).test(object) || predicates.get(32).test(object) || predicates.get(33).test(object); + case 35 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object) || predicates.get(21).test(object) || predicates.get(22).test(object) || predicates.get(23).test(object) || predicates.get(24).test(object) || predicates.get(25).test(object) || predicates.get(26).test(object) || predicates.get(27).test(object) || predicates.get(28).test(object) || predicates.get(29).test(object) || predicates.get(30).test(object) || predicates.get(31).test(object) || predicates.get(32).test(object) || predicates.get(33).test(object) || predicates.get(34).test(object); + case 36 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object) || predicates.get(21).test(object) || predicates.get(22).test(object) || predicates.get(23).test(object) || predicates.get(24).test(object) || predicates.get(25).test(object) || predicates.get(26).test(object) || predicates.get(27).test(object) || predicates.get(28).test(object) || predicates.get(29).test(object) || predicates.get(30).test(object) || predicates.get(31).test(object) || predicates.get(32).test(object) || predicates.get(33).test(object) || predicates.get(34).test(object) || predicates.get(35).test(object); + case 37 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object) || predicates.get(21).test(object) || predicates.get(22).test(object) || predicates.get(23).test(object) || predicates.get(24).test(object) || predicates.get(25).test(object) || predicates.get(26).test(object) || predicates.get(27).test(object) || predicates.get(28).test(object) || predicates.get(29).test(object) || predicates.get(30).test(object) || predicates.get(31).test(object) || predicates.get(32).test(object) || predicates.get(33).test(object) || predicates.get(34).test(object) || predicates.get(35).test(object) || predicates.get(36).test(object); + case 38 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object) || predicates.get(21).test(object) || predicates.get(22).test(object) || predicates.get(23).test(object) || predicates.get(24).test(object) || predicates.get(25).test(object) || predicates.get(26).test(object) || predicates.get(27).test(object) || predicates.get(28).test(object) || predicates.get(29).test(object) || predicates.get(30).test(object) || predicates.get(31).test(object) || predicates.get(32).test(object) || predicates.get(33).test(object) || predicates.get(34).test(object) || predicates.get(35).test(object) || predicates.get(36).test(object) || predicates.get(37).test(object); + case 39 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object) || predicates.get(21).test(object) || predicates.get(22).test(object) || predicates.get(23).test(object) || predicates.get(24).test(object) || predicates.get(25).test(object) || predicates.get(26).test(object) || predicates.get(27).test(object) || predicates.get(28).test(object) || predicates.get(29).test(object) || predicates.get(30).test(object) || predicates.get(31).test(object) || predicates.get(32).test(object) || predicates.get(33).test(object) || predicates.get(34).test(object) || predicates.get(35).test(object) || predicates.get(36).test(object) || predicates.get(37).test(object) || predicates.get(38).test(object); + case 40 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object) || predicates.get(21).test(object) || predicates.get(22).test(object) || predicates.get(23).test(object) || predicates.get(24).test(object) || predicates.get(25).test(object) || predicates.get(26).test(object) || predicates.get(27).test(object) || predicates.get(28).test(object) || predicates.get(29).test(object) || predicates.get(30).test(object) || predicates.get(31).test(object) || predicates.get(32).test(object) || predicates.get(33).test(object) || predicates.get(34).test(object) || predicates.get(35).test(object) || predicates.get(36).test(object) || predicates.get(37).test(object) || predicates.get(38).test(object) || predicates.get(39).test(object); + case 41 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object) || predicates.get(21).test(object) || predicates.get(22).test(object) || predicates.get(23).test(object) || predicates.get(24).test(object) || predicates.get(25).test(object) || predicates.get(26).test(object) || predicates.get(27).test(object) || predicates.get(28).test(object) || predicates.get(29).test(object) || predicates.get(30).test(object) || predicates.get(31).test(object) || predicates.get(32).test(object) || predicates.get(33).test(object) || predicates.get(34).test(object) || predicates.get(35).test(object) || predicates.get(36).test(object) || predicates.get(37).test(object) || predicates.get(38).test(object) || predicates.get(39).test(object) || predicates.get(40).test(object); + case 42 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object) || predicates.get(21).test(object) || predicates.get(22).test(object) || predicates.get(23).test(object) || predicates.get(24).test(object) || predicates.get(25).test(object) || predicates.get(26).test(object) || predicates.get(27).test(object) || predicates.get(28).test(object) || predicates.get(29).test(object) || predicates.get(30).test(object) || predicates.get(31).test(object) || predicates.get(32).test(object) || predicates.get(33).test(object) || predicates.get(34).test(object) || predicates.get(35).test(object) || predicates.get(36).test(object) || predicates.get(37).test(object) || predicates.get(38).test(object) || predicates.get(39).test(object) || predicates.get(40).test(object) || predicates.get(41).test(object); + case 43 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object) || predicates.get(21).test(object) || predicates.get(22).test(object) || predicates.get(23).test(object) || predicates.get(24).test(object) || predicates.get(25).test(object) || predicates.get(26).test(object) || predicates.get(27).test(object) || predicates.get(28).test(object) || predicates.get(29).test(object) || predicates.get(30).test(object) || predicates.get(31).test(object) || predicates.get(32).test(object) || predicates.get(33).test(object) || predicates.get(34).test(object) || predicates.get(35).test(object) || predicates.get(36).test(object) || predicates.get(37).test(object) || predicates.get(38).test(object) || predicates.get(39).test(object) || predicates.get(40).test(object) || predicates.get(41).test(object) || predicates.get(42).test(object); + case 44 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object) || predicates.get(21).test(object) || predicates.get(22).test(object) || predicates.get(23).test(object) || predicates.get(24).test(object) || predicates.get(25).test(object) || predicates.get(26).test(object) || predicates.get(27).test(object) || predicates.get(28).test(object) || predicates.get(29).test(object) || predicates.get(30).test(object) || predicates.get(31).test(object) || predicates.get(32).test(object) || predicates.get(33).test(object) || predicates.get(34).test(object) || predicates.get(35).test(object) || predicates.get(36).test(object) || predicates.get(37).test(object) || predicates.get(38).test(object) || predicates.get(39).test(object) || predicates.get(40).test(object) || predicates.get(41).test(object) || predicates.get(42).test(object) || predicates.get(43).test(object); + case 45 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object) || predicates.get(21).test(object) || predicates.get(22).test(object) || predicates.get(23).test(object) || predicates.get(24).test(object) || predicates.get(25).test(object) || predicates.get(26).test(object) || predicates.get(27).test(object) || predicates.get(28).test(object) || predicates.get(29).test(object) || predicates.get(30).test(object) || predicates.get(31).test(object) || predicates.get(32).test(object) || predicates.get(33).test(object) || predicates.get(34).test(object) || predicates.get(35).test(object) || predicates.get(36).test(object) || predicates.get(37).test(object) || predicates.get(38).test(object) || predicates.get(39).test(object) || predicates.get(40).test(object) || predicates.get(41).test(object) || predicates.get(42).test(object) || predicates.get(43).test(object) || predicates.get(44).test(object); + case 46 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object) || predicates.get(21).test(object) || predicates.get(22).test(object) || predicates.get(23).test(object) || predicates.get(24).test(object) || predicates.get(25).test(object) || predicates.get(26).test(object) || predicates.get(27).test(object) || predicates.get(28).test(object) || predicates.get(29).test(object) || predicates.get(30).test(object) || predicates.get(31).test(object) || predicates.get(32).test(object) || predicates.get(33).test(object) || predicates.get(34).test(object) || predicates.get(35).test(object) || predicates.get(36).test(object) || predicates.get(37).test(object) || predicates.get(38).test(object) || predicates.get(39).test(object) || predicates.get(40).test(object) || predicates.get(41).test(object) || predicates.get(42).test(object) || predicates.get(43).test(object) || predicates.get(44).test(object) || predicates.get(45).test(object); + case 47 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object) || predicates.get(21).test(object) || predicates.get(22).test(object) || predicates.get(23).test(object) || predicates.get(24).test(object) || predicates.get(25).test(object) || predicates.get(26).test(object) || predicates.get(27).test(object) || predicates.get(28).test(object) || predicates.get(29).test(object) || predicates.get(30).test(object) || predicates.get(31).test(object) || predicates.get(32).test(object) || predicates.get(33).test(object) || predicates.get(34).test(object) || predicates.get(35).test(object) || predicates.get(36).test(object) || predicates.get(37).test(object) || predicates.get(38).test(object) || predicates.get(39).test(object) || predicates.get(40).test(object) || predicates.get(41).test(object) || predicates.get(42).test(object) || predicates.get(43).test(object) || predicates.get(44).test(object) || predicates.get(45).test(object) || predicates.get(46).test(object); + case 48 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object) || predicates.get(21).test(object) || predicates.get(22).test(object) || predicates.get(23).test(object) || predicates.get(24).test(object) || predicates.get(25).test(object) || predicates.get(26).test(object) || predicates.get(27).test(object) || predicates.get(28).test(object) || predicates.get(29).test(object) || predicates.get(30).test(object) || predicates.get(31).test(object) || predicates.get(32).test(object) || predicates.get(33).test(object) || predicates.get(34).test(object) || predicates.get(35).test(object) || predicates.get(36).test(object) || predicates.get(37).test(object) || predicates.get(38).test(object) || predicates.get(39).test(object) || predicates.get(40).test(object) || predicates.get(41).test(object) || predicates.get(42).test(object) || predicates.get(43).test(object) || predicates.get(44).test(object) || predicates.get(45).test(object) || predicates.get(46).test(object) || predicates.get(47).test(object); + case 49 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object) || predicates.get(21).test(object) || predicates.get(22).test(object) || predicates.get(23).test(object) || predicates.get(24).test(object) || predicates.get(25).test(object) || predicates.get(26).test(object) || predicates.get(27).test(object) || predicates.get(28).test(object) || predicates.get(29).test(object) || predicates.get(30).test(object) || predicates.get(31).test(object) || predicates.get(32).test(object) || predicates.get(33).test(object) || predicates.get(34).test(object) || predicates.get(35).test(object) || predicates.get(36).test(object) || predicates.get(37).test(object) || predicates.get(38).test(object) || predicates.get(39).test(object) || predicates.get(40).test(object) || predicates.get(41).test(object) || predicates.get(42).test(object) || predicates.get(43).test(object) || predicates.get(44).test(object) || predicates.get(45).test(object) || predicates.get(46).test(object) || predicates.get(47).test(object) || predicates.get(48).test(object); + case 50 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object) || predicates.get(21).test(object) || predicates.get(22).test(object) || predicates.get(23).test(object) || predicates.get(24).test(object) || predicates.get(25).test(object) || predicates.get(26).test(object) || predicates.get(27).test(object) || predicates.get(28).test(object) || predicates.get(29).test(object) || predicates.get(30).test(object) || predicates.get(31).test(object) || predicates.get(32).test(object) || predicates.get(33).test(object) || predicates.get(34).test(object) || predicates.get(35).test(object) || predicates.get(36).test(object) || predicates.get(37).test(object) || predicates.get(38).test(object) || predicates.get(39).test(object) || predicates.get(40).test(object) || predicates.get(41).test(object) || predicates.get(42).test(object) || predicates.get(43).test(object) || predicates.get(44).test(object) || predicates.get(45).test(object) || predicates.get(46).test(object) || predicates.get(47).test(object) || predicates.get(48).test(object) || predicates.get(49).test(object); + case 51 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object) || predicates.get(21).test(object) || predicates.get(22).test(object) || predicates.get(23).test(object) || predicates.get(24).test(object) || predicates.get(25).test(object) || predicates.get(26).test(object) || predicates.get(27).test(object) || predicates.get(28).test(object) || predicates.get(29).test(object) || predicates.get(30).test(object) || predicates.get(31).test(object) || predicates.get(32).test(object) || predicates.get(33).test(object) || predicates.get(34).test(object) || predicates.get(35).test(object) || predicates.get(36).test(object) || predicates.get(37).test(object) || predicates.get(38).test(object) || predicates.get(39).test(object) || predicates.get(40).test(object) || predicates.get(41).test(object) || predicates.get(42).test(object) || predicates.get(43).test(object) || predicates.get(44).test(object) || predicates.get(45).test(object) || predicates.get(46).test(object) || predicates.get(47).test(object) || predicates.get(48).test(object) || predicates.get(49).test(object) || predicates.get(50).test(object); + case 52 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object) || predicates.get(21).test(object) || predicates.get(22).test(object) || predicates.get(23).test(object) || predicates.get(24).test(object) || predicates.get(25).test(object) || predicates.get(26).test(object) || predicates.get(27).test(object) || predicates.get(28).test(object) || predicates.get(29).test(object) || predicates.get(30).test(object) || predicates.get(31).test(object) || predicates.get(32).test(object) || predicates.get(33).test(object) || predicates.get(34).test(object) || predicates.get(35).test(object) || predicates.get(36).test(object) || predicates.get(37).test(object) || predicates.get(38).test(object) || predicates.get(39).test(object) || predicates.get(40).test(object) || predicates.get(41).test(object) || predicates.get(42).test(object) || predicates.get(43).test(object) || predicates.get(44).test(object) || predicates.get(45).test(object) || predicates.get(46).test(object) || predicates.get(47).test(object) || predicates.get(48).test(object) || predicates.get(49).test(object) || predicates.get(50).test(object) || predicates.get(51).test(object); + case 53 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object) || predicates.get(21).test(object) || predicates.get(22).test(object) || predicates.get(23).test(object) || predicates.get(24).test(object) || predicates.get(25).test(object) || predicates.get(26).test(object) || predicates.get(27).test(object) || predicates.get(28).test(object) || predicates.get(29).test(object) || predicates.get(30).test(object) || predicates.get(31).test(object) || predicates.get(32).test(object) || predicates.get(33).test(object) || predicates.get(34).test(object) || predicates.get(35).test(object) || predicates.get(36).test(object) || predicates.get(37).test(object) || predicates.get(38).test(object) || predicates.get(39).test(object) || predicates.get(40).test(object) || predicates.get(41).test(object) || predicates.get(42).test(object) || predicates.get(43).test(object) || predicates.get(44).test(object) || predicates.get(45).test(object) || predicates.get(46).test(object) || predicates.get(47).test(object) || predicates.get(48).test(object) || predicates.get(49).test(object) || predicates.get(50).test(object) || predicates.get(51).test(object) || predicates.get(52).test(object); + case 54 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object) || predicates.get(21).test(object) || predicates.get(22).test(object) || predicates.get(23).test(object) || predicates.get(24).test(object) || predicates.get(25).test(object) || predicates.get(26).test(object) || predicates.get(27).test(object) || predicates.get(28).test(object) || predicates.get(29).test(object) || predicates.get(30).test(object) || predicates.get(31).test(object) || predicates.get(32).test(object) || predicates.get(33).test(object) || predicates.get(34).test(object) || predicates.get(35).test(object) || predicates.get(36).test(object) || predicates.get(37).test(object) || predicates.get(38).test(object) || predicates.get(39).test(object) || predicates.get(40).test(object) || predicates.get(41).test(object) || predicates.get(42).test(object) || predicates.get(43).test(object) || predicates.get(44).test(object) || predicates.get(45).test(object) || predicates.get(46).test(object) || predicates.get(47).test(object) || predicates.get(48).test(object) || predicates.get(49).test(object) || predicates.get(50).test(object) || predicates.get(51).test(object) || predicates.get(52).test(object) || predicates.get(53).test(object); + case 55 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object) || predicates.get(21).test(object) || predicates.get(22).test(object) || predicates.get(23).test(object) || predicates.get(24).test(object) || predicates.get(25).test(object) || predicates.get(26).test(object) || predicates.get(27).test(object) || predicates.get(28).test(object) || predicates.get(29).test(object) || predicates.get(30).test(object) || predicates.get(31).test(object) || predicates.get(32).test(object) || predicates.get(33).test(object) || predicates.get(34).test(object) || predicates.get(35).test(object) || predicates.get(36).test(object) || predicates.get(37).test(object) || predicates.get(38).test(object) || predicates.get(39).test(object) || predicates.get(40).test(object) || predicates.get(41).test(object) || predicates.get(42).test(object) || predicates.get(43).test(object) || predicates.get(44).test(object) || predicates.get(45).test(object) || predicates.get(46).test(object) || predicates.get(47).test(object) || predicates.get(48).test(object) || predicates.get(49).test(object) || predicates.get(50).test(object) || predicates.get(51).test(object) || predicates.get(52).test(object) || predicates.get(53).test(object) || predicates.get(54).test(object); + case 56 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object) || predicates.get(21).test(object) || predicates.get(22).test(object) || predicates.get(23).test(object) || predicates.get(24).test(object) || predicates.get(25).test(object) || predicates.get(26).test(object) || predicates.get(27).test(object) || predicates.get(28).test(object) || predicates.get(29).test(object) || predicates.get(30).test(object) || predicates.get(31).test(object) || predicates.get(32).test(object) || predicates.get(33).test(object) || predicates.get(34).test(object) || predicates.get(35).test(object) || predicates.get(36).test(object) || predicates.get(37).test(object) || predicates.get(38).test(object) || predicates.get(39).test(object) || predicates.get(40).test(object) || predicates.get(41).test(object) || predicates.get(42).test(object) || predicates.get(43).test(object) || predicates.get(44).test(object) || predicates.get(45).test(object) || predicates.get(46).test(object) || predicates.get(47).test(object) || predicates.get(48).test(object) || predicates.get(49).test(object) || predicates.get(50).test(object) || predicates.get(51).test(object) || predicates.get(52).test(object) || predicates.get(53).test(object) || predicates.get(54).test(object) || predicates.get(55).test(object); + case 57 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object) || predicates.get(21).test(object) || predicates.get(22).test(object) || predicates.get(23).test(object) || predicates.get(24).test(object) || predicates.get(25).test(object) || predicates.get(26).test(object) || predicates.get(27).test(object) || predicates.get(28).test(object) || predicates.get(29).test(object) || predicates.get(30).test(object) || predicates.get(31).test(object) || predicates.get(32).test(object) || predicates.get(33).test(object) || predicates.get(34).test(object) || predicates.get(35).test(object) || predicates.get(36).test(object) || predicates.get(37).test(object) || predicates.get(38).test(object) || predicates.get(39).test(object) || predicates.get(40).test(object) || predicates.get(41).test(object) || predicates.get(42).test(object) || predicates.get(43).test(object) || predicates.get(44).test(object) || predicates.get(45).test(object) || predicates.get(46).test(object) || predicates.get(47).test(object) || predicates.get(48).test(object) || predicates.get(49).test(object) || predicates.get(50).test(object) || predicates.get(51).test(object) || predicates.get(52).test(object) || predicates.get(53).test(object) || predicates.get(54).test(object) || predicates.get(55).test(object) || predicates.get(56).test(object); + case 58 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object) || predicates.get(21).test(object) || predicates.get(22).test(object) || predicates.get(23).test(object) || predicates.get(24).test(object) || predicates.get(25).test(object) || predicates.get(26).test(object) || predicates.get(27).test(object) || predicates.get(28).test(object) || predicates.get(29).test(object) || predicates.get(30).test(object) || predicates.get(31).test(object) || predicates.get(32).test(object) || predicates.get(33).test(object) || predicates.get(34).test(object) || predicates.get(35).test(object) || predicates.get(36).test(object) || predicates.get(37).test(object) || predicates.get(38).test(object) || predicates.get(39).test(object) || predicates.get(40).test(object) || predicates.get(41).test(object) || predicates.get(42).test(object) || predicates.get(43).test(object) || predicates.get(44).test(object) || predicates.get(45).test(object) || predicates.get(46).test(object) || predicates.get(47).test(object) || predicates.get(48).test(object) || predicates.get(49).test(object) || predicates.get(50).test(object) || predicates.get(51).test(object) || predicates.get(52).test(object) || predicates.get(53).test(object) || predicates.get(54).test(object) || predicates.get(55).test(object) || predicates.get(56).test(object) || predicates.get(57).test(object); + case 59 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object) || predicates.get(21).test(object) || predicates.get(22).test(object) || predicates.get(23).test(object) || predicates.get(24).test(object) || predicates.get(25).test(object) || predicates.get(26).test(object) || predicates.get(27).test(object) || predicates.get(28).test(object) || predicates.get(29).test(object) || predicates.get(30).test(object) || predicates.get(31).test(object) || predicates.get(32).test(object) || predicates.get(33).test(object) || predicates.get(34).test(object) || predicates.get(35).test(object) || predicates.get(36).test(object) || predicates.get(37).test(object) || predicates.get(38).test(object) || predicates.get(39).test(object) || predicates.get(40).test(object) || predicates.get(41).test(object) || predicates.get(42).test(object) || predicates.get(43).test(object) || predicates.get(44).test(object) || predicates.get(45).test(object) || predicates.get(46).test(object) || predicates.get(47).test(object) || predicates.get(48).test(object) || predicates.get(49).test(object) || predicates.get(50).test(object) || predicates.get(51).test(object) || predicates.get(52).test(object) || predicates.get(53).test(object) || predicates.get(54).test(object) || predicates.get(55).test(object) || predicates.get(56).test(object) || predicates.get(57).test(object) || predicates.get(58).test(object); + case 60 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object) || predicates.get(21).test(object) || predicates.get(22).test(object) || predicates.get(23).test(object) || predicates.get(24).test(object) || predicates.get(25).test(object) || predicates.get(26).test(object) || predicates.get(27).test(object) || predicates.get(28).test(object) || predicates.get(29).test(object) || predicates.get(30).test(object) || predicates.get(31).test(object) || predicates.get(32).test(object) || predicates.get(33).test(object) || predicates.get(34).test(object) || predicates.get(35).test(object) || predicates.get(36).test(object) || predicates.get(37).test(object) || predicates.get(38).test(object) || predicates.get(39).test(object) || predicates.get(40).test(object) || predicates.get(41).test(object) || predicates.get(42).test(object) || predicates.get(43).test(object) || predicates.get(44).test(object) || predicates.get(45).test(object) || predicates.get(46).test(object) || predicates.get(47).test(object) || predicates.get(48).test(object) || predicates.get(49).test(object) || predicates.get(50).test(object) || predicates.get(51).test(object) || predicates.get(52).test(object) || predicates.get(53).test(object) || predicates.get(54).test(object) || predicates.get(55).test(object) || predicates.get(56).test(object) || predicates.get(57).test(object) || predicates.get(58).test(object) || predicates.get(59).test(object); + case 61 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object) || predicates.get(21).test(object) || predicates.get(22).test(object) || predicates.get(23).test(object) || predicates.get(24).test(object) || predicates.get(25).test(object) || predicates.get(26).test(object) || predicates.get(27).test(object) || predicates.get(28).test(object) || predicates.get(29).test(object) || predicates.get(30).test(object) || predicates.get(31).test(object) || predicates.get(32).test(object) || predicates.get(33).test(object) || predicates.get(34).test(object) || predicates.get(35).test(object) || predicates.get(36).test(object) || predicates.get(37).test(object) || predicates.get(38).test(object) || predicates.get(39).test(object) || predicates.get(40).test(object) || predicates.get(41).test(object) || predicates.get(42).test(object) || predicates.get(43).test(object) || predicates.get(44).test(object) || predicates.get(45).test(object) || predicates.get(46).test(object) || predicates.get(47).test(object) || predicates.get(48).test(object) || predicates.get(49).test(object) || predicates.get(50).test(object) || predicates.get(51).test(object) || predicates.get(52).test(object) || predicates.get(53).test(object) || predicates.get(54).test(object) || predicates.get(55).test(object) || predicates.get(56).test(object) || predicates.get(57).test(object) || predicates.get(58).test(object) || predicates.get(59).test(object) || predicates.get(60).test(object); + case 62 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object) || predicates.get(21).test(object) || predicates.get(22).test(object) || predicates.get(23).test(object) || predicates.get(24).test(object) || predicates.get(25).test(object) || predicates.get(26).test(object) || predicates.get(27).test(object) || predicates.get(28).test(object) || predicates.get(29).test(object) || predicates.get(30).test(object) || predicates.get(31).test(object) || predicates.get(32).test(object) || predicates.get(33).test(object) || predicates.get(34).test(object) || predicates.get(35).test(object) || predicates.get(36).test(object) || predicates.get(37).test(object) || predicates.get(38).test(object) || predicates.get(39).test(object) || predicates.get(40).test(object) || predicates.get(41).test(object) || predicates.get(42).test(object) || predicates.get(43).test(object) || predicates.get(44).test(object) || predicates.get(45).test(object) || predicates.get(46).test(object) || predicates.get(47).test(object) || predicates.get(48).test(object) || predicates.get(49).test(object) || predicates.get(50).test(object) || predicates.get(51).test(object) || predicates.get(52).test(object) || predicates.get(53).test(object) || predicates.get(54).test(object) || predicates.get(55).test(object) || predicates.get(56).test(object) || predicates.get(57).test(object) || predicates.get(58).test(object) || predicates.get(59).test(object) || predicates.get(60).test(object) || predicates.get(61).test(object); + case 63 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object) || predicates.get(21).test(object) || predicates.get(22).test(object) || predicates.get(23).test(object) || predicates.get(24).test(object) || predicates.get(25).test(object) || predicates.get(26).test(object) || predicates.get(27).test(object) || predicates.get(28).test(object) || predicates.get(29).test(object) || predicates.get(30).test(object) || predicates.get(31).test(object) || predicates.get(32).test(object) || predicates.get(33).test(object) || predicates.get(34).test(object) || predicates.get(35).test(object) || predicates.get(36).test(object) || predicates.get(37).test(object) || predicates.get(38).test(object) || predicates.get(39).test(object) || predicates.get(40).test(object) || predicates.get(41).test(object) || predicates.get(42).test(object) || predicates.get(43).test(object) || predicates.get(44).test(object) || predicates.get(45).test(object) || predicates.get(46).test(object) || predicates.get(47).test(object) || predicates.get(48).test(object) || predicates.get(49).test(object) || predicates.get(50).test(object) || predicates.get(51).test(object) || predicates.get(52).test(object) || predicates.get(53).test(object) || predicates.get(54).test(object) || predicates.get(55).test(object) || predicates.get(56).test(object) || predicates.get(57).test(object) || predicates.get(58).test(object) || predicates.get(59).test(object) || predicates.get(60).test(object) || predicates.get(61).test(object) || predicates.get(62).test(object); + case 64 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object) || predicates.get(21).test(object) || predicates.get(22).test(object) || predicates.get(23).test(object) || predicates.get(24).test(object) || predicates.get(25).test(object) || predicates.get(26).test(object) || predicates.get(27).test(object) || predicates.get(28).test(object) || predicates.get(29).test(object) || predicates.get(30).test(object) || predicates.get(31).test(object) || predicates.get(32).test(object) || predicates.get(33).test(object) || predicates.get(34).test(object) || predicates.get(35).test(object) || predicates.get(36).test(object) || predicates.get(37).test(object) || predicates.get(38).test(object) || predicates.get(39).test(object) || predicates.get(40).test(object) || predicates.get(41).test(object) || predicates.get(42).test(object) || predicates.get(43).test(object) || predicates.get(44).test(object) || predicates.get(45).test(object) || predicates.get(46).test(object) || predicates.get(47).test(object) || predicates.get(48).test(object) || predicates.get(49).test(object) || predicates.get(50).test(object) || predicates.get(51).test(object) || predicates.get(52).test(object) || predicates.get(53).test(object) || predicates.get(54).test(object) || predicates.get(55).test(object) || predicates.get(56).test(object) || predicates.get(57).test(object) || predicates.get(58).test(object) || predicates.get(59).test(object) || predicates.get(60).test(object) || predicates.get(61).test(object) || predicates.get(62).test(object) || predicates.get(63).test(object); + case 65 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object) || predicates.get(21).test(object) || predicates.get(22).test(object) || predicates.get(23).test(object) || predicates.get(24).test(object) || predicates.get(25).test(object) || predicates.get(26).test(object) || predicates.get(27).test(object) || predicates.get(28).test(object) || predicates.get(29).test(object) || predicates.get(30).test(object) || predicates.get(31).test(object) || predicates.get(32).test(object) || predicates.get(33).test(object) || predicates.get(34).test(object) || predicates.get(35).test(object) || predicates.get(36).test(object) || predicates.get(37).test(object) || predicates.get(38).test(object) || predicates.get(39).test(object) || predicates.get(40).test(object) || predicates.get(41).test(object) || predicates.get(42).test(object) || predicates.get(43).test(object) || predicates.get(44).test(object) || predicates.get(45).test(object) || predicates.get(46).test(object) || predicates.get(47).test(object) || predicates.get(48).test(object) || predicates.get(49).test(object) || predicates.get(50).test(object) || predicates.get(51).test(object) || predicates.get(52).test(object) || predicates.get(53).test(object) || predicates.get(54).test(object) || predicates.get(55).test(object) || predicates.get(56).test(object) || predicates.get(57).test(object) || predicates.get(58).test(object) || predicates.get(59).test(object) || predicates.get(60).test(object) || predicates.get(61).test(object) || predicates.get(62).test(object) || predicates.get(63).test(object) || predicates.get(64).test(object); + case 66 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object) || predicates.get(21).test(object) || predicates.get(22).test(object) || predicates.get(23).test(object) || predicates.get(24).test(object) || predicates.get(25).test(object) || predicates.get(26).test(object) || predicates.get(27).test(object) || predicates.get(28).test(object) || predicates.get(29).test(object) || predicates.get(30).test(object) || predicates.get(31).test(object) || predicates.get(32).test(object) || predicates.get(33).test(object) || predicates.get(34).test(object) || predicates.get(35).test(object) || predicates.get(36).test(object) || predicates.get(37).test(object) || predicates.get(38).test(object) || predicates.get(39).test(object) || predicates.get(40).test(object) || predicates.get(41).test(object) || predicates.get(42).test(object) || predicates.get(43).test(object) || predicates.get(44).test(object) || predicates.get(45).test(object) || predicates.get(46).test(object) || predicates.get(47).test(object) || predicates.get(48).test(object) || predicates.get(49).test(object) || predicates.get(50).test(object) || predicates.get(51).test(object) || predicates.get(52).test(object) || predicates.get(53).test(object) || predicates.get(54).test(object) || predicates.get(55).test(object) || predicates.get(56).test(object) || predicates.get(57).test(object) || predicates.get(58).test(object) || predicates.get(59).test(object) || predicates.get(60).test(object) || predicates.get(61).test(object) || predicates.get(62).test(object) || predicates.get(63).test(object) || predicates.get(64).test(object) || predicates.get(65).test(object); + case 67 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object) || predicates.get(21).test(object) || predicates.get(22).test(object) || predicates.get(23).test(object) || predicates.get(24).test(object) || predicates.get(25).test(object) || predicates.get(26).test(object) || predicates.get(27).test(object) || predicates.get(28).test(object) || predicates.get(29).test(object) || predicates.get(30).test(object) || predicates.get(31).test(object) || predicates.get(32).test(object) || predicates.get(33).test(object) || predicates.get(34).test(object) || predicates.get(35).test(object) || predicates.get(36).test(object) || predicates.get(37).test(object) || predicates.get(38).test(object) || predicates.get(39).test(object) || predicates.get(40).test(object) || predicates.get(41).test(object) || predicates.get(42).test(object) || predicates.get(43).test(object) || predicates.get(44).test(object) || predicates.get(45).test(object) || predicates.get(46).test(object) || predicates.get(47).test(object) || predicates.get(48).test(object) || predicates.get(49).test(object) || predicates.get(50).test(object) || predicates.get(51).test(object) || predicates.get(52).test(object) || predicates.get(53).test(object) || predicates.get(54).test(object) || predicates.get(55).test(object) || predicates.get(56).test(object) || predicates.get(57).test(object) || predicates.get(58).test(object) || predicates.get(59).test(object) || predicates.get(60).test(object) || predicates.get(61).test(object) || predicates.get(62).test(object) || predicates.get(63).test(object) || predicates.get(64).test(object) || predicates.get(65).test(object) || predicates.get(66).test(object); + case 68 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object) || predicates.get(21).test(object) || predicates.get(22).test(object) || predicates.get(23).test(object) || predicates.get(24).test(object) || predicates.get(25).test(object) || predicates.get(26).test(object) || predicates.get(27).test(object) || predicates.get(28).test(object) || predicates.get(29).test(object) || predicates.get(30).test(object) || predicates.get(31).test(object) || predicates.get(32).test(object) || predicates.get(33).test(object) || predicates.get(34).test(object) || predicates.get(35).test(object) || predicates.get(36).test(object) || predicates.get(37).test(object) || predicates.get(38).test(object) || predicates.get(39).test(object) || predicates.get(40).test(object) || predicates.get(41).test(object) || predicates.get(42).test(object) || predicates.get(43).test(object) || predicates.get(44).test(object) || predicates.get(45).test(object) || predicates.get(46).test(object) || predicates.get(47).test(object) || predicates.get(48).test(object) || predicates.get(49).test(object) || predicates.get(50).test(object) || predicates.get(51).test(object) || predicates.get(52).test(object) || predicates.get(53).test(object) || predicates.get(54).test(object) || predicates.get(55).test(object) || predicates.get(56).test(object) || predicates.get(57).test(object) || predicates.get(58).test(object) || predicates.get(59).test(object) || predicates.get(60).test(object) || predicates.get(61).test(object) || predicates.get(62).test(object) || predicates.get(63).test(object) || predicates.get(64).test(object) || predicates.get(65).test(object) || predicates.get(66).test(object) || predicates.get(67).test(object); + case 69 -> object -> predicates.getFirst().test(object) || predicates.get(1).test(object) || predicates.get(2).test(object) || predicates.get(3).test(object) || predicates.get(4).test(object) || predicates.get(5).test(object) || predicates.get(6).test(object) || predicates.get(7).test(object) || predicates.get(8).test(object) || predicates.get(9).test(object) || predicates.get(10).test(object) || predicates.get(11).test(object) || predicates.get(12).test(object) || predicates.get(13).test(object) || predicates.get(14).test(object) || predicates.get(15).test(object) || predicates.get(16).test(object) || predicates.get(17).test(object) || predicates.get(18).test(object) || predicates.get(19).test(object) || predicates.get(20).test(object) || predicates.get(21).test(object) || predicates.get(22).test(object) || predicates.get(23).test(object) || predicates.get(24).test(object) || predicates.get(25).test(object) || predicates.get(26).test(object) || predicates.get(27).test(object) || predicates.get(28).test(object) || predicates.get(29).test(object) || predicates.get(30).test(object) || predicates.get(31).test(object) || predicates.get(32).test(object) || predicates.get(33).test(object) || predicates.get(34).test(object) || predicates.get(35).test(object) || predicates.get(36).test(object) || predicates.get(37).test(object) || predicates.get(38).test(object) || predicates.get(39).test(object) || predicates.get(40).test(object) || predicates.get(41).test(object) || predicates.get(42).test(object) || predicates.get(43).test(object) || predicates.get(44).test(object) || predicates.get(45).test(object) || predicates.get(46).test(object) || predicates.get(47).test(object) || predicates.get(48).test(object) || predicates.get(49).test(object) || predicates.get(50).test(object) || predicates.get(51).test(object) || predicates.get(52).test(object) || predicates.get(53).test(object) || predicates.get(54).test(object) || predicates.get(55).test(object) || predicates.get(56).test(object) || predicates.get(57).test(object) || predicates.get(58).test(object) || predicates.get(59).test(object) || predicates.get(60).test(object) || predicates.get(61).test(object) || predicates.get(62).test(object) || predicates.get(63).test(object) || predicates.get(64).test(object) || predicates.get(65).test(object) || predicates.get(66).test(object) || predicates.get(67).test(object) || predicates.get(68).test(object); + default -> anyOf2(predicates); + }; + } + + private static Predicate anyOf2(List> predicates) { + return object -> { + for (final Predicate predicate : predicates) { + if (predicate.test(object)) return true; + } + return false; + }; + } +} diff --git a/src/main/resources/assets/loot-table-modifier/icon.png b/common/src/main/resources/assets/loot-table-modifier/icon.png similarity index 100% rename from src/main/resources/assets/loot-table-modifier/icon.png rename to common/src/main/resources/assets/loot-table-modifier/icon.png diff --git a/docker-compose-template.yml b/docker-compose-template.yml deleted file mode 100644 index 96c558a..0000000 --- a/docker-compose-template.yml +++ /dev/null @@ -1,17 +0,0 @@ -# Hosts a static page -services: - ${URL_PREFIX}loot-table-modifier: - image: registry.oracle.offsetmonkey538.top/loot-table-modifier/docs:${SHORT_COMMIT_HASH} - restart: unless-stopped - networks: - - traefik-proxy - labels: - - "traefik.enable=true" - - - "traefik.http.routers.${URL_PREFIX}loot-table-modifier.rule=Host(`${URL_PREFIX}loot-table-modifier.docs.offsetmonkey538.top`)" - - "traefik.http.routers.${URL_PREFIX}loot-table-modifier.service=${URL_PREFIX}loot-table-modifier" - - "traefik.http.services.${URL_PREFIX}loot-table-modifier.loadbalancer.server.port=80" - -networks: - traefik-proxy: - external: true \ No newline at end of file diff --git a/docs/.gitignore b/docs/.gitignore deleted file mode 100644 index 6240da8..0000000 --- a/docs/.gitignore +++ /dev/null @@ -1,21 +0,0 @@ -# build output -dist/ -# generated types -.astro/ - -# dependencies -node_modules/ - -# logs -npm-debug.log* -yarn-debug.log* -yarn-error.log* -pnpm-debug.log* - - -# environment variables -.env -.env.production - -# macOS-specific files -.DS_Store diff --git a/docs/.vscode/extensions.json b/docs/.vscode/extensions.json deleted file mode 100644 index 22a1505..0000000 --- a/docs/.vscode/extensions.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "recommendations": ["astro-build.astro-vscode"], - "unwantedRecommendations": [] -} diff --git a/docs/.vscode/launch.json b/docs/.vscode/launch.json deleted file mode 100644 index d642209..0000000 --- a/docs/.vscode/launch.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "version": "0.2.0", - "configurations": [ - { - "command": "./node_modules/.bin/astro dev", - "name": "Development server", - "request": "launch", - "type": "node-terminal" - } - ] -} diff --git a/docs/README.md b/docs/README.md deleted file mode 100644 index 70f4d8b..0000000 --- a/docs/README.md +++ /dev/null @@ -1,54 +0,0 @@ -# Starlight Starter Kit: Basics - -[![Built with Starlight](https://astro.badg.es/v2/built-with-starlight/tiny.svg)](https://starlight.astro.build) - -``` -pnpm create astro@latest -- --template starlight -``` - -[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/withastro/starlight/tree/main/examples/basics) -[![Open with CodeSandbox](https://assets.codesandbox.io/github/button-edit-lime.svg)](https://codesandbox.io/p/sandbox/github/withastro/starlight/tree/main/examples/basics) -[![Deploy to Netlify](https://www.netlify.com/img/deploy/button.svg)](https://app.netlify.com/start/deploy?repository=https://github.com/withastro/starlight&create_from_path=examples/basics) -[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fwithastro%2Fstarlight%2Ftree%2Fmain%2Fexamples%2Fbasics&project-name=my-starlight-docs&repository-name=my-starlight-docs) - -> 🧑‍🚀 **Seasoned astronaut?** Delete this file. Have fun! - -## 🚀 Project Structure - -Inside of your Astro + Starlight project, you'll see the following folders and files: - -``` -. -├── public/ -├── src/ -│ ├── assets/ -│ ├── content/ -│ │ ├── docs/ -│ └── content.config.ts -├── astro.config.mjs -├── package.json -└── tsconfig.json -``` - -Starlight looks for `.md` or `.mdx` files in the `src/content/docs/` directory. Each file is exposed as a route based on its file name. - -Images can be added to `src/assets/` and embedded in Markdown with a relative link. - -Static assets, like favicons, can be placed in the `public/` directory. - -## 🧞 Commands - -All commands are run from the root of the project, from a terminal: - -| Command | Action | -| :------------------------ | :----------------------------------------------- | -| `pnpm install` | Installs dependencies | -| `pnpm dev` | Starts local dev server at `localhost:4321` | -| `pnpm build` | Build your production site to `./dist/` | -| `pnpm preview` | Preview your build locally, before deploying | -| `pnpm astro ...` | Run CLI commands like `astro add`, `astro check` | -| `pnpm astro -- --help` | Get help using the Astro CLI | - -## 👀 Want to learn more? - -Check out [Starlight’s docs](https://starlight.astro.build/), read [the Astro documentation](https://docs.astro.build), or jump into the [Astro Discord server](https://astro.build/chat). diff --git a/docs/astro.config.mjs b/docs/astro.config.mjs deleted file mode 100644 index fea992e..0000000 --- a/docs/astro.config.mjs +++ /dev/null @@ -1,53 +0,0 @@ -// @ts-check -import { defineConfig } from 'astro/config'; -import starlightSocialIcons from './src/utils/socialIcons'; -import starlight from '@astrojs/starlight'; - -// https://astro.build/config -export default defineConfig({ - integrations: [ - starlightSocialIcons({ - modrinth: "https://modrinth.com/mod/loot-table-modifier" - }), - starlight({ - title: 'Loot Table Modifier', - credits: true, - logo: { - src: './src/assets/face.svg' - }, - customCss: [ - './src/styles/custom.css' - ], - components: { - SocialIcons: './src/utils/SocialIcons.astro', - PageFrame: './src/utils/PageFrame.astro' - }, - social: [ - {icon: 'github', label: 'GitHub', href: 'https://github.com/OffsetMods538/Loot-Table-Modifier'}, - {icon: 'discord', label: 'Discord', href: 'https://discord.offsetmonkey538.top'} - ], - sidebar: [ - {label: 'Getting Started', slug: 'getting_started'}, - { - label: 'Examples', - items: [ - {label: 'Replace any ingot with a diamond', slug: 'examples/replace_ingot_w_diamond'}, - {label: 'Make Creepers and Zombies drop tnt', slug: 'examples/creepers_and_zombies_drop_tnt'}, - {label: 'Remove sticks', slug: 'examples/remove_sticks'}, - {label: 'Remove glowstone and gunpowder from witches', slug: 'examples/remove_glowstone_and_gunpowder_witches'}, - ], - }, - { - label: 'Reference', - items: [ - {label: 'Loot Modifier', slug: 'reference/loot_modifier'}, - {label: 'Actions', slug: 'reference/actions'}, - {label: 'Regex Identifier', slug: 'reference/regex_identifier'}, - {label: 'Predicates', slug: 'reference/predicates'}, - {label: 'Badges', slug: 'reference/badges'}, - ], - }, - ], - }), - ] -}); diff --git a/docs/package.json b/docs/package.json deleted file mode 100644 index f50ef1e..0000000 --- a/docs/package.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "name": "docs", - "type": "module", - "version": "0.0.1", - "scripts": { - "dev": "astro dev", - "start": "astro dev", - "build": "astro build", - "preview": "astro preview", - "astro": "astro" - }, - "dependencies": { - "@astrojs/starlight": "^0.35.1", - "astro": "^5.12.0", - "pathe": "^2.0.3", - "sharp": "^0.34.2" - } -} \ No newline at end of file diff --git a/docs/pnpm-lock.yaml b/docs/pnpm-lock.yaml deleted file mode 100644 index b25848d..0000000 --- a/docs/pnpm-lock.yaml +++ /dev/null @@ -1,4306 +0,0 @@ -lockfileVersion: '9.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -importers: - - .: - dependencies: - '@astrojs/starlight': - specifier: ^0.35.1 - version: 0.35.1(astro@5.12.0(@types/node@24.0.10)(rollup@4.44.2)(typescript@5.8.3)) - astro: - specifier: ^5.12.0 - version: 5.12.0(@types/node@24.0.10)(rollup@4.44.2)(typescript@5.8.3) - pathe: - specifier: ^2.0.3 - version: 2.0.3 - sharp: - specifier: ^0.34.2 - version: 0.34.2 - -packages: - - '@astrojs/compiler@2.12.2': - resolution: {integrity: sha512-w2zfvhjNCkNMmMMOn5b0J8+OmUaBL1o40ipMvqcG6NRpdC+lKxmTi48DT8Xw0SzJ3AfmeFLB45zXZXtmbsjcgw==} - - '@astrojs/internal-helpers@0.6.1': - resolution: {integrity: sha512-l5Pqf6uZu31aG+3Lv8nl/3s4DbUzdlxTWDof4pEpto6GUJNhhCbelVi9dEyurOVyqaelwmS9oSyOWOENSfgo9A==} - - '@astrojs/markdown-remark@6.3.2': - resolution: {integrity: sha512-bO35JbWpVvyKRl7cmSJD822e8YA8ThR/YbUsciWNA7yTcqpIAL2hJDToWP5KcZBWxGT6IOdOkHSXARSNZc4l/Q==} - - '@astrojs/markdown-remark@6.3.3': - resolution: {integrity: sha512-DDRtD1sPvAuA7ms2btc9A7/7DApKqgLMNrE6kh5tmkfy8utD0Z738gqd3p5aViYYdUtHIyEJ1X4mCMxfCfu15w==} - - '@astrojs/mdx@4.3.0': - resolution: {integrity: sha512-OGX2KvPeBzjSSKhkCqrUoDMyzFcjKt5nTE5SFw3RdoLf0nrhyCXBQcCyclzWy1+P+XpOamn+p+hm1EhpCRyPxw==} - engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0} - peerDependencies: - astro: ^5.0.0 - - '@astrojs/prism@3.3.0': - resolution: {integrity: sha512-q8VwfU/fDZNoDOf+r7jUnMC2//H2l0TuQ6FkGJL8vD8nw/q5KiL3DS1KKBI3QhI9UQhpJ5dc7AtqfbXWuOgLCQ==} - engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0} - - '@astrojs/sitemap@3.4.1': - resolution: {integrity: sha512-VjZvr1e4FH6NHyyHXOiQgLiw94LnCVY4v06wN/D0gZKchTMkg71GrAHJz81/huafcmavtLkIv26HnpfDq6/h/Q==} - - '@astrojs/starlight@0.35.1': - resolution: {integrity: sha512-/hshlAayMd3B+E+h8wY6JWT1lNmX/K1+ugiZPirW5XFo5QUcNMk/Bsa4oHgg+TFoU6kbxPtijo0VppATfD9XuA==} - peerDependencies: - astro: ^5.5.0 - - '@astrojs/telemetry@3.3.0': - resolution: {integrity: sha512-UFBgfeldP06qu6khs/yY+q1cDAaArM2/7AEIqQ9Cuvf7B1hNLq0xDrZkct+QoIGyjq56y8IaE2I3CTvG99mlhQ==} - engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0} - - '@babel/helper-string-parser@7.27.1': - resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} - engines: {node: '>=6.9.0'} - - '@babel/helper-validator-identifier@7.27.1': - resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} - engines: {node: '>=6.9.0'} - - '@babel/parser@7.28.0': - resolution: {integrity: sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==} - engines: {node: '>=6.0.0'} - hasBin: true - - '@babel/runtime@7.27.6': - resolution: {integrity: sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==} - engines: {node: '>=6.9.0'} - - '@babel/types@7.28.0': - resolution: {integrity: sha512-jYnje+JyZG5YThjHiF28oT4SIZLnYOcSBb6+SDaFIyzDVSkXQmQQYclJ2R+YxcdmK0AX6x1E5OQNtuh3jHDrUg==} - engines: {node: '>=6.9.0'} - - '@capsizecss/unpack@2.4.0': - resolution: {integrity: sha512-GrSU71meACqcmIUxPYOJvGKF0yryjN/L1aCuE9DViCTJI7bfkjgYDPD1zbNDcINJwSSP6UaBZY9GAbYDO7re0Q==} - - '@ctrl/tinycolor@4.1.0': - resolution: {integrity: sha512-WyOx8cJQ+FQus4Mm4uPIZA64gbk3Wxh0so5Lcii0aJifqwoVOlfFtorjLE0Hen4OYyHZMXDWqMmaQemBhgxFRQ==} - engines: {node: '>=14'} - - '@emnapi/runtime@1.4.3': - resolution: {integrity: sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==} - - '@esbuild/aix-ppc64@0.25.5': - resolution: {integrity: sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] - - '@esbuild/android-arm64@0.25.5': - resolution: {integrity: sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm@0.25.5': - resolution: {integrity: sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==} - engines: {node: '>=18'} - cpu: [arm] - os: [android] - - '@esbuild/android-x64@0.25.5': - resolution: {integrity: sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==} - engines: {node: '>=18'} - cpu: [x64] - os: [android] - - '@esbuild/darwin-arm64@0.25.5': - resolution: {integrity: sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-x64@0.25.5': - resolution: {integrity: sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [darwin] - - '@esbuild/freebsd-arm64@0.25.5': - resolution: {integrity: sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.25.5': - resolution: {integrity: sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==} - engines: {node: '>=18'} - cpu: [x64] - os: [freebsd] - - '@esbuild/linux-arm64@0.25.5': - resolution: {integrity: sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm@0.25.5': - resolution: {integrity: sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==} - engines: {node: '>=18'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-ia32@0.25.5': - resolution: {integrity: sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==} - engines: {node: '>=18'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-loong64@0.25.5': - resolution: {integrity: sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==} - engines: {node: '>=18'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-mips64el@0.25.5': - resolution: {integrity: sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==} - engines: {node: '>=18'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-ppc64@0.25.5': - resolution: {integrity: sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-riscv64@0.25.5': - resolution: {integrity: sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==} - engines: {node: '>=18'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-s390x@0.25.5': - resolution: {integrity: sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==} - engines: {node: '>=18'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-x64@0.25.5': - resolution: {integrity: sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==} - engines: {node: '>=18'} - cpu: [x64] - os: [linux] - - '@esbuild/netbsd-arm64@0.25.5': - resolution: {integrity: sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [netbsd] - - '@esbuild/netbsd-x64@0.25.5': - resolution: {integrity: sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [netbsd] - - '@esbuild/openbsd-arm64@0.25.5': - resolution: {integrity: sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] - - '@esbuild/openbsd-x64@0.25.5': - resolution: {integrity: sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==} - engines: {node: '>=18'} - cpu: [x64] - os: [openbsd] - - '@esbuild/sunos-x64@0.25.5': - resolution: {integrity: sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==} - engines: {node: '>=18'} - cpu: [x64] - os: [sunos] - - '@esbuild/win32-arm64@0.25.5': - resolution: {integrity: sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-ia32@0.25.5': - resolution: {integrity: sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==} - engines: {node: '>=18'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-x64@0.25.5': - resolution: {integrity: sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==} - engines: {node: '>=18'} - cpu: [x64] - os: [win32] - - '@expressive-code/core@0.41.2': - resolution: {integrity: sha512-AJW5Tp9czbLqKMzwudL9Rv4js9afXBxkSGLmCNPq1iRgAYcx9NkTPJiSNCesjKRWoVC328AdSu6fqrD22zDgDg==} - - '@expressive-code/plugin-frames@0.41.2': - resolution: {integrity: sha512-pfy0hkJI4nbaONjmksFDcuHmIuyPTFmi1JpABe4q2ajskiJtfBf+WDAL2pg595R9JNoPrrH5+aT9lbkx2noicw==} - - '@expressive-code/plugin-shiki@0.41.2': - resolution: {integrity: sha512-xD4zwqAkDccXqye+235BH5bN038jYiSMLfUrCOmMlzxPDGWdxJDk5z4uUB/aLfivEF2tXyO2zyaarL3Oqht0fQ==} - - '@expressive-code/plugin-text-markers@0.41.2': - resolution: {integrity: sha512-JFWBz2qYxxJOJkkWf96LpeolbnOqJY95TvwYc0hXIHf9oSWV0h0SY268w/5N3EtQaD9KktzDE+VIVwb9jdb3nw==} - - '@img/sharp-darwin-arm64@0.33.5': - resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [darwin] - - '@img/sharp-darwin-arm64@0.34.2': - resolution: {integrity: sha512-OfXHZPppddivUJnqyKoi5YVeHRkkNE2zUFT2gbpKxp/JZCFYEYubnMg+gOp6lWfasPrTS+KPosKqdI+ELYVDtg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [darwin] - - '@img/sharp-darwin-x64@0.33.5': - resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [darwin] - - '@img/sharp-darwin-x64@0.34.2': - resolution: {integrity: sha512-dYvWqmjU9VxqXmjEtjmvHnGqF8GrVjM2Epj9rJ6BUIXvk8slvNDJbhGFvIoXzkDhrJC2jUxNLz/GUjjvSzfw+g==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [darwin] - - '@img/sharp-libvips-darwin-arm64@1.0.4': - resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==} - cpu: [arm64] - os: [darwin] - - '@img/sharp-libvips-darwin-arm64@1.1.0': - resolution: {integrity: sha512-HZ/JUmPwrJSoM4DIQPv/BfNh9yrOA8tlBbqbLz4JZ5uew2+o22Ik+tHQJcih7QJuSa0zo5coHTfD5J8inqj9DA==} - cpu: [arm64] - os: [darwin] - - '@img/sharp-libvips-darwin-x64@1.0.4': - resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==} - cpu: [x64] - os: [darwin] - - '@img/sharp-libvips-darwin-x64@1.1.0': - resolution: {integrity: sha512-Xzc2ToEmHN+hfvsl9wja0RlnXEgpKNmftriQp6XzY/RaSfwD9th+MSh0WQKzUreLKKINb3afirxW7A0fz2YWuQ==} - cpu: [x64] - os: [darwin] - - '@img/sharp-libvips-linux-arm64@1.0.4': - resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==} - cpu: [arm64] - os: [linux] - - '@img/sharp-libvips-linux-arm64@1.1.0': - resolution: {integrity: sha512-IVfGJa7gjChDET1dK9SekxFFdflarnUB8PwW8aGwEoF3oAsSDuNUTYS+SKDOyOJxQyDC1aPFMuRYLoDInyV9Ew==} - cpu: [arm64] - os: [linux] - - '@img/sharp-libvips-linux-arm@1.0.5': - resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==} - cpu: [arm] - os: [linux] - - '@img/sharp-libvips-linux-arm@1.1.0': - resolution: {integrity: sha512-s8BAd0lwUIvYCJyRdFqvsj+BJIpDBSxs6ivrOPm/R7piTs5UIwY5OjXrP2bqXC9/moGsyRa37eYWYCOGVXxVrA==} - cpu: [arm] - os: [linux] - - '@img/sharp-libvips-linux-ppc64@1.1.0': - resolution: {integrity: sha512-tiXxFZFbhnkWE2LA8oQj7KYR+bWBkiV2nilRldT7bqoEZ4HiDOcePr9wVDAZPi/Id5fT1oY9iGnDq20cwUz8lQ==} - cpu: [ppc64] - os: [linux] - - '@img/sharp-libvips-linux-s390x@1.0.4': - resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==} - cpu: [s390x] - os: [linux] - - '@img/sharp-libvips-linux-s390x@1.1.0': - resolution: {integrity: sha512-xukSwvhguw7COyzvmjydRb3x/09+21HykyapcZchiCUkTThEQEOMtBj9UhkaBRLuBrgLFzQ2wbxdeCCJW/jgJA==} - cpu: [s390x] - os: [linux] - - '@img/sharp-libvips-linux-x64@1.0.4': - resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==} - cpu: [x64] - os: [linux] - - '@img/sharp-libvips-linux-x64@1.1.0': - resolution: {integrity: sha512-yRj2+reB8iMg9W5sULM3S74jVS7zqSzHG3Ol/twnAAkAhnGQnpjj6e4ayUz7V+FpKypwgs82xbRdYtchTTUB+Q==} - cpu: [x64] - os: [linux] - - '@img/sharp-libvips-linuxmusl-arm64@1.0.4': - resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==} - cpu: [arm64] - os: [linux] - - '@img/sharp-libvips-linuxmusl-arm64@1.1.0': - resolution: {integrity: sha512-jYZdG+whg0MDK+q2COKbYidaqW/WTz0cc1E+tMAusiDygrM4ypmSCjOJPmFTvHHJ8j/6cAGyeDWZOsK06tP33w==} - cpu: [arm64] - os: [linux] - - '@img/sharp-libvips-linuxmusl-x64@1.0.4': - resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==} - cpu: [x64] - os: [linux] - - '@img/sharp-libvips-linuxmusl-x64@1.1.0': - resolution: {integrity: sha512-wK7SBdwrAiycjXdkPnGCPLjYb9lD4l6Ze2gSdAGVZrEL05AOUJESWU2lhlC+Ffn5/G+VKuSm6zzbQSzFX/P65A==} - cpu: [x64] - os: [linux] - - '@img/sharp-linux-arm64@0.33.5': - resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [linux] - - '@img/sharp-linux-arm64@0.34.2': - resolution: {integrity: sha512-D8n8wgWmPDakc83LORcfJepdOSN6MvWNzzz2ux0MnIbOqdieRZwVYY32zxVx+IFUT8er5KPcyU3XXsn+GzG/0Q==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [linux] - - '@img/sharp-linux-arm@0.33.5': - resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm] - os: [linux] - - '@img/sharp-linux-arm@0.34.2': - resolution: {integrity: sha512-0DZzkvuEOqQUP9mo2kjjKNok5AmnOr1jB2XYjkaoNRwpAYMDzRmAqUIa1nRi58S2WswqSfPOWLNOr0FDT3H5RQ==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm] - os: [linux] - - '@img/sharp-linux-s390x@0.33.5': - resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [s390x] - os: [linux] - - '@img/sharp-linux-s390x@0.34.2': - resolution: {integrity: sha512-EGZ1xwhBI7dNISwxjChqBGELCWMGDvmxZXKjQRuqMrakhO8QoMgqCrdjnAqJq/CScxfRn+Bb7suXBElKQpPDiw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [s390x] - os: [linux] - - '@img/sharp-linux-x64@0.33.5': - resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [linux] - - '@img/sharp-linux-x64@0.34.2': - resolution: {integrity: sha512-sD7J+h5nFLMMmOXYH4DD9UtSNBD05tWSSdWAcEyzqW8Cn5UxXvsHAxmxSesYUsTOBmUnjtxghKDl15EvfqLFbQ==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [linux] - - '@img/sharp-linuxmusl-arm64@0.33.5': - resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [linux] - - '@img/sharp-linuxmusl-arm64@0.34.2': - resolution: {integrity: sha512-NEE2vQ6wcxYav1/A22OOxoSOGiKnNmDzCYFOZ949xFmrWZOVII1Bp3NqVVpvj+3UeHMFyN5eP/V5hzViQ5CZNA==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [linux] - - '@img/sharp-linuxmusl-x64@0.33.5': - resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [linux] - - '@img/sharp-linuxmusl-x64@0.34.2': - resolution: {integrity: sha512-DOYMrDm5E6/8bm/yQLCWyuDJwUnlevR8xtF8bs+gjZ7cyUNYXiSf/E8Kp0Ss5xasIaXSHzb888V1BE4i1hFhAA==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [linux] - - '@img/sharp-wasm32@0.33.5': - resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [wasm32] - - '@img/sharp-wasm32@0.34.2': - resolution: {integrity: sha512-/VI4mdlJ9zkaq53MbIG6rZY+QRN3MLbR6usYlgITEzi4Rpx5S6LFKsycOQjkOGmqTNmkIdLjEvooFKwww6OpdQ==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [wasm32] - - '@img/sharp-win32-arm64@0.34.2': - resolution: {integrity: sha512-cfP/r9FdS63VA5k0xiqaNaEoGxBg9k7uE+RQGzuK9fHt7jib4zAVVseR9LsE4gJcNWgT6APKMNnCcnyOtmSEUQ==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [win32] - - '@img/sharp-win32-ia32@0.33.5': - resolution: {integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [ia32] - os: [win32] - - '@img/sharp-win32-ia32@0.34.2': - resolution: {integrity: sha512-QLjGGvAbj0X/FXl8n1WbtQ6iVBpWU7JO94u/P2M4a8CFYsvQi4GW2mRy/JqkRx0qpBzaOdKJKw8uc930EX2AHw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [ia32] - os: [win32] - - '@img/sharp-win32-x64@0.33.5': - resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [win32] - - '@img/sharp-win32-x64@0.34.2': - resolution: {integrity: sha512-aUdT6zEYtDKCaxkofmmJDJYGCf0+pJg3eU9/oBuqvEeoB9dKI6ZLc/1iLJCTuJQDO4ptntAlkUmHgGjyuobZbw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [win32] - - '@jridgewell/sourcemap-codec@1.5.4': - resolution: {integrity: sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==} - - '@mdx-js/mdx@3.1.0': - resolution: {integrity: sha512-/QxEhPAvGwbQmy1Px8F899L5Uc2KZ6JtXwlCgJmjSTBedwOZkByYcBG4GceIGPXRDsmfxhHazuS+hlOShRLeDw==} - - '@oslojs/encoding@1.1.0': - resolution: {integrity: sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==} - - '@pagefind/darwin-arm64@1.3.0': - resolution: {integrity: sha512-365BEGl6ChOsauRjyVpBjXybflXAOvoMROw3TucAROHIcdBvXk9/2AmEvGFU0r75+vdQI4LJdJdpH4Y6Yqaj4A==} - cpu: [arm64] - os: [darwin] - - '@pagefind/darwin-x64@1.3.0': - resolution: {integrity: sha512-zlGHA23uuXmS8z3XxEGmbHpWDxXfPZ47QS06tGUq0HDcZjXjXHeLG+cboOy828QIV5FXsm9MjfkP5e4ZNbOkow==} - cpu: [x64] - os: [darwin] - - '@pagefind/default-ui@1.3.0': - resolution: {integrity: sha512-CGKT9ccd3+oRK6STXGgfH+m0DbOKayX6QGlq38TfE1ZfUcPc5+ulTuzDbZUnMo+bubsEOIypm4Pl2iEyzZ1cNg==} - - '@pagefind/linux-arm64@1.3.0': - resolution: {integrity: sha512-8lsxNAiBRUk72JvetSBXs4WRpYrQrVJXjlRRnOL6UCdBN9Nlsz0t7hWstRk36+JqHpGWOKYiuHLzGYqYAqoOnQ==} - cpu: [arm64] - os: [linux] - - '@pagefind/linux-x64@1.3.0': - resolution: {integrity: sha512-hAvqdPJv7A20Ucb6FQGE6jhjqy+vZ6pf+s2tFMNtMBG+fzcdc91uTw7aP/1Vo5plD0dAOHwdxfkyw0ugal4kcQ==} - cpu: [x64] - os: [linux] - - '@pagefind/windows-x64@1.3.0': - resolution: {integrity: sha512-BR1bIRWOMqkf8IoU576YDhij1Wd/Zf2kX/kCI0b2qzCKC8wcc2GQJaaRMCpzvCCrmliO4vtJ6RITp/AnoYUUmQ==} - cpu: [x64] - os: [win32] - - '@rollup/pluginutils@5.2.0': - resolution: {integrity: sha512-qWJ2ZTbmumwiLFomfzTyt5Kng4hwPi9rwCYN4SHb6eaRU1KNO4ccxINHr/VhH4GgPlt1XfSTLX2LBTme8ne4Zw==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - - '@rollup/rollup-android-arm-eabi@4.44.2': - resolution: {integrity: sha512-g0dF8P1e2QYPOj1gu7s/3LVP6kze9A7m6x0BZ9iTdXK8N5c2V7cpBKHV3/9A4Zd8xxavdhK0t4PnqjkqVmUc9Q==} - cpu: [arm] - os: [android] - - '@rollup/rollup-android-arm64@4.44.2': - resolution: {integrity: sha512-Yt5MKrOosSbSaAK5Y4J+vSiID57sOvpBNBR6K7xAaQvk3MkcNVV0f9fE20T+41WYN8hDn6SGFlFrKudtx4EoxA==} - cpu: [arm64] - os: [android] - - '@rollup/rollup-darwin-arm64@4.44.2': - resolution: {integrity: sha512-EsnFot9ZieM35YNA26nhbLTJBHD0jTwWpPwmRVDzjylQT6gkar+zenfb8mHxWpRrbn+WytRRjE0WKsfaxBkVUA==} - cpu: [arm64] - os: [darwin] - - '@rollup/rollup-darwin-x64@4.44.2': - resolution: {integrity: sha512-dv/t1t1RkCvJdWWxQ2lWOO+b7cMsVw5YFaS04oHpZRWehI1h0fV1gF4wgGCTyQHHjJDfbNpwOi6PXEafRBBezw==} - cpu: [x64] - os: [darwin] - - '@rollup/rollup-freebsd-arm64@4.44.2': - resolution: {integrity: sha512-W4tt4BLorKND4qeHElxDoim0+BsprFTwb+vriVQnFFtT/P6v/xO5I99xvYnVzKWrK6j7Hb0yp3x7V5LUbaeOMg==} - cpu: [arm64] - os: [freebsd] - - '@rollup/rollup-freebsd-x64@4.44.2': - resolution: {integrity: sha512-tdT1PHopokkuBVyHjvYehnIe20fxibxFCEhQP/96MDSOcyjM/shlTkZZLOufV3qO6/FQOSiJTBebhVc12JyPTA==} - cpu: [x64] - os: [freebsd] - - '@rollup/rollup-linux-arm-gnueabihf@4.44.2': - resolution: {integrity: sha512-+xmiDGGaSfIIOXMzkhJ++Oa0Gwvl9oXUeIiwarsdRXSe27HUIvjbSIpPxvnNsRebsNdUo7uAiQVgBD1hVriwSQ==} - cpu: [arm] - os: [linux] - - '@rollup/rollup-linux-arm-musleabihf@4.44.2': - resolution: {integrity: sha512-bDHvhzOfORk3wt8yxIra8N4k/N0MnKInCW5OGZaeDYa/hMrdPaJzo7CSkjKZqX4JFUWjUGm88lI6QJLCM7lDrA==} - cpu: [arm] - os: [linux] - - '@rollup/rollup-linux-arm64-gnu@4.44.2': - resolution: {integrity: sha512-NMsDEsDiYghTbeZWEGnNi4F0hSbGnsuOG+VnNvxkKg0IGDvFh7UVpM/14mnMwxRxUf9AdAVJgHPvKXf6FpMB7A==} - cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-arm64-musl@4.44.2': - resolution: {integrity: sha512-lb5bxXnxXglVq+7imxykIp5xMq+idehfl+wOgiiix0191av84OqbjUED+PRC5OA8eFJYj5xAGcpAZ0pF2MnW+A==} - cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-loongarch64-gnu@4.44.2': - resolution: {integrity: sha512-Yl5Rdpf9pIc4GW1PmkUGHdMtbx0fBLE1//SxDmuf3X0dUC57+zMepow2LK0V21661cjXdTn8hO2tXDdAWAqE5g==} - cpu: [loong64] - os: [linux] - - '@rollup/rollup-linux-powerpc64le-gnu@4.44.2': - resolution: {integrity: sha512-03vUDH+w55s680YYryyr78jsO1RWU9ocRMaeV2vMniJJW/6HhoTBwyyiiTPVHNWLnhsnwcQ0oH3S9JSBEKuyqw==} - cpu: [ppc64] - os: [linux] - - '@rollup/rollup-linux-riscv64-gnu@4.44.2': - resolution: {integrity: sha512-iYtAqBg5eEMG4dEfVlkqo05xMOk6y/JXIToRca2bAWuqjrJYJlx/I7+Z+4hSrsWU8GdJDFPL4ktV3dy4yBSrzg==} - cpu: [riscv64] - os: [linux] - - '@rollup/rollup-linux-riscv64-musl@4.44.2': - resolution: {integrity: sha512-e6vEbgaaqz2yEHqtkPXa28fFuBGmUJ0N2dOJK8YUfijejInt9gfCSA7YDdJ4nYlv67JfP3+PSWFX4IVw/xRIPg==} - cpu: [riscv64] - os: [linux] - - '@rollup/rollup-linux-s390x-gnu@4.44.2': - resolution: {integrity: sha512-evFOtkmVdY3udE+0QKrV5wBx7bKI0iHz5yEVx5WqDJkxp9YQefy4Mpx3RajIVcM6o7jxTvVd/qpC1IXUhGc1Mw==} - cpu: [s390x] - os: [linux] - - '@rollup/rollup-linux-x64-gnu@4.44.2': - resolution: {integrity: sha512-/bXb0bEsWMyEkIsUL2Yt5nFB5naLAwyOWMEviQfQY1x3l5WsLKgvZf66TM7UTfED6erckUVUJQ/jJ1FSpm3pRQ==} - cpu: [x64] - os: [linux] - - '@rollup/rollup-linux-x64-musl@4.44.2': - resolution: {integrity: sha512-3D3OB1vSSBXmkGEZR27uiMRNiwN08/RVAcBKwhUYPaiZ8bcvdeEwWPvbnXvvXHY+A/7xluzcN+kaiOFNiOZwWg==} - cpu: [x64] - os: [linux] - - '@rollup/rollup-win32-arm64-msvc@4.44.2': - resolution: {integrity: sha512-VfU0fsMK+rwdK8mwODqYeM2hDrF2WiHaSmCBrS7gColkQft95/8tphyzv2EupVxn3iE0FI78wzffoULH1G+dkw==} - cpu: [arm64] - os: [win32] - - '@rollup/rollup-win32-ia32-msvc@4.44.2': - resolution: {integrity: sha512-+qMUrkbUurpE6DVRjiJCNGZBGo9xM4Y0FXU5cjgudWqIBWbcLkjE3XprJUsOFgC6xjBClwVa9k6O3A7K3vxb5Q==} - cpu: [ia32] - os: [win32] - - '@rollup/rollup-win32-x64-msvc@4.44.2': - resolution: {integrity: sha512-3+QZROYfJ25PDcxFF66UEk8jGWigHJeecZILvkPkyQN7oc5BvFo4YEXFkOs154j3FTMp9mn9Ky8RCOwastduEA==} - cpu: [x64] - os: [win32] - - '@shikijs/core@3.7.0': - resolution: {integrity: sha512-yilc0S9HvTPyahHpcum8eonYrQtmGTU0lbtwxhA6jHv4Bm1cAdlPFRCJX4AHebkCm75aKTjjRAW+DezqD1b/cg==} - - '@shikijs/engine-javascript@3.7.0': - resolution: {integrity: sha512-0t17s03Cbv+ZcUvv+y33GtX75WBLQELgNdVghnsdhTgU3hVcWcMsoP6Lb0nDTl95ZJfbP1mVMO0p3byVh3uuzA==} - - '@shikijs/engine-oniguruma@3.7.0': - resolution: {integrity: sha512-5BxcD6LjVWsGu4xyaBC5bu8LdNgPCVBnAkWTtOCs/CZxcB22L8rcoWfv7Hh/3WooVjBZmFtyxhgvkQFedPGnFw==} - - '@shikijs/langs@3.7.0': - resolution: {integrity: sha512-1zYtdfXLr9xDKLTGy5kb7O0zDQsxXiIsw1iIBcNOO8Yi5/Y1qDbJ+0VsFoqTlzdmneO8Ij35g7QKF8kcLyznCQ==} - - '@shikijs/themes@3.7.0': - resolution: {integrity: sha512-VJx8497iZPy5zLiiCTSIaOChIcKQwR0FebwE9S3rcN0+J/GTWwQ1v/bqhTbpbY3zybPKeO8wdammqkpXc4NVjQ==} - - '@shikijs/types@3.7.0': - resolution: {integrity: sha512-MGaLeaRlSWpnP0XSAum3kP3a8vtcTsITqoEPYdt3lQG3YCdQH4DnEhodkYcNMcU0uW0RffhoD1O3e0vG5eSBBg==} - - '@shikijs/vscode-textmate@10.0.2': - resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} - - '@swc/helpers@0.5.17': - resolution: {integrity: sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==} - - '@types/debug@4.1.12': - resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} - - '@types/estree-jsx@1.0.5': - resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} - - '@types/estree@1.0.8': - resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} - - '@types/fontkit@2.0.8': - resolution: {integrity: sha512-wN+8bYxIpJf+5oZdrdtaX04qUuWHcKxcDEgRS9Qm9ZClSHjzEn13SxUC+5eRM+4yXIeTYk8mTzLAWGF64847ew==} - - '@types/hast@3.0.4': - resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} - - '@types/js-yaml@4.0.9': - resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==} - - '@types/mdast@4.0.4': - resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} - - '@types/mdx@2.0.13': - resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==} - - '@types/ms@2.1.0': - resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} - - '@types/nlcst@2.0.3': - resolution: {integrity: sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA==} - - '@types/node@17.0.45': - resolution: {integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==} - - '@types/node@24.0.10': - resolution: {integrity: sha512-ENHwaH+JIRTDIEEbDK6QSQntAYGtbvdDXnMXnZaZ6k13Du1dPMmprkEHIL7ok2Wl2aZevetwTAb5S+7yIF+enA==} - - '@types/sax@1.2.7': - resolution: {integrity: sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==} - - '@types/unist@2.0.11': - resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} - - '@types/unist@3.0.3': - resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} - - '@ungap/structured-clone@1.3.0': - resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} - - acorn-jsx@5.3.2: - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - - acorn@8.15.0: - resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} - engines: {node: '>=0.4.0'} - hasBin: true - - ansi-align@3.0.1: - resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==} - - ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} - - ansi-regex@6.1.0: - resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} - engines: {node: '>=12'} - - ansi-styles@6.2.1: - resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} - engines: {node: '>=12'} - - anymatch@3.1.3: - resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} - engines: {node: '>= 8'} - - arg@5.0.2: - resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} - - argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - - aria-query@5.3.2: - resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} - engines: {node: '>= 0.4'} - - array-iterate@2.0.1: - resolution: {integrity: sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==} - - astring@1.9.0: - resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==} - hasBin: true - - astro-expressive-code@0.41.2: - resolution: {integrity: sha512-HN0jWTnhr7mIV/2e6uu4PPRNNo/k4UEgTLZqbp3MrHU+caCARveG2yZxaZVBmxyiVdYqW5Pd3u3n2zjnshixbw==} - peerDependencies: - astro: ^4.0.0-beta || ^5.0.0-beta || ^3.3.0 - - astro@5.12.0: - resolution: {integrity: sha512-Oov5JsMFHuUmuO+Nx6plfv3nQNK1Xl/8CgLvR8lBhZTjYnraxhuPX5COVAzbom+YLgwaDfK7KBd8zOEopRf9mg==} - engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0'} - hasBin: true - - axobject-query@4.1.0: - resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} - engines: {node: '>= 0.4'} - - bail@2.0.2: - resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} - - base-64@1.0.0: - resolution: {integrity: sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==} - - base64-js@1.5.1: - resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - - bcp-47-match@2.0.3: - resolution: {integrity: sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ==} - - bcp-47@2.1.0: - resolution: {integrity: sha512-9IIS3UPrvIa1Ej+lVDdDwO7zLehjqsaByECw0bu2RRGP73jALm6FYbzI5gWbgHLvNdkvfXB5YrSbocZdOS0c0w==} - - blob-to-buffer@1.2.9: - resolution: {integrity: sha512-BF033y5fN6OCofD3vgHmNtwZWRcq9NLyyxyILx9hfMy1sXYy4ojFl765hJ2lP0YaN2fuxPaLO2Vzzoxy0FLFFA==} - - boolbase@1.0.0: - resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} - - boxen@8.0.1: - resolution: {integrity: sha512-F3PH5k5juxom4xktynS7MoFY+NUWH5LC4CnH11YB8NPew+HLpmBLCybSAEyb2F+4pRXhuhWqFesoQd6DAyc2hw==} - engines: {node: '>=18'} - - brotli@1.3.3: - resolution: {integrity: sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg==} - - camelcase@8.0.0: - resolution: {integrity: sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==} - engines: {node: '>=16'} - - ccount@2.0.1: - resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} - - chalk@5.4.1: - resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==} - engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - - character-entities-html4@2.1.0: - resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} - - character-entities-legacy@3.0.0: - resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} - - character-entities@2.0.2: - resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} - - character-reference-invalid@2.0.1: - resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} - - chokidar@4.0.3: - resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} - engines: {node: '>= 14.16.0'} - - ci-info@4.2.0: - resolution: {integrity: sha512-cYY9mypksY8NRqgDB1XD1RiJL338v/551niynFTGkZOO2LHuB2OmOYxDIe/ttN9AHwrqdum1360G3ald0W9kCg==} - engines: {node: '>=8'} - - cli-boxes@3.0.0: - resolution: {integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==} - engines: {node: '>=10'} - - clone@2.1.2: - resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==} - engines: {node: '>=0.8'} - - clsx@2.1.1: - resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} - engines: {node: '>=6'} - - collapse-white-space@2.1.0: - resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==} - - color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} - - color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - - color-string@1.9.1: - resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} - - color@4.2.3: - resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} - engines: {node: '>=12.5.0'} - - comma-separated-tokens@2.0.3: - resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} - - common-ancestor-path@1.0.1: - resolution: {integrity: sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==} - - cookie-es@1.2.2: - resolution: {integrity: sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==} - - cookie@1.0.2: - resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==} - engines: {node: '>=18'} - - cross-fetch@3.2.0: - resolution: {integrity: sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==} - - crossws@0.3.5: - resolution: {integrity: sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==} - - css-selector-parser@3.1.3: - resolution: {integrity: sha512-gJMigczVZqYAk0hPVzx/M4Hm1D9QOtqkdQk9005TNzDIUGzo5cnHEDiKUT7jGPximL/oYb+LIitcHFQ4aKupxg==} - - css-tree@3.1.0: - resolution: {integrity: sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==} - engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} - - cssesc@3.0.0: - resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} - engines: {node: '>=4'} - hasBin: true - - debug@4.4.1: - resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - decode-named-character-reference@1.2.0: - resolution: {integrity: sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==} - - defu@6.1.4: - resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} - - dequal@2.0.3: - resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} - engines: {node: '>=6'} - - destr@2.0.5: - resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} - - detect-libc@2.0.4: - resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==} - engines: {node: '>=8'} - - deterministic-object-hash@2.0.2: - resolution: {integrity: sha512-KxektNH63SrbfUyDiwXqRb1rLwKt33AmMv+5Nhsw1kqZ13SJBRTgZHtGbE+hH3a1mVW1cz+4pqSWVPAtLVXTzQ==} - engines: {node: '>=18'} - - devalue@5.1.1: - resolution: {integrity: sha512-maua5KUiapvEwiEAe+XnlZ3Rh0GD+qI1J/nb9vrJc3muPXvcF/8gXYTWF76+5DAqHyDUtOIImEuo0YKE9mshVw==} - - devlop@1.1.0: - resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} - - dfa@1.2.0: - resolution: {integrity: sha512-ED3jP8saaweFTjeGX8HQPjeC1YYyZs98jGNZx6IiBvxW7JG5v492kamAQB3m2wop07CvU/RQmzcKr6bgcC5D/Q==} - - diff@5.2.0: - resolution: {integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==} - engines: {node: '>=0.3.1'} - - direction@2.0.1: - resolution: {integrity: sha512-9S6m9Sukh1cZNknO1CWAr2QAWsbKLafQiyM5gZ7VgXHeuaoUwffKN4q6NC4A/Mf9iiPlOXQEKW/Mv/mh9/3YFA==} - hasBin: true - - dlv@1.1.3: - resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} - - dset@3.1.4: - resolution: {integrity: sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==} - engines: {node: '>=4'} - - emoji-regex@10.4.0: - resolution: {integrity: sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==} - - emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - - entities@6.0.1: - resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} - engines: {node: '>=0.12'} - - es-module-lexer@1.7.0: - resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} - - esast-util-from-estree@2.0.0: - resolution: {integrity: sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==} - - esast-util-from-js@2.0.1: - resolution: {integrity: sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==} - - esbuild@0.25.5: - resolution: {integrity: sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==} - engines: {node: '>=18'} - hasBin: true - - escape-string-regexp@5.0.0: - resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} - engines: {node: '>=12'} - - estree-util-attach-comments@3.0.0: - resolution: {integrity: sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==} - - estree-util-build-jsx@3.0.1: - resolution: {integrity: sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==} - - estree-util-is-identifier-name@3.0.0: - resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==} - - estree-util-scope@1.0.0: - resolution: {integrity: sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==} - - estree-util-to-js@2.0.0: - resolution: {integrity: sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==} - - estree-util-visit@2.0.0: - resolution: {integrity: sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==} - - estree-walker@2.0.2: - resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} - - estree-walker@3.0.3: - resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} - - eventemitter3@5.0.1: - resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} - - expressive-code@0.41.2: - resolution: {integrity: sha512-aLZiZaqorRtNExtGpUjK9zFH9aTpWeoTXMyLo4b4IcuXfPqtLPPxhRm/QlPb8QqIcMMXnSiGRHSFpQfX0m7HJw==} - - extend@3.0.2: - resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} - - fast-deep-equal@3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - - fdir@6.4.6: - resolution: {integrity: sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==} - peerDependencies: - picomatch: ^3 || ^4 - peerDependenciesMeta: - picomatch: - optional: true - - flattie@1.1.1: - resolution: {integrity: sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ==} - engines: {node: '>=8'} - - fontace@0.3.0: - resolution: {integrity: sha512-czoqATrcnxgWb/nAkfyIrRp6Q8biYj7nGnL6zfhTcX+JKKpWHFBnb8uNMw/kZr7u++3Y3wYSYoZgHkCcsuBpBg==} - - fontkit@2.0.4: - resolution: {integrity: sha512-syetQadaUEDNdxdugga9CpEYVaQIxOwk7GlwZWWZ19//qW4zE5bknOKeMBDYAASwnpaSHKJITRLMF9m1fp3s6g==} - - fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - - get-east-asian-width@1.3.0: - resolution: {integrity: sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==} - engines: {node: '>=18'} - - github-slugger@2.0.0: - resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==} - - h3@1.15.3: - resolution: {integrity: sha512-z6GknHqyX0h9aQaTx22VZDf6QyZn+0Nh+Ym8O/u0SGSkyF5cuTJYKlc8MkzW3Nzf9LE1ivcpmYC3FUGpywhuUQ==} - - hast-util-embedded@3.0.0: - resolution: {integrity: sha512-naH8sld4Pe2ep03qqULEtvYr7EjrLK2QHY8KJR6RJkTUjPGObe1vnx585uzem2hGra+s1q08DZZpfgDVYRbaXA==} - - hast-util-format@1.1.0: - resolution: {integrity: sha512-yY1UDz6bC9rDvCWHpx12aIBGRG7krurX0p0Fm6pT547LwDIZZiNr8a+IHDogorAdreULSEzP82Nlv5SZkHZcjA==} - - hast-util-from-html@2.0.3: - resolution: {integrity: sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==} - - hast-util-from-parse5@8.0.3: - resolution: {integrity: sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==} - - hast-util-has-property@3.0.0: - resolution: {integrity: sha512-MNilsvEKLFpV604hwfhVStK0usFY/QmM5zX16bo7EjnAEGofr5YyI37kzopBlZJkHD4t887i+q/C8/tr5Q94cA==} - - hast-util-is-body-ok-link@3.0.1: - resolution: {integrity: sha512-0qpnzOBLztXHbHQenVB8uNuxTnm/QBFUOmdOSsEn7GnBtyY07+ENTWVFBAnXd/zEgd9/SUG3lRY7hSIBWRgGpQ==} - - hast-util-is-element@3.0.0: - resolution: {integrity: sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==} - - hast-util-minify-whitespace@1.0.1: - resolution: {integrity: sha512-L96fPOVpnclQE0xzdWb/D12VT5FabA7SnZOUMtL1DbXmYiHJMXZvFkIZfiMmTCNJHUeO2K9UYNXoVyfz+QHuOw==} - - hast-util-parse-selector@4.0.0: - resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==} - - hast-util-phrasing@3.0.1: - resolution: {integrity: sha512-6h60VfI3uBQUxHqTyMymMZnEbNl1XmEGtOxxKYL7stY2o601COo62AWAYBQR9lZbYXYSBoxag8UpPRXK+9fqSQ==} - - hast-util-raw@9.1.0: - resolution: {integrity: sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==} - - hast-util-select@6.0.4: - resolution: {integrity: sha512-RqGS1ZgI0MwxLaKLDxjprynNzINEkRHY2i8ln4DDjgv9ZhcYVIHN9rlpiYsqtFwrgpYU361SyWDQcGNIBVu3lw==} - - hast-util-to-estree@3.1.3: - resolution: {integrity: sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==} - - hast-util-to-html@9.0.5: - resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==} - - hast-util-to-jsx-runtime@2.3.6: - resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==} - - hast-util-to-parse5@8.0.0: - resolution: {integrity: sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==} - - hast-util-to-string@3.0.1: - resolution: {integrity: sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==} - - hast-util-to-text@4.0.2: - resolution: {integrity: sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==} - - hast-util-whitespace@3.0.0: - resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} - - hastscript@9.0.1: - resolution: {integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==} - - html-escaper@3.0.3: - resolution: {integrity: sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==} - - html-void-elements@3.0.0: - resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} - - html-whitespace-sensitive-tag-names@3.0.1: - resolution: {integrity: sha512-q+310vW8zmymYHALr1da4HyXUQ0zgiIwIicEfotYPWGN0OJVEN/58IJ3A4GBYcEq3LGAZqKb+ugvP0GNB9CEAA==} - - http-cache-semantics@4.2.0: - resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} - - i18next@23.16.8: - resolution: {integrity: sha512-06r/TitrM88Mg5FdUXAKL96dJMzgqLE5dv3ryBAra4KCwD9mJ4ndOTS95ZuymIGoE+2hzfdaMak2X11/es7ZWg==} - - import-meta-resolve@4.1.0: - resolution: {integrity: sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==} - - inline-style-parser@0.2.4: - resolution: {integrity: sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==} - - iron-webcrypto@1.2.1: - resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==} - - is-alphabetical@2.0.1: - resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} - - is-alphanumerical@2.0.1: - resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} - - is-arrayish@0.3.2: - resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} - - is-decimal@2.0.1: - resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} - - is-docker@3.0.0: - resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - hasBin: true - - is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} - - is-hexadecimal@2.0.1: - resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} - - is-inside-container@1.0.0: - resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} - engines: {node: '>=14.16'} - hasBin: true - - is-plain-obj@4.1.0: - resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} - engines: {node: '>=12'} - - is-wsl@3.1.0: - resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==} - engines: {node: '>=16'} - - js-yaml@4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} - hasBin: true - - kleur@3.0.3: - resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} - engines: {node: '>=6'} - - kleur@4.1.5: - resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} - engines: {node: '>=6'} - - klona@2.0.6: - resolution: {integrity: sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==} - engines: {node: '>= 8'} - - longest-streak@3.1.0: - resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} - - lru-cache@10.4.3: - resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - - magic-string@0.30.17: - resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} - - magicast@0.3.5: - resolution: {integrity: sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==} - - markdown-extensions@2.0.0: - resolution: {integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==} - engines: {node: '>=16'} - - markdown-table@3.0.4: - resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} - - mdast-util-definitions@6.0.0: - resolution: {integrity: sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ==} - - mdast-util-directive@3.1.0: - resolution: {integrity: sha512-I3fNFt+DHmpWCYAT7quoM6lHf9wuqtI+oCOfvILnoicNIqjh5E3dEJWiXuYME2gNe8vl1iMQwyUHa7bgFmak6Q==} - - mdast-util-find-and-replace@3.0.2: - resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==} - - mdast-util-from-markdown@2.0.2: - resolution: {integrity: sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==} - - mdast-util-gfm-autolink-literal@2.0.1: - resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==} - - mdast-util-gfm-footnote@2.1.0: - resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==} - - mdast-util-gfm-strikethrough@2.0.0: - resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==} - - mdast-util-gfm-table@2.0.0: - resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==} - - mdast-util-gfm-task-list-item@2.0.0: - resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} - - mdast-util-gfm@3.1.0: - resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==} - - mdast-util-mdx-expression@2.0.1: - resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==} - - mdast-util-mdx-jsx@3.2.0: - resolution: {integrity: sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==} - - mdast-util-mdx@3.0.0: - resolution: {integrity: sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==} - - mdast-util-mdxjs-esm@2.0.1: - resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==} - - mdast-util-phrasing@4.1.0: - resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} - - mdast-util-to-hast@13.2.0: - resolution: {integrity: sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==} - - mdast-util-to-markdown@2.1.2: - resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==} - - mdast-util-to-string@4.0.0: - resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} - - mdn-data@2.12.2: - resolution: {integrity: sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==} - - micromark-core-commonmark@2.0.3: - resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} - - micromark-extension-directive@3.0.2: - resolution: {integrity: sha512-wjcXHgk+PPdmvR58Le9d7zQYWy+vKEU9Se44p2CrCDPiLr2FMyiT4Fyb5UFKFC66wGB3kPlgD7q3TnoqPS7SZA==} - - micromark-extension-gfm-autolink-literal@2.1.0: - resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} - - micromark-extension-gfm-footnote@2.1.0: - resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==} - - micromark-extension-gfm-strikethrough@2.1.0: - resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==} - - micromark-extension-gfm-table@2.1.1: - resolution: {integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==} - - micromark-extension-gfm-tagfilter@2.0.0: - resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} - - micromark-extension-gfm-task-list-item@2.1.0: - resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==} - - micromark-extension-gfm@3.0.0: - resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} - - micromark-extension-mdx-expression@3.0.1: - resolution: {integrity: sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==} - - micromark-extension-mdx-jsx@3.0.2: - resolution: {integrity: sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ==} - - micromark-extension-mdx-md@2.0.0: - resolution: {integrity: sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==} - - micromark-extension-mdxjs-esm@3.0.0: - resolution: {integrity: sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==} - - micromark-extension-mdxjs@3.0.0: - resolution: {integrity: sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==} - - micromark-factory-destination@2.0.1: - resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} - - micromark-factory-label@2.0.1: - resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} - - micromark-factory-mdx-expression@2.0.3: - resolution: {integrity: sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==} - - micromark-factory-space@2.0.1: - resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==} - - micromark-factory-title@2.0.1: - resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==} - - micromark-factory-whitespace@2.0.1: - resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==} - - micromark-util-character@2.1.1: - resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} - - micromark-util-chunked@2.0.1: - resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==} - - micromark-util-classify-character@2.0.1: - resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==} - - micromark-util-combine-extensions@2.0.1: - resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==} - - micromark-util-decode-numeric-character-reference@2.0.2: - resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==} - - micromark-util-decode-string@2.0.1: - resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==} - - micromark-util-encode@2.0.1: - resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} - - micromark-util-events-to-acorn@2.0.3: - resolution: {integrity: sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==} - - micromark-util-html-tag-name@2.0.1: - resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} - - micromark-util-normalize-identifier@2.0.1: - resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==} - - micromark-util-resolve-all@2.0.1: - resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==} - - micromark-util-sanitize-uri@2.0.1: - resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} - - micromark-util-subtokenize@2.1.0: - resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==} - - micromark-util-symbol@2.0.1: - resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} - - micromark-util-types@2.0.2: - resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} - - micromark@4.0.2: - resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} - - mrmime@2.0.1: - resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} - engines: {node: '>=10'} - - ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - - nanoid@3.3.11: - resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - - neotraverse@0.6.18: - resolution: {integrity: sha512-Z4SmBUweYa09+o6pG+eASabEpP6QkQ70yHj351pQoEXIs8uHbaU2DWVmzBANKgflPa47A50PtB2+NgRpQvr7vA==} - engines: {node: '>= 10'} - - nlcst-to-string@4.0.0: - resolution: {integrity: sha512-YKLBCcUYKAg0FNlOBT6aI91qFmSiFKiluk655WzPF+DDMA02qIyy8uiRqI8QXtcFpEvll12LpL5MXqEmAZ+dcA==} - - node-fetch-native@1.6.6: - resolution: {integrity: sha512-8Mc2HhqPdlIfedsuZoc3yioPuzp6b+L5jRCRY1QzuWZh2EGJVQrGppC6V6cF0bLdbW0+O2YpqCA25aF/1lvipQ==} - - node-fetch@2.7.0: - resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} - engines: {node: 4.x || >=6.0.0} - peerDependencies: - encoding: ^0.1.0 - peerDependenciesMeta: - encoding: - optional: true - - node-mock-http@1.0.1: - resolution: {integrity: sha512-0gJJgENizp4ghds/Ywu2FCmcRsgBTmRQzYPZm61wy+Em2sBarSka0OhQS5huLBg6od1zkNpnWMCZloQDFVvOMQ==} - - normalize-path@3.0.0: - resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} - engines: {node: '>=0.10.0'} - - nth-check@2.1.1: - resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} - - ofetch@1.4.1: - resolution: {integrity: sha512-QZj2DfGplQAr2oj9KzceK9Hwz6Whxazmn85yYeVuS3u9XTMOGMRx0kO95MQ+vLsj/S/NwBDMMLU5hpxvI6Tklw==} - - ohash@2.0.11: - resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==} - - oniguruma-parser@0.12.1: - resolution: {integrity: sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==} - - oniguruma-to-es@4.3.3: - resolution: {integrity: sha512-rPiZhzC3wXwE59YQMRDodUwwT9FZ9nNBwQQfsd1wfdtlKEyCdRV0avrTcSZ5xlIvGRVPd/cx6ZN45ECmS39xvg==} - - p-limit@6.2.0: - resolution: {integrity: sha512-kuUqqHNUqoIWp/c467RI4X6mmyuojY5jGutNU0wVTmEOOfcuwLqyMVoAi9MKi2Ak+5i9+nhmrK4ufZE8069kHA==} - engines: {node: '>=18'} - - p-queue@8.1.0: - resolution: {integrity: sha512-mxLDbbGIBEXTJL0zEx8JIylaj3xQ7Z/7eEVjcF9fJX4DBiH9oqe+oahYnlKKxm0Ci9TlWTyhSHgygxMxjIB2jw==} - engines: {node: '>=18'} - - p-timeout@6.1.4: - resolution: {integrity: sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==} - engines: {node: '>=14.16'} - - package-manager-detector@1.3.0: - resolution: {integrity: sha512-ZsEbbZORsyHuO00lY1kV3/t72yp6Ysay6Pd17ZAlNGuGwmWDLCJxFpRs0IzfXfj1o4icJOkUEioexFHzyPurSQ==} - - pagefind@1.3.0: - resolution: {integrity: sha512-8KPLGT5g9s+olKMRTU9LFekLizkVIu9tes90O1/aigJ0T5LmyPqTzGJrETnSw3meSYg58YH7JTzhTTW/3z6VAw==} - hasBin: true - - pako@0.2.9: - resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==} - - parse-entities@4.0.2: - resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} - - parse-latin@7.0.0: - resolution: {integrity: sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ==} - - parse5@7.3.0: - resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} - - pathe@2.0.3: - resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} - - picocolors@1.1.1: - resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - - picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} - - picomatch@4.0.2: - resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} - engines: {node: '>=12'} - - postcss-nested@6.2.0: - resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==} - engines: {node: '>=12.0'} - peerDependencies: - postcss: ^8.2.14 - - postcss-selector-parser@6.1.2: - resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} - engines: {node: '>=4'} - - postcss@8.5.6: - resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} - engines: {node: ^10 || ^12 || >=14} - - prismjs@1.30.0: - resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==} - engines: {node: '>=6'} - - prompts@2.4.2: - resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} - engines: {node: '>= 6'} - - property-information@6.5.0: - resolution: {integrity: sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==} - - property-information@7.1.0: - resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} - - radix3@1.1.2: - resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==} - - readdirp@4.1.2: - resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} - engines: {node: '>= 14.18.0'} - - recma-build-jsx@1.0.0: - resolution: {integrity: sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==} - - recma-jsx@1.0.0: - resolution: {integrity: sha512-5vwkv65qWwYxg+Atz95acp8DMu1JDSqdGkA2Of1j6rCreyFUE/gp15fC8MnGEuG1W68UKjM6x6+YTWIh7hZM/Q==} - - recma-parse@1.0.0: - resolution: {integrity: sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==} - - recma-stringify@1.0.0: - resolution: {integrity: sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==} - - regex-recursion@6.0.2: - resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==} - - regex-utilities@2.3.0: - resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==} - - regex@6.0.1: - resolution: {integrity: sha512-uorlqlzAKjKQZ5P+kTJr3eeJGSVroLKoHmquUj4zHWuR+hEyNqlXsSKlYYF5F4NI6nl7tWCs0apKJ0lmfsXAPA==} - - rehype-expressive-code@0.41.2: - resolution: {integrity: sha512-vHYfWO9WxAw6kHHctddOt+P4266BtyT1mrOIuxJD+1ELuvuJAa5uBIhYt0OVMyOhlvf57hzWOXJkHnMhpaHyxw==} - - rehype-format@5.0.1: - resolution: {integrity: sha512-zvmVru9uB0josBVpr946OR8ui7nJEdzZobwLOOqHb/OOD88W0Vk2SqLwoVOj0fM6IPCCO6TaV9CvQvJMWwukFQ==} - - rehype-parse@9.0.1: - resolution: {integrity: sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==} - - rehype-raw@7.0.0: - resolution: {integrity: sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==} - - rehype-recma@1.0.0: - resolution: {integrity: sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==} - - rehype-stringify@10.0.1: - resolution: {integrity: sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==} - - rehype@13.0.2: - resolution: {integrity: sha512-j31mdaRFrwFRUIlxGeuPXXKWQxet52RBQRvCmzl5eCefn/KGbomK5GMHNMsOJf55fgo3qw5tST5neDuarDYR2A==} - - remark-directive@3.0.1: - resolution: {integrity: sha512-gwglrEQEZcZYgVyG1tQuA+h58EZfq5CSULw7J90AFuCTyib1thgHPoqQ+h9iFvU6R+vnZ5oNFQR5QKgGpk741A==} - - remark-gfm@4.0.1: - resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==} - - remark-mdx@3.1.0: - resolution: {integrity: sha512-Ngl/H3YXyBV9RcRNdlYsZujAmhsxwzxpDzpDEhFBVAGthS4GDgnctpDjgFl/ULx5UEDzqtW1cyBSNKqYYrqLBA==} - - remark-parse@11.0.0: - resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} - - remark-rehype@11.1.2: - resolution: {integrity: sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==} - - remark-smartypants@3.0.2: - resolution: {integrity: sha512-ILTWeOriIluwEvPjv67v7Blgrcx+LZOkAUVtKI3putuhlZm84FnqDORNXPPm+HY3NdZOMhyDwZ1E+eZB/Df5dA==} - engines: {node: '>=16.0.0'} - - remark-stringify@11.0.0: - resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} - - restructure@3.0.2: - resolution: {integrity: sha512-gSfoiOEA0VPE6Tukkrr7I0RBdE0s7H1eFCDBk05l1KIQT1UIKNc5JZy6jdyW6eYH3aR3g5b3PuL77rq0hvwtAw==} - - retext-latin@4.0.0: - resolution: {integrity: sha512-hv9woG7Fy0M9IlRQloq/N6atV82NxLGveq+3H2WOi79dtIYWN8OaxogDm77f8YnVXJL2VD3bbqowu5E3EMhBYA==} - - retext-smartypants@6.2.0: - resolution: {integrity: sha512-kk0jOU7+zGv//kfjXEBjdIryL1Acl4i9XNkHxtM7Tm5lFiCog576fjNC9hjoR7LTKQ0DsPWy09JummSsH1uqfQ==} - - retext-stringify@4.0.0: - resolution: {integrity: sha512-rtfN/0o8kL1e+78+uxPTqu1Klt0yPzKuQ2BfWwwfgIUSayyzxpM1PJzkKt4V8803uB9qSy32MvI7Xep9khTpiA==} - - retext@9.0.0: - resolution: {integrity: sha512-sbMDcpHCNjvlheSgMfEcVrZko3cDzdbe1x/e7G66dFp0Ff7Mldvi2uv6JkJQzdRcvLYE8CA8Oe8siQx8ZOgTcA==} - - rollup@4.44.2: - resolution: {integrity: sha512-PVoapzTwSEcelaWGth3uR66u7ZRo6qhPHc0f2uRO9fX6XDVNrIiGYS0Pj9+R8yIIYSD/mCx2b16Ws9itljKSPg==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} - hasBin: true - - sax@1.4.1: - resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==} - - semver@7.7.2: - resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} - engines: {node: '>=10'} - hasBin: true - - sharp@0.33.5: - resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - - sharp@0.34.2: - resolution: {integrity: sha512-lszvBmB9QURERtyKT2bNmsgxXK0ShJrL/fvqlonCo7e6xBF8nT8xU6pW+PMIbLsz0RxQk3rgH9kd8UmvOzlMJg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - - shiki@3.7.0: - resolution: {integrity: sha512-ZcI4UT9n6N2pDuM2n3Jbk0sR4Swzq43nLPgS/4h0E3B/NrFn2HKElrDtceSf8Zx/OWYOo7G1SAtBLypCp+YXqg==} - - simple-swizzle@0.2.2: - resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} - - sisteransi@1.0.5: - resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} - - sitemap@8.0.0: - resolution: {integrity: sha512-+AbdxhM9kJsHtruUF39bwS/B0Fytw6Fr1o4ZAIAEqA6cke2xcoO2GleBw9Zw7nRzILVEgz7zBM5GiTJjie1G9A==} - engines: {node: '>=14.0.0', npm: '>=6.0.0'} - hasBin: true - - smol-toml@1.4.1: - resolution: {integrity: sha512-CxdwHXyYTONGHThDbq5XdwbFsuY4wlClRGejfE2NtwUtiHYsP1QtNsHb/hnj31jKYSchztJsaA8pSQoVzkfCFg==} - engines: {node: '>= 18'} - - source-map-js@1.2.1: - resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} - engines: {node: '>=0.10.0'} - - source-map@0.7.4: - resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} - engines: {node: '>= 8'} - - space-separated-tokens@2.0.2: - resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} - - stream-replace-string@2.0.0: - resolution: {integrity: sha512-TlnjJ1C0QrmxRNrON00JvaFFlNh5TTG00APw23j74ET7gkQpTASi6/L2fuiav8pzK715HXtUeClpBTw2NPSn6w==} - - string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} - - string-width@7.2.0: - resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} - engines: {node: '>=18'} - - stringify-entities@4.0.4: - resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} - - strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} - - strip-ansi@7.1.0: - resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} - engines: {node: '>=12'} - - style-to-js@1.1.17: - resolution: {integrity: sha512-xQcBGDxJb6jjFCTzvQtfiPn6YvvP2O8U1MDIPNfJQlWMYfktPy+iGsHE7cssjs7y84d9fQaK4UF3RIJaAHSoYA==} - - style-to-object@1.0.9: - resolution: {integrity: sha512-G4qppLgKu/k6FwRpHiGiKPaPTFcG3g4wNVX/Qsfu+RqQM30E7Tyu/TEgxcL9PNLF5pdRLwQdE3YKKf+KF2Dzlw==} - - tiny-inflate@1.0.3: - resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==} - - tinyexec@0.3.2: - resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} - - tinyglobby@0.2.14: - resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==} - engines: {node: '>=12.0.0'} - - tr46@0.0.3: - resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} - - trim-lines@3.0.1: - resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} - - trough@2.2.0: - resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} - - tsconfck@3.1.6: - resolution: {integrity: sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==} - engines: {node: ^18 || >=20} - hasBin: true - peerDependencies: - typescript: ^5.0.0 - peerDependenciesMeta: - typescript: - optional: true - - tslib@2.8.1: - resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - - type-fest@4.41.0: - resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} - engines: {node: '>=16'} - - typescript@5.8.3: - resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} - engines: {node: '>=14.17'} - hasBin: true - - ufo@1.6.1: - resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} - - ultrahtml@1.6.0: - resolution: {integrity: sha512-R9fBn90VTJrqqLDwyMph+HGne8eqY1iPfYhPzZrvKpIfwkWZbcYlfpsb8B9dTvBfpy1/hqAD7Wi8EKfP9e8zdw==} - - uncrypto@0.1.3: - resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==} - - undici-types@7.8.0: - resolution: {integrity: sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==} - - unicode-properties@1.4.1: - resolution: {integrity: sha512-CLjCCLQ6UuMxWnbIylkisbRj31qxHPAurvena/0iwSVbQ2G1VY5/HjV0IRabOEbDHlzZlRdCrD4NhB0JtU40Pg==} - - unicode-trie@2.0.0: - resolution: {integrity: sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==} - - unified@11.0.5: - resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} - - unifont@0.5.2: - resolution: {integrity: sha512-LzR4WUqzH9ILFvjLAUU7dK3Lnou/qd5kD+IakBtBK4S15/+x2y9VX+DcWQv6s551R6W+vzwgVS6tFg3XggGBgg==} - - unist-util-find-after@5.0.0: - resolution: {integrity: sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==} - - unist-util-is@6.0.0: - resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==} - - unist-util-modify-children@4.0.0: - resolution: {integrity: sha512-+tdN5fGNddvsQdIzUF3Xx82CU9sMM+fA0dLgR9vOmT0oPT2jH+P1nd5lSqfCfXAw+93NhcXNY2qqvTUtE4cQkw==} - - unist-util-position-from-estree@2.0.0: - resolution: {integrity: sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==} - - unist-util-position@5.0.0: - resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} - - unist-util-remove-position@5.0.0: - resolution: {integrity: sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==} - - unist-util-stringify-position@4.0.0: - resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} - - unist-util-visit-children@3.0.0: - resolution: {integrity: sha512-RgmdTfSBOg04sdPcpTSD1jzoNBjt9a80/ZCzp5cI9n1qPzLZWF9YdvWGN2zmTumP1HWhXKdUWexjy/Wy/lJ7tA==} - - unist-util-visit-parents@6.0.1: - resolution: {integrity: sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==} - - unist-util-visit@5.0.0: - resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} - - unstorage@1.16.0: - resolution: {integrity: sha512-WQ37/H5A7LcRPWfYOrDa1Ys02xAbpPJq6q5GkO88FBXVSQzHd7+BjEwfRqyaSWCv9MbsJy058GWjjPjcJ16GGA==} - peerDependencies: - '@azure/app-configuration': ^1.8.0 - '@azure/cosmos': ^4.2.0 - '@azure/data-tables': ^13.3.0 - '@azure/identity': ^4.6.0 - '@azure/keyvault-secrets': ^4.9.0 - '@azure/storage-blob': ^12.26.0 - '@capacitor/preferences': ^6.0.3 || ^7.0.0 - '@deno/kv': '>=0.9.0' - '@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0 - '@planetscale/database': ^1.19.0 - '@upstash/redis': ^1.34.3 - '@vercel/blob': '>=0.27.1' - '@vercel/kv': ^1.0.1 - aws4fetch: ^1.0.20 - db0: '>=0.2.1' - idb-keyval: ^6.2.1 - ioredis: ^5.4.2 - uploadthing: ^7.4.4 - peerDependenciesMeta: - '@azure/app-configuration': - optional: true - '@azure/cosmos': - optional: true - '@azure/data-tables': - optional: true - '@azure/identity': - optional: true - '@azure/keyvault-secrets': - optional: true - '@azure/storage-blob': - optional: true - '@capacitor/preferences': - optional: true - '@deno/kv': - optional: true - '@netlify/blobs': - optional: true - '@planetscale/database': - optional: true - '@upstash/redis': - optional: true - '@vercel/blob': - optional: true - '@vercel/kv': - optional: true - aws4fetch: - optional: true - db0: - optional: true - idb-keyval: - optional: true - ioredis: - optional: true - uploadthing: - optional: true - - util-deprecate@1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - - vfile-location@5.0.3: - resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==} - - vfile-message@4.0.2: - resolution: {integrity: sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==} - - vfile@6.0.3: - resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} - - vite@6.3.5: - resolution: {integrity: sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} - hasBin: true - peerDependencies: - '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 - jiti: '>=1.21.0' - less: '*' - lightningcss: ^1.21.0 - sass: '*' - sass-embedded: '*' - stylus: '*' - sugarss: '*' - terser: ^5.16.0 - tsx: ^4.8.1 - yaml: ^2.4.2 - peerDependenciesMeta: - '@types/node': - optional: true - jiti: - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - sass-embedded: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - tsx: - optional: true - yaml: - optional: true - - vitefu@1.1.1: - resolution: {integrity: sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==} - peerDependencies: - vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0 - peerDependenciesMeta: - vite: - optional: true - - web-namespaces@2.0.1: - resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} - - webidl-conversions@3.0.1: - resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} - - whatwg-url@5.0.0: - resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} - - which-pm-runs@1.1.0: - resolution: {integrity: sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==} - engines: {node: '>=4'} - - widest-line@5.0.0: - resolution: {integrity: sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA==} - engines: {node: '>=18'} - - wrap-ansi@9.0.0: - resolution: {integrity: sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==} - engines: {node: '>=18'} - - xxhash-wasm@1.1.0: - resolution: {integrity: sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==} - - yargs-parser@21.1.1: - resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} - engines: {node: '>=12'} - - yocto-queue@1.2.1: - resolution: {integrity: sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg==} - engines: {node: '>=12.20'} - - yocto-spinner@0.2.3: - resolution: {integrity: sha512-sqBChb33loEnkoXte1bLg45bEBsOP9N1kzQh5JZNKj/0rik4zAPTNSAVPj3uQAdc6slYJ0Ksc403G2XgxsJQFQ==} - engines: {node: '>=18.19'} - - yoctocolors@2.1.1: - resolution: {integrity: sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ==} - engines: {node: '>=18'} - - zod-to-json-schema@3.24.6: - resolution: {integrity: sha512-h/z3PKvcTcTetyjl1fkj79MHNEjm+HpD6NXheWjzOekY7kV+lwDYnHw+ivHkijnCSMz1yJaWBD9vu/Fcmk+vEg==} - peerDependencies: - zod: ^3.24.1 - - zod-to-ts@1.2.0: - resolution: {integrity: sha512-x30XE43V+InwGpvTySRNz9kB7qFU8DlyEy7BsSTCHPH1R0QasMmHWZDCzYm6bVXtj/9NNJAZF3jW8rzFvH5OFA==} - peerDependencies: - typescript: ^4.9.4 || ^5.0.2 - zod: ^3 - - zod@3.25.74: - resolution: {integrity: sha512-J8poo92VuhKjNknViHRAIuuN6li/EwFbAC8OedzI8uxpEPGiXHGQu9wemIAioIpqgfB4SySaJhdk0mH5Y4ICBg==} - - zwitch@2.0.4: - resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} - -snapshots: - - '@astrojs/compiler@2.12.2': {} - - '@astrojs/internal-helpers@0.6.1': {} - - '@astrojs/markdown-remark@6.3.2': - dependencies: - '@astrojs/internal-helpers': 0.6.1 - '@astrojs/prism': 3.3.0 - github-slugger: 2.0.0 - hast-util-from-html: 2.0.3 - hast-util-to-text: 4.0.2 - import-meta-resolve: 4.1.0 - js-yaml: 4.1.0 - mdast-util-definitions: 6.0.0 - rehype-raw: 7.0.0 - rehype-stringify: 10.0.1 - remark-gfm: 4.0.1 - remark-parse: 11.0.0 - remark-rehype: 11.1.2 - remark-smartypants: 3.0.2 - shiki: 3.7.0 - smol-toml: 1.4.1 - unified: 11.0.5 - unist-util-remove-position: 5.0.0 - unist-util-visit: 5.0.0 - unist-util-visit-parents: 6.0.1 - vfile: 6.0.3 - transitivePeerDependencies: - - supports-color - - '@astrojs/markdown-remark@6.3.3': - dependencies: - '@astrojs/internal-helpers': 0.6.1 - '@astrojs/prism': 3.3.0 - github-slugger: 2.0.0 - hast-util-from-html: 2.0.3 - hast-util-to-text: 4.0.2 - import-meta-resolve: 4.1.0 - js-yaml: 4.1.0 - mdast-util-definitions: 6.0.0 - rehype-raw: 7.0.0 - rehype-stringify: 10.0.1 - remark-gfm: 4.0.1 - remark-parse: 11.0.0 - remark-rehype: 11.1.2 - remark-smartypants: 3.0.2 - shiki: 3.7.0 - smol-toml: 1.4.1 - unified: 11.0.5 - unist-util-remove-position: 5.0.0 - unist-util-visit: 5.0.0 - unist-util-visit-parents: 6.0.1 - vfile: 6.0.3 - transitivePeerDependencies: - - supports-color - - '@astrojs/mdx@4.3.0(astro@5.12.0(@types/node@24.0.10)(rollup@4.44.2)(typescript@5.8.3))': - dependencies: - '@astrojs/markdown-remark': 6.3.2 - '@mdx-js/mdx': 3.1.0(acorn@8.15.0) - acorn: 8.15.0 - astro: 5.12.0(@types/node@24.0.10)(rollup@4.44.2)(typescript@5.8.3) - es-module-lexer: 1.7.0 - estree-util-visit: 2.0.0 - hast-util-to-html: 9.0.5 - kleur: 4.1.5 - rehype-raw: 7.0.0 - remark-gfm: 4.0.1 - remark-smartypants: 3.0.2 - source-map: 0.7.4 - unist-util-visit: 5.0.0 - vfile: 6.0.3 - transitivePeerDependencies: - - supports-color - - '@astrojs/prism@3.3.0': - dependencies: - prismjs: 1.30.0 - - '@astrojs/sitemap@3.4.1': - dependencies: - sitemap: 8.0.0 - stream-replace-string: 2.0.0 - zod: 3.25.74 - - '@astrojs/starlight@0.35.1(astro@5.12.0(@types/node@24.0.10)(rollup@4.44.2)(typescript@5.8.3))': - dependencies: - '@astrojs/markdown-remark': 6.3.2 - '@astrojs/mdx': 4.3.0(astro@5.12.0(@types/node@24.0.10)(rollup@4.44.2)(typescript@5.8.3)) - '@astrojs/sitemap': 3.4.1 - '@pagefind/default-ui': 1.3.0 - '@types/hast': 3.0.4 - '@types/js-yaml': 4.0.9 - '@types/mdast': 4.0.4 - astro: 5.12.0(@types/node@24.0.10)(rollup@4.44.2)(typescript@5.8.3) - astro-expressive-code: 0.41.2(astro@5.12.0(@types/node@24.0.10)(rollup@4.44.2)(typescript@5.8.3)) - bcp-47: 2.1.0 - hast-util-from-html: 2.0.3 - hast-util-select: 6.0.4 - hast-util-to-string: 3.0.1 - hastscript: 9.0.1 - i18next: 23.16.8 - js-yaml: 4.1.0 - klona: 2.0.6 - mdast-util-directive: 3.1.0 - mdast-util-to-markdown: 2.1.2 - mdast-util-to-string: 4.0.0 - pagefind: 1.3.0 - rehype: 13.0.2 - rehype-format: 5.0.1 - remark-directive: 3.0.1 - ultrahtml: 1.6.0 - unified: 11.0.5 - unist-util-visit: 5.0.0 - vfile: 6.0.3 - transitivePeerDependencies: - - supports-color - - '@astrojs/telemetry@3.3.0': - dependencies: - ci-info: 4.2.0 - debug: 4.4.1 - dlv: 1.1.3 - dset: 3.1.4 - is-docker: 3.0.0 - is-wsl: 3.1.0 - which-pm-runs: 1.1.0 - transitivePeerDependencies: - - supports-color - - '@babel/helper-string-parser@7.27.1': {} - - '@babel/helper-validator-identifier@7.27.1': {} - - '@babel/parser@7.28.0': - dependencies: - '@babel/types': 7.28.0 - - '@babel/runtime@7.27.6': {} - - '@babel/types@7.28.0': - dependencies: - '@babel/helper-string-parser': 7.27.1 - '@babel/helper-validator-identifier': 7.27.1 - - '@capsizecss/unpack@2.4.0': - dependencies: - blob-to-buffer: 1.2.9 - cross-fetch: 3.2.0 - fontkit: 2.0.4 - transitivePeerDependencies: - - encoding - - '@ctrl/tinycolor@4.1.0': {} - - '@emnapi/runtime@1.4.3': - dependencies: - tslib: 2.8.1 - optional: true - - '@esbuild/aix-ppc64@0.25.5': - optional: true - - '@esbuild/android-arm64@0.25.5': - optional: true - - '@esbuild/android-arm@0.25.5': - optional: true - - '@esbuild/android-x64@0.25.5': - optional: true - - '@esbuild/darwin-arm64@0.25.5': - optional: true - - '@esbuild/darwin-x64@0.25.5': - optional: true - - '@esbuild/freebsd-arm64@0.25.5': - optional: true - - '@esbuild/freebsd-x64@0.25.5': - optional: true - - '@esbuild/linux-arm64@0.25.5': - optional: true - - '@esbuild/linux-arm@0.25.5': - optional: true - - '@esbuild/linux-ia32@0.25.5': - optional: true - - '@esbuild/linux-loong64@0.25.5': - optional: true - - '@esbuild/linux-mips64el@0.25.5': - optional: true - - '@esbuild/linux-ppc64@0.25.5': - optional: true - - '@esbuild/linux-riscv64@0.25.5': - optional: true - - '@esbuild/linux-s390x@0.25.5': - optional: true - - '@esbuild/linux-x64@0.25.5': - optional: true - - '@esbuild/netbsd-arm64@0.25.5': - optional: true - - '@esbuild/netbsd-x64@0.25.5': - optional: true - - '@esbuild/openbsd-arm64@0.25.5': - optional: true - - '@esbuild/openbsd-x64@0.25.5': - optional: true - - '@esbuild/sunos-x64@0.25.5': - optional: true - - '@esbuild/win32-arm64@0.25.5': - optional: true - - '@esbuild/win32-ia32@0.25.5': - optional: true - - '@esbuild/win32-x64@0.25.5': - optional: true - - '@expressive-code/core@0.41.2': - dependencies: - '@ctrl/tinycolor': 4.1.0 - hast-util-select: 6.0.4 - hast-util-to-html: 9.0.5 - hast-util-to-text: 4.0.2 - hastscript: 9.0.1 - postcss: 8.5.6 - postcss-nested: 6.2.0(postcss@8.5.6) - unist-util-visit: 5.0.0 - unist-util-visit-parents: 6.0.1 - - '@expressive-code/plugin-frames@0.41.2': - dependencies: - '@expressive-code/core': 0.41.2 - - '@expressive-code/plugin-shiki@0.41.2': - dependencies: - '@expressive-code/core': 0.41.2 - shiki: 3.7.0 - - '@expressive-code/plugin-text-markers@0.41.2': - dependencies: - '@expressive-code/core': 0.41.2 - - '@img/sharp-darwin-arm64@0.33.5': - optionalDependencies: - '@img/sharp-libvips-darwin-arm64': 1.0.4 - optional: true - - '@img/sharp-darwin-arm64@0.34.2': - optionalDependencies: - '@img/sharp-libvips-darwin-arm64': 1.1.0 - optional: true - - '@img/sharp-darwin-x64@0.33.5': - optionalDependencies: - '@img/sharp-libvips-darwin-x64': 1.0.4 - optional: true - - '@img/sharp-darwin-x64@0.34.2': - optionalDependencies: - '@img/sharp-libvips-darwin-x64': 1.1.0 - optional: true - - '@img/sharp-libvips-darwin-arm64@1.0.4': - optional: true - - '@img/sharp-libvips-darwin-arm64@1.1.0': - optional: true - - '@img/sharp-libvips-darwin-x64@1.0.4': - optional: true - - '@img/sharp-libvips-darwin-x64@1.1.0': - optional: true - - '@img/sharp-libvips-linux-arm64@1.0.4': - optional: true - - '@img/sharp-libvips-linux-arm64@1.1.0': - optional: true - - '@img/sharp-libvips-linux-arm@1.0.5': - optional: true - - '@img/sharp-libvips-linux-arm@1.1.0': - optional: true - - '@img/sharp-libvips-linux-ppc64@1.1.0': - optional: true - - '@img/sharp-libvips-linux-s390x@1.0.4': - optional: true - - '@img/sharp-libvips-linux-s390x@1.1.0': - optional: true - - '@img/sharp-libvips-linux-x64@1.0.4': - optional: true - - '@img/sharp-libvips-linux-x64@1.1.0': - optional: true - - '@img/sharp-libvips-linuxmusl-arm64@1.0.4': - optional: true - - '@img/sharp-libvips-linuxmusl-arm64@1.1.0': - optional: true - - '@img/sharp-libvips-linuxmusl-x64@1.0.4': - optional: true - - '@img/sharp-libvips-linuxmusl-x64@1.1.0': - optional: true - - '@img/sharp-linux-arm64@0.33.5': - optionalDependencies: - '@img/sharp-libvips-linux-arm64': 1.0.4 - optional: true - - '@img/sharp-linux-arm64@0.34.2': - optionalDependencies: - '@img/sharp-libvips-linux-arm64': 1.1.0 - optional: true - - '@img/sharp-linux-arm@0.33.5': - optionalDependencies: - '@img/sharp-libvips-linux-arm': 1.0.5 - optional: true - - '@img/sharp-linux-arm@0.34.2': - optionalDependencies: - '@img/sharp-libvips-linux-arm': 1.1.0 - optional: true - - '@img/sharp-linux-s390x@0.33.5': - optionalDependencies: - '@img/sharp-libvips-linux-s390x': 1.0.4 - optional: true - - '@img/sharp-linux-s390x@0.34.2': - optionalDependencies: - '@img/sharp-libvips-linux-s390x': 1.1.0 - optional: true - - '@img/sharp-linux-x64@0.33.5': - optionalDependencies: - '@img/sharp-libvips-linux-x64': 1.0.4 - optional: true - - '@img/sharp-linux-x64@0.34.2': - optionalDependencies: - '@img/sharp-libvips-linux-x64': 1.1.0 - optional: true - - '@img/sharp-linuxmusl-arm64@0.33.5': - optionalDependencies: - '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 - optional: true - - '@img/sharp-linuxmusl-arm64@0.34.2': - optionalDependencies: - '@img/sharp-libvips-linuxmusl-arm64': 1.1.0 - optional: true - - '@img/sharp-linuxmusl-x64@0.33.5': - optionalDependencies: - '@img/sharp-libvips-linuxmusl-x64': 1.0.4 - optional: true - - '@img/sharp-linuxmusl-x64@0.34.2': - optionalDependencies: - '@img/sharp-libvips-linuxmusl-x64': 1.1.0 - optional: true - - '@img/sharp-wasm32@0.33.5': - dependencies: - '@emnapi/runtime': 1.4.3 - optional: true - - '@img/sharp-wasm32@0.34.2': - dependencies: - '@emnapi/runtime': 1.4.3 - optional: true - - '@img/sharp-win32-arm64@0.34.2': - optional: true - - '@img/sharp-win32-ia32@0.33.5': - optional: true - - '@img/sharp-win32-ia32@0.34.2': - optional: true - - '@img/sharp-win32-x64@0.33.5': - optional: true - - '@img/sharp-win32-x64@0.34.2': - optional: true - - '@jridgewell/sourcemap-codec@1.5.4': {} - - '@mdx-js/mdx@3.1.0(acorn@8.15.0)': - dependencies: - '@types/estree': 1.0.8 - '@types/estree-jsx': 1.0.5 - '@types/hast': 3.0.4 - '@types/mdx': 2.0.13 - collapse-white-space: 2.1.0 - devlop: 1.1.0 - estree-util-is-identifier-name: 3.0.0 - estree-util-scope: 1.0.0 - estree-walker: 3.0.3 - hast-util-to-jsx-runtime: 2.3.6 - markdown-extensions: 2.0.0 - recma-build-jsx: 1.0.0 - recma-jsx: 1.0.0(acorn@8.15.0) - recma-stringify: 1.0.0 - rehype-recma: 1.0.0 - remark-mdx: 3.1.0 - remark-parse: 11.0.0 - remark-rehype: 11.1.2 - source-map: 0.7.4 - unified: 11.0.5 - unist-util-position-from-estree: 2.0.0 - unist-util-stringify-position: 4.0.0 - unist-util-visit: 5.0.0 - vfile: 6.0.3 - transitivePeerDependencies: - - acorn - - supports-color - - '@oslojs/encoding@1.1.0': {} - - '@pagefind/darwin-arm64@1.3.0': - optional: true - - '@pagefind/darwin-x64@1.3.0': - optional: true - - '@pagefind/default-ui@1.3.0': {} - - '@pagefind/linux-arm64@1.3.0': - optional: true - - '@pagefind/linux-x64@1.3.0': - optional: true - - '@pagefind/windows-x64@1.3.0': - optional: true - - '@rollup/pluginutils@5.2.0(rollup@4.44.2)': - dependencies: - '@types/estree': 1.0.8 - estree-walker: 2.0.2 - picomatch: 4.0.2 - optionalDependencies: - rollup: 4.44.2 - - '@rollup/rollup-android-arm-eabi@4.44.2': - optional: true - - '@rollup/rollup-android-arm64@4.44.2': - optional: true - - '@rollup/rollup-darwin-arm64@4.44.2': - optional: true - - '@rollup/rollup-darwin-x64@4.44.2': - optional: true - - '@rollup/rollup-freebsd-arm64@4.44.2': - optional: true - - '@rollup/rollup-freebsd-x64@4.44.2': - optional: true - - '@rollup/rollup-linux-arm-gnueabihf@4.44.2': - optional: true - - '@rollup/rollup-linux-arm-musleabihf@4.44.2': - optional: true - - '@rollup/rollup-linux-arm64-gnu@4.44.2': - optional: true - - '@rollup/rollup-linux-arm64-musl@4.44.2': - optional: true - - '@rollup/rollup-linux-loongarch64-gnu@4.44.2': - optional: true - - '@rollup/rollup-linux-powerpc64le-gnu@4.44.2': - optional: true - - '@rollup/rollup-linux-riscv64-gnu@4.44.2': - optional: true - - '@rollup/rollup-linux-riscv64-musl@4.44.2': - optional: true - - '@rollup/rollup-linux-s390x-gnu@4.44.2': - optional: true - - '@rollup/rollup-linux-x64-gnu@4.44.2': - optional: true - - '@rollup/rollup-linux-x64-musl@4.44.2': - optional: true - - '@rollup/rollup-win32-arm64-msvc@4.44.2': - optional: true - - '@rollup/rollup-win32-ia32-msvc@4.44.2': - optional: true - - '@rollup/rollup-win32-x64-msvc@4.44.2': - optional: true - - '@shikijs/core@3.7.0': - dependencies: - '@shikijs/types': 3.7.0 - '@shikijs/vscode-textmate': 10.0.2 - '@types/hast': 3.0.4 - hast-util-to-html: 9.0.5 - - '@shikijs/engine-javascript@3.7.0': - dependencies: - '@shikijs/types': 3.7.0 - '@shikijs/vscode-textmate': 10.0.2 - oniguruma-to-es: 4.3.3 - - '@shikijs/engine-oniguruma@3.7.0': - dependencies: - '@shikijs/types': 3.7.0 - '@shikijs/vscode-textmate': 10.0.2 - - '@shikijs/langs@3.7.0': - dependencies: - '@shikijs/types': 3.7.0 - - '@shikijs/themes@3.7.0': - dependencies: - '@shikijs/types': 3.7.0 - - '@shikijs/types@3.7.0': - dependencies: - '@shikijs/vscode-textmate': 10.0.2 - '@types/hast': 3.0.4 - - '@shikijs/vscode-textmate@10.0.2': {} - - '@swc/helpers@0.5.17': - dependencies: - tslib: 2.8.1 - - '@types/debug@4.1.12': - dependencies: - '@types/ms': 2.1.0 - - '@types/estree-jsx@1.0.5': - dependencies: - '@types/estree': 1.0.8 - - '@types/estree@1.0.8': {} - - '@types/fontkit@2.0.8': - dependencies: - '@types/node': 24.0.10 - - '@types/hast@3.0.4': - dependencies: - '@types/unist': 3.0.3 - - '@types/js-yaml@4.0.9': {} - - '@types/mdast@4.0.4': - dependencies: - '@types/unist': 3.0.3 - - '@types/mdx@2.0.13': {} - - '@types/ms@2.1.0': {} - - '@types/nlcst@2.0.3': - dependencies: - '@types/unist': 3.0.3 - - '@types/node@17.0.45': {} - - '@types/node@24.0.10': - dependencies: - undici-types: 7.8.0 - - '@types/sax@1.2.7': - dependencies: - '@types/node': 24.0.10 - - '@types/unist@2.0.11': {} - - '@types/unist@3.0.3': {} - - '@ungap/structured-clone@1.3.0': {} - - acorn-jsx@5.3.2(acorn@8.15.0): - dependencies: - acorn: 8.15.0 - - acorn@8.15.0: {} - - ansi-align@3.0.1: - dependencies: - string-width: 4.2.3 - - ansi-regex@5.0.1: {} - - ansi-regex@6.1.0: {} - - ansi-styles@6.2.1: {} - - anymatch@3.1.3: - dependencies: - normalize-path: 3.0.0 - picomatch: 2.3.1 - - arg@5.0.2: {} - - argparse@2.0.1: {} - - aria-query@5.3.2: {} - - array-iterate@2.0.1: {} - - astring@1.9.0: {} - - astro-expressive-code@0.41.2(astro@5.12.0(@types/node@24.0.10)(rollup@4.44.2)(typescript@5.8.3)): - dependencies: - astro: 5.12.0(@types/node@24.0.10)(rollup@4.44.2)(typescript@5.8.3) - rehype-expressive-code: 0.41.2 - - astro@5.12.0(@types/node@24.0.10)(rollup@4.44.2)(typescript@5.8.3): - dependencies: - '@astrojs/compiler': 2.12.2 - '@astrojs/internal-helpers': 0.6.1 - '@astrojs/markdown-remark': 6.3.3 - '@astrojs/telemetry': 3.3.0 - '@capsizecss/unpack': 2.4.0 - '@oslojs/encoding': 1.1.0 - '@rollup/pluginutils': 5.2.0(rollup@4.44.2) - acorn: 8.15.0 - aria-query: 5.3.2 - axobject-query: 4.1.0 - boxen: 8.0.1 - ci-info: 4.2.0 - clsx: 2.1.1 - common-ancestor-path: 1.0.1 - cookie: 1.0.2 - cssesc: 3.0.0 - debug: 4.4.1 - deterministic-object-hash: 2.0.2 - devalue: 5.1.1 - diff: 5.2.0 - dlv: 1.1.3 - dset: 3.1.4 - es-module-lexer: 1.7.0 - esbuild: 0.25.5 - estree-walker: 3.0.3 - flattie: 1.1.1 - fontace: 0.3.0 - github-slugger: 2.0.0 - html-escaper: 3.0.3 - http-cache-semantics: 4.2.0 - import-meta-resolve: 4.1.0 - js-yaml: 4.1.0 - kleur: 4.1.5 - magic-string: 0.30.17 - magicast: 0.3.5 - mrmime: 2.0.1 - neotraverse: 0.6.18 - p-limit: 6.2.0 - p-queue: 8.1.0 - package-manager-detector: 1.3.0 - picomatch: 4.0.2 - prompts: 2.4.2 - rehype: 13.0.2 - semver: 7.7.2 - shiki: 3.7.0 - smol-toml: 1.4.1 - tinyexec: 0.3.2 - tinyglobby: 0.2.14 - tsconfck: 3.1.6(typescript@5.8.3) - ultrahtml: 1.6.0 - unifont: 0.5.2 - unist-util-visit: 5.0.0 - unstorage: 1.16.0 - vfile: 6.0.3 - vite: 6.3.5(@types/node@24.0.10) - vitefu: 1.1.1(vite@6.3.5(@types/node@24.0.10)) - xxhash-wasm: 1.1.0 - yargs-parser: 21.1.1 - yocto-spinner: 0.2.3 - zod: 3.25.74 - zod-to-json-schema: 3.24.6(zod@3.25.74) - zod-to-ts: 1.2.0(typescript@5.8.3)(zod@3.25.74) - optionalDependencies: - sharp: 0.33.5 - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@deno/kv' - - '@netlify/blobs' - - '@planetscale/database' - - '@types/node' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/kv' - - aws4fetch - - db0 - - encoding - - idb-keyval - - ioredis - - jiti - - less - - lightningcss - - rollup - - sass - - sass-embedded - - stylus - - sugarss - - supports-color - - terser - - tsx - - typescript - - uploadthing - - yaml - - axobject-query@4.1.0: {} - - bail@2.0.2: {} - - base-64@1.0.0: {} - - base64-js@1.5.1: {} - - bcp-47-match@2.0.3: {} - - bcp-47@2.1.0: - dependencies: - is-alphabetical: 2.0.1 - is-alphanumerical: 2.0.1 - is-decimal: 2.0.1 - - blob-to-buffer@1.2.9: {} - - boolbase@1.0.0: {} - - boxen@8.0.1: - dependencies: - ansi-align: 3.0.1 - camelcase: 8.0.0 - chalk: 5.4.1 - cli-boxes: 3.0.0 - string-width: 7.2.0 - type-fest: 4.41.0 - widest-line: 5.0.0 - wrap-ansi: 9.0.0 - - brotli@1.3.3: - dependencies: - base64-js: 1.5.1 - - camelcase@8.0.0: {} - - ccount@2.0.1: {} - - chalk@5.4.1: {} - - character-entities-html4@2.1.0: {} - - character-entities-legacy@3.0.0: {} - - character-entities@2.0.2: {} - - character-reference-invalid@2.0.1: {} - - chokidar@4.0.3: - dependencies: - readdirp: 4.1.2 - - ci-info@4.2.0: {} - - cli-boxes@3.0.0: {} - - clone@2.1.2: {} - - clsx@2.1.1: {} - - collapse-white-space@2.1.0: {} - - color-convert@2.0.1: - dependencies: - color-name: 1.1.4 - - color-name@1.1.4: {} - - color-string@1.9.1: - dependencies: - color-name: 1.1.4 - simple-swizzle: 0.2.2 - - color@4.2.3: - dependencies: - color-convert: 2.0.1 - color-string: 1.9.1 - - comma-separated-tokens@2.0.3: {} - - common-ancestor-path@1.0.1: {} - - cookie-es@1.2.2: {} - - cookie@1.0.2: {} - - cross-fetch@3.2.0: - dependencies: - node-fetch: 2.7.0 - transitivePeerDependencies: - - encoding - - crossws@0.3.5: - dependencies: - uncrypto: 0.1.3 - - css-selector-parser@3.1.3: {} - - css-tree@3.1.0: - dependencies: - mdn-data: 2.12.2 - source-map-js: 1.2.1 - - cssesc@3.0.0: {} - - debug@4.4.1: - dependencies: - ms: 2.1.3 - - decode-named-character-reference@1.2.0: - dependencies: - character-entities: 2.0.2 - - defu@6.1.4: {} - - dequal@2.0.3: {} - - destr@2.0.5: {} - - detect-libc@2.0.4: {} - - deterministic-object-hash@2.0.2: - dependencies: - base-64: 1.0.0 - - devalue@5.1.1: {} - - devlop@1.1.0: - dependencies: - dequal: 2.0.3 - - dfa@1.2.0: {} - - diff@5.2.0: {} - - direction@2.0.1: {} - - dlv@1.1.3: {} - - dset@3.1.4: {} - - emoji-regex@10.4.0: {} - - emoji-regex@8.0.0: {} - - entities@6.0.1: {} - - es-module-lexer@1.7.0: {} - - esast-util-from-estree@2.0.0: - dependencies: - '@types/estree-jsx': 1.0.5 - devlop: 1.1.0 - estree-util-visit: 2.0.0 - unist-util-position-from-estree: 2.0.0 - - esast-util-from-js@2.0.1: - dependencies: - '@types/estree-jsx': 1.0.5 - acorn: 8.15.0 - esast-util-from-estree: 2.0.0 - vfile-message: 4.0.2 - - esbuild@0.25.5: - optionalDependencies: - '@esbuild/aix-ppc64': 0.25.5 - '@esbuild/android-arm': 0.25.5 - '@esbuild/android-arm64': 0.25.5 - '@esbuild/android-x64': 0.25.5 - '@esbuild/darwin-arm64': 0.25.5 - '@esbuild/darwin-x64': 0.25.5 - '@esbuild/freebsd-arm64': 0.25.5 - '@esbuild/freebsd-x64': 0.25.5 - '@esbuild/linux-arm': 0.25.5 - '@esbuild/linux-arm64': 0.25.5 - '@esbuild/linux-ia32': 0.25.5 - '@esbuild/linux-loong64': 0.25.5 - '@esbuild/linux-mips64el': 0.25.5 - '@esbuild/linux-ppc64': 0.25.5 - '@esbuild/linux-riscv64': 0.25.5 - '@esbuild/linux-s390x': 0.25.5 - '@esbuild/linux-x64': 0.25.5 - '@esbuild/netbsd-arm64': 0.25.5 - '@esbuild/netbsd-x64': 0.25.5 - '@esbuild/openbsd-arm64': 0.25.5 - '@esbuild/openbsd-x64': 0.25.5 - '@esbuild/sunos-x64': 0.25.5 - '@esbuild/win32-arm64': 0.25.5 - '@esbuild/win32-ia32': 0.25.5 - '@esbuild/win32-x64': 0.25.5 - - escape-string-regexp@5.0.0: {} - - estree-util-attach-comments@3.0.0: - dependencies: - '@types/estree': 1.0.8 - - estree-util-build-jsx@3.0.1: - dependencies: - '@types/estree-jsx': 1.0.5 - devlop: 1.1.0 - estree-util-is-identifier-name: 3.0.0 - estree-walker: 3.0.3 - - estree-util-is-identifier-name@3.0.0: {} - - estree-util-scope@1.0.0: - dependencies: - '@types/estree': 1.0.8 - devlop: 1.1.0 - - estree-util-to-js@2.0.0: - dependencies: - '@types/estree-jsx': 1.0.5 - astring: 1.9.0 - source-map: 0.7.4 - - estree-util-visit@2.0.0: - dependencies: - '@types/estree-jsx': 1.0.5 - '@types/unist': 3.0.3 - - estree-walker@2.0.2: {} - - estree-walker@3.0.3: - dependencies: - '@types/estree': 1.0.8 - - eventemitter3@5.0.1: {} - - expressive-code@0.41.2: - dependencies: - '@expressive-code/core': 0.41.2 - '@expressive-code/plugin-frames': 0.41.2 - '@expressive-code/plugin-shiki': 0.41.2 - '@expressive-code/plugin-text-markers': 0.41.2 - - extend@3.0.2: {} - - fast-deep-equal@3.1.3: {} - - fdir@6.4.6(picomatch@4.0.2): - optionalDependencies: - picomatch: 4.0.2 - - flattie@1.1.1: {} - - fontace@0.3.0: - dependencies: - '@types/fontkit': 2.0.8 - fontkit: 2.0.4 - - fontkit@2.0.4: - dependencies: - '@swc/helpers': 0.5.17 - brotli: 1.3.3 - clone: 2.1.2 - dfa: 1.2.0 - fast-deep-equal: 3.1.3 - restructure: 3.0.2 - tiny-inflate: 1.0.3 - unicode-properties: 1.4.1 - unicode-trie: 2.0.0 - - fsevents@2.3.3: - optional: true - - get-east-asian-width@1.3.0: {} - - github-slugger@2.0.0: {} - - h3@1.15.3: - dependencies: - cookie-es: 1.2.2 - crossws: 0.3.5 - defu: 6.1.4 - destr: 2.0.5 - iron-webcrypto: 1.2.1 - node-mock-http: 1.0.1 - radix3: 1.1.2 - ufo: 1.6.1 - uncrypto: 0.1.3 - - hast-util-embedded@3.0.0: - dependencies: - '@types/hast': 3.0.4 - hast-util-is-element: 3.0.0 - - hast-util-format@1.1.0: - dependencies: - '@types/hast': 3.0.4 - hast-util-embedded: 3.0.0 - hast-util-minify-whitespace: 1.0.1 - hast-util-phrasing: 3.0.1 - hast-util-whitespace: 3.0.0 - html-whitespace-sensitive-tag-names: 3.0.1 - unist-util-visit-parents: 6.0.1 - - hast-util-from-html@2.0.3: - dependencies: - '@types/hast': 3.0.4 - devlop: 1.1.0 - hast-util-from-parse5: 8.0.3 - parse5: 7.3.0 - vfile: 6.0.3 - vfile-message: 4.0.2 - - hast-util-from-parse5@8.0.3: - dependencies: - '@types/hast': 3.0.4 - '@types/unist': 3.0.3 - devlop: 1.1.0 - hastscript: 9.0.1 - property-information: 7.1.0 - vfile: 6.0.3 - vfile-location: 5.0.3 - web-namespaces: 2.0.1 - - hast-util-has-property@3.0.0: - dependencies: - '@types/hast': 3.0.4 - - hast-util-is-body-ok-link@3.0.1: - dependencies: - '@types/hast': 3.0.4 - - hast-util-is-element@3.0.0: - dependencies: - '@types/hast': 3.0.4 - - hast-util-minify-whitespace@1.0.1: - dependencies: - '@types/hast': 3.0.4 - hast-util-embedded: 3.0.0 - hast-util-is-element: 3.0.0 - hast-util-whitespace: 3.0.0 - unist-util-is: 6.0.0 - - hast-util-parse-selector@4.0.0: - dependencies: - '@types/hast': 3.0.4 - - hast-util-phrasing@3.0.1: - dependencies: - '@types/hast': 3.0.4 - hast-util-embedded: 3.0.0 - hast-util-has-property: 3.0.0 - hast-util-is-body-ok-link: 3.0.1 - hast-util-is-element: 3.0.0 - - hast-util-raw@9.1.0: - dependencies: - '@types/hast': 3.0.4 - '@types/unist': 3.0.3 - '@ungap/structured-clone': 1.3.0 - hast-util-from-parse5: 8.0.3 - hast-util-to-parse5: 8.0.0 - html-void-elements: 3.0.0 - mdast-util-to-hast: 13.2.0 - parse5: 7.3.0 - unist-util-position: 5.0.0 - unist-util-visit: 5.0.0 - vfile: 6.0.3 - web-namespaces: 2.0.1 - zwitch: 2.0.4 - - hast-util-select@6.0.4: - dependencies: - '@types/hast': 3.0.4 - '@types/unist': 3.0.3 - bcp-47-match: 2.0.3 - comma-separated-tokens: 2.0.3 - css-selector-parser: 3.1.3 - devlop: 1.1.0 - direction: 2.0.1 - hast-util-has-property: 3.0.0 - hast-util-to-string: 3.0.1 - hast-util-whitespace: 3.0.0 - nth-check: 2.1.1 - property-information: 7.1.0 - space-separated-tokens: 2.0.2 - unist-util-visit: 5.0.0 - zwitch: 2.0.4 - - hast-util-to-estree@3.1.3: - dependencies: - '@types/estree': 1.0.8 - '@types/estree-jsx': 1.0.5 - '@types/hast': 3.0.4 - comma-separated-tokens: 2.0.3 - devlop: 1.1.0 - estree-util-attach-comments: 3.0.0 - estree-util-is-identifier-name: 3.0.0 - hast-util-whitespace: 3.0.0 - mdast-util-mdx-expression: 2.0.1 - mdast-util-mdx-jsx: 3.2.0 - mdast-util-mdxjs-esm: 2.0.1 - property-information: 7.1.0 - space-separated-tokens: 2.0.2 - style-to-js: 1.1.17 - unist-util-position: 5.0.0 - zwitch: 2.0.4 - transitivePeerDependencies: - - supports-color - - hast-util-to-html@9.0.5: - dependencies: - '@types/hast': 3.0.4 - '@types/unist': 3.0.3 - ccount: 2.0.1 - comma-separated-tokens: 2.0.3 - hast-util-whitespace: 3.0.0 - html-void-elements: 3.0.0 - mdast-util-to-hast: 13.2.0 - property-information: 7.1.0 - space-separated-tokens: 2.0.2 - stringify-entities: 4.0.4 - zwitch: 2.0.4 - - hast-util-to-jsx-runtime@2.3.6: - dependencies: - '@types/estree': 1.0.8 - '@types/hast': 3.0.4 - '@types/unist': 3.0.3 - comma-separated-tokens: 2.0.3 - devlop: 1.1.0 - estree-util-is-identifier-name: 3.0.0 - hast-util-whitespace: 3.0.0 - mdast-util-mdx-expression: 2.0.1 - mdast-util-mdx-jsx: 3.2.0 - mdast-util-mdxjs-esm: 2.0.1 - property-information: 7.1.0 - space-separated-tokens: 2.0.2 - style-to-js: 1.1.17 - unist-util-position: 5.0.0 - vfile-message: 4.0.2 - transitivePeerDependencies: - - supports-color - - hast-util-to-parse5@8.0.0: - dependencies: - '@types/hast': 3.0.4 - comma-separated-tokens: 2.0.3 - devlop: 1.1.0 - property-information: 6.5.0 - space-separated-tokens: 2.0.2 - web-namespaces: 2.0.1 - zwitch: 2.0.4 - - hast-util-to-string@3.0.1: - dependencies: - '@types/hast': 3.0.4 - - hast-util-to-text@4.0.2: - dependencies: - '@types/hast': 3.0.4 - '@types/unist': 3.0.3 - hast-util-is-element: 3.0.0 - unist-util-find-after: 5.0.0 - - hast-util-whitespace@3.0.0: - dependencies: - '@types/hast': 3.0.4 - - hastscript@9.0.1: - dependencies: - '@types/hast': 3.0.4 - comma-separated-tokens: 2.0.3 - hast-util-parse-selector: 4.0.0 - property-information: 7.1.0 - space-separated-tokens: 2.0.2 - - html-escaper@3.0.3: {} - - html-void-elements@3.0.0: {} - - html-whitespace-sensitive-tag-names@3.0.1: {} - - http-cache-semantics@4.2.0: {} - - i18next@23.16.8: - dependencies: - '@babel/runtime': 7.27.6 - - import-meta-resolve@4.1.0: {} - - inline-style-parser@0.2.4: {} - - iron-webcrypto@1.2.1: {} - - is-alphabetical@2.0.1: {} - - is-alphanumerical@2.0.1: - dependencies: - is-alphabetical: 2.0.1 - is-decimal: 2.0.1 - - is-arrayish@0.3.2: {} - - is-decimal@2.0.1: {} - - is-docker@3.0.0: {} - - is-fullwidth-code-point@3.0.0: {} - - is-hexadecimal@2.0.1: {} - - is-inside-container@1.0.0: - dependencies: - is-docker: 3.0.0 - - is-plain-obj@4.1.0: {} - - is-wsl@3.1.0: - dependencies: - is-inside-container: 1.0.0 - - js-yaml@4.1.0: - dependencies: - argparse: 2.0.1 - - kleur@3.0.3: {} - - kleur@4.1.5: {} - - klona@2.0.6: {} - - longest-streak@3.1.0: {} - - lru-cache@10.4.3: {} - - magic-string@0.30.17: - dependencies: - '@jridgewell/sourcemap-codec': 1.5.4 - - magicast@0.3.5: - dependencies: - '@babel/parser': 7.28.0 - '@babel/types': 7.28.0 - source-map-js: 1.2.1 - - markdown-extensions@2.0.0: {} - - markdown-table@3.0.4: {} - - mdast-util-definitions@6.0.0: - dependencies: - '@types/mdast': 4.0.4 - '@types/unist': 3.0.3 - unist-util-visit: 5.0.0 - - mdast-util-directive@3.1.0: - dependencies: - '@types/mdast': 4.0.4 - '@types/unist': 3.0.3 - ccount: 2.0.1 - devlop: 1.1.0 - mdast-util-from-markdown: 2.0.2 - mdast-util-to-markdown: 2.1.2 - parse-entities: 4.0.2 - stringify-entities: 4.0.4 - unist-util-visit-parents: 6.0.1 - transitivePeerDependencies: - - supports-color - - mdast-util-find-and-replace@3.0.2: - dependencies: - '@types/mdast': 4.0.4 - escape-string-regexp: 5.0.0 - unist-util-is: 6.0.0 - unist-util-visit-parents: 6.0.1 - - mdast-util-from-markdown@2.0.2: - dependencies: - '@types/mdast': 4.0.4 - '@types/unist': 3.0.3 - decode-named-character-reference: 1.2.0 - devlop: 1.1.0 - mdast-util-to-string: 4.0.0 - micromark: 4.0.2 - micromark-util-decode-numeric-character-reference: 2.0.2 - micromark-util-decode-string: 2.0.1 - micromark-util-normalize-identifier: 2.0.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - unist-util-stringify-position: 4.0.0 - transitivePeerDependencies: - - supports-color - - mdast-util-gfm-autolink-literal@2.0.1: - dependencies: - '@types/mdast': 4.0.4 - ccount: 2.0.1 - devlop: 1.1.0 - mdast-util-find-and-replace: 3.0.2 - micromark-util-character: 2.1.1 - - mdast-util-gfm-footnote@2.1.0: - dependencies: - '@types/mdast': 4.0.4 - devlop: 1.1.0 - mdast-util-from-markdown: 2.0.2 - mdast-util-to-markdown: 2.1.2 - micromark-util-normalize-identifier: 2.0.1 - transitivePeerDependencies: - - supports-color - - mdast-util-gfm-strikethrough@2.0.0: - dependencies: - '@types/mdast': 4.0.4 - mdast-util-from-markdown: 2.0.2 - mdast-util-to-markdown: 2.1.2 - transitivePeerDependencies: - - supports-color - - mdast-util-gfm-table@2.0.0: - dependencies: - '@types/mdast': 4.0.4 - devlop: 1.1.0 - markdown-table: 3.0.4 - mdast-util-from-markdown: 2.0.2 - mdast-util-to-markdown: 2.1.2 - transitivePeerDependencies: - - supports-color - - mdast-util-gfm-task-list-item@2.0.0: - dependencies: - '@types/mdast': 4.0.4 - devlop: 1.1.0 - mdast-util-from-markdown: 2.0.2 - mdast-util-to-markdown: 2.1.2 - transitivePeerDependencies: - - supports-color - - mdast-util-gfm@3.1.0: - dependencies: - mdast-util-from-markdown: 2.0.2 - mdast-util-gfm-autolink-literal: 2.0.1 - mdast-util-gfm-footnote: 2.1.0 - mdast-util-gfm-strikethrough: 2.0.0 - mdast-util-gfm-table: 2.0.0 - mdast-util-gfm-task-list-item: 2.0.0 - mdast-util-to-markdown: 2.1.2 - transitivePeerDependencies: - - supports-color - - mdast-util-mdx-expression@2.0.1: - dependencies: - '@types/estree-jsx': 1.0.5 - '@types/hast': 3.0.4 - '@types/mdast': 4.0.4 - devlop: 1.1.0 - mdast-util-from-markdown: 2.0.2 - mdast-util-to-markdown: 2.1.2 - transitivePeerDependencies: - - supports-color - - mdast-util-mdx-jsx@3.2.0: - dependencies: - '@types/estree-jsx': 1.0.5 - '@types/hast': 3.0.4 - '@types/mdast': 4.0.4 - '@types/unist': 3.0.3 - ccount: 2.0.1 - devlop: 1.1.0 - mdast-util-from-markdown: 2.0.2 - mdast-util-to-markdown: 2.1.2 - parse-entities: 4.0.2 - stringify-entities: 4.0.4 - unist-util-stringify-position: 4.0.0 - vfile-message: 4.0.2 - transitivePeerDependencies: - - supports-color - - mdast-util-mdx@3.0.0: - dependencies: - mdast-util-from-markdown: 2.0.2 - mdast-util-mdx-expression: 2.0.1 - mdast-util-mdx-jsx: 3.2.0 - mdast-util-mdxjs-esm: 2.0.1 - mdast-util-to-markdown: 2.1.2 - transitivePeerDependencies: - - supports-color - - mdast-util-mdxjs-esm@2.0.1: - dependencies: - '@types/estree-jsx': 1.0.5 - '@types/hast': 3.0.4 - '@types/mdast': 4.0.4 - devlop: 1.1.0 - mdast-util-from-markdown: 2.0.2 - mdast-util-to-markdown: 2.1.2 - transitivePeerDependencies: - - supports-color - - mdast-util-phrasing@4.1.0: - dependencies: - '@types/mdast': 4.0.4 - unist-util-is: 6.0.0 - - mdast-util-to-hast@13.2.0: - dependencies: - '@types/hast': 3.0.4 - '@types/mdast': 4.0.4 - '@ungap/structured-clone': 1.3.0 - devlop: 1.1.0 - micromark-util-sanitize-uri: 2.0.1 - trim-lines: 3.0.1 - unist-util-position: 5.0.0 - unist-util-visit: 5.0.0 - vfile: 6.0.3 - - mdast-util-to-markdown@2.1.2: - dependencies: - '@types/mdast': 4.0.4 - '@types/unist': 3.0.3 - longest-streak: 3.1.0 - mdast-util-phrasing: 4.1.0 - mdast-util-to-string: 4.0.0 - micromark-util-classify-character: 2.0.1 - micromark-util-decode-string: 2.0.1 - unist-util-visit: 5.0.0 - zwitch: 2.0.4 - - mdast-util-to-string@4.0.0: - dependencies: - '@types/mdast': 4.0.4 - - mdn-data@2.12.2: {} - - micromark-core-commonmark@2.0.3: - dependencies: - decode-named-character-reference: 1.2.0 - devlop: 1.1.0 - micromark-factory-destination: 2.0.1 - micromark-factory-label: 2.0.1 - micromark-factory-space: 2.0.1 - micromark-factory-title: 2.0.1 - micromark-factory-whitespace: 2.0.1 - micromark-util-character: 2.1.1 - micromark-util-chunked: 2.0.1 - micromark-util-classify-character: 2.0.1 - micromark-util-html-tag-name: 2.0.1 - micromark-util-normalize-identifier: 2.0.1 - micromark-util-resolve-all: 2.0.1 - micromark-util-subtokenize: 2.1.0 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-extension-directive@3.0.2: - dependencies: - devlop: 1.1.0 - micromark-factory-space: 2.0.1 - micromark-factory-whitespace: 2.0.1 - micromark-util-character: 2.1.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - parse-entities: 4.0.2 - - micromark-extension-gfm-autolink-literal@2.1.0: - dependencies: - micromark-util-character: 2.1.1 - micromark-util-sanitize-uri: 2.0.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-extension-gfm-footnote@2.1.0: - dependencies: - devlop: 1.1.0 - micromark-core-commonmark: 2.0.3 - micromark-factory-space: 2.0.1 - micromark-util-character: 2.1.1 - micromark-util-normalize-identifier: 2.0.1 - micromark-util-sanitize-uri: 2.0.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-extension-gfm-strikethrough@2.1.0: - dependencies: - devlop: 1.1.0 - micromark-util-chunked: 2.0.1 - micromark-util-classify-character: 2.0.1 - micromark-util-resolve-all: 2.0.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-extension-gfm-table@2.1.1: - dependencies: - devlop: 1.1.0 - micromark-factory-space: 2.0.1 - micromark-util-character: 2.1.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-extension-gfm-tagfilter@2.0.0: - dependencies: - micromark-util-types: 2.0.2 - - micromark-extension-gfm-task-list-item@2.1.0: - dependencies: - devlop: 1.1.0 - micromark-factory-space: 2.0.1 - micromark-util-character: 2.1.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-extension-gfm@3.0.0: - dependencies: - micromark-extension-gfm-autolink-literal: 2.1.0 - micromark-extension-gfm-footnote: 2.1.0 - micromark-extension-gfm-strikethrough: 2.1.0 - micromark-extension-gfm-table: 2.1.1 - micromark-extension-gfm-tagfilter: 2.0.0 - micromark-extension-gfm-task-list-item: 2.1.0 - micromark-util-combine-extensions: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-extension-mdx-expression@3.0.1: - dependencies: - '@types/estree': 1.0.8 - devlop: 1.1.0 - micromark-factory-mdx-expression: 2.0.3 - micromark-factory-space: 2.0.1 - micromark-util-character: 2.1.1 - micromark-util-events-to-acorn: 2.0.3 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-extension-mdx-jsx@3.0.2: - dependencies: - '@types/estree': 1.0.8 - devlop: 1.1.0 - estree-util-is-identifier-name: 3.0.0 - micromark-factory-mdx-expression: 2.0.3 - micromark-factory-space: 2.0.1 - micromark-util-character: 2.1.1 - micromark-util-events-to-acorn: 2.0.3 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - vfile-message: 4.0.2 - - micromark-extension-mdx-md@2.0.0: - dependencies: - micromark-util-types: 2.0.2 - - micromark-extension-mdxjs-esm@3.0.0: - dependencies: - '@types/estree': 1.0.8 - devlop: 1.1.0 - micromark-core-commonmark: 2.0.3 - micromark-util-character: 2.1.1 - micromark-util-events-to-acorn: 2.0.3 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - unist-util-position-from-estree: 2.0.0 - vfile-message: 4.0.2 - - micromark-extension-mdxjs@3.0.0: - dependencies: - acorn: 8.15.0 - acorn-jsx: 5.3.2(acorn@8.15.0) - micromark-extension-mdx-expression: 3.0.1 - micromark-extension-mdx-jsx: 3.0.2 - micromark-extension-mdx-md: 2.0.0 - micromark-extension-mdxjs-esm: 3.0.0 - micromark-util-combine-extensions: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-factory-destination@2.0.1: - dependencies: - micromark-util-character: 2.1.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-factory-label@2.0.1: - dependencies: - devlop: 1.1.0 - micromark-util-character: 2.1.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-factory-mdx-expression@2.0.3: - dependencies: - '@types/estree': 1.0.8 - devlop: 1.1.0 - micromark-factory-space: 2.0.1 - micromark-util-character: 2.1.1 - micromark-util-events-to-acorn: 2.0.3 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - unist-util-position-from-estree: 2.0.0 - vfile-message: 4.0.2 - - micromark-factory-space@2.0.1: - dependencies: - micromark-util-character: 2.1.1 - micromark-util-types: 2.0.2 - - micromark-factory-title@2.0.1: - dependencies: - micromark-factory-space: 2.0.1 - micromark-util-character: 2.1.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-factory-whitespace@2.0.1: - dependencies: - micromark-factory-space: 2.0.1 - micromark-util-character: 2.1.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-util-character@2.1.1: - dependencies: - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-util-chunked@2.0.1: - dependencies: - micromark-util-symbol: 2.0.1 - - micromark-util-classify-character@2.0.1: - dependencies: - micromark-util-character: 2.1.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-util-combine-extensions@2.0.1: - dependencies: - micromark-util-chunked: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-util-decode-numeric-character-reference@2.0.2: - dependencies: - micromark-util-symbol: 2.0.1 - - micromark-util-decode-string@2.0.1: - dependencies: - decode-named-character-reference: 1.2.0 - micromark-util-character: 2.1.1 - micromark-util-decode-numeric-character-reference: 2.0.2 - micromark-util-symbol: 2.0.1 - - micromark-util-encode@2.0.1: {} - - micromark-util-events-to-acorn@2.0.3: - dependencies: - '@types/estree': 1.0.8 - '@types/unist': 3.0.3 - devlop: 1.1.0 - estree-util-visit: 2.0.0 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - vfile-message: 4.0.2 - - micromark-util-html-tag-name@2.0.1: {} - - micromark-util-normalize-identifier@2.0.1: - dependencies: - micromark-util-symbol: 2.0.1 - - micromark-util-resolve-all@2.0.1: - dependencies: - micromark-util-types: 2.0.2 - - micromark-util-sanitize-uri@2.0.1: - dependencies: - micromark-util-character: 2.1.1 - micromark-util-encode: 2.0.1 - micromark-util-symbol: 2.0.1 - - micromark-util-subtokenize@2.1.0: - dependencies: - devlop: 1.1.0 - micromark-util-chunked: 2.0.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-util-symbol@2.0.1: {} - - micromark-util-types@2.0.2: {} - - micromark@4.0.2: - dependencies: - '@types/debug': 4.1.12 - debug: 4.4.1 - decode-named-character-reference: 1.2.0 - devlop: 1.1.0 - micromark-core-commonmark: 2.0.3 - micromark-factory-space: 2.0.1 - micromark-util-character: 2.1.1 - micromark-util-chunked: 2.0.1 - micromark-util-combine-extensions: 2.0.1 - micromark-util-decode-numeric-character-reference: 2.0.2 - micromark-util-encode: 2.0.1 - micromark-util-normalize-identifier: 2.0.1 - micromark-util-resolve-all: 2.0.1 - micromark-util-sanitize-uri: 2.0.1 - micromark-util-subtokenize: 2.1.0 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - transitivePeerDependencies: - - supports-color - - mrmime@2.0.1: {} - - ms@2.1.3: {} - - nanoid@3.3.11: {} - - neotraverse@0.6.18: {} - - nlcst-to-string@4.0.0: - dependencies: - '@types/nlcst': 2.0.3 - - node-fetch-native@1.6.6: {} - - node-fetch@2.7.0: - dependencies: - whatwg-url: 5.0.0 - - node-mock-http@1.0.1: {} - - normalize-path@3.0.0: {} - - nth-check@2.1.1: - dependencies: - boolbase: 1.0.0 - - ofetch@1.4.1: - dependencies: - destr: 2.0.5 - node-fetch-native: 1.6.6 - ufo: 1.6.1 - - ohash@2.0.11: {} - - oniguruma-parser@0.12.1: {} - - oniguruma-to-es@4.3.3: - dependencies: - oniguruma-parser: 0.12.1 - regex: 6.0.1 - regex-recursion: 6.0.2 - - p-limit@6.2.0: - dependencies: - yocto-queue: 1.2.1 - - p-queue@8.1.0: - dependencies: - eventemitter3: 5.0.1 - p-timeout: 6.1.4 - - p-timeout@6.1.4: {} - - package-manager-detector@1.3.0: {} - - pagefind@1.3.0: - optionalDependencies: - '@pagefind/darwin-arm64': 1.3.0 - '@pagefind/darwin-x64': 1.3.0 - '@pagefind/linux-arm64': 1.3.0 - '@pagefind/linux-x64': 1.3.0 - '@pagefind/windows-x64': 1.3.0 - - pako@0.2.9: {} - - parse-entities@4.0.2: - dependencies: - '@types/unist': 2.0.11 - character-entities-legacy: 3.0.0 - character-reference-invalid: 2.0.1 - decode-named-character-reference: 1.2.0 - is-alphanumerical: 2.0.1 - is-decimal: 2.0.1 - is-hexadecimal: 2.0.1 - - parse-latin@7.0.0: - dependencies: - '@types/nlcst': 2.0.3 - '@types/unist': 3.0.3 - nlcst-to-string: 4.0.0 - unist-util-modify-children: 4.0.0 - unist-util-visit-children: 3.0.0 - vfile: 6.0.3 - - parse5@7.3.0: - dependencies: - entities: 6.0.1 - - pathe@2.0.3: {} - - picocolors@1.1.1: {} - - picomatch@2.3.1: {} - - picomatch@4.0.2: {} - - postcss-nested@6.2.0(postcss@8.5.6): - dependencies: - postcss: 8.5.6 - postcss-selector-parser: 6.1.2 - - postcss-selector-parser@6.1.2: - dependencies: - cssesc: 3.0.0 - util-deprecate: 1.0.2 - - postcss@8.5.6: - dependencies: - nanoid: 3.3.11 - picocolors: 1.1.1 - source-map-js: 1.2.1 - - prismjs@1.30.0: {} - - prompts@2.4.2: - dependencies: - kleur: 3.0.3 - sisteransi: 1.0.5 - - property-information@6.5.0: {} - - property-information@7.1.0: {} - - radix3@1.1.2: {} - - readdirp@4.1.2: {} - - recma-build-jsx@1.0.0: - dependencies: - '@types/estree': 1.0.8 - estree-util-build-jsx: 3.0.1 - vfile: 6.0.3 - - recma-jsx@1.0.0(acorn@8.15.0): - dependencies: - acorn-jsx: 5.3.2(acorn@8.15.0) - estree-util-to-js: 2.0.0 - recma-parse: 1.0.0 - recma-stringify: 1.0.0 - unified: 11.0.5 - transitivePeerDependencies: - - acorn - - recma-parse@1.0.0: - dependencies: - '@types/estree': 1.0.8 - esast-util-from-js: 2.0.1 - unified: 11.0.5 - vfile: 6.0.3 - - recma-stringify@1.0.0: - dependencies: - '@types/estree': 1.0.8 - estree-util-to-js: 2.0.0 - unified: 11.0.5 - vfile: 6.0.3 - - regex-recursion@6.0.2: - dependencies: - regex-utilities: 2.3.0 - - regex-utilities@2.3.0: {} - - regex@6.0.1: - dependencies: - regex-utilities: 2.3.0 - - rehype-expressive-code@0.41.2: - dependencies: - expressive-code: 0.41.2 - - rehype-format@5.0.1: - dependencies: - '@types/hast': 3.0.4 - hast-util-format: 1.1.0 - - rehype-parse@9.0.1: - dependencies: - '@types/hast': 3.0.4 - hast-util-from-html: 2.0.3 - unified: 11.0.5 - - rehype-raw@7.0.0: - dependencies: - '@types/hast': 3.0.4 - hast-util-raw: 9.1.0 - vfile: 6.0.3 - - rehype-recma@1.0.0: - dependencies: - '@types/estree': 1.0.8 - '@types/hast': 3.0.4 - hast-util-to-estree: 3.1.3 - transitivePeerDependencies: - - supports-color - - rehype-stringify@10.0.1: - dependencies: - '@types/hast': 3.0.4 - hast-util-to-html: 9.0.5 - unified: 11.0.5 - - rehype@13.0.2: - dependencies: - '@types/hast': 3.0.4 - rehype-parse: 9.0.1 - rehype-stringify: 10.0.1 - unified: 11.0.5 - - remark-directive@3.0.1: - dependencies: - '@types/mdast': 4.0.4 - mdast-util-directive: 3.1.0 - micromark-extension-directive: 3.0.2 - unified: 11.0.5 - transitivePeerDependencies: - - supports-color - - remark-gfm@4.0.1: - dependencies: - '@types/mdast': 4.0.4 - mdast-util-gfm: 3.1.0 - micromark-extension-gfm: 3.0.0 - remark-parse: 11.0.0 - remark-stringify: 11.0.0 - unified: 11.0.5 - transitivePeerDependencies: - - supports-color - - remark-mdx@3.1.0: - dependencies: - mdast-util-mdx: 3.0.0 - micromark-extension-mdxjs: 3.0.0 - transitivePeerDependencies: - - supports-color - - remark-parse@11.0.0: - dependencies: - '@types/mdast': 4.0.4 - mdast-util-from-markdown: 2.0.2 - micromark-util-types: 2.0.2 - unified: 11.0.5 - transitivePeerDependencies: - - supports-color - - remark-rehype@11.1.2: - dependencies: - '@types/hast': 3.0.4 - '@types/mdast': 4.0.4 - mdast-util-to-hast: 13.2.0 - unified: 11.0.5 - vfile: 6.0.3 - - remark-smartypants@3.0.2: - dependencies: - retext: 9.0.0 - retext-smartypants: 6.2.0 - unified: 11.0.5 - unist-util-visit: 5.0.0 - - remark-stringify@11.0.0: - dependencies: - '@types/mdast': 4.0.4 - mdast-util-to-markdown: 2.1.2 - unified: 11.0.5 - - restructure@3.0.2: {} - - retext-latin@4.0.0: - dependencies: - '@types/nlcst': 2.0.3 - parse-latin: 7.0.0 - unified: 11.0.5 - - retext-smartypants@6.2.0: - dependencies: - '@types/nlcst': 2.0.3 - nlcst-to-string: 4.0.0 - unist-util-visit: 5.0.0 - - retext-stringify@4.0.0: - dependencies: - '@types/nlcst': 2.0.3 - nlcst-to-string: 4.0.0 - unified: 11.0.5 - - retext@9.0.0: - dependencies: - '@types/nlcst': 2.0.3 - retext-latin: 4.0.0 - retext-stringify: 4.0.0 - unified: 11.0.5 - - rollup@4.44.2: - dependencies: - '@types/estree': 1.0.8 - optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.44.2 - '@rollup/rollup-android-arm64': 4.44.2 - '@rollup/rollup-darwin-arm64': 4.44.2 - '@rollup/rollup-darwin-x64': 4.44.2 - '@rollup/rollup-freebsd-arm64': 4.44.2 - '@rollup/rollup-freebsd-x64': 4.44.2 - '@rollup/rollup-linux-arm-gnueabihf': 4.44.2 - '@rollup/rollup-linux-arm-musleabihf': 4.44.2 - '@rollup/rollup-linux-arm64-gnu': 4.44.2 - '@rollup/rollup-linux-arm64-musl': 4.44.2 - '@rollup/rollup-linux-loongarch64-gnu': 4.44.2 - '@rollup/rollup-linux-powerpc64le-gnu': 4.44.2 - '@rollup/rollup-linux-riscv64-gnu': 4.44.2 - '@rollup/rollup-linux-riscv64-musl': 4.44.2 - '@rollup/rollup-linux-s390x-gnu': 4.44.2 - '@rollup/rollup-linux-x64-gnu': 4.44.2 - '@rollup/rollup-linux-x64-musl': 4.44.2 - '@rollup/rollup-win32-arm64-msvc': 4.44.2 - '@rollup/rollup-win32-ia32-msvc': 4.44.2 - '@rollup/rollup-win32-x64-msvc': 4.44.2 - fsevents: 2.3.3 - - sax@1.4.1: {} - - semver@7.7.2: {} - - sharp@0.33.5: - dependencies: - color: 4.2.3 - detect-libc: 2.0.4 - semver: 7.7.2 - optionalDependencies: - '@img/sharp-darwin-arm64': 0.33.5 - '@img/sharp-darwin-x64': 0.33.5 - '@img/sharp-libvips-darwin-arm64': 1.0.4 - '@img/sharp-libvips-darwin-x64': 1.0.4 - '@img/sharp-libvips-linux-arm': 1.0.5 - '@img/sharp-libvips-linux-arm64': 1.0.4 - '@img/sharp-libvips-linux-s390x': 1.0.4 - '@img/sharp-libvips-linux-x64': 1.0.4 - '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 - '@img/sharp-libvips-linuxmusl-x64': 1.0.4 - '@img/sharp-linux-arm': 0.33.5 - '@img/sharp-linux-arm64': 0.33.5 - '@img/sharp-linux-s390x': 0.33.5 - '@img/sharp-linux-x64': 0.33.5 - '@img/sharp-linuxmusl-arm64': 0.33.5 - '@img/sharp-linuxmusl-x64': 0.33.5 - '@img/sharp-wasm32': 0.33.5 - '@img/sharp-win32-ia32': 0.33.5 - '@img/sharp-win32-x64': 0.33.5 - optional: true - - sharp@0.34.2: - dependencies: - color: 4.2.3 - detect-libc: 2.0.4 - semver: 7.7.2 - optionalDependencies: - '@img/sharp-darwin-arm64': 0.34.2 - '@img/sharp-darwin-x64': 0.34.2 - '@img/sharp-libvips-darwin-arm64': 1.1.0 - '@img/sharp-libvips-darwin-x64': 1.1.0 - '@img/sharp-libvips-linux-arm': 1.1.0 - '@img/sharp-libvips-linux-arm64': 1.1.0 - '@img/sharp-libvips-linux-ppc64': 1.1.0 - '@img/sharp-libvips-linux-s390x': 1.1.0 - '@img/sharp-libvips-linux-x64': 1.1.0 - '@img/sharp-libvips-linuxmusl-arm64': 1.1.0 - '@img/sharp-libvips-linuxmusl-x64': 1.1.0 - '@img/sharp-linux-arm': 0.34.2 - '@img/sharp-linux-arm64': 0.34.2 - '@img/sharp-linux-s390x': 0.34.2 - '@img/sharp-linux-x64': 0.34.2 - '@img/sharp-linuxmusl-arm64': 0.34.2 - '@img/sharp-linuxmusl-x64': 0.34.2 - '@img/sharp-wasm32': 0.34.2 - '@img/sharp-win32-arm64': 0.34.2 - '@img/sharp-win32-ia32': 0.34.2 - '@img/sharp-win32-x64': 0.34.2 - - shiki@3.7.0: - dependencies: - '@shikijs/core': 3.7.0 - '@shikijs/engine-javascript': 3.7.0 - '@shikijs/engine-oniguruma': 3.7.0 - '@shikijs/langs': 3.7.0 - '@shikijs/themes': 3.7.0 - '@shikijs/types': 3.7.0 - '@shikijs/vscode-textmate': 10.0.2 - '@types/hast': 3.0.4 - - simple-swizzle@0.2.2: - dependencies: - is-arrayish: 0.3.2 - - sisteransi@1.0.5: {} - - sitemap@8.0.0: - dependencies: - '@types/node': 17.0.45 - '@types/sax': 1.2.7 - arg: 5.0.2 - sax: 1.4.1 - - smol-toml@1.4.1: {} - - source-map-js@1.2.1: {} - - source-map@0.7.4: {} - - space-separated-tokens@2.0.2: {} - - stream-replace-string@2.0.0: {} - - string-width@4.2.3: - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 - - string-width@7.2.0: - dependencies: - emoji-regex: 10.4.0 - get-east-asian-width: 1.3.0 - strip-ansi: 7.1.0 - - stringify-entities@4.0.4: - dependencies: - character-entities-html4: 2.1.0 - character-entities-legacy: 3.0.0 - - strip-ansi@6.0.1: - dependencies: - ansi-regex: 5.0.1 - - strip-ansi@7.1.0: - dependencies: - ansi-regex: 6.1.0 - - style-to-js@1.1.17: - dependencies: - style-to-object: 1.0.9 - - style-to-object@1.0.9: - dependencies: - inline-style-parser: 0.2.4 - - tiny-inflate@1.0.3: {} - - tinyexec@0.3.2: {} - - tinyglobby@0.2.14: - dependencies: - fdir: 6.4.6(picomatch@4.0.2) - picomatch: 4.0.2 - - tr46@0.0.3: {} - - trim-lines@3.0.1: {} - - trough@2.2.0: {} - - tsconfck@3.1.6(typescript@5.8.3): - optionalDependencies: - typescript: 5.8.3 - - tslib@2.8.1: {} - - type-fest@4.41.0: {} - - typescript@5.8.3: {} - - ufo@1.6.1: {} - - ultrahtml@1.6.0: {} - - uncrypto@0.1.3: {} - - undici-types@7.8.0: {} - - unicode-properties@1.4.1: - dependencies: - base64-js: 1.5.1 - unicode-trie: 2.0.0 - - unicode-trie@2.0.0: - dependencies: - pako: 0.2.9 - tiny-inflate: 1.0.3 - - unified@11.0.5: - dependencies: - '@types/unist': 3.0.3 - bail: 2.0.2 - devlop: 1.1.0 - extend: 3.0.2 - is-plain-obj: 4.1.0 - trough: 2.2.0 - vfile: 6.0.3 - - unifont@0.5.2: - dependencies: - css-tree: 3.1.0 - ofetch: 1.4.1 - ohash: 2.0.11 - - unist-util-find-after@5.0.0: - dependencies: - '@types/unist': 3.0.3 - unist-util-is: 6.0.0 - - unist-util-is@6.0.0: - dependencies: - '@types/unist': 3.0.3 - - unist-util-modify-children@4.0.0: - dependencies: - '@types/unist': 3.0.3 - array-iterate: 2.0.1 - - unist-util-position-from-estree@2.0.0: - dependencies: - '@types/unist': 3.0.3 - - unist-util-position@5.0.0: - dependencies: - '@types/unist': 3.0.3 - - unist-util-remove-position@5.0.0: - dependencies: - '@types/unist': 3.0.3 - unist-util-visit: 5.0.0 - - unist-util-stringify-position@4.0.0: - dependencies: - '@types/unist': 3.0.3 - - unist-util-visit-children@3.0.0: - dependencies: - '@types/unist': 3.0.3 - - unist-util-visit-parents@6.0.1: - dependencies: - '@types/unist': 3.0.3 - unist-util-is: 6.0.0 - - unist-util-visit@5.0.0: - dependencies: - '@types/unist': 3.0.3 - unist-util-is: 6.0.0 - unist-util-visit-parents: 6.0.1 - - unstorage@1.16.0: - dependencies: - anymatch: 3.1.3 - chokidar: 4.0.3 - destr: 2.0.5 - h3: 1.15.3 - lru-cache: 10.4.3 - node-fetch-native: 1.6.6 - ofetch: 1.4.1 - ufo: 1.6.1 - - util-deprecate@1.0.2: {} - - vfile-location@5.0.3: - dependencies: - '@types/unist': 3.0.3 - vfile: 6.0.3 - - vfile-message@4.0.2: - dependencies: - '@types/unist': 3.0.3 - unist-util-stringify-position: 4.0.0 - - vfile@6.0.3: - dependencies: - '@types/unist': 3.0.3 - vfile-message: 4.0.2 - - vite@6.3.5(@types/node@24.0.10): - dependencies: - esbuild: 0.25.5 - fdir: 6.4.6(picomatch@4.0.2) - picomatch: 4.0.2 - postcss: 8.5.6 - rollup: 4.44.2 - tinyglobby: 0.2.14 - optionalDependencies: - '@types/node': 24.0.10 - fsevents: 2.3.3 - - vitefu@1.1.1(vite@6.3.5(@types/node@24.0.10)): - optionalDependencies: - vite: 6.3.5(@types/node@24.0.10) - - web-namespaces@2.0.1: {} - - webidl-conversions@3.0.1: {} - - whatwg-url@5.0.0: - dependencies: - tr46: 0.0.3 - webidl-conversions: 3.0.1 - - which-pm-runs@1.1.0: {} - - widest-line@5.0.0: - dependencies: - string-width: 7.2.0 - - wrap-ansi@9.0.0: - dependencies: - ansi-styles: 6.2.1 - string-width: 7.2.0 - strip-ansi: 7.1.0 - - xxhash-wasm@1.1.0: {} - - yargs-parser@21.1.1: {} - - yocto-queue@1.2.1: {} - - yocto-spinner@0.2.3: - dependencies: - yoctocolors: 2.1.1 - - yoctocolors@2.1.1: {} - - zod-to-json-schema@3.24.6(zod@3.25.74): - dependencies: - zod: 3.25.74 - - zod-to-ts@1.2.0(typescript@5.8.3)(zod@3.25.74): - dependencies: - typescript: 5.8.3 - zod: 3.25.74 - - zod@3.25.74: {} - - zwitch@2.0.4: {} diff --git a/docs/pnpm-workspace.yaml b/docs/pnpm-workspace.yaml deleted file mode 100644 index d0b7dbe..0000000 --- a/docs/pnpm-workspace.yaml +++ /dev/null @@ -1,3 +0,0 @@ -onlyBuiltDependencies: - - esbuild - - sharp diff --git a/docs/public/favicon.svg b/docs/public/favicon.svg deleted file mode 100644 index a24ca8b..0000000 --- a/docs/public/favicon.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/src/assets/face.svg b/docs/src/assets/face.svg deleted file mode 100644 index a24ca8b..0000000 --- a/docs/src/assets/face.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/src/assets/icon.svg b/docs/src/assets/icon.svg deleted file mode 100644 index 77253df..0000000 --- a/docs/src/assets/icon.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/docs/src/content.config.ts b/docs/src/content.config.ts deleted file mode 100644 index d9ee8c9..0000000 --- a/docs/src/content.config.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { defineCollection } from 'astro:content'; -import { docsLoader } from '@astrojs/starlight/loaders'; -import { docsSchema } from '@astrojs/starlight/schema'; - -export const collections = { - docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }), -}; diff --git a/docs/src/content/docs/examples/creepers_and_zombies_drop_tnt.md b/docs/src/content/docs/examples/creepers_and_zombies_drop_tnt.md deleted file mode 100644 index 61bea66..0000000 --- a/docs/src/content/docs/examples/creepers_and_zombies_drop_tnt.md +++ /dev/null @@ -1,121 +0,0 @@ ---- -title: Make Creepers and Zombies drop tnt ---- - -There are two ways to go about doing this, depending on how you want the tnt to drop. -You can either add them in a pool that's separate from the existing drops or do it in the same pool. - -But what's the difference? -In a loot table, each pool generates drops by choosing one or multiple entries from itself. -Adding the tnt in a separate pool means that the tnt will *always* drop no matter what other drops are in the table. -Adding the tnt to an existing pool means that the tnt is one of the options that the game may drop, among the normal drops. - -## In a separate pool -```json -{ - "actions": [ - { - "type": "loot-table-modifier:pool_add", - "pools": [ - { - "rolls": 1, - "entries": [ - { - "type": "minecraft:item", - "name": "minecraft:tnt" - } - ] - } - ] - } - ], - "predicate": { - "type": "loot-table-modifier:table", - "identifiers": [ - "minecraft:entities/creeper", - "minecraft:entities/zombie" - ] - } -} -``` - -### Explanation - -The action [`pool_add`](/reference/actions#add-pool) adds the pool to the matched tables. - -The predicate [`table`](/reference/predicates#loot-table) matches either the creeper or zombie loot tables. - -## In an existing pool -```json -{ - "actions": [ - { - "type": "loot-table-modifier:entry_add", - "entries": [ - { - "type": "minecraft:item", - "name": "minecraft:tnt" - } - ] - } - ], - "predicate": { - "type": "loot-table-modifier:table", - "identifiers": [ - "minecraft:entities/creeper", - "minecraft:entities/zombie" - ] - } -} -``` - -### Explanation - -The action [`entry_add`](/reference/actions#add-entry) adds the entry to a pool. - -The predicate [`table`](/reference/predicates#loot-table) matches either the creeper or zombie loot tables. - -The action will only be applied on the first pool it finds in the target table, so you may want to use a predicate like below to specify which pool it should be added to. -(Also, if adding some configuration to how many pools it would try matching or whatever would be useful for your use case, hit me up on [discord](https://discord.offsetmonkey538.top)) -```json {"Creeper predicate, matches the pool dropping gunpowder":5-20} {"Zombie predicate, matches the pool dropping rotten flesh":22-37} -{ - "predicate": { - "type": "loot-table-modifier:any_of", - "terms": [ - - { - "type": "loot-table-modifier:all_of", - "terms": [ - { - "type": "loot-table-modifier:table", - "identifiers": [ - "minecraft:entities/creeper" - ] - }, - { - "type": "loot-table-modifier:entry_item", - "name": "minecraft:gunpowder" - } - ] - }, - - - { - "type": "loot-table-modifier:all_of", - "terms": [ - { - "type": "loot-table-modifier:table", - "identifiers": [ - "minecraft:entities/zombie" - ] - }, - { - "type": "loot-table-modifier:entry_item", - "name": "minecraft:rotten_flesh" - } - ] - } - ] - } -} -``` diff --git a/docs/src/content/docs/examples/remove_glowstone_and_gunpowder_witches.md b/docs/src/content/docs/examples/remove_glowstone_and_gunpowder_witches.md deleted file mode 100644 index 7e724d7..0000000 --- a/docs/src/content/docs/examples/remove_glowstone_and_gunpowder_witches.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: Remove glowstone and gunpowder from witches ---- - -For removing an item from a loot table, the [`entry_remove`](/reference/actions#remove-entry) action should be used in most cases. -Using [`pool_remove`](/reference/actions#remove-pool) would remove the whole pool, including all the other entries in there. - -```json {"First part matches the witch table":10-16} {"Second part matches either glowstone dust or gunpowder":18-31} -{ - "actions": [ - { - "type": "loot-table-modifier:entry_remove" - } - ], - "predicate": { - "type": "loot-table-modifier:all_of", - "terms": [ - - { - "type": "loot-table-modifier:table", - "identifiers": [ - "minecraft:entities/witch" - ] - }, - - - { - "type": "loot-table-modifier:any_of", - "terms": [ - { - "type": "loot-table-modifier:entry_item", - "name": "minecraft:glowstone_dust" - }, - { - "type": "loot-table-modifier:entry_item", - "name": "minecraft:gunpowder" - } - ] - } - ] - } -} -``` diff --git a/docs/src/content/docs/examples/remove_sticks.md b/docs/src/content/docs/examples/remove_sticks.md deleted file mode 100644 index c6fc8ab..0000000 --- a/docs/src/content/docs/examples/remove_sticks.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: Remove sticks ---- - -For removing an item from a loot table, the [`entry_remove`](/reference/actions#remove-entry) action should be used in most cases. -Using [`pool_remove`](/reference/actions#remove-pool) would remove the whole pool, including all the other entries in there. - -```json -{ - "actions": [ - { - "type": "loot-table-modifier:entry_remove" - } - ], - "predicate": { - "type": "loot-table-modifier:entry_item", - "name": "minecraft:stick" - } -} -``` - -### Explanation - -The action [`entry_remove`](../../reference/loot_modifier#add-pool) removes the matched entries from their pools. - -The predicate [`entry_item`](../../reference/loot_modifier#loot-table) matches entries containing a stick. diff --git a/docs/src/content/docs/examples/replace_ingot_w_diamond.md b/docs/src/content/docs/examples/replace_ingot_w_diamond.md deleted file mode 100644 index 6dc9b0d..0000000 --- a/docs/src/content/docs/examples/replace_ingot_w_diamond.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: Replace any Minecraft ingot with a diamond ---- - -The following loot modifier will replace any Minecraft ingot item with a diamond: -```json -{ - "actions": - [ - { - "type": "loot-table-modifier:entry_item_set", - "name": "minecraft:diamond" - } - ], - "predicate": { - "type": "loot-table-modifier:entry_item", - "name": { - "regexPattern": "minecraft:.*_ingot" - } - } -} -``` - -### Explanation - -The action [`entry_item_set`](/reference/actions#set-item-in-item-entry) replaces the item in an existing matched item entry. - -The predicate [`entry_item`](/reference/predicates#item-entry) matches specific item entries based on their IDs. It can match using a [regex identifier](/reference/regex_identifier), which allows using regex patterns. -The regex pattern `minecraft:.*_ingot` will match every item that has an identifier that begins with `minecraft:` and ends with `_ingot`. For example `minecraft:iron_ingot` and `minecraft:gold_ingot` will both be matched. diff --git a/docs/src/content/docs/getting_started.md b/docs/src/content/docs/getting_started.md deleted file mode 100644 index 77a8f62..0000000 --- a/docs/src/content/docs/getting_started.md +++ /dev/null @@ -1,62 +0,0 @@ ---- -title: Getting Started ---- - -## Installing -:::note -Currently, as of v2 alpha 1, only **fabric** is supported. Running though [Sinytra Connector](https://modrinth.com/mod/connector) may or may not be possible (please do let me know on [discord](https://discord.offsetmonkey538.top) if you test it :D), but a NeoForge version is planned for the future. -::: - -To use Loot Table Modifier, you first gotta have it installed (I am so damn good at writing useful documentation, no need to thank me 👍) - -When developing a plain datapack, all you need to do is download it from [modrinth](https://modrinth.com/mod/loot-table-modifier) and put it in your mods folder. - -You may also want to show the `Requires` badge in your readme, see below for an example and [here](/reference/badges) for more info. -[![This project requires Loot Table Modifier to be installed](https://raw.githubusercontent.com/OffsetMods538/Loot-Table-Modifier/master/images/requires_badge.svg)](https://modrinth.com/mod/loot-table-modifier) - -### Mod developers -Mods can depend on Loot Table Modifier like this: -```groovy -repositories { - // ...rest of repositories block - maven { - name = "OffsetMods538" - url = "https://maven.offsetmonkey538.top/releases" - content { - includeGroup "top.offsetmonkey538.loottablemodifer" - } - } -} - -dependencies { - // ...rest of dependencies block - - implementation "top.offsetmonkey538.loottablemodifier:loot-table-modifier:VERSION_HERE" -} -``` -Make sure to replace `VERSION_HERE` with the actual version you want to use! -See my maven page [here](https://maven.offsetmonkey538.top/#/releases/top/offsetmonkey538/loottablemodifier/loot-table-modifier) for all available versions and their javadocs. - -Also add this to your `fabric.mod.json` file: -```json {" This matches the major version of 2":3-4} -{ - "depends": { - - "loot-table-modifier": ">=2.0.0 <3.0.0" - } -} -``` - -## Development Mode - -Development mode enables additional logging and the ability to export modified loot tables. - -Dev mode will automatically be enabled when Minecraft is launched from an IDE or can be enabled by setting the JVM property `lootTableModifierDev` to `true`. -That can be done with Prism Launcher by going to `Settings`, selecting `Java` and then adding `-DlootTableModifierDev=true` into `JVM arguments`. - -Mod developers who, for some weird reason, *don't* want their logs to be spammed with random unnecessary stuff can set the property to `false` to override the IDE check. - -Modified loot tables can then be exported using the command `/loot-table-modifier debug export`. - -## Next Up -Take a look at how loot modifiers work [here](/reference/loot_modifier) and then take a look at the examples. diff --git a/docs/src/content/docs/index.md b/docs/src/content/docs/index.md deleted file mode 100644 index 14473de..0000000 --- a/docs/src/content/docs/index.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -title: Loot Table Modifier -template: splash -hero: - tagline: Makes it possible for datapacks to modify loot tables, instead of just replacing them. - image: - file: ../../assets/icon.svg - actions: - - text: Get Started - link: /getting_started/ - icon: right-arrow - - text: View on Modrinth - link: https://modrinth.com/mod/loot-table-modifier - icon: external - variant: minimal - - text: Chat with me on Discord - link: https://discord.offsetmonkey538.top - icon: discord - variant: minimal ---- - -# About - -:::caution -This documentation is written for Loot Table Modifier v2 alpha 1. -Both the mod and this wiki are in development. -If you encounter any issues or have suggestions, please *please* **please** come join my [discord](https://discord.offsetmonkey538.top) and yell at me about them. -::: - - -Vanilla datapacks can only replace existing loot tables, which is not good for being compatible with other datapacks that may also try to replace the same loot tables. -This mod fixes that by implementing a system of *loot modifiers*, which do just that, modify loot (tables)! - -Loot modifiers are in datapacks, meaning mods and modpacks are able to use them too! - -Unlike some mods which replace stuff at runtime, Loot Table Modifier does all of its processing during data loading. This means that the mod will have no performance impact during gameplay! (Except of course if you make a zombie drop a bajillion stacks of diamonds, though that's not the mod's fault...) diff --git a/docs/src/content/docs/reference/actions.md b/docs/src/content/docs/reference/actions.md deleted file mode 100644 index d4a3826..0000000 --- a/docs/src/content/docs/reference/actions.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -title: Actions ---- - -:::note -Fields marked as `Optional` have their value set to the default ones. -::: - -Actions tell the mod how a matched loot table, pool or entry should be modified. - -Actions are json objects that consist of their identifier `type` and then any other fields specific to each action. -Below is a list of all currently supported actions: - -| | | -|-----------------------------------------------------------------|--------------------------------------------| -| [`loot-table-modifier:pool_add`](#add-pool) | Adds the provided pools to matched tables | -| [`loot-table-modifier:pool_remove`](#remove-pool) | Removes matched pools | -| [`loot-table-modifier:entry_add`](#add-entry) | Adds the provided entries to matched pools | -| [`loot-table-modifier:entry_remove`](#remove-entry) | Removes matched entries | -| [`loot-table-modifier:entry_item_set`](#set-item-in-item-entry) | Sets the item in matched item entries | - -### Add pool -```json -{ - "type": "loot-table-modifier:pool_add", - "pools": [ - { - /* Loot pool */ - }, - { - /* Loot pool */ - } - ] -} -``` -This action adds the provided loot pools to matched tables. - -See: [Make Creepers and Zombies drop tnt](/examples/creepers_and_zombies_drop_tnt) - -### Remove pool -```json -{ - "type": "loot-table-modifier:pool_remove" -} -``` -This action removes all matched pools. - -### Add entry -```json -{ - "type": "loot-table-modifier:entry_add", - "entries": [ - { - /* Loot entry */ - }, - { - /* Loot entry */ - } - ] -} -``` -This action adds the provided loot entries to matched pools. - -See: [Make Creepers and Zombies drop tnt](/examples/creepers_and_zombies_drop_tnt) - -### Remove entry -```json -{ - "type": "loot-table-modifier:entry_remove" -} -``` -This action removes all matched entries. - -See: [Remove sticks](/examples/remove_sticks), [Remove glowstone and gunpowder from witches](/examples/remove_glowstone_and_gunpowder_witches) - -### Set item in item entry -```json {" Optional":4-5} -{ - "type": "loot-table-modifier:entry_item_set", - "name": /* Identifier of an item */, - - "canReplaceEntry": false -} -``` -This action will replace the item in a matched item entry with the provided item. -If `canReplaceEntry` is enabled, any other matched entry will be replaced with an item entry containing the provided item. -By default, it will not replace other types of entries, but that can be enabled by setting `canReplaceEntry` to true. - -See: [Replace any Minecraft ingot with a diamond](/examples/replace_ingot_w_diamond) diff --git a/docs/src/content/docs/reference/badges.md b/docs/src/content/docs/reference/badges.md deleted file mode 100644 index 3c6ff4d..0000000 --- a/docs/src/content/docs/reference/badges.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: Badges ---- -Badges are meant for developers to put on their project pages, so users can see that Loot Table Modifier is used or required. -They're based on [Devin's Badges](https://github.com/intergrav/devins-badges). - -The `requires` badge is meant for datapacks or mods which want to display that Loot Table Modifier is required for them to function. -It can be used in Markdown like this: `[![This project requires Loot Table Modifier to be installed](https://raw.githubusercontent.com/OffsetMods538/Loot-Table-Modifier/master/images/requires_badge.svg)](https://modrinth.com/mod/loot-table-modifier)` -And will look like this: -[![This project requires Loot Table Modifier to be installed](https://raw.githubusercontent.com/OffsetMods538/Loot-Table-Modifier/master/images/requires_badge.svg)](https://modrinth.com/mod/loot-table-modifier) - -Clicking it will bring the user to the Modrinth page for Loot Table Modifier - -
- -The `uses` badge is meant for mods or modpacks which want to display that Loot Table Modifier is included. (Honestly not sure why I made this 'cause I can't imagine anyone would do that but uhh sure 😅) -It can be used in Markdown like this: `[![This project includes Loot Table Modifier](https://raw.githubusercontent.com/OffsetMods538/Loot-Table-Modifier/master/images/uses_badge.svg)](https://modrinth.com/mod/loot-table-modifier)` -And will look like this: -[![This project includes Loot Table Modifier](https://raw.githubusercontent.com/OffsetMods538/Loot-Table-Modifier/master/images/uses_badge.svg)](https://modrinth.com/mod/loot-table-modifier) - -Clicking it will bring the user to the Modrinth page for Loot Table Modifier diff --git a/docs/src/content/docs/reference/loot_modifier.md b/docs/src/content/docs/reference/loot_modifier.md deleted file mode 100644 index a8799ef..0000000 --- a/docs/src/content/docs/reference/loot_modifier.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: Loot Modifier ---- -The mod uses loot modifiers to figure out how and what it should modify. -Loot modifiers are JSON files located in datapacks at `data/namespace/loot-table-modifier/loot_modifier/modifier_name.json`. - -Loot modifiers consist of two parts: the [actions](/reference/actions) and a [predicate](/reference/predicates). - -During data loading, the mod looks through every existing loot table and its pools and entries. -For every entry, pool and table, it will try matching the predicates of loot modifiers. -When a loot modifier's predicate matches, its actions will be executed on the matched entry, pool or table. - -The mod counts less specific predicates as matching everything underneath. -This means that using the [`add_entry`](/reference/actions#add-entry) action with the [`table`](/reference/predicates#loot-table) predicate will add the entries to all pools in the matched table. -The same applies in reverse; a more specific predicate also counts as matching everything above it, meaning that using the [`add_pool`](/reference/actions#add-pool) action with the [`entry_item`](/reference/predicates#item-entry) predicate will add the pools to all tables that contain a matching item entry. - -## Generation -Loot modifiers can be generated using the misode generator available [here](https://misode-itd7xiyf1-misodes-projects.vercel.app/) under `Modded Generators` - -Mod developers can use the `LootModifierProvider` datagen provider. Javadoc can be seen in-IDE or [here](https://maven.offsetmonkey538.top/#/releases/top/offsetmonkey538/loottablemodifier/loot-table-modifier). diff --git a/docs/src/content/docs/reference/predicates.md b/docs/src/content/docs/reference/predicates.md deleted file mode 100644 index c2ab931..0000000 --- a/docs/src/content/docs/reference/predicates.md +++ /dev/null @@ -1,84 +0,0 @@ ---- -title: Predicates ---- - -:::note -Predicates may use this thing I call a `RegexIdentifier`, which you can read about [here](/reference/regex_identifier). -::: - -Predicates tell the mod which loot tables, pools or entries should be modified. -Different predicates can be combined using `invert`, `any_of` and `all_of`. - -Below is a list of all supported predicates: - -| | | -|-------------------------------------------------|---------------------------------------------------| -| [`loot-table-modifier:inverted`](#invert) | Inverts the result of the provided predicate | -| [`loot-table-modifier:any_of`](#any-of) | Matches when any of the provided predicates match | -| [`loot-table-modifier:all_of`](#all-of) | Matches when all of the provided predicates match | -| [`loot-table-modifier:entry_item`](#item-entry) | Matches an item entry based on its identifier | -| [`loot-table-modifier:table`](#loot-table) | Matches a table based on its identifier or type | - -### Invert -```json -{ - "type": "loot-table-modifier:inverted", - "term": { - /* Predicate */ - } -} -``` -This predicate will match when the provided predicate doesn't. A logical `NOT` operation. - -### Any of -```json -{ - "type": "loot-table-modifier:any_of", - "terms": [ - { - /* Predicate */ - }, - { - /* Predicate */ - } - ] -} -``` -This predicate will match when any of the provided predicates match. A logical `OR` operation. - -### All of -```json -{ - "type": "loot-table-modifier:all_of", - "terms": [ - { - /* Predicate */ - }, - { - /* Predicate */ - } - ] -} -``` -This predicate will match when all of the provided predicates match. A logical `AND` operation. - -### Item Entry -```json -{ - "type": "loot-table-modifier:entry_item", - "name": /* RegexIdentifier */ -} -``` -This predicate will match item entries based on their identifiers. - -### Loot Table -```json {" Optional":3-4} {" Optional":5-6} -{ - "type": "loot-table-modifier:table", - - "identifiers": /* RegexIdentifier */, - - "types": /* RegexIdentifier */ -} -``` -This predicate will match loot tables based on their identifiers or types. diff --git a/docs/src/content/docs/reference/regex_identifier.md b/docs/src/content/docs/reference/regex_identifier.md deleted file mode 100644 index 3aba7f8..0000000 --- a/docs/src/content/docs/reference/regex_identifier.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: Regex Identifier ---- - -Identifiers (officially resource locations) are used all over Minecraft for identifying stuff like items, blocks, entities, loot tables and so on. -They consist of a namespace and a path, separated by a colon. Full documentation on identifiers can be found [here](https://minecraft.wiki/w/Resource_location). - -Loot modifier predicates often use regex identifiers for matching these identifiers. -A regex identifier allows matching either a literal identifier or a regex pattern. - -Instead of matching an exact piece of text, regex allows describing a pattern to match many possible variations. -For that, regex uses *metacharacters*. The most useful combination of which for matching identifiers is `.*`, which matches any character from zero to infinite times. -This is very useful for loot modifier predicates because you can build patterns like `minecraft:.*_ingot` for matching any ingot from minecraft. - -Full documentation on supported regex syntax can be found [here](https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html), and you can use a site like [regex101](https://regex101.com/) to write and test you regular expressions (just make sure to choose the `Java 8` flavor) - -A `RegexIdentifier` in json can either be an inlined string or an object with the `regexPattern` field. -Examples: -```json {"Matches only the exact identifier of minecraft:diamond_sword":2-3} {"Matches all minecraft sword types (minecraft:stone_sword, minecraft:iron_sword, etc)":5-8} {"Matches anything from minecraft":10-13} {"Matches any minecraft oak block/item, except for the stripped variants":15-18} -{ - - "value1": "minecraft:diamond_sword", - - - "value2": { - "regexPattern": "minecraft:.*_sword" - }, - - - "value3": { - "regexPattern": "minecraft:.*" - }, - - - "value4": { - "regexPattern": "minecraft:oak_.*" - } -} -``` diff --git a/docs/src/styles/custom.css b/docs/src/styles/custom.css deleted file mode 100644 index 7cec2c0..0000000 --- a/docs/src/styles/custom.css +++ /dev/null @@ -1,37 +0,0 @@ -/* Dark mode colors. */ -:root { - --sl-color-accent-low: #420d1f; - --sl-color-accent: #c1005c; - --sl-color-accent-high: #f7b3c2; - --sl-color-white: #ffffff; - --sl-color-gray-1: #eceef2; - --sl-color-gray-2: #c6c8ce; - --sl-color-gray-3: #a0a4ae; - --sl-color-gray-4: #545861; - --sl-color-gray-5: #353841; - --sl-color-gray-6: #24272f; - --sl-color-black: #17181c; -} -/* Light mode colors. */ -:root[data-theme='light'] { - --sl-color-accent-low: #fbc7d2; - --sl-color-accent: #a2004c; - --sl-color-accent-high: #60052b; - --sl-color-white: #17181c; - --sl-color-gray-1: #24272f; - --sl-color-gray-2: #353841; - --sl-color-gray-3: #545861; - --sl-color-gray-4: #888b96; - --sl-color-gray-5: #c0c2c7; - --sl-color-gray-6: #eceef2; - --sl-color-gray-7: #f5f6f8; - --sl-color-black: #ffffff; -} - -.site-title > img { - border: 1px solid #420d1f; -} - -.site-title > span { - color: #FFFFFF; -} diff --git a/docs/src/utils/PageFrame.astro b/docs/src/utils/PageFrame.astro deleted file mode 100644 index 7f7ab1d..0000000 --- a/docs/src/utils/PageFrame.astro +++ /dev/null @@ -1,98 +0,0 @@ ---- -import MobileMenuToggle from 'virtual:starlight/components/MobileMenuToggle'; - -const { hasSidebar } = Astro.locals.starlightRoute; ---- - -
-
- { - hasSidebar && ( - - ) - } -
-
- - \ No newline at end of file diff --git a/docs/src/utils/SocialIcons.astro b/docs/src/utils/SocialIcons.astro deleted file mode 100644 index b073bdc..0000000 --- a/docs/src/utils/SocialIcons.astro +++ /dev/null @@ -1,57 +0,0 @@ ---- -import config from "virtual:starlight/user-config"; -// @ts-expect-error - This is a custom Virtual Module -import augment from "virtual:starlight-social-icon-augment"; -import { Icon } from "@astrojs/starlight/components"; -import type { ComponentProps } from "astro/types"; - -type IconProps = ComponentProps; - -const customIcons = { - modrinth: - '', -} as const; - -const combinedLinks: { - main: { label: string; href: string; icon: IconProps["name"] }[]; - custom: { label: string; href: string; icon: keyof typeof customIcons }[]; -} = { main: config.social || [], custom: augment || [] }; ---- - -{ - combinedLinks.main.length > 0 && ( - <> - {combinedLinks.main.map(({ label, href, icon }) => ( - - {label} - - - ))} - - ) -} -{ - combinedLinks.custom.length > 0 && ( - <> - {combinedLinks.custom.map(({ label, href, icon }) => ( - - {label} - - - ))} - - ) -} - - diff --git a/docs/src/utils/socialIcons.ts b/docs/src/utils/socialIcons.ts deleted file mode 100644 index 6bef9aa..0000000 --- a/docs/src/utils/socialIcons.ts +++ /dev/null @@ -1,39 +0,0 @@ -import type { AstroIntegration } from 'astro'; - -export function starlightSocialIcons(socials: { - modrinth: string; -}): AstroIntegration { - const labelMap = { - modrinth: 'Modrinth' - } - - return { - name: 'starlight-social-icon-augment', - hooks: { - 'astro:config:setup': ({ updateConfig }) => { - updateConfig({ - vite: { - plugins: [ - { - name: 'virtual-config-plugin', - resolveId(id) { - if (id === 'virtual:starlight-social-icon-augment') { - return '\0virtual:starlight-social-icon-augment'; // Prefix with \0 to mark as virtual - } - }, - load(id) { - if (id === '\0virtual:starlight-social-icon-augment') { - const config = socials; - return `export default ${JSON.stringify(Object.entries(config).flatMap(([key , value]) => ({ label: labelMap[key as keyof typeof labelMap], href: value, icon: key })))};`; - } - }, - } - ] - } - }) - }, - }, - }; -} - -export default starlightSocialIcons; \ No newline at end of file diff --git a/docs/tsconfig.json b/docs/tsconfig.json deleted file mode 100644 index 8bf91d3..0000000 --- a/docs/tsconfig.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "extends": "astro/tsconfigs/strict", - "include": [".astro/types.d.ts", "**/*"], - "exclude": ["dist"] -} diff --git a/gradle.properties b/gradle.properties index 67f3c54..edcac28 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,21 +1,20 @@ # Increase memory and *parallel* -org.gradle.jvmargs = -Xmx6G +org.gradle.jvmargs = -Xmx8G org.gradle.parallel = true -# Fabric -# Check at https://fabricmc.net/develop -minecraft_version = 1.21.8 - -# These should be automatically updated, unless the environment -# variable "DISABLE_PROPERTIES_UPDATE" is set. -fapi_version = 0.136.0+1.21.8 -yarn_version = 1.21.8+build.1 -loader_version = 0.18.0 - # Dependencies +# MonkeyLib538, check at https://github.com/OffsetMods538/MonkeyLib538 +monkeylib538_version = 3.0.0-beta.1 +## DataFixerUpper, check at https://github.com/Mojang/DataFixerUpper +datafixerupper_version = 8.0.16 +## Brigadier, check at https://github.com/Mojang/Brigadier +brigadier_version = 1.3.10 +## Apache Commons IO, check at I have no clue +commonsio_version = 2.17.0 +## JetBrains Annotations, check at https://github.com/JetBrains/java-annotations +jetbrainsannotations_version = 26.0.2 ## DevAuth, check at https://github.com/DJtheRedstoner/DevAuth devauth_version = 1.2.1 # Mod Properties -mod_version = 2.0.0-alpha.2 -supported_minecraft_versions = >=1.21.5 <=1.21.8 +mod_version = 2.0.0-beta.3 diff --git a/loader/fabric/1.20.1/gradle.properties b/loader/fabric/1.20.1/gradle.properties new file mode 100644 index 0000000..1bc38d7 --- /dev/null +++ b/loader/fabric/1.20.1/gradle.properties @@ -0,0 +1,14 @@ +project_name = fabric-1.20.1 +commonModdedVersion = 1.20.1 +fabricDatagenEntrypoint = top.offsetmonkey538.loottablemodifier.fabric.v1201.datagen.LootTableModifierDatagen + +monkeylib538_suffix = 1.20.1 + +# Miminum Minecraft version supported, check at https://fabricmc.net/develop +minecraft_version = 1.20.1 +supported_minecraft_versions = 1.20.1 + +# These should be automatically updated, unless the environment +# variable "DISABLE_PROPERTIES_UPDATE" is set. +loader_version = 0.18.4 +fapi_version = 0.92.6+1.20.1 diff --git a/loader/fabric/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/fabric/v1201/datagen/LootTableModifierDatagen.java b/loader/fabric/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/fabric/v1201/datagen/LootTableModifierDatagen.java new file mode 100644 index 0000000..3e7bf1c --- /dev/null +++ b/loader/fabric/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/fabric/v1201/datagen/LootTableModifierDatagen.java @@ -0,0 +1,179 @@ +package top.offsetmonkey538.loottablemodifier.fabric.v1201.datagen; + +import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint; +import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator; + +/** + * Datagen for loot modifiers used for testing. + */ +public class LootTableModifierDatagen implements DataGeneratorEntrypoint { + + @Override + public void onInitializeDataGenerator(FabricDataGenerator fabricDataGenerator) { + //final FabricDataGenerator.Pack pack = fabricDataGenerator.createBuiltinResourcePack(id("example_pack")); + + //pack.addProvider(ModLootModifierProvider::new); + //pack.addProvider(LootProvider::new); + } +/* + private static class ModLootModifierProvider extends LootModifierProvider { + public ModLootModifierProvider(FabricDataOutput dataOutput, CompletableFuture registriesFuture) { + super(dataOutput, registriesFuture); + } + + @Override + protected void generate(HolderLookup.Provider lookup) { + addModifier( + id("replace_ingots_with_command_block"), + LootModifier.builder() + .conditionally( + EntryItemPredicate.builder(RegexPattern.compile("minecraft:.*_ingot")) + ) + .action( + EntryItemSetAction.builder(new ItemWrapper(BuiltInRegistries.ITEM.wrapAsHolder(Items.COMMAND_BLOCK))) + ) + ); + addModifier( + id("sugarcane_drop_tnt"), + LootModifier.builder() + .conditionally( + EntryItemPredicate.builder(new ItemWrapper(BuiltInRegistries.ITEM.wrapAsHolder(Items.SUGAR_CANE))) + ) + .action( + PoolAddAction.builder() + .pool( + new LootPoolWrapper(LootPool.lootPool() + .setRolls(ConstantValue.exactly(1)) + .add( + LootItem.lootTableItem(Items.TNT) + .apply(SetItemCountFunction.setCount(UniformGenerator.between(1, 1))) + ).build()) + ) + ) + ); + addModifier( + id("mobs_drop_tnt"), + LootModifier.builder() + .conditionally( + TablePredicate.builder() + .name(EntityType.CREEPER.getDefaultLootTable().location().toString()) // TODO: absraction for LootTableIdGetter in modded + .name(EntityType.ZOMBIE.getDefaultLootTable().location().toString()) + ) + .action( + PoolAddAction.builder() + .pool( + new LootPoolWrapper(LootPool.lootPool() + .setRolls(ConstantValue.exactly(1)) + .add( + LootItem.lootTableItem(Items.TNT) + .apply(SetItemCountFunction.setCount(UniformGenerator.between(1, 1))) + ).build()) + ) + ) + ); + addModifier( + id("empty_table_test"), + LootModifier.builder() + .conditionally( + TablePredicate.builder() + .name(ResourceKey.create(Registries.LOOT_TABLE, id("test_empty_table")).location().toString()) + ) + .action( + PoolAddAction.builder() + .pool( + new LootPoolWrapper(LootPool.lootPool() + .setRolls(ConstantValue.exactly(1)) + .add( + LootItem.lootTableItem(Items.TNT) + .apply(SetItemCountFunction.setCount(UniformGenerator.between(1, 1))) + ).build()) + ) + ) + ); + addModifier( + id("remove_pools_with_sticks"), + LootModifier.builder() + .conditionally( + EntryItemPredicate.builder(new ItemWrapper(BuiltInRegistries.ITEM.wrapAsHolder(Items.STICK))) + // Exclude witch to test if AllOf and Inverted work + so I can test RemoveEntry on witch. + .and(TablePredicate.builder().name(EntityType.WITCH.getDefaultLootTable().location().toString()).invert()) + ) + .action( + PoolRemoveAction.builder() + ) + ); + addModifier( + id("add_cake_entry_to_dirt_block"), + LootModifier.builder() + .conditionally( + TablePredicate.builder() + .name(Blocks.DIRT.getLootTable().location().toString()) + ) + .action( + EntryAddAction.builder() + .entry( + LootPoolEntryWrapper.create(LootItem.lootTableItem(Items.CAKE) + .apply(SetItemCountFunction.setCount(UniformGenerator.between(1, 1))).build()) + ) + ) + ); + addModifier( + id("add_command_block_to_all_blocks"), + LootModifier.builder() + .conditionally( + TablePredicate.builder() + .type(LootContextTypesAccessor.getMAP().inverse().get(LootContextParamSets.BLOCK).toString()) + ) + .action( + EntryAddAction.builder() + .entry( + LootPoolEntryWrapper.create(LootItem.lootTableItem(Items.CAKE) + .apply(SetItemCountFunction.setCount(UniformGenerator.between(1, 1))).build()) + ) + ) + ); + addModifier( + id("remove_glowstone_and_gunpowder_from_witch"), + LootModifier.builder() + .conditionally( + TablePredicate.builder().name(EntityType.WITCH.getDefaultLootTable().location().toString()) + .and( + EntryItemPredicate.builder(new ItemWrapper(BuiltInRegistries.ITEM.wrapAsHolder(Items.GLOWSTONE_DUST))) + .or(EntryItemPredicate.builder(new ItemWrapper(BuiltInRegistries.ITEM.wrapAsHolder(Items.GUNPOWDER)))) + ) + ) + .action( + EntryRemoveAction.builder() + ) + ); + addModifier( + id("squid_ink_sac_only_from_player"), + LootModifier.builder() + .conditionally( + TablePredicate.builder() + .name(EntityType.SQUID.getDefaultLootTable().location().toString()) + .and(EntryItemPredicate.builder(new ItemWrapper(BuiltInRegistries.ITEM.wrapAsHolder(Items.INK_SAC)))) + ) + .action( + ConditionAddAction.builder() + .onlyPools() + .condition( + new LootConditionWrapper(LootItemKilledByPlayerCondition.killedByPlayer().build()) + ) + ) + ); + } + } + + private static class LootProvider extends SimpleFabricLootTableProvider { + public LootProvider(FabricDataOutput output, CompletableFuture registryLookup) { + super(output, registryLookup, LootContextParamSets.CHEST); + } + + @Override + public void generate(HolderLookup.Provider registryLookup, BiConsumer, LootTable.Builder> consumer) { + consumer.accept(ResourceKey.create(Registries.LOOT_TABLE, id("test_empty_table")), LootTable.lootTable()); + } + } + */ +} diff --git a/loader/fabric/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/fabric/v1201/mixin/LootDataManagerMixin.java b/loader/fabric/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/fabric/v1201/mixin/LootDataManagerMixin.java new file mode 100644 index 0000000..a66decc --- /dev/null +++ b/loader/fabric/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/fabric/v1201/mixin/LootDataManagerMixin.java @@ -0,0 +1,48 @@ +package top.offsetmonkey538.loottablemodifier.fabric.v1201.mixin; + +import com.mojang.serialization.JsonOps; +import it.unimi.dsi.fastutil.Pair; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.packs.resources.ResourceManager; +import net.minecraft.world.level.storage.loot.LootDataManager; +import net.minecraft.world.level.storage.loot.LootDataType; +import net.minecraft.world.level.storage.loot.LootTable; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import top.offsetmonkey538.loottablemodifier.common.LootTableModifierCommon; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.IdentifierWrapper; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.ResourceManagerWrapper; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootTableWrapper; + +import java.util.Map; + +@Mixin( + value = LootDataManager.class, + priority = 900 +) +public abstract class LootDataManagerMixin { + @Inject( + // Works for fabric >=1.20.1 <=1.20.4 + method = "method_51189(Lnet/minecraft/server/packs/resources/ResourceManager;Lnet/minecraft/world/level/storage/loot/LootDataType;Ljava/util/Map;)V", + at = @At("RETURN") + ) + private static void loot_table_modifier$modifyLootTables(ResourceManager resourceManager, LootDataType lootDataType, Map map, CallbackInfo ci) { + if (lootDataType != LootDataType.TABLE) return; + + //noinspection unchecked + final Map lootRegistry = (Map) map; + + LootTableModifierCommon.runModification( + new ResourceManagerWrapper(resourceManager), + lootRegistry.entrySet() + .stream() + .map(entry -> Pair.of( + new IdentifierWrapper(entry.getKey()), + new LootTableWrapper(entry.getValue()) + )), + JsonOps.INSTANCE // TODO: Is a RegistryOps not needed on 1.20.1? Doesn't look like the loot table loader uses it so maybe not? + ); + } +} diff --git a/loader/fabric/1.20.1/src/main/resources/loot-table-modifier.version.loader.mixins.json b/loader/fabric/1.20.1/src/main/resources/loot-table-modifier.version.loader.mixins.json new file mode 100644 index 0000000..1cea96c --- /dev/null +++ b/loader/fabric/1.20.1/src/main/resources/loot-table-modifier.version.loader.mixins.json @@ -0,0 +1,11 @@ +{ + "required": true, + "package": "top.offsetmonkey538.loottablemodifier.fabric.v1201.mixin", + "compatibilityLevel": "JAVA_21", + "mixins": [ + "LootDataManagerMixin" + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/loader/fabric/1.20.2/gradle.properties b/loader/fabric/1.20.2/gradle.properties new file mode 100644 index 0000000..832e969 --- /dev/null +++ b/loader/fabric/1.20.2/gradle.properties @@ -0,0 +1,14 @@ +project_name = fabric-1.20.2 +commonModdedVersion = 1.20.2 +fabricDatagenEntrypoint = top.offsetmonkey538.loottablemodifier.fabric.v1202.datagen.LootTableModifierDatagen + +monkeylib538_suffix = 1.20.1 + +# Miminum Minecraft version supported, check at https://fabricmc.net/develop +minecraft_version = 1.20.2 +supported_minecraft_versions = >=1.20.2 <=1.20.4 + +# These should be automatically updated, unless the environment +# variable "DISABLE_PROPERTIES_UPDATE" is set. +loader_version = 0.18.4 +fapi_version = 0.91.6+1.20.2 diff --git a/src/main/java/top/offsetmonkey538/loottablemodifier/datagen/LootTableModifierDatagen.java b/loader/fabric/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/fabric/v1202/datagen/LootTableModifierDatagen.java similarity index 55% rename from src/main/java/top/offsetmonkey538/loottablemodifier/datagen/LootTableModifierDatagen.java rename to loader/fabric/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/fabric/v1202/datagen/LootTableModifierDatagen.java index 426b7e8..968f9f0 100644 --- a/src/main/java/top/offsetmonkey538/loottablemodifier/datagen/LootTableModifierDatagen.java +++ b/loader/fabric/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/fabric/v1202/datagen/LootTableModifierDatagen.java @@ -1,39 +1,7 @@ -package top.offsetmonkey538.loottablemodifier.datagen; +package top.offsetmonkey538.loottablemodifier.fabric.v1202.datagen; import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint; import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator; -import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; -import net.fabricmc.fabric.api.datagen.v1.provider.SimpleFabricLootTableProvider; -import net.minecraft.block.Blocks; -import net.minecraft.entity.EntityType; -import net.minecraft.item.Items; -import net.minecraft.loot.LootPool; -import net.minecraft.loot.LootTable; -import net.minecraft.loot.condition.KilledByPlayerLootCondition; -import net.minecraft.loot.context.LootContextTypes; -import net.minecraft.loot.entry.ItemEntry; -import net.minecraft.loot.function.SetCountLootFunction; -import net.minecraft.loot.provider.number.ConstantLootNumberProvider; -import net.minecraft.loot.provider.number.UniformLootNumberProvider; -import net.minecraft.registry.RegistryKey; -import net.minecraft.registry.RegistryKeys; -import net.minecraft.registry.RegistryWrapper; -import top.offsetmonkey538.loottablemodifier.api.datagen.LootModifierProvider; -import top.offsetmonkey538.loottablemodifier.api.resource.LootModifier; -import top.offsetmonkey538.loottablemodifier.api.resource.action.condition.ConditionAddAction; -import top.offsetmonkey538.loottablemodifier.api.resource.action.entry.EntryAddAction; -import top.offsetmonkey538.loottablemodifier.api.resource.action.entry.EntryRemoveAction; -import top.offsetmonkey538.loottablemodifier.api.resource.predicate.table.TablePredicate; -import top.offsetmonkey538.loottablemodifier.api.resource.util.RegexPattern; -import top.offsetmonkey538.loottablemodifier.api.resource.action.pool.PoolAddAction; -import top.offsetmonkey538.loottablemodifier.api.resource.action.entry.EntryItemSetAction; -import top.offsetmonkey538.loottablemodifier.api.resource.action.pool.PoolRemoveAction; -import top.offsetmonkey538.loottablemodifier.api.resource.predicate.entry.EntryItemPredicate; - -import java.util.concurrent.CompletableFuture; -import java.util.function.BiConsumer; - -import static top.offsetmonkey538.loottablemodifier.LootTableModifier.id; /** * Datagen for loot modifiers used for testing. @@ -42,19 +10,19 @@ public class LootTableModifierDatagen implements DataGeneratorEntrypoint { @Override public void onInitializeDataGenerator(FabricDataGenerator fabricDataGenerator) { - final FabricDataGenerator.Pack pack = fabricDataGenerator.createBuiltinResourcePack(id("example_pack")); + //final FabricDataGenerator.Pack pack = fabricDataGenerator.createBuiltinResourcePack(id("example_pack")); - pack.addProvider(ModLootModifierProvider::new); - pack.addProvider(LootProvider::new); + //pack.addProvider(ModLootModifierProvider::new); + //pack.addProvider(LootProvider::new); } - +/* private static class ModLootModifierProvider extends LootModifierProvider { - public ModLootModifierProvider(FabricDataOutput dataOutput, CompletableFuture registriesFuture) { + public ModLootModifierProvider(FabricDataOutput dataOutput, CompletableFuture registriesFuture) { super(dataOutput, registriesFuture); } @Override - protected void generate(RegistryWrapper.WrapperLookup lookup) { + protected void generate(HolderLookup.Provider lookup) { addModifier( id("replace_ingots_with_command_block"), LootModifier.builder() @@ -62,24 +30,24 @@ protected void generate(RegistryWrapper.WrapperLookup lookup) { EntryItemPredicate.builder(RegexPattern.compile("minecraft:.*_ingot")) ) .action( - EntryItemSetAction.builder(Items.COMMAND_BLOCK) + EntryItemSetAction.builder(new ItemWrapper(BuiltInRegistries.ITEM.wrapAsHolder(Items.COMMAND_BLOCK))) ) ); addModifier( id("sugarcane_drop_tnt"), LootModifier.builder() .conditionally( - EntryItemPredicate.builder(Items.SUGAR_CANE) + EntryItemPredicate.builder(new ItemWrapper(BuiltInRegistries.ITEM.wrapAsHolder(Items.SUGAR_CANE))) ) .action( PoolAddAction.builder() .pool( - LootPool.builder() - .rolls(ConstantLootNumberProvider.create(1)) - .with( - ItemEntry.builder(Items.TNT) - .apply(SetCountLootFunction.builder(UniformLootNumberProvider.create(1, 1))) - ) + new LootPoolWrapper(LootPool.lootPool() + .setRolls(ConstantValue.exactly(1)) + .add( + LootItem.lootTableItem(Items.TNT) + .apply(SetItemCountFunction.setCount(UniformGenerator.between(1, 1))) + ).build()) ) ) ); @@ -88,18 +56,18 @@ protected void generate(RegistryWrapper.WrapperLookup lookup) { LootModifier.builder() .conditionally( TablePredicate.builder() - .name(EntityType.CREEPER) - .name(EntityType.ZOMBIE) + .name(EntityType.CREEPER.getDefaultLootTable().location().toString()) // TODO: absraction for LootTableIdGetter in modded + .name(EntityType.ZOMBIE.getDefaultLootTable().location().toString()) ) .action( PoolAddAction.builder() .pool( - LootPool.builder() - .rolls(ConstantLootNumberProvider.create(1)) - .with( - ItemEntry.builder(Items.TNT) - .apply(SetCountLootFunction.builder(UniformLootNumberProvider.create(1, 1))) - ) + new LootPoolWrapper(LootPool.lootPool() + .setRolls(ConstantValue.exactly(1)) + .add( + LootItem.lootTableItem(Items.TNT) + .apply(SetItemCountFunction.setCount(UniformGenerator.between(1, 1))) + ).build()) ) ) ); @@ -108,17 +76,17 @@ protected void generate(RegistryWrapper.WrapperLookup lookup) { LootModifier.builder() .conditionally( TablePredicate.builder() - .name(RegistryKey.of(RegistryKeys.LOOT_TABLE, id("test_empty_table"))) + .name(ResourceKey.create(Registries.LOOT_TABLE, id("test_empty_table")).location().toString()) ) .action( PoolAddAction.builder() .pool( - LootPool.builder() - .rolls(ConstantLootNumberProvider.create(1)) - .with( - ItemEntry.builder(Items.TNT) - .apply(SetCountLootFunction.builder(UniformLootNumberProvider.create(1, 1))) - ) + new LootPoolWrapper(LootPool.lootPool() + .setRolls(ConstantValue.exactly(1)) + .add( + LootItem.lootTableItem(Items.TNT) + .apply(SetItemCountFunction.setCount(UniformGenerator.between(1, 1))) + ).build()) ) ) ); @@ -126,9 +94,9 @@ protected void generate(RegistryWrapper.WrapperLookup lookup) { id("remove_pools_with_sticks"), LootModifier.builder() .conditionally( - EntryItemPredicate.builder(Items.STICK) + EntryItemPredicate.builder(new ItemWrapper(BuiltInRegistries.ITEM.wrapAsHolder(Items.STICK))) // Exclude witch to test if AllOf and Inverted work + so I can test RemoveEntry on witch. - .and(TablePredicate.builder().name(EntityType.WITCH).invert()) + .and(TablePredicate.builder().name(EntityType.WITCH.getDefaultLootTable().location().toString()).invert()) ) .action( PoolRemoveAction.builder() @@ -139,13 +107,13 @@ protected void generate(RegistryWrapper.WrapperLookup lookup) { LootModifier.builder() .conditionally( TablePredicate.builder() - .name(Blocks.DIRT) + .name(Blocks.DIRT.getLootTable().location().toString()) ) .action( EntryAddAction.builder() .entry( - ItemEntry.builder(Items.CAKE) - .apply(SetCountLootFunction.builder(UniformLootNumberProvider.create(1, 1))) + LootPoolEntryWrapper.create(LootItem.lootTableItem(Items.CAKE) + .apply(SetItemCountFunction.setCount(UniformGenerator.between(1, 1))).build()) ) ) ); @@ -154,13 +122,13 @@ protected void generate(RegistryWrapper.WrapperLookup lookup) { LootModifier.builder() .conditionally( TablePredicate.builder() - .type(LootContextTypes.BLOCK) + .type(LootContextTypesAccessor.getMAP().inverse().get(LootContextParamSets.BLOCK).toString()) ) .action( EntryAddAction.builder() .entry( - ItemEntry.builder(Items.CAKE) - .apply(SetCountLootFunction.builder(UniformLootNumberProvider.create(1, 1))) + LootPoolEntryWrapper.create(LootItem.lootTableItem(Items.CAKE) + .apply(SetItemCountFunction.setCount(UniformGenerator.between(1, 1))).build()) ) ) ); @@ -168,10 +136,10 @@ protected void generate(RegistryWrapper.WrapperLookup lookup) { id("remove_glowstone_and_gunpowder_from_witch"), LootModifier.builder() .conditionally( - TablePredicate.builder().name(EntityType.WITCH) + TablePredicate.builder().name(EntityType.WITCH.getDefaultLootTable().location().toString()) .and( - EntryItemPredicate.builder(Items.GLOWSTONE_DUST) - .or(EntryItemPredicate.builder(Items.GUNPOWDER)) + EntryItemPredicate.builder(new ItemWrapper(BuiltInRegistries.ITEM.wrapAsHolder(Items.GLOWSTONE_DUST))) + .or(EntryItemPredicate.builder(new ItemWrapper(BuiltInRegistries.ITEM.wrapAsHolder(Items.GUNPOWDER)))) ) ) .action( @@ -183,14 +151,14 @@ protected void generate(RegistryWrapper.WrapperLookup lookup) { LootModifier.builder() .conditionally( TablePredicate.builder() - .name(EntityType.SQUID) - .and(EntryItemPredicate.builder(Items.INK_SAC)) + .name(EntityType.SQUID.getDefaultLootTable().location().toString()) + .and(EntryItemPredicate.builder(new ItemWrapper(BuiltInRegistries.ITEM.wrapAsHolder(Items.INK_SAC)))) ) .action( ConditionAddAction.builder() .onlyPools() .condition( - KilledByPlayerLootCondition.builder() + new LootConditionWrapper(LootItemKilledByPlayerCondition.killedByPlayer().build()) ) ) ); @@ -198,13 +166,14 @@ protected void generate(RegistryWrapper.WrapperLookup lookup) { } private static class LootProvider extends SimpleFabricLootTableProvider { - public LootProvider(FabricDataOutput output, CompletableFuture registryLookup) { - super(output, registryLookup, LootContextTypes.CHEST); + public LootProvider(FabricDataOutput output, CompletableFuture registryLookup) { + super(output, registryLookup, LootContextParamSets.CHEST); } @Override - public void accept(BiConsumer, LootTable.Builder> lootTableBiConsumer) { - lootTableBiConsumer.accept(RegistryKey.of(RegistryKeys.LOOT_TABLE, id("test_empty_table")), LootTable.builder()); + public void generate(HolderLookup.Provider registryLookup, BiConsumer, LootTable.Builder> consumer) { + consumer.accept(ResourceKey.create(Registries.LOOT_TABLE, id("test_empty_table")), LootTable.lootTable()); } } + */ } diff --git a/loader/fabric/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/fabric/v1202/mixin/LootDataManagerMixin.java b/loader/fabric/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/fabric/v1202/mixin/LootDataManagerMixin.java new file mode 100644 index 0000000..c49df64 --- /dev/null +++ b/loader/fabric/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/fabric/v1202/mixin/LootDataManagerMixin.java @@ -0,0 +1,48 @@ +package top.offsetmonkey538.loottablemodifier.fabric.v1202.mixin; + +import com.mojang.serialization.JsonOps; +import it.unimi.dsi.fastutil.Pair; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.packs.resources.ResourceManager; +import net.minecraft.world.level.storage.loot.LootDataManager; +import net.minecraft.world.level.storage.loot.LootDataType; +import net.minecraft.world.level.storage.loot.LootTable; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import top.offsetmonkey538.loottablemodifier.common.LootTableModifierCommon; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.IdentifierWrapper; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.ResourceManagerWrapper; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootTableWrapper; + +import java.util.Map; + +@Mixin( + value = LootDataManager.class, + priority = 900 +) +public abstract class LootDataManagerMixin { + @Inject( + // Works for fabric >=1.20.1 <=1.20.4 + method = "method_51189(Lnet/minecraft/server/packs/resources/ResourceManager;Lnet/minecraft/world/level/storage/loot/LootDataType;Ljava/util/Map;)V", + at = @At("RETURN") + ) + private static void loot_table_modifier$modifyLootTables(ResourceManager resourceManager, LootDataType lootDataType, Map map, CallbackInfo ci) { + if (lootDataType != LootDataType.TABLE) return; + + //noinspection unchecked + final Map lootRegistry = (Map) map; + + LootTableModifierCommon.runModification( + new ResourceManagerWrapper(resourceManager), + lootRegistry.entrySet() + .stream() + .map(entry -> Pair.of( + new IdentifierWrapper(entry.getKey()), + new LootTableWrapper(entry.getValue()) + )), + JsonOps.INSTANCE // TODO: Is a RegistryOps not needed on 1.20.1? Doesn't look like the loot table loader uses it so maybe not? + ); + } +} diff --git a/loader/fabric/1.20.2/src/main/resources/loot-table-modifier.version.loader.mixins.json b/loader/fabric/1.20.2/src/main/resources/loot-table-modifier.version.loader.mixins.json new file mode 100644 index 0000000..c5dcf60 --- /dev/null +++ b/loader/fabric/1.20.2/src/main/resources/loot-table-modifier.version.loader.mixins.json @@ -0,0 +1,11 @@ +{ + "required": true, + "package": "top.offsetmonkey538.loottablemodifier.fabric.v1202.mixin", + "compatibilityLevel": "JAVA_21", + "mixins": [ + "LootDataManagerMixin" + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/loader/fabric/1.20.5/gradle.properties b/loader/fabric/1.20.5/gradle.properties new file mode 100644 index 0000000..36df605 --- /dev/null +++ b/loader/fabric/1.20.5/gradle.properties @@ -0,0 +1,14 @@ +project_name = fabric-1.20.5 +commonModdedVersion = 1.20.5 +fabricDatagenEntrypoint = top.offsetmonkey538.loottablemodifier.fabric.v1205.datagen.LootTableModifierDatagen + +monkeylib538_suffix = 1.20.1 + +# Miminum Minecraft version supported, check at https://fabricmc.net/develop +minecraft_version = 1.20.5 +supported_minecraft_versions = >=1.20.5 <=1.20.6 + +# These should be automatically updated, unless the environment +# variable "DISABLE_PROPERTIES_UPDATE" is set. +loader_version = 0.18.4 +fapi_version = 0.97.8+1.20.5 diff --git a/loader/fabric/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/fabric/v1205/datagen/LootTableModifierDatagen.java b/loader/fabric/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/fabric/v1205/datagen/LootTableModifierDatagen.java new file mode 100644 index 0000000..c9c3d9e --- /dev/null +++ b/loader/fabric/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/fabric/v1205/datagen/LootTableModifierDatagen.java @@ -0,0 +1,180 @@ +package top.offsetmonkey538.loottablemodifier.fabric.v1205.datagen; + +import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint; +import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator; + +/** + * Datagen for loot modifiers used for testing. + */ +public class LootTableModifierDatagen implements DataGeneratorEntrypoint { + + @Override + public void onInitializeDataGenerator(FabricDataGenerator fabricDataGenerator) { + //final FabricDataGenerator.Pack pack = fabricDataGenerator.createBuiltinResourcePack(id("example_pack")); + + //pack.addProvider(ModLootModifierProvider::new); + //pack.addProvider(LootProvider::new); + } + + /* + private static class ModLootModifierProvider extends LootModifierProvider { + public ModLootModifierProvider(FabricDataOutput dataOutput, CompletableFuture registriesFuture) { + super(dataOutput, registriesFuture); + } + + @Override + protected void generate(HolderLookup.Provider lookup) { + addModifier( + id("replace_ingots_with_command_block"), + LootModifier.builder() + .conditionally( + EntryItemPredicate.builder(RegexPattern.compile("minecraft:.*_ingot")) + ) + .action( + EntryItemSetAction.builder(new ItemWrapper(BuiltInRegistries.ITEM.wrapAsHolder(Items.COMMAND_BLOCK))) + ) + ); + addModifier( + id("sugarcane_drop_tnt"), + LootModifier.builder() + .conditionally( + EntryItemPredicate.builder(new ItemWrapper(BuiltInRegistries.ITEM.wrapAsHolder(Items.SUGAR_CANE))) + ) + .action( + PoolAddAction.builder() + .pool( + new LootPoolWrapper(LootPool.lootPool() + .setRolls(ConstantValue.exactly(1)) + .add( + LootItem.lootTableItem(Items.TNT) + .apply(SetItemCountFunction.setCount(UniformGenerator.between(1, 1))) + ).build()) + ) + ) + ); + addModifier( + id("mobs_drop_tnt"), + LootModifier.builder() + .conditionally( + TablePredicate.builder() + .name(EntityType.CREEPER.getDefaultLootTable().location().toString()) // TODO: absraction for LootTableIdGetter in modded + .name(EntityType.ZOMBIE.getDefaultLootTable().location().toString()) + ) + .action( + PoolAddAction.builder() + .pool( + new LootPoolWrapper(LootPool.lootPool() + .setRolls(ConstantValue.exactly(1)) + .add( + LootItem.lootTableItem(Items.TNT) + .apply(SetItemCountFunction.setCount(UniformGenerator.between(1, 1))) + ).build()) + ) + ) + ); + addModifier( + id("empty_table_test"), + LootModifier.builder() + .conditionally( + TablePredicate.builder() + .name(ResourceKey.create(Registries.LOOT_TABLE, id("test_empty_table")).location().toString()) + ) + .action( + PoolAddAction.builder() + .pool( + new LootPoolWrapper(LootPool.lootPool() + .setRolls(ConstantValue.exactly(1)) + .add( + LootItem.lootTableItem(Items.TNT) + .apply(SetItemCountFunction.setCount(UniformGenerator.between(1, 1))) + ).build()) + ) + ) + ); + addModifier( + id("remove_pools_with_sticks"), + LootModifier.builder() + .conditionally( + EntryItemPredicate.builder(new ItemWrapper(BuiltInRegistries.ITEM.wrapAsHolder(Items.STICK))) + // Exclude witch to test if AllOf and Inverted work + so I can test RemoveEntry on witch. + .and(TablePredicate.builder().name(EntityType.WITCH.getDefaultLootTable().location().toString()).invert()) + ) + .action( + PoolRemoveAction.builder() + ) + ); + addModifier( + id("add_cake_entry_to_dirt_block"), + LootModifier.builder() + .conditionally( + TablePredicate.builder() + .name(Blocks.DIRT.getLootTable().location().toString()) + ) + .action( + EntryAddAction.builder() + .entry( + LootPoolEntryWrapper.create(LootItem.lootTableItem(Items.CAKE) + .apply(SetItemCountFunction.setCount(UniformGenerator.between(1, 1))).build()) + ) + ) + ); + addModifier( + id("add_command_block_to_all_blocks"), + LootModifier.builder() + .conditionally( + TablePredicate.builder() + .type(LootContextTypesAccessor.getMAP().inverse().get(LootContextParamSets.BLOCK).toString()) + ) + .action( + EntryAddAction.builder() + .entry( + LootPoolEntryWrapper.create(LootItem.lootTableItem(Items.CAKE) + .apply(SetItemCountFunction.setCount(UniformGenerator.between(1, 1))).build()) + ) + ) + ); + addModifier( + id("remove_glowstone_and_gunpowder_from_witch"), + LootModifier.builder() + .conditionally( + TablePredicate.builder().name(EntityType.WITCH.getDefaultLootTable().location().toString()) + .and( + EntryItemPredicate.builder(new ItemWrapper(BuiltInRegistries.ITEM.wrapAsHolder(Items.GLOWSTONE_DUST))) + .or(EntryItemPredicate.builder(new ItemWrapper(BuiltInRegistries.ITEM.wrapAsHolder(Items.GUNPOWDER)))) + ) + ) + .action( + EntryRemoveAction.builder() + ) + ); + addModifier( + id("squid_ink_sac_only_from_player"), + LootModifier.builder() + .conditionally( + TablePredicate.builder() + .name(EntityType.SQUID.getDefaultLootTable().location().toString()) + .and(EntryItemPredicate.builder(new ItemWrapper(BuiltInRegistries.ITEM.wrapAsHolder(Items.INK_SAC)))) + ) + .action( + ConditionAddAction.builder() + .onlyPools() + .condition( + new LootConditionWrapper(LootItemKilledByPlayerCondition.killedByPlayer().build()) + ) + ) + ); + } + } + + private static class LootProvider extends SimpleFabricLootTableProvider { + public LootProvider(FabricDataOutput output, CompletableFuture registryLookup) { + super(output, registryLookup, LootContextParamSets.CHEST); + } + + @Override + public void generate(HolderLookup.Provider registryLookup, BiConsumer, LootTable.Builder> consumer) { + consumer.accept(ResourceKey.create(Registries.LOOT_TABLE, id("test_empty_table")), LootTable.lootTable()); + } + } + */ +} diff --git a/loader/fabric/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/fabric/v1205/mixin/ReloadableRegistriesMixin.java b/loader/fabric/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/fabric/v1205/mixin/ReloadableRegistriesMixin.java new file mode 100644 index 0000000..3d5f81b --- /dev/null +++ b/loader/fabric/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/fabric/v1205/mixin/ReloadableRegistriesMixin.java @@ -0,0 +1,48 @@ +package top.offsetmonkey538.loottablemodifier.fabric.v1205.mixin; + +import com.google.gson.JsonElement; +import it.unimi.dsi.fastutil.Pair; +import net.minecraft.core.Registry; +import net.minecraft.core.WritableRegistry; +import net.minecraft.resources.RegistryOps; +import net.minecraft.server.ReloadableServerRegistries; +import net.minecraft.server.packs.resources.ResourceManager; +import net.minecraft.world.level.storage.loot.LootDataType; +import net.minecraft.world.level.storage.loot.LootTable; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import top.offsetmonkey538.loottablemodifier.common.LootTableModifierCommon; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.IdentifierWrapper; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.ResourceManagerWrapper; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootTableWrapper; + +@Mixin( + value = ReloadableServerRegistries.class, + priority = 900 +) +public abstract class ReloadableRegistriesMixin { + @Inject( + // Works for fabric >=1.20.5 <=1.21.1 + method = "method_58279(Lnet/minecraft/world/level/storage/loot/LootDataType;Lnet/minecraft/server/packs/resources/ResourceManager;Lnet/minecraft/resources/RegistryOps;)Lnet/minecraft/core/WritableRegistry;", + at = @At("RETURN") + ) + private static void loot_table_modifier$modifyLootTables(LootDataType lootDataType, ResourceManager resourceManager, RegistryOps registryOps, CallbackInfoReturnable> cir) { + if (lootDataType != LootDataType.TABLE) return; + + //noinspection unchecked + final Registry lootRegistry = (Registry) cir.getReturnValue(); + + LootTableModifierCommon.runModification( + new ResourceManagerWrapper(resourceManager), + lootRegistry.asLookup() + .listElements() + .map(registryEntry -> Pair.of( + new IdentifierWrapper(registryEntry.key().location()), + new LootTableWrapper(lootRegistry.get(registryEntry.key())) + )), + registryOps + ); + } +} diff --git a/loader/fabric/1.20.5/src/main/resources/loot-table-modifier.version.loader.mixins.json b/loader/fabric/1.20.5/src/main/resources/loot-table-modifier.version.loader.mixins.json new file mode 100644 index 0000000..3f6a544 --- /dev/null +++ b/loader/fabric/1.20.5/src/main/resources/loot-table-modifier.version.loader.mixins.json @@ -0,0 +1,11 @@ +{ + "required": true, + "package": "top.offsetmonkey538.loottablemodifier.fabric.v1205.mixin", + "compatibilityLevel": "JAVA_21", + "mixins": [ + "ReloadableRegistriesMixin" + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/loader/fabric/1.21.2/gradle.properties b/loader/fabric/1.21.2/gradle.properties new file mode 100644 index 0000000..be0ae3c --- /dev/null +++ b/loader/fabric/1.21.2/gradle.properties @@ -0,0 +1,14 @@ +project_name = fabric-1.21.2 +commonModdedVersion = 1.21.2 +fabricDatagenEntrypoint = top.offsetmonkey538.loottablemodifier.fabric.v1212.datagen.LootTableModifierDatagen + +monkeylib538_suffix = 1.20.1 + +# Miminum Minecraft version supported, check at https://fabricmc.net/develop +minecraft_version = 1.21.2 +supported_minecraft_versions = >=1.21.2 + +# These should be automatically updated, unless the environment +# variable "DISABLE_PROPERTIES_UPDATE" is set. +loader_version = 0.18.4 +fapi_version = 0.106.1+1.21.2 diff --git a/loader/fabric/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/fabric/v1212/datagen/LootTableModifierDatagen.java b/loader/fabric/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/fabric/v1212/datagen/LootTableModifierDatagen.java new file mode 100644 index 0000000..d6c32a7 --- /dev/null +++ b/loader/fabric/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/fabric/v1212/datagen/LootTableModifierDatagen.java @@ -0,0 +1,180 @@ +package top.offsetmonkey538.loottablemodifier.fabric.v1212.datagen; + +import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint; +import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator; + +/** + * Datagen for loot modifiers used for testing. + */ +public class LootTableModifierDatagen implements DataGeneratorEntrypoint { + + @Override + public void onInitializeDataGenerator(FabricDataGenerator fabricDataGenerator) { + //final FabricDataGenerator.Pack pack = fabricDataGenerator.createBuiltinResourcePack(id("example_pack")); + + //pack.addProvider(ModLootModifierProvider::new); + //pack.addProvider(LootProvider::new); + } +/* + private static class ModLootModifierProvider extends LootModifierProvider { + public ModLootModifierProvider(FabricDataOutput dataOutput, CompletableFuture registriesFuture) { + super(dataOutput, registriesFuture); + } + + @Override + protected void generate(HolderLookup.Provider lookup) { + addModifier( + id("replace_ingots_with_command_block"), + LootModifier.builder() + .conditionally( + EntryItemPredicate.builder(RegexPattern.compile("minecraft:.*_ingot")) + ) + .action( + EntryItemSetAction.builder(new ItemWrapper(BuiltInRegistries.ITEM.wrapAsHolder(Items.COMMAND_BLOCK))) + ) + ); + addModifier( + id("sugarcane_drop_tnt"), + LootModifier.builder() + .conditionally( + EntryItemPredicate.builder(new ItemWrapper(BuiltInRegistries.ITEM.wrapAsHolder(Items.SUGAR_CANE))) + ) + .action( + PoolAddAction.builder() + .pool( + new LootPoolWrapper(LootPool.lootPool() + .setRolls(ConstantValue.exactly(1)) + .add( + LootItem.lootTableItem(Items.TNT) + .apply(SetItemCountFunction.setCount(UniformGenerator.between(1, 1))) + ).build()) + ) + ) + ); + addModifier( + id("mobs_drop_tnt"), + LootModifier.builder() + .conditionally( + TablePredicate.builder() + .name(EntityType.CREEPER.getDefaultLootTable().map(ResourceKey::location).map(ResourceLocation::toString).orElse("")) + .name(EntityType.ZOMBIE.getDefaultLootTable().map(ResourceKey::location).map(ResourceLocation::toString).orElse("")) + ) + .action( + PoolAddAction.builder() + .pool( + new LootPoolWrapper(LootPool.lootPool() + .setRolls(ConstantValue.exactly(1)) + .add( + LootItem.lootTableItem(Items.TNT) + .apply(SetItemCountFunction.setCount(UniformGenerator.between(1, 1))) + ).build()) + ) + ) + ); + addModifier( + id("empty_table_test"), + LootModifier.builder() + .conditionally( + TablePredicate.builder() + .name(ResourceKey.create(Registries.LOOT_TABLE, id("test_empty_table")).location().toString()) + ) + .action( + PoolAddAction.builder() + .pool( + new LootPoolWrapper(LootPool.lootPool() + .setRolls(ConstantValue.exactly(1)) + .add( + LootItem.lootTableItem(Items.TNT) + .apply(SetItemCountFunction.setCount(UniformGenerator.between(1, 1))) + ).build()) + ) + ) + ); + addModifier( + id("remove_pools_with_sticks"), + LootModifier.builder() + .conditionally( + EntryItemPredicate.builder(new ItemWrapper(BuiltInRegistries.ITEM.wrapAsHolder(Items.STICK))) + // Exclude witch to test if AllOf and Inverted work + so I can test RemoveEntry on witch. + .and(TablePredicate.builder().name(EntityType.WITCH.getDefaultLootTable().map(ResourceKey::location).map(ResourceLocation::toString).orElse("")).invert()) + ) + .action( + PoolRemoveAction.builder() + ) + ); + addModifier( + id("add_cake_entry_to_dirt_block"), + LootModifier.builder() + .conditionally( + TablePredicate.builder() + .name(Blocks.DIRT.getLootTable().map(ResourceKey::location).map(ResourceLocation::toString).orElse("")) + ) + .action( + EntryAddAction.builder() + .entry( + LootPoolEntryWrapper.create(LootItem.lootTableItem(Items.CAKE) + .apply(SetItemCountFunction.setCount(UniformGenerator.between(1, 1))).build()) + ) + ) + ); + addModifier( + id("add_command_block_to_all_blocks"), + LootModifier.builder() + .conditionally( + TablePredicate.builder() + .type(LootContextTypesAccessor.getMAP().inverse().get(LootContextParamSets.BLOCK).toString()) + ) + .action( + EntryAddAction.builder() + .entry( + LootPoolEntryWrapper.create(LootItem.lootTableItem(Items.CAKE) + .apply(SetItemCountFunction.setCount(UniformGenerator.between(1, 1))).build()) + ) + ) + ); + addModifier( + id("remove_glowstone_and_gunpowder_from_witch"), + LootModifier.builder() + .conditionally( + TablePredicate.builder().name(EntityType.WITCH.getDefaultLootTable().map(ResourceKey::location).map(ResourceLocation::toString).orElse("")) + .and( + EntryItemPredicate.builder(new ItemWrapper(BuiltInRegistries.ITEM.wrapAsHolder(Items.GLOWSTONE_DUST))) + .or(EntryItemPredicate.builder(new ItemWrapper(BuiltInRegistries.ITEM.wrapAsHolder(Items.GUNPOWDER)))) + ) + ) + .action( + EntryRemoveAction.builder() + ) + ); + addModifier( + id("squid_ink_sac_only_from_player"), + LootModifier.builder() + .conditionally( + TablePredicate.builder() + .name(EntityType.SQUID.getDefaultLootTable().map(ResourceKey::location).map(ResourceLocation::toString).orElse("")) + .and(EntryItemPredicate.builder(new ItemWrapper(BuiltInRegistries.ITEM.wrapAsHolder(Items.INK_SAC)))) + ) + .action( + ConditionAddAction.builder() + .onlyPools() + .condition( + new LootConditionWrapper(LootItemKilledByPlayerCondition.killedByPlayer().build()) + ) + ) + ); + } + } + + private static class LootProvider extends SimpleFabricLootTableProvider { + public LootProvider(FabricDataOutput output, CompletableFuture registryLookup) { + super(output, registryLookup, LootContextParamSets.CHEST); + } + + @Override + public void generate(BiConsumer, LootTable.Builder> lootTableBiConsumer) { + lootTableBiConsumer.accept(ResourceKey.create(Registries.LOOT_TABLE, id("test_empty_table")), LootTable.lootTable()); + } + } + + */ +} diff --git a/loader/fabric/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/fabric/v1212/mixin/ReloadableRegistriesMixin.java b/loader/fabric/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/fabric/v1212/mixin/ReloadableRegistriesMixin.java new file mode 100644 index 0000000..0b05321 --- /dev/null +++ b/loader/fabric/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/fabric/v1212/mixin/ReloadableRegistriesMixin.java @@ -0,0 +1,48 @@ +package top.offsetmonkey538.loottablemodifier.fabric.v1212.mixin; + +import com.google.gson.JsonElement; +import it.unimi.dsi.fastutil.Pair; +import net.minecraft.core.Registry; +import net.minecraft.core.WritableRegistry; +import net.minecraft.resources.RegistryOps; +import net.minecraft.server.ReloadableServerRegistries; +import net.minecraft.server.packs.resources.ResourceManager; +import net.minecraft.world.level.storage.loot.LootDataType; +import net.minecraft.world.level.storage.loot.LootTable; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import top.offsetmonkey538.loottablemodifier.common.LootTableModifierCommon; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.IdentifierWrapper; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.ResourceManagerWrapper; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootTableWrapper; + +@Mixin( + value = ReloadableServerRegistries.class, + priority = 900 +) +public abstract class ReloadableRegistriesMixin { + @Inject( + // Works for fabric >=1.21.2 + method = "method_61240(Lnet/minecraft/world/level/storage/loot/LootDataType;Lnet/minecraft/server/packs/resources/ResourceManager;Lnet/minecraft/resources/RegistryOps;)Lnet/minecraft/core/WritableRegistry;", + at = @At("RETURN") + ) + private static void loot_table_modifier$modifyLootTables(LootDataType lootDataType, ResourceManager resourceManager, RegistryOps registryOps, CallbackInfoReturnable> cir) { + if (lootDataType != LootDataType.TABLE) return; + + //noinspection unchecked + final Registry lootRegistry = (Registry) cir.getReturnValue(); + + LootTableModifierCommon.runModification( + new ResourceManagerWrapper(resourceManager), + lootRegistry + .listElements() + .map(registryEntry -> Pair.of( + new IdentifierWrapper(registryEntry.key().location()), + new LootTableWrapper(lootRegistry.getValue(registryEntry.key())) + )), + registryOps + ); + } +} diff --git a/loader/fabric/1.21.2/src/main/resources/loot-table-modifier.version.loader.mixins.json b/loader/fabric/1.21.2/src/main/resources/loot-table-modifier.version.loader.mixins.json new file mode 100644 index 0000000..7d7e1df --- /dev/null +++ b/loader/fabric/1.21.2/src/main/resources/loot-table-modifier.version.loader.mixins.json @@ -0,0 +1,11 @@ +{ + "required": true, + "package": "top.offsetmonkey538.loottablemodifier.fabric.v1212.mixin", + "compatibilityLevel": "JAVA_21", + "mixins": [ + "ReloadableRegistriesMixin" + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/loader/fabric/1.21/gradle.properties b/loader/fabric/1.21/gradle.properties new file mode 100644 index 0000000..94660aa --- /dev/null +++ b/loader/fabric/1.21/gradle.properties @@ -0,0 +1,14 @@ +project_name = fabric-1.21 +commonModdedVersion = 1.21 +fabricDatagenEntrypoint = top.offsetmonkey538.loottablemodifier.fabric.v121.datagen.LootTableModifierDatagen + +monkeylib538_suffix = 1.20.1 + +# Miminum Minecraft version supported, check at https://fabricmc.net/develop +minecraft_version = 1.21 +supported_minecraft_versions = >=1.21 <=1.21.1 + +# These should be automatically updated, unless the environment +# variable "DISABLE_PROPERTIES_UPDATE" is set. +loader_version = 0.18.4 +fapi_version = 0.102.0+1.21 diff --git a/loader/fabric/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/fabric/v121/datagen/LootTableModifierDatagen.java b/loader/fabric/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/fabric/v121/datagen/LootTableModifierDatagen.java new file mode 100644 index 0000000..883daf8 --- /dev/null +++ b/loader/fabric/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/fabric/v121/datagen/LootTableModifierDatagen.java @@ -0,0 +1,180 @@ +package top.offsetmonkey538.loottablemodifier.fabric.v121.datagen; + +import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint; +import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator; + +/** + * Datagen for loot modifiers used for testing. + */ +public class LootTableModifierDatagen implements DataGeneratorEntrypoint { + + @Override + public void onInitializeDataGenerator(FabricDataGenerator fabricDataGenerator) { + //final FabricDataGenerator.Pack pack = fabricDataGenerator.createBuiltinResourcePack(id("example_pack")); + + //pack.addProvider(ModLootModifierProvider::new); + //pack.addProvider(LootProvider::new); + } +/* + private static class ModLootModifierProvider extends LootModifierProvider { + public ModLootModifierProvider(FabricDataOutput dataOutput, CompletableFuture registriesFuture) { + super(dataOutput, registriesFuture); + } + + @Override + protected void generate(HolderLookup.Provider lookup) { + addModifier( + id("replace_ingots_with_command_block"), + LootModifier.builder() + .conditionally( + EntryItemPredicate.builder(RegexPattern.compile("minecraft:.*_ingot")) + ) + .action( + EntryItemSetAction.builder(new ItemWrapper(BuiltInRegistries.ITEM.wrapAsHolder(Items.COMMAND_BLOCK))) + ) + ); + addModifier( + id("sugarcane_drop_tnt"), + LootModifier.builder() + .conditionally( + EntryItemPredicate.builder(new ItemWrapper(BuiltInRegistries.ITEM.wrapAsHolder(Items.SUGAR_CANE))) + ) + .action( + PoolAddAction.builder() + .pool( + new LootPoolWrapper(LootPool.lootPool() + .setRolls(ConstantValue.exactly(1)) + .add( + LootItem.lootTableItem(Items.TNT) + .apply(SetItemCountFunction.setCount(UniformGenerator.between(1, 1))) + ).build()) + ) + ) + ); + addModifier( + id("mobs_drop_tnt"), + LootModifier.builder() + .conditionally( + TablePredicate.builder() + .name(EntityType.CREEPER.getDefaultLootTable().location().toString()) + .name(EntityType.ZOMBIE.getDefaultLootTable().location().toString()) + ) + .action( + PoolAddAction.builder() + .pool( + new LootPoolWrapper(LootPool.lootPool() + .setRolls(ConstantValue.exactly(1)) + .add( + LootItem.lootTableItem(Items.TNT) + .apply(SetItemCountFunction.setCount(UniformGenerator.between(1, 1))) + ).build()) + ) + ) + ); + addModifier( + id("empty_table_test"), + LootModifier.builder() + .conditionally( + TablePredicate.builder() + .name(ResourceKey.create(Registries.LOOT_TABLE, id("test_empty_table")).location().toString()) + ) + .action( + PoolAddAction.builder() + .pool( + new LootPoolWrapper(LootPool.lootPool() + .setRolls(ConstantValue.exactly(1)) + .add( + LootItem.lootTableItem(Items.TNT) + .apply(SetItemCountFunction.setCount(UniformGenerator.between(1, 1))) + ).build()) + ) + ) + ); + addModifier( + id("remove_pools_with_sticks"), + LootModifier.builder() + .conditionally( + EntryItemPredicate.builder(new ItemWrapper(BuiltInRegistries.ITEM.wrapAsHolder(Items.STICK))) + // Exclude witch to test if AllOf and Inverted work + so I can test RemoveEntry on witch. + .and(TablePredicate.builder().name(EntityType.WITCH.getDefaultLootTable().location().toString()).invert()) + ) + .action( + PoolRemoveAction.builder() + ) + ); + addModifier( + id("add_cake_entry_to_dirt_block"), + LootModifier.builder() + .conditionally( + TablePredicate.builder() + .name(Blocks.DIRT.getLootTable().location().toString()) + ) + .action( + EntryAddAction.builder() + .entry( + LootPoolEntryWrapper.create(LootItem.lootTableItem(Items.CAKE) + .apply(SetItemCountFunction.setCount(UniformGenerator.between(1, 1))).build()) + ) + ) + ); + addModifier( + id("add_command_block_to_all_blocks"), + LootModifier.builder() + .conditionally( + TablePredicate.builder() + .type(LootContextTypesAccessor.getMAP().inverse().get(LootContextParamSets.BLOCK).toString()) + ) + .action( + EntryAddAction.builder() + .entry( + LootPoolEntryWrapper.create(LootItem.lootTableItem(Items.CAKE) + .apply(SetItemCountFunction.setCount(UniformGenerator.between(1, 1))).build()) + ) + ) + ); + addModifier( + id("remove_glowstone_and_gunpowder_from_witch"), + LootModifier.builder() + .conditionally( + TablePredicate.builder().name(EntityType.WITCH.getDefaultLootTable().location().toString()) + .and( + EntryItemPredicate.builder(new ItemWrapper(BuiltInRegistries.ITEM.wrapAsHolder(Items.GLOWSTONE_DUST))) + .or(EntryItemPredicate.builder(new ItemWrapper(BuiltInRegistries.ITEM.wrapAsHolder(Items.GUNPOWDER)))) + ) + ) + .action( + EntryRemoveAction.builder() + ) + ); + addModifier( + id("squid_ink_sac_only_from_player"), + LootModifier.builder() + .conditionally( + TablePredicate.builder() + .name(EntityType.SQUID.getDefaultLootTable().location().toString()) + .and(EntryItemPredicate.builder(new ItemWrapper(BuiltInRegistries.ITEM.wrapAsHolder(Items.INK_SAC)))) + ) + .action( + ConditionAddAction.builder() + .onlyPools() + .condition( + new LootConditionWrapper(LootItemKilledByPlayerCondition.killedByPlayer().build()) + ) + ) + ); + } + } + + private static class LootProvider extends SimpleFabricLootTableProvider { + public LootProvider(FabricDataOutput output, CompletableFuture registryLookup) { + super(output, registryLookup, LootContextParamSets.CHEST); + } + + @Override + public void generate(BiConsumer, LootTable.Builder> consumer) { + consumer.accept(ResourceKey.create(Registries.LOOT_TABLE, id("test_empty_table")), LootTable.lootTable()); + } + } + + */ +} diff --git a/loader/fabric/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/fabric/v121/mixin/ReloadableRegistriesMixin.java b/loader/fabric/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/fabric/v121/mixin/ReloadableRegistriesMixin.java new file mode 100644 index 0000000..f4a946b --- /dev/null +++ b/loader/fabric/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/fabric/v121/mixin/ReloadableRegistriesMixin.java @@ -0,0 +1,48 @@ +package top.offsetmonkey538.loottablemodifier.fabric.v121.mixin; + +import com.google.gson.JsonElement; +import it.unimi.dsi.fastutil.Pair; +import net.minecraft.core.Registry; +import net.minecraft.core.WritableRegistry; +import net.minecraft.resources.RegistryOps; +import net.minecraft.server.ReloadableServerRegistries; +import net.minecraft.server.packs.resources.ResourceManager; +import net.minecraft.world.level.storage.loot.LootDataType; +import net.minecraft.world.level.storage.loot.LootTable; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import top.offsetmonkey538.loottablemodifier.common.LootTableModifierCommon; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.IdentifierWrapper; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.ResourceManagerWrapper; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootTableWrapper; + +@Mixin( + value = ReloadableServerRegistries.class, + priority = 900 +) +public abstract class ReloadableRegistriesMixin { + @Inject( + // Works for fabric >=1.20.5 <=1.21.1 + method = "method_58279(Lnet/minecraft/world/level/storage/loot/LootDataType;Lnet/minecraft/server/packs/resources/ResourceManager;Lnet/minecraft/resources/RegistryOps;)Lnet/minecraft/core/WritableRegistry;", + at = @At("RETURN") + ) + private static void loot_table_modifier$modifyLootTables(LootDataType lootDataType, ResourceManager resourceManager, RegistryOps registryOps, CallbackInfoReturnable> cir) { + if (lootDataType != LootDataType.TABLE) return; + + //noinspection unchecked + final Registry lootRegistry = (Registry) cir.getReturnValue(); + + LootTableModifierCommon.runModification( + new ResourceManagerWrapper(resourceManager), + lootRegistry.asLookup() + .listElements() + .map(registryEntry -> Pair.of( + new IdentifierWrapper(registryEntry.key().location()), + new LootTableWrapper(lootRegistry.get(registryEntry.key())) + )), + registryOps + ); + } +} diff --git a/loader/fabric/1.21/src/main/resources/loot-table-modifier.version.loader.mixins.json b/loader/fabric/1.21/src/main/resources/loot-table-modifier.version.loader.mixins.json new file mode 100644 index 0000000..068f2f5 --- /dev/null +++ b/loader/fabric/1.21/src/main/resources/loot-table-modifier.version.loader.mixins.json @@ -0,0 +1,11 @@ +{ + "required": true, + "package": "top.offsetmonkey538.loottablemodifier.fabric.v121.mixin", + "compatibilityLevel": "JAVA_21", + "mixins": [ + "ReloadableRegistriesMixin" + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/loader/fabric/build.gradle b/loader/fabric/build.gradle new file mode 100644 index 0000000..be63582 --- /dev/null +++ b/loader/fabric/build.gradle @@ -0,0 +1,157 @@ +import dex.plugins.outlet.v2.util.ReleaseType + +plugins { + id 'multiloader-modded' + id 'fabric-loom' + id 'io.github.dexman545.outlet' + id 'com.modrinth.minotaur' apply false +} + +loom { + afterEvaluate { + runClient.setEnabled(false) + runServer.setEnabled(false) + } +} + +allprojects { + apply plugin: "multiloader-modded" + apply plugin: "fabric-loom" + apply plugin: "io.github.dexman545.outlet" + + outlet { + maintainPropertiesFile = System.getenv("DISABLE_PROPERTIES_UPDATE") == null + mcVersionRange = project.supported_minecraft_versions + allowedReleaseTypes = [ReleaseType.RELEASE] + propertiesData = [ + 'loader_version': outlet.loaderVersion(), + 'fapi_version' : outlet.fapiVersion(project.minecraft_version) + ] + } + + dependencies { + compileOnly project(":common") + commonJava project(path: ":common", configuration: "commonJava") + commonResources project(path: ":common", configuration: "commonResources") + compileOnly project(":modded") + commonJava project(path: ":modded", configuration: "commonJava") + commonResources project(path: ":modded", configuration: "commonResources") + + minecraft "com.mojang:minecraft:${project.minecraft_version}" + mappings loom.officialMojangMappings() + modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" + + modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fapi_version}" + + modCompileOnly("top.offsetmonkey538.monkeylib538:monkeylib538-fabric:${rootProject.monkeylib538_version}+fabric") { + exclude(group: "net.fabricmc.fabric-api") + } + } +} + +subprojects { + apply plugin: "io.github.dexman545.outlet" + apply plugin: "com.modrinth.minotaur" + + tasks.modrinth.dependsOn(tasks.modrinthSyncBody) + + repositories { + maven { + name = "DevAuth" + url = "https://pkgs.dev.azure.com/djtheredstoner/DevAuth/_packaging/public/maven/v1" + content { + includeGroup "me.djtheredstoner" + } + } + } + + dependencies { + compileOnly project(":loader:fabric") + commonJava project(path: ":loader:fabric", configuration: "commonJava") + commonResources project(path: ":loader:fabric", configuration: "commonResources") + + compileOnly project(":modded:${project.commonModdedVersion}") + commonJava project(path: ":modded:${project.commonModdedVersion}", configuration: "commonJava") + commonResources project(path: ":modded:${project.commonModdedVersion}", configuration: "commonResources") + + modRuntimeOnly("top.offsetmonkey538.monkeylib538:monkeylib538-fabric-${project.monkeylib538_suffix}:${rootProject.monkeylib538_version}+fabric+${project.monkeylib538_suffix}") { + exclude(group: "net.fabricmc.fabric-api") + //TODO: can remove? exclude(group: "top.offsetmonkey538.monkeylib538:monkeylib538-fabric") + } + + // DevAuth + modLocalRuntime "me.djtheredstoner:DevAuth-fabric:${rootProject.devauth_version}" + } + + loom { + runs { + server { + name = "${project.project_name} Server" + runDir "run/server" + ideConfigGenerated(true) + } + client { + name = "${project.project_name} Client" + runDir "run/client" + vmArg "-Ddevauth.enabled=true" + ideConfigGenerated(true) + } + datagenClient { + name = "${project.project_name} Datagen" + inherit client + runDir "build/datagen" + vmArg "-Dfabric-api.datagen" + vmArg "-Dfabric-api.datagen.output-dir=${file("src/main/generated")}" + vmArg "-Dfabric-api.datagen.modid=loot-table-modifier" + vmArg "-Ddevauth.enabled=false" + ideConfigGenerated(true) + } + } + } + + sourceSets { + main { + resources { + srcDirs += [ + "src/main/generated" + ] + } + } + } + + modrinth { + // Main properties + token = System.getenv("MODRINTH_TOKEN") + projectId = "loot-table-modifier" + gameVersions = outlet.mcVersions() + loaders = ["fabric"] + + // Version stuff + def customVersionName = System.getenv("VERSION_NAME") + if (customVersionName != null) versionName = customVersionName + + versionNumber = "${project.version}" + + versionType = Boolean.parseBoolean(System.getenv("VERSION_IS_PRERELEASE")) ? "beta" : "release" + + if (rootProject.mod_version.contains("beta")) versionType = "beta" + if (rootProject.mod_version.contains("alpha")) versionType = "alpha" + + + // Files + uploadFile = remapJar.archiveFile + additionalFiles = [sourcesJar.archiveFile] + + + // Project info + syncBodyFrom = rootProject.file("README.md").text + def changelogEnv = System.getenv("VERSION_CHANGELOG") + if (changelogEnv != null) changelog = changelogEnv + + + // Dependencies + dependencies { + //TODO: not actually required? just cause datagen... required.project "fabric-api" + } + } +} diff --git a/loader/fabric/gradle.properties b/loader/fabric/gradle.properties new file mode 100644 index 0000000..f0d98bf --- /dev/null +++ b/loader/fabric/gradle.properties @@ -0,0 +1,14 @@ +project_name = fabric + + +## "Common" fabric one should depend on the latest version just so it can access Minecraft and Fabric. +## It MUST NOT include version-specific code + +# Minecraft version, check at https://fabricmc.net/develop +minecraft_version = 1.21.8 +supported_minecraft_versions = * + +# These should be automatically updated, unless the environment +# variable "DISABLE_PROPERTIES_UPDATE" is set. +loader_version = 0.18.4 +fapi_version = 0.136.1+1.21.8 diff --git a/src/main/java/top/offsetmonkey538/loottablemodifier/api/datagen/LootModifierProvider.java b/loader/fabric/src/main/java/top/offsetmonkey538/loottablemodifier/fabric/api/datagen/LootModifierProvider.java similarity index 56% rename from src/main/java/top/offsetmonkey538/loottablemodifier/api/datagen/LootModifierProvider.java rename to loader/fabric/src/main/java/top/offsetmonkey538/loottablemodifier/fabric/api/datagen/LootModifierProvider.java index 8e52fad..446869a 100644 --- a/src/main/java/top/offsetmonkey538/loottablemodifier/api/datagen/LootModifierProvider.java +++ b/loader/fabric/src/main/java/top/offsetmonkey538/loottablemodifier/fabric/api/datagen/LootModifierProvider.java @@ -1,22 +1,22 @@ -package top.offsetmonkey538.loottablemodifier.api.datagen; +/*package top.offsetmonkey538.loottablemodifier.fabric.api.datagen; import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; import net.fabricmc.fabric.api.datagen.v1.provider.FabricCodecDataProvider; -import net.minecraft.data.DataOutput; -import net.minecraft.registry.RegistryWrapper; -import net.minecraft.util.Identifier; +import net.minecraft.core.HolderLookup; +import net.minecraft.data.PackOutput; +import net.minecraft.resources.ResourceLocation; import org.jetbrains.annotations.NotNull; -import top.offsetmonkey538.loottablemodifier.api.resource.LootModifier; +import top.offsetmonkey538.loottablemodifier.common.api.resource.LootModifier; import java.util.concurrent.CompletableFuture; import java.util.function.BiConsumer; -import static top.offsetmonkey538.loottablemodifier.LootTableModifier.MOD_ID; +import static top.offsetmonkey538.loottablemodifier.common.LootTableModifierCommon.MOD_ID; /** * A datagen provider for creating loot modifiers. *
- * Override {@link #generate(RegistryWrapper.WrapperLookup) generate()} and use the {@link #addModifier(Identifier, LootModifier.Builder)} method to add modifiers. + * Override {@link #generate(HolderLookup.Provider) generate()} and use the {@link #addModifier(ResourceLocation, LootModifier.Builder)} method to add modifiers. *
*
{@code
  * @Override
@@ -32,7 +32,7 @@
  *                  .action(
  *                      PoolAddAction.builder()
  *                          .pool(
- *                              LootPool.builder()
+ *                              LootPoolWrapper.builder()
  *                                  .rolls(ConstantLootNumberProvider.create(1))
  *                                  .with(
  *                                      ItemEntry.builder(Items.TNT)
@@ -43,39 +43,41 @@
  *     );
  * }
  * }
- */ + *//* +// TODO: FIXME: Datagen part of api should be platform specific and probably include helper methods for turning vanilla things into wrappers cause calling the constructors seems annoying public abstract class LootModifierProvider extends FabricCodecDataProvider { - private BiConsumer provider; + private BiConsumer provider; - public LootModifierProvider(FabricDataOutput dataOutput, CompletableFuture registriesFuture) { - super(dataOutput, registriesFuture, DataOutput.OutputType.DATA_PACK, MOD_ID + "/loot_modifier", LootModifier.CODEC); + public LootModifierProvider(FabricDataOutput dataOutput, CompletableFuture registriesFuture) { + super(dataOutput, registriesFuture, PackOutput.Target.DATA_PACK, MOD_ID + "/loot_modifier", LootModifier.CODEC); } @Override - protected void configure(BiConsumer provider, RegistryWrapper.WrapperLookup lookup) { + protected void configure(BiConsumer provider, HolderLookup.Provider lookup) { this.provider = provider; generate(lookup); } @Override - public String getName() { + public @NotNull String getName() { return "Loot Table Modifiers"; } /** - * Override and use {@link #addModifier(Identifier, LootModifier.Builder)} method to add modifiers. + * Override and use {@link #addModifier(ResourceLocation, LootModifier.Builder)} method to add modifiers. * * @param lookup A lookup for registries. - */ - protected abstract void generate(RegistryWrapper.WrapperLookup lookup); + *//* + protected abstract void generate(HolderLookup.Provider lookup); /** * Adds a loot modifier using the provided name and builder. * * @param name the identifier of the modifier * @param builder the builder to generate the loot modifier from - */ - protected void addModifier(@NotNull Identifier name, @NotNull LootModifier.Builder builder) { + *//* + protected void addModifier(@NotNull ResourceLocation name, @NotNull LootModifier.Builder builder) { provider.accept(name, builder.build()); } } +*/ \ No newline at end of file diff --git a/loader/fabric/src/main/java/top/offsetmonkey538/loottablemodifier/fabric/platform/FabricPlatformMain.java b/loader/fabric/src/main/java/top/offsetmonkey538/loottablemodifier/fabric/platform/FabricPlatformMain.java new file mode 100644 index 0000000..e87608e --- /dev/null +++ b/loader/fabric/src/main/java/top/offsetmonkey538/loottablemodifier/fabric/platform/FabricPlatformMain.java @@ -0,0 +1,20 @@ +package top.offsetmonkey538.loottablemodifier.fabric.platform; + +import net.fabricmc.api.ModInitializer; +import net.fabricmc.fabric.api.resource.ResourceManagerHelper; +import net.fabricmc.fabric.api.resource.ResourcePackActivationType; +import net.fabricmc.loader.api.FabricLoader; +import net.minecraft.network.chat.Component; +import top.offsetmonkey538.loottablemodifier.common.LootTableModifierCommon; + +import static top.offsetmonkey538.loottablemodifier.common.LootTableModifierCommon.IS_DEV; +import static top.offsetmonkey538.loottablemodifier.common.LootTableModifierCommon.MOD_ID; +import static top.offsetmonkey538.loottablemodifier.modded.platform.ModdedPlatformMain.id; + +public class FabricPlatformMain implements ModInitializer { + @Override + public void onInitialize() { + LootTableModifierCommon.initialize(); + if (IS_DEV) ResourceManagerHelper.registerBuiltinResourcePack(id("example_pack"), FabricLoader.getInstance().getModContainer(MOD_ID).orElseThrow(), Component.nullToEmpty("Example Pack"), ResourcePackActivationType.NORMAL); + } +} diff --git a/loader/fabric/src/main/resources/fabric.mod.json b/loader/fabric/src/main/resources/fabric.mod.json new file mode 100644 index 0000000..02e1a4a --- /dev/null +++ b/loader/fabric/src/main/resources/fabric.mod.json @@ -0,0 +1,36 @@ +{ + "schemaVersion": 1, + "id": "loot-table-modifier", + "version": "${modVersion}", + "name": "Loot Table Modifier", + "description": "Makes it possible to modify instead of replace loot tables through datapacks", + "authors": [ + "OffsetMonkey538" + ], + "contact": { + "sources": "https://github.com/OffsetMods538/Loot-Table-Modifier", + "issues": "https://github.com/OffsetMods538/Loot-Table-Modifier/issues", + "homepage": "https://modrinth.com/mod/loot-table-modifier", + "discord": "https://discord.offsetmonkey538.top/" + }, + "license": "MIT", + "icon": "assets/loot-table-modifier/icon.png", + "environment": "*", + "entrypoints": { + "main": [ + "top.offsetmonkey538.loottablemodifier.fabric.platform.FabricPlatformMain" + ], + "fabric-datagen": [ + "${fabricDatagenEntrypoint}" + ] + }, + "mixins": [ + "loot-table-modifier.modded.mixins.json", + "loot-table-modifier.version.modded.mixins.json", + "loot-table-modifier.version.loader.mixins.json" + ], + "depends": { + "minecraft": "${fabricSupportedMinecraftVersions}", + "java": ">=21" + } +} diff --git a/loader/neoforge/1.21.2/gradle.properties b/loader/neoforge/1.21.2/gradle.properties new file mode 100644 index 0000000..4898463 --- /dev/null +++ b/loader/neoforge/1.21.2/gradle.properties @@ -0,0 +1,13 @@ +project_name = neoforge-1.21.2 +commonModdedVersion = 1.21.2 + +monkeylib538_suffix = 1.21 + +# Miminum Minecraft version supported, check at https://fabricmc.net/develop +minecraft_version = 1.21.2 +supported_minecraft_versions = >=1.21.2 +minecraft_version_range = [1.21.2,) + +neoforge_version = 21.2.1-beta +parchment_minecraft_version = 1.21.1 +parchment_mappings_version = 2024.11.17 diff --git a/loader/neoforge/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/neoforge/v1212/datagen/LootTableModifierDatagen.java b/loader/neoforge/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/neoforge/v1212/datagen/LootTableModifierDatagen.java new file mode 100644 index 0000000..cb44243 --- /dev/null +++ b/loader/neoforge/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/neoforge/v1212/datagen/LootTableModifierDatagen.java @@ -0,0 +1,218 @@ +package top.offsetmonkey538.loottablemodifier.neoforge.v1212.datagen; + +//import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint; +//import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator; +//import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; +//import net.fabricmc.fabric.api.datagen.v1.provider.SimpleFabricLootTableProvider; +//import net.minecraft.core.HolderLookup; +//import net.minecraft.core.registries.BuiltInRegistries; +//import net.minecraft.core.registries.Registries; +//import net.minecraft.resources.ResourceKey; +//import net.minecraft.resources.ResourceLocation; +//import net.minecraft.world.entity.EntityType; +//import net.minecraft.world.item.Items; +//import net.minecraft.world.level.block.Blocks; +//import net.minecraft.world.level.storage.loot.LootPool; +//import net.minecraft.world.level.storage.loot.LootTable; +//import net.minecraft.world.level.storage.loot.entries.LootItem; +//import net.minecraft.world.level.storage.loot.functions.SetItemCountFunction; +//import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets; +//import net.minecraft.world.level.storage.loot.predicates.LootItemKilledByPlayerCondition; +//import net.minecraft.world.level.storage.loot.providers.number.ConstantValue; +//import net.minecraft.world.level.storage.loot.providers.number.UniformGenerator; +//import top.offsetmonkey538.loottablemodifier.neoforge.api.datagen.LootModifierProvider; +//import top.offsetmonkey538.loottablemodifier.common.api.resource.LootModifier; +//import top.offsetmonkey538.loottablemodifier.common.api.resource.action.condition.ConditionAddAction; +//import top.offsetmonkey538.loottablemodifier.common.api.resource.action.entry.EntryAddAction; +//import top.offsetmonkey538.loottablemodifier.common.api.resource.action.entry.EntryRemoveAction; +//import top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.table.TablePredicate; +//import top.offsetmonkey538.loottablemodifier.common.api.resource.util.RegexPattern; +//import top.offsetmonkey538.loottablemodifier.common.api.resource.action.pool.PoolAddAction; +//import top.offsetmonkey538.loottablemodifier.common.api.resource.action.entry.EntryItemSetAction; +//import top.offsetmonkey538.loottablemodifier.common.api.resource.action.pool.PoolRemoveAction; +//import top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.entry.EntryItemPredicate; +//import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.ItemWrapper; +//import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootConditionWrapper; +//import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootPoolWrapper; +//import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.entry.LootPoolEntryWrapper; +//import top.offsetmonkey538.loottablemodifier.modded.v1212.mixin.LootContextTypesAccessor; +// +//import java.util.concurrent.CompletableFuture; +//import java.util.function.BiConsumer; +// +//import static top.offsetmonkey538.loottablemodifier.modded.platform.LootTableModifierInitializer.id; +// +///** +// * Datagen for loot modifiers used for testing. +// */ +//public class LootTableModifierDatagen implements DataGeneratorEntrypoint { +// +// @Override +// public void onInitializeDataGenerator(FabricDataGenerator fabricDataGenerator) { +// final FabricDataGenerator.Pack pack = fabricDataGenerator.createBuiltinResourcePack(id("example_pack")); +// +// pack.addProvider(ModLootModifierProvider::new); +// pack.addProvider(LootProvider::new); +// } +// +// private static class ModLootModifierProvider extends LootModifierProvider { +// public ModLootModifierProvider(FabricDataOutput dataOutput, CompletableFuture registriesFuture) { +// super(dataOutput, registriesFuture); +// } +// +// @Override +// protected void generate(HolderLookup.Provider lookup) { +// addModifier( +// id("replace_ingots_with_command_block"), +// LootModifier.builder() +// .conditionally( +// EntryItemPredicate.builder(RegexPattern.compile("minecraft:.*_ingot")) +// ) +// .action( +// EntryItemSetAction.builder(new ItemWrapper(BuiltInRegistries.ITEM.wrapAsHolder(Items.COMMAND_BLOCK))) +// ) +// ); +// addModifier( +// id("sugarcane_drop_tnt"), +// LootModifier.builder() +// .conditionally( +// EntryItemPredicate.builder(new ItemWrapper(BuiltInRegistries.ITEM.wrapAsHolder(Items.SUGAR_CANE))) +// ) +// .action( +// PoolAddAction.builder() +// .pool( +// new LootPoolWrapper(LootPool.lootPool() +// .setRolls(ConstantValue.exactly(1)) +// .add( +// LootItem.lootTableItem(Items.TNT) +// .apply(SetItemCountFunction.setCount(UniformGenerator.between(1, 1))) +// ).build()) +// ) +// ) +// ); +// addModifier( +// id("mobs_drop_tnt"), +// LootModifier.builder() +// .conditionally( +// TablePredicate.builder() +// .name(EntityType.CREEPER.getDefaultLootTable().map(ResourceKey::location).map(ResourceLocation::toString).orElse("")) +// .name(EntityType.ZOMBIE.getDefaultLootTable().map(ResourceKey::location).map(ResourceLocation::toString).orElse("")) +// ) +// .action( +// PoolAddAction.builder() +// .pool( +// new LootPoolWrapper(LootPool.lootPool() +// .setRolls(ConstantValue.exactly(1)) +// .add( +// LootItem.lootTableItem(Items.TNT) +// .apply(SetItemCountFunction.setCount(UniformGenerator.between(1, 1))) +// ).build()) +// ) +// ) +// ); +// addModifier( +// id("empty_table_test"), +// LootModifier.builder() +// .conditionally( +// TablePredicate.builder() +// .name(ResourceKey.create(Registries.LOOT_TABLE, id("test_empty_table")).location().toString()) +// ) +// .action( +// PoolAddAction.builder() +// .pool( +// new LootPoolWrapper(LootPool.lootPool() +// .setRolls(ConstantValue.exactly(1)) +// .add( +// LootItem.lootTableItem(Items.TNT) +// .apply(SetItemCountFunction.setCount(UniformGenerator.between(1, 1))) +// ).build()) +// ) +// ) +// ); +// addModifier( +// id("remove_pools_with_sticks"), +// LootModifier.builder() +// .conditionally( +// EntryItemPredicate.builder(new ItemWrapper(BuiltInRegistries.ITEM.wrapAsHolder(Items.STICK))) +// // Exclude witch to test if AllOf and Inverted work + so I can test RemoveEntry on witch. +// .and(TablePredicate.builder().name(EntityType.WITCH.getDefaultLootTable().map(ResourceKey::location).map(ResourceLocation::toString).orElse("")).invert()) +// ) +// .action( +// PoolRemoveAction.builder() +// ) +// ); +// addModifier( +// id("add_cake_entry_to_dirt_block"), +// LootModifier.builder() +// .conditionally( +// TablePredicate.builder() +// .name(Blocks.DIRT.getLootTable().map(ResourceKey::location).map(ResourceLocation::toString).orElse("")) +// ) +// .action( +// EntryAddAction.builder() +// .entry( +// LootPoolEntryWrapper.create(LootItem.lootTableItem(Items.CAKE) +// .apply(SetItemCountFunction.setCount(UniformGenerator.between(1, 1))).build()) +// ) +// ) +// ); +// addModifier( +// id("add_command_block_to_all_blocks"), +// LootModifier.builder() +// .conditionally( +// TablePredicate.builder() +// .type(LootContextTypesAccessor.getMAP().inverse().get(LootContextParamSets.BLOCK).toString()) +// ) +// .action( +// EntryAddAction.builder() +// .entry( +// LootPoolEntryWrapper.create(LootItem.lootTableItem(Items.CAKE) +// .apply(SetItemCountFunction.setCount(UniformGenerator.between(1, 1))).build()) +// ) +// ) +// ); +// addModifier( +// id("remove_glowstone_and_gunpowder_from_witch"), +// LootModifier.builder() +// .conditionally( +// TablePredicate.builder().name(EntityType.WITCH.getDefaultLootTable().map(ResourceKey::location).map(ResourceLocation::toString).orElse("")) +// .and( +// EntryItemPredicate.builder(new ItemWrapper(BuiltInRegistries.ITEM.wrapAsHolder(Items.GLOWSTONE_DUST))) +// .or(EntryItemPredicate.builder(new ItemWrapper(BuiltInRegistries.ITEM.wrapAsHolder(Items.GUNPOWDER)))) +// ) +// ) +// .action( +// EntryRemoveAction.builder() +// ) +// ); +// addModifier( +// id("squid_ink_sac_only_from_player"), +// LootModifier.builder() +// .conditionally( +// TablePredicate.builder() +// .name(EntityType.SQUID.getDefaultLootTable().map(ResourceKey::location).map(ResourceLocation::toString).orElse("")) +// .and(EntryItemPredicate.builder(new ItemWrapper(BuiltInRegistries.ITEM.wrapAsHolder(Items.INK_SAC)))) +// ) +// .action( +// ConditionAddAction.builder() +// .onlyPools() +// .condition( +// new LootConditionWrapper(LootItemKilledByPlayerCondition.killedByPlayer().build()) +// ) +// ) +// ); +// } +// } +// +// private static class LootProvider extends SimpleFabricLootTableProvider { +// public LootProvider(FabricDataOutput output, CompletableFuture registryLookup) { +// super(output, registryLookup, LootContextParamSets.CHEST); +// } +// +// @Override +// public void generate(BiConsumer, LootTable.Builder> lootTableBiConsumer) { +// lootTableBiConsumer.accept(ResourceKey.create(Registries.LOOT_TABLE, id("test_empty_table")), LootTable.lootTable()); +// } +// } +//} +// \ No newline at end of file diff --git a/loader/neoforge/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/neoforge/v1212/mixin/ReloadableRegistriesMixin.java b/loader/neoforge/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/neoforge/v1212/mixin/ReloadableRegistriesMixin.java new file mode 100644 index 0000000..27e7b08 --- /dev/null +++ b/loader/neoforge/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/neoforge/v1212/mixin/ReloadableRegistriesMixin.java @@ -0,0 +1,47 @@ +package top.offsetmonkey538.loottablemodifier.neoforge.v1212.mixin; + +import com.google.gson.JsonElement; +import it.unimi.dsi.fastutil.Pair; +import net.minecraft.core.Registry; +import net.minecraft.core.WritableRegistry; +import net.minecraft.resources.RegistryOps; +import net.minecraft.server.ReloadableServerRegistries; +import net.minecraft.server.packs.resources.ResourceManager; +import net.minecraft.world.level.storage.loot.LootDataType; +import net.minecraft.world.level.storage.loot.LootTable; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import top.offsetmonkey538.loottablemodifier.common.LootTableModifierCommon; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.IdentifierWrapper; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.ResourceManagerWrapper; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootTableWrapper; + +@Mixin( + value = ReloadableServerRegistries.class, + priority = 900 +) +public abstract class ReloadableRegistriesMixin { + @Inject( + method = "lambda$scheduleRegistryLoad$5(Lnet/minecraft/world/level/storage/loot/LootDataType;Lnet/minecraft/server/packs/resources/ResourceManager;Lnet/minecraft/resources/RegistryOps;)Lnet/minecraft/core/WritableRegistry;", + at = @At("RETURN") + ) + private static void loot_table_modifier$modifyLootTables(LootDataType lootDataType, ResourceManager resourceManager, RegistryOps registryOps, CallbackInfoReturnable> cir) { + if (lootDataType != LootDataType.TABLE) return; + + //noinspection unchecked + final Registry lootRegistry = (Registry) cir.getReturnValue(); + + LootTableModifierCommon.runModification( + new ResourceManagerWrapper(resourceManager), + lootRegistry + .listElements() + .map(registryEntry -> Pair.of( + new IdentifierWrapper(registryEntry.key().location()), + new LootTableWrapper(lootRegistry.getValue(registryEntry.key())) + )), + registryOps + ); + } +} diff --git a/loader/neoforge/1.21.2/src/main/resources/loot-table-modifier.version.loader.mixins.json b/loader/neoforge/1.21.2/src/main/resources/loot-table-modifier.version.loader.mixins.json new file mode 100644 index 0000000..b15d1cc --- /dev/null +++ b/loader/neoforge/1.21.2/src/main/resources/loot-table-modifier.version.loader.mixins.json @@ -0,0 +1,11 @@ +{ + "required": true, + "package": "top.offsetmonkey538.loottablemodifier.neoforge.v1212.mixin", + "compatibilityLevel": "JAVA_21", + "mixins": [ + "ReloadableRegistriesMixin" + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/loader/neoforge/1.21/gradle.properties b/loader/neoforge/1.21/gradle.properties new file mode 100644 index 0000000..e630058 --- /dev/null +++ b/loader/neoforge/1.21/gradle.properties @@ -0,0 +1,13 @@ +project_name = neoforge-1.21 +commonModdedVersion = 1.21 + +monkeylib538_suffix = 1.21 + +# Miminum Minecraft version supported, check at https://fabricmc.net/develop +minecraft_version = 1.21 +supported_minecraft_versions = >=1.21 <=1.21.1 +minecraft_version_range = [1.21,1.21.1] + +neoforge_version = 21.0.167 +parchment_minecraft_version = 1.21.1 +parchment_mappings_version = 2024.11.17 diff --git a/loader/neoforge/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/neoforge/v121/datagen/LootTableModifierDatagen.java b/loader/neoforge/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/neoforge/v121/datagen/LootTableModifierDatagen.java new file mode 100644 index 0000000..246ff1b --- /dev/null +++ b/loader/neoforge/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/neoforge/v121/datagen/LootTableModifierDatagen.java @@ -0,0 +1,217 @@ +//package top.offsetmonkey538.loottablemodifier.neoforge.v121.datagen; +// +//import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint; +//import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator; +//import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; +//import net.fabricmc.fabric.api.datagen.v1.provider.SimpleFabricLootTableProvider; +//import net.minecraft.core.HolderLookup; +//import net.minecraft.core.registries.BuiltInRegistries; +//import net.minecraft.core.registries.Registries; +//import net.minecraft.resources.ResourceKey; +//import net.minecraft.world.entity.EntityType; +//import net.minecraft.world.item.Items; +//import net.minecraft.world.level.block.Blocks; +//import net.minecraft.world.level.storage.loot.LootPool; +//import net.minecraft.world.level.storage.loot.LootTable; +//import net.minecraft.world.level.storage.loot.entries.LootItem; +//import net.minecraft.world.level.storage.loot.functions.SetItemCountFunction; +//import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets; +//import net.minecraft.world.level.storage.loot.predicates.LootItemKilledByPlayerCondition; +//import net.minecraft.world.level.storage.loot.providers.number.ConstantValue; +//import net.minecraft.world.level.storage.loot.providers.number.UniformGenerator; +//import top.offsetmonkey538.loottablemodifier.neoforge.api.datagen.LootModifierProvider; +//import top.offsetmonkey538.loottablemodifier.common.api.resource.LootModifier; +//import top.offsetmonkey538.loottablemodifier.common.api.resource.action.condition.ConditionAddAction; +//import top.offsetmonkey538.loottablemodifier.common.api.resource.action.entry.EntryAddAction; +//import top.offsetmonkey538.loottablemodifier.common.api.resource.action.entry.EntryRemoveAction; +//import top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.table.TablePredicate; +//import top.offsetmonkey538.loottablemodifier.common.api.resource.util.RegexPattern; +//import top.offsetmonkey538.loottablemodifier.common.api.resource.action.pool.PoolAddAction; +//import top.offsetmonkey538.loottablemodifier.common.api.resource.action.entry.EntryItemSetAction; +//import top.offsetmonkey538.loottablemodifier.common.api.resource.action.pool.PoolRemoveAction; +//import top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.entry.EntryItemPredicate; +//import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.ItemWrapper; +//import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootConditionWrapper; +//import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootPoolWrapper; +//import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.entry.LootPoolEntryWrapper; +//import top.offsetmonkey538.loottablemodifier.modded.v121.mixin.LootContextTypesAccessor; +// +//import java.util.concurrent.CompletableFuture; +//import java.util.function.BiConsumer; +// +//import static top.offsetmonkey538.loottablemodifier.modded.platform.LootTableModifierInitializer.id; +// +///** +// * Datagen for loot modifiers used for testing. +// */ +//public class LootTableModifierDatagen implements DataGeneratorEntrypoint { +// +// @Override +// public void onInitializeDataGenerator(FabricDataGenerator fabricDataGenerator) { +// final FabricDataGenerator.Pack pack = fabricDataGenerator.createBuiltinResourcePack(id("example_pack")); +// +// pack.addProvider(ModLootModifierProvider::new); +// pack.addProvider(LootProvider::new); +// } +// +// private static class ModLootModifierProvider extends LootModifierProvider { +// public ModLootModifierProvider(FabricDataOutput dataOutput, CompletableFuture registriesFuture) { +// super(dataOutput, registriesFuture); +// } +// +// @Override +// protected void generate(HolderLookup.Provider lookup) { +// addModifier( +// id("replace_ingots_with_command_block"), +// LootModifier.builder() +// .conditionally( +// EntryItemPredicate.builder(RegexPattern.compile("minecraft:.*_ingot")) +// ) +// .action( +// EntryItemSetAction.builder(new ItemWrapper(BuiltInRegistries.ITEM.wrapAsHolder(Items.COMMAND_BLOCK))) +// ) +// ); +// addModifier( +// id("sugarcane_drop_tnt"), +// LootModifier.builder() +// .conditionally( +// EntryItemPredicate.builder(new ItemWrapper(BuiltInRegistries.ITEM.wrapAsHolder(Items.SUGAR_CANE))) +// ) +// .action( +// PoolAddAction.builder() +// .pool( +// new LootPoolWrapper(LootPool.lootPool() +// .setRolls(ConstantValue.exactly(1)) +// .add( +// LootItem.lootTableItem(Items.TNT) +// .apply(SetItemCountFunction.setCount(UniformGenerator.between(1, 1))) +// ).build()) +// ) +// ) +// ); +// addModifier( +// id("mobs_drop_tnt"), +// LootModifier.builder() +// .conditionally( +// TablePredicate.builder() +// .name(EntityType.CREEPER.getDefaultLootTable().location().toString()) +// .name(EntityType.ZOMBIE.getDefaultLootTable().location().toString()) +// ) +// .action( +// PoolAddAction.builder() +// .pool( +// new LootPoolWrapper(LootPool.lootPool() +// .setRolls(ConstantValue.exactly(1)) +// .add( +// LootItem.lootTableItem(Items.TNT) +// .apply(SetItemCountFunction.setCount(UniformGenerator.between(1, 1))) +// ).build()) +// ) +// ) +// ); +// addModifier( +// id("empty_table_test"), +// LootModifier.builder() +// .conditionally( +// TablePredicate.builder() +// .name(ResourceKey.create(Registries.LOOT_TABLE, id("test_empty_table")).location().toString()) +// ) +// .action( +// PoolAddAction.builder() +// .pool( +// new LootPoolWrapper(LootPool.lootPool() +// .setRolls(ConstantValue.exactly(1)) +// .add( +// LootItem.lootTableItem(Items.TNT) +// .apply(SetItemCountFunction.setCount(UniformGenerator.between(1, 1))) +// ).build()) +// ) +// ) +// ); +// addModifier( +// id("remove_pools_with_sticks"), +// LootModifier.builder() +// .conditionally( +// EntryItemPredicate.builder(new ItemWrapper(BuiltInRegistries.ITEM.wrapAsHolder(Items.STICK))) +// // Exclude witch to test if AllOf and Inverted work + so I can test RemoveEntry on witch. +// .and(TablePredicate.builder().name(EntityType.WITCH.getDefaultLootTable().location().toString()).invert()) +// ) +// .action( +// PoolRemoveAction.builder() +// ) +// ); +// addModifier( +// id("add_cake_entry_to_dirt_block"), +// LootModifier.builder() +// .conditionally( +// TablePredicate.builder() +// .name(Blocks.DIRT.getLootTable().location().toString()) +// ) +// .action( +// EntryAddAction.builder() +// .entry( +// LootPoolEntryWrapper.create(LootItem.lootTableItem(Items.CAKE) +// .apply(SetItemCountFunction.setCount(UniformGenerator.between(1, 1))).build()) +// ) +// ) +// ); +// addModifier( +// id("add_command_block_to_all_blocks"), +// LootModifier.builder() +// .conditionally( +// TablePredicate.builder() +// .type(LootContextTypesAccessor.getMAP().inverse().get(LootContextParamSets.BLOCK).toString()) +// ) +// .action( +// EntryAddAction.builder() +// .entry( +// LootPoolEntryWrapper.create(LootItem.lootTableItem(Items.CAKE) +// .apply(SetItemCountFunction.setCount(UniformGenerator.between(1, 1))).build()) +// ) +// ) +// ); +// addModifier( +// id("remove_glowstone_and_gunpowder_from_witch"), +// LootModifier.builder() +// .conditionally( +// TablePredicate.builder().name(EntityType.WITCH.getDefaultLootTable().location().toString()) +// .and( +// EntryItemPredicate.builder(new ItemWrapper(BuiltInRegistries.ITEM.wrapAsHolder(Items.GLOWSTONE_DUST))) +// .or(EntryItemPredicate.builder(new ItemWrapper(BuiltInRegistries.ITEM.wrapAsHolder(Items.GUNPOWDER)))) +// ) +// ) +// .action( +// EntryRemoveAction.builder() +// ) +// ); +// addModifier( +// id("squid_ink_sac_only_from_player"), +// LootModifier.builder() +// .conditionally( +// TablePredicate.builder() +// .name(EntityType.SQUID.getDefaultLootTable().location().toString()) +// .and(EntryItemPredicate.builder(new ItemWrapper(BuiltInRegistries.ITEM.wrapAsHolder(Items.INK_SAC)))) +// ) +// .action( +// ConditionAddAction.builder() +// .onlyPools() +// .condition( +// new LootConditionWrapper(LootItemKilledByPlayerCondition.killedByPlayer().build()) +// ) +// ) +// ); +// } +// } +// +// private static class LootProvider extends SimpleFabricLootTableProvider { +// public LootProvider(FabricDataOutput output, CompletableFuture registryLookup) { +// super(output, registryLookup, LootContextParamSets.CHEST); +// } +// +// @Override +// public void generate(BiConsumer, LootTable.Builder> consumer) { +// consumer.accept(ResourceKey.create(Registries.LOOT_TABLE, id("test_empty_table")), LootTable.lootTable()); +// } +// } +//} +// \ No newline at end of file diff --git a/loader/neoforge/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/neoforge/v121/mixin/ReloadableRegistriesMixin.java b/loader/neoforge/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/neoforge/v121/mixin/ReloadableRegistriesMixin.java new file mode 100644 index 0000000..1c432e0 --- /dev/null +++ b/loader/neoforge/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/neoforge/v121/mixin/ReloadableRegistriesMixin.java @@ -0,0 +1,47 @@ +package top.offsetmonkey538.loottablemodifier.neoforge.v121.mixin; + +import com.google.gson.JsonElement; +import it.unimi.dsi.fastutil.Pair; +import net.minecraft.core.Registry; +import net.minecraft.core.WritableRegistry; +import net.minecraft.resources.RegistryOps; +import net.minecraft.server.ReloadableServerRegistries; +import net.minecraft.server.packs.resources.ResourceManager; +import net.minecraft.world.level.storage.loot.LootDataType; +import net.minecraft.world.level.storage.loot.LootTable; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import top.offsetmonkey538.loottablemodifier.common.LootTableModifierCommon; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.IdentifierWrapper; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.ResourceManagerWrapper; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootTableWrapper; + +@Mixin( + value = ReloadableServerRegistries.class, + priority = 900 +) +public abstract class ReloadableRegistriesMixin { + @Inject( + method = "lambda$scheduleElementParse$4(Lnet/minecraft/world/level/storage/loot/LootDataType;Lnet/minecraft/server/packs/resources/ResourceManager;Lnet/minecraft/resources/RegistryOps;)Lnet/minecraft/core/WritableRegistry;", + at = @At("RETURN") + ) + private static void loot_table_modifier$modifyLootTables(LootDataType lootDataType, ResourceManager resourceManager, RegistryOps registryOps, CallbackInfoReturnable> cir) { + if (lootDataType != LootDataType.TABLE) return; + + //noinspection unchecked + final Registry lootRegistry = (Registry) cir.getReturnValue(); + + LootTableModifierCommon.runModification( + new ResourceManagerWrapper(resourceManager), + lootRegistry.asLookup() + .listElements() + .map(registryEntry -> Pair.of( + new IdentifierWrapper(registryEntry.key().location()), + new LootTableWrapper(lootRegistry.get(registryEntry.key())) + )), + registryOps + ); + } +} diff --git a/loader/neoforge/1.21/src/main/resources/loot-table-modifier.version.loader.mixins.json b/loader/neoforge/1.21/src/main/resources/loot-table-modifier.version.loader.mixins.json new file mode 100644 index 0000000..04a7864 --- /dev/null +++ b/loader/neoforge/1.21/src/main/resources/loot-table-modifier.version.loader.mixins.json @@ -0,0 +1,11 @@ +{ + "required": true, + "package": "top.offsetmonkey538.loottablemodifier.neoforge.v121.mixin", + "compatibilityLevel": "JAVA_21", + "mixins": [ + "ReloadableRegistriesMixin" + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/loader/neoforge/build.gradle b/loader/neoforge/build.gradle new file mode 100644 index 0000000..8687fec --- /dev/null +++ b/loader/neoforge/build.gradle @@ -0,0 +1,150 @@ +import dex.plugins.outlet.v2.util.ReleaseType + +plugins { + id 'multiloader-modded' + id 'net.neoforged.moddev' + id 'io.github.dexman545.outlet' apply false + id 'com.modrinth.minotaur' apply false +} + +neoForge { + runs { + + } +} + +allprojects { + apply plugin: "multiloader-modded" + apply plugin: "net.neoforged.moddev" + + dependencies { + compileOnly project(":common") + commonJava project(path: ":common", configuration: "commonJava") + commonResources project(path: ":common", configuration: "commonResources") + compileOnly project(":modded") + commonJava project(path: ":modded", configuration: "commonJava") + commonResources project(path: ":modded", configuration: "commonResources") + + compileOnly "top.offsetmonkey538.monkeylib538:monkeylib538-neoforge:${rootProject.monkeylib538_version}+neoforge" + } + + neoForge { + version = project.neoforge_version + + parchment { + minecraftVersion = project.parchment_minecraft_version + mappingsVersion = project.parchment_mappings_version + } + + mods { + "loot-table-modifier" { + sourceSet(sourceSets.main) + } + } + } +} + +subprojects { + apply plugin: "net.neoforged.moddev" + apply plugin: "io.github.dexman545.outlet" + apply plugin: "com.modrinth.minotaur" + + tasks.modrinth.dependsOn(tasks.modrinthSyncBody) + + outlet { + mcVersionRange = project.supported_minecraft_versions + allowedReleaseTypes = Set.of(ReleaseType.RELEASE) + } + + configurations { + runtimeClasspath.extendsFrom localRuntime + } + + repositories { + maven { + name = "DevAuth" + url = "https://pkgs.dev.azure.com/djtheredstoner/DevAuth/_packaging/public/maven/v1" + content { + includeGroup "me.djtheredstoner" + } + } + } + + dependencies { + compileOnly project(":loader:neoforge") + commonJava project(path: ":loader:neoforge", configuration: "commonJava") + commonResources project(path: ":loader:neoforge", configuration: "commonResources") + + compileOnly project(":modded:${project.commonModdedVersion}") + commonJava project(path: ":modded:${project.commonModdedVersion}", configuration: "commonJava") + commonResources project(path: ":modded:${project.commonModdedVersion}", configuration: "commonResources") + + runtimeOnly "top.offsetmonkey538.monkeylib538:monkeylib538-neoforge-${project.monkeylib538_suffix}:${rootProject.monkeylib538_version}+neoforge+${project.monkeylib538_suffix}" + + // DevAuth + localRuntime "me.djtheredstoner:DevAuth-neoforge:${rootProject.devauth_version}" + } + + neoForge { + runs { + client { + client() + } + + server { + server() + } + + configureEach { + systemProperty 'forge.logging.markers', 'REGISTRIES' + logLevel = org.slf4j.event.Level.INFO + } + } + } + + sourceSets { + main { + resources { + srcDirs += [ + "src/main/generated" // TODO: figure out how to datagen + ] + } + } + } + + modrinth { + // Main properties + token = System.getenv("MODRINTH_TOKEN") + projectId = "loot-table-modifier" + gameVersions = outlet.mcVersions() + loaders = ["neoforge"] + + // Version stuff + def customVersionName = System.getenv("VERSION_NAME") + if (customVersionName != null) versionName = customVersionName + + versionNumber = "${project.version}" + + versionType = Boolean.parseBoolean(System.getenv("VERSION_IS_PRERELEASE")) ? "beta" : "release" + + if (rootProject.mod_version.contains("beta")) versionType = "beta" + if (rootProject.mod_version.contains("alpha")) versionType = "alpha" + + + // Files + uploadFile = jar.archiveFile + additionalFiles = [sourcesJar.archiveFile] + + + // Project info + syncBodyFrom = rootProject.file("README.md").text + def changelogEnv = System.getenv("VERSION_CHANGELOG") + if (changelogEnv != null) changelog = changelogEnv + + + // Dependencies + dependencies { + + } + } +} diff --git a/loader/neoforge/gradle.properties b/loader/neoforge/gradle.properties new file mode 100644 index 0000000..0261d48 --- /dev/null +++ b/loader/neoforge/gradle.properties @@ -0,0 +1,11 @@ +project_name = neoforge + + +## "Common" fabric one should depend on the latest version just so it can access Minecraft and Fabric. +## It MUST NOT include version-specific code + +# Minecraft version, check at https://fabricmc.net/develop +minecraft_version = 1.21.8 +neoforge_version = 21.8.52 +parchment_minecraft_version = 1.21.8 +parchment_mappings_version = 2025.09.14 diff --git a/loader/neoforge/src/main/java/top/offsetmonkey538/loottablemodifier/neoforge/api/datagen/LootModifierProvider.java b/loader/neoforge/src/main/java/top/offsetmonkey538/loottablemodifier/neoforge/api/datagen/LootModifierProvider.java new file mode 100644 index 0000000..2cfcffd --- /dev/null +++ b/loader/neoforge/src/main/java/top/offsetmonkey538/loottablemodifier/neoforge/api/datagen/LootModifierProvider.java @@ -0,0 +1,18 @@ +//package top.offsetmonkey538.loottablemodifier.neoforge.api.datagen; +// +//import com.mojang.serialization.Codec; +//import net.minecraft.core.HolderLookup; +//import net.minecraft.data.PackOutput; +//import net.neoforged.neoforge.common.data.JsonCodecProvider; +//import top.offsetmonkey538.loottablemodifier.common.api.resource.LootModifier; +// +//import java.util.concurrent.CompletableFuture; +// +//import static top.offsetmonkey538.loottablemodifier.common.LootTableModifierCommon.MOD_ID; +// +//public abstract class LootModifierProvider extends JsonCodecProvider { +// public LootModifierProvider(PackOutput output, CompletableFuture lookupProvider, String modId) { +// super(output, PackOutput.Target.DATA_PACK, MOD_ID + "/loot_modifier", LootModifier.CODEC, lookupProvider, modId); +// } +//} +// \ No newline at end of file diff --git a/loader/neoforge/src/main/java/top/offsetmonkey538/loottablemodifier/neoforge/platform/LootTableModifierInitializer.java b/loader/neoforge/src/main/java/top/offsetmonkey538/loottablemodifier/neoforge/platform/LootTableModifierInitializer.java new file mode 100644 index 0000000..7d63725 --- /dev/null +++ b/loader/neoforge/src/main/java/top/offsetmonkey538/loottablemodifier/neoforge/platform/LootTableModifierInitializer.java @@ -0,0 +1,22 @@ +package top.offsetmonkey538.loottablemodifier.neoforge.platform; + +import net.neoforged.bus.api.IEventBus; +import net.neoforged.fml.ModContainer; +import net.neoforged.fml.common.Mod; +import top.offsetmonkey538.loottablemodifier.common.LootTableModifierCommon; + +@Mod("loot_table_modifier") +public class LootTableModifierInitializer { + + public LootTableModifierInitializer(IEventBus modEventBus, ModContainer modContainer) { + LootTableModifierCommon.initialize(); + //TODO: if (IS_DEV) NeoForge.EVENT_BUS.addListener(AddPackFindersEvent.class, event -> event.addPackFinders( + //TODO: id("example_pack"), + //TODO: PackType.SERVER_DATA, + //TODO: Component.literal("Example Pack"), + //TODO: PackSource.BUILT_IN, + //TODO: false, + //TODO: Pack.Position.TOP + //TODO: )); + } +} diff --git a/loader/neoforge/src/main/resources/META-INF/neoforge.mods.toml b/loader/neoforge/src/main/resources/META-INF/neoforge.mods.toml new file mode 100644 index 0000000..b9d7b60 --- /dev/null +++ b/loader/neoforge/src/main/resources/META-INF/neoforge.mods.toml @@ -0,0 +1,34 @@ +modLoader = "javafml" +loaderVersion = "[1,)" +license="MIT" + +issueTrackerURL="https://github.com/OffsetMods538/Loot-Table-Modifier/issues" + + +[[mixins]] +config="loot-table-modifier.modded.mixins.json" +[[mixins]] +config="loot-table-modifier.version.modded.mixins.json" +[[mixins]] +config="loot-table-modifier.version.loader.mixins.json" + + +[[mods]] +modId="loot_table_modifier" +version="${modVersion}" +displayName="Loot Table Modifier" +description="Makes it possible to modify instead of replace loot tables through datapacks" +logoFile="assets/loot-table-modifier/icon.png" +logoBlur=false +features={javaVersion="[21,)"} +modUrl="https://modrinth.com/mod/loot-table-modifier" +authors="OffsetMonkey538" +displayURL="https://modrinth.com/mod/loot-table-modifier" + + +[[dependencies.loot_table_modifier]] +modId="minecraft" +type="required" +versionRange="${neoforgeSupportedMinecraftVersions}" +ordering="NONE" +side="BOTH" diff --git a/modded/1.20.1/gradle.properties b/modded/1.20.1/gradle.properties new file mode 100644 index 0000000..6b8d81f --- /dev/null +++ b/modded/1.20.1/gradle.properties @@ -0,0 +1,6 @@ +project_name = modded-1.20.1 + +monkeylib538_suffix = 1.20.1 + +# Miminum Minecraft version supported, check at https://fabricmc.net/develop +minecraft_version = 1.20.1 diff --git a/modded/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1201/codec/GSONCodec.java b/modded/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1201/codec/GSONCodec.java new file mode 100644 index 0000000..a3ddf13 --- /dev/null +++ b/modded/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1201/codec/GSONCodec.java @@ -0,0 +1,39 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1201.codec; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonSyntaxException; +import com.mojang.datafixers.util.Pair; +import com.mojang.serialization.*; + +public final class GSONCodec implements Codec { + private final Gson gson; + private final Class clazz; + + public GSONCodec(final GsonBuilder gsonBuilder, final Class clazz) { + this.gson = gsonBuilder.create(); + this.clazz = clazz; + } + + @Override + public DataResult> decode(DynamicOps ops, T input) { + try { + return DataResult.success(Pair.of( + gson.fromJson(ops.convertTo(JsonOps.INSTANCE, input), clazz), + input + )); + } catch (JsonSyntaxException e) { + return DataResult.error(e::getMessage); + } + } + + @Override + public DataResult encode(C input, DynamicOps ops, T prefix) { + try { + return ops.getMap(JsonOps.INSTANCE.convertTo(ops, gson.toJsonTree(input))) + .flatMap(map -> ops.mergeToMap(prefix, map)); + } catch (JsonSyntaxException e) { + return DataResult.error(e::getMessage); + } + } +} diff --git a/modded/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1201/impl/TableGetterById.java b/modded/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1201/impl/TableGetterById.java new file mode 100644 index 0000000..d7a2b03 --- /dev/null +++ b/modded/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1201/impl/TableGetterById.java @@ -0,0 +1,15 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1201.impl; + +import net.minecraft.commands.CommandSourceStack; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.Identifier; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootTable; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.IdentifierWrapper; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootTableWrapper; +import top.offsetmonkey538.loottablemodifier.modded.platform.ModdedPlatformCommandUtils; + +public final class TableGetterById implements ModdedPlatformCommandUtils.TableGetterById { + @Override + public LootTable getTableForIdImpl(CommandSourceStack source, Identifier id) { + return new LootTableWrapper(source.getServer().getLootData().getLootTable(((IdentifierWrapper) id).vanillaIdentifier())); + } +} diff --git a/modded/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1201/impl/resource/action/LootModifierActionTypeCodecProviderImpl.java b/modded/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1201/impl/resource/action/LootModifierActionTypeCodecProviderImpl.java new file mode 100644 index 0000000..b5feeb6 --- /dev/null +++ b/modded/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1201/impl/resource/action/LootModifierActionTypeCodecProviderImpl.java @@ -0,0 +1,15 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1201.impl.resource.action; + +import com.mojang.serialization.Codec; +import top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierAction; +import top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierActionType; +import top.offsetmonkey538.loottablemodifier.modded.impl.resource.action.LootModifierActionTypeRegistryImpl; + +public final class LootModifierActionTypeCodecProviderImpl implements LootModifierActionType.CodecProvider { + private static final Codec CODEC = LootModifierActionTypeRegistryImpl.REGISTRY.byNameCodec().dispatch(LootModifierAction::getType, lootModifierActionType -> lootModifierActionType.codec().codec()); + + @Override + public Codec get() { + return CODEC; + } +} diff --git a/modded/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1201/impl/resource/predicate/LootModifierPredicateTypeCodecProviderImpl.java b/modded/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1201/impl/resource/predicate/LootModifierPredicateTypeCodecProviderImpl.java new file mode 100644 index 0000000..0dcd9bd --- /dev/null +++ b/modded/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1201/impl/resource/predicate/LootModifierPredicateTypeCodecProviderImpl.java @@ -0,0 +1,15 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1201.impl.resource.predicate; + +import com.mojang.serialization.Codec; +import top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicate; +import top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicateType; +import top.offsetmonkey538.loottablemodifier.modded.impl.resource.predicate.LootModifierPredicateTypeRegistryImpl; + +public final class LootModifierPredicateTypeCodecProviderImpl implements LootModifierPredicateType.CodecProvider { + private static final Codec CODEC = LootModifierPredicateTypeRegistryImpl.REGISTRY.byNameCodec().dispatch(LootModifierPredicate::getType, lootModifierPredicateType -> lootModifierPredicateType.codec().codec()); + + @Override + public Codec get() { + return CODEC; + } +} diff --git a/modded/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1201/impl/wrapper/IdentifierInstantiator.java b/modded/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1201/impl/wrapper/IdentifierInstantiator.java new file mode 100644 index 0000000..f887f11 --- /dev/null +++ b/modded/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1201/impl/wrapper/IdentifierInstantiator.java @@ -0,0 +1,12 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1201.impl.wrapper; + +import net.minecraft.resources.ResourceLocation; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.Identifier; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.IdentifierWrapper; + +public final class IdentifierInstantiator implements Identifier.Instantiator { + @Override + public Identifier apply(String s) { + return new IdentifierWrapper(new ResourceLocation(s)); + } +} diff --git a/modded/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1201/impl/wrapper/ItemCodecProviderImpl.java b/modded/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1201/impl/wrapper/ItemCodecProviderImpl.java new file mode 100644 index 0000000..08f4f47 --- /dev/null +++ b/modded/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1201/impl/wrapper/ItemCodecProviderImpl.java @@ -0,0 +1,13 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1201.impl.wrapper; + +import com.mojang.serialization.Codec; +import net.minecraft.core.registries.BuiltInRegistries; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.Item; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.ItemWrapper; + +public final class ItemCodecProviderImpl implements Item.CodecProvider { + @Override + public Codec get() { + return BuiltInRegistries.ITEM.holderByNameCodec().xmap(ItemWrapper::new, wrappedItem -> ((ItemWrapper) wrappedItem).vanillaItem()); + } +} diff --git a/modded/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1201/impl/wrapper/loot/LootConditionCodecProviderImpl.java b/modded/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1201/impl/wrapper/loot/LootConditionCodecProviderImpl.java new file mode 100644 index 0000000..521abc1 --- /dev/null +++ b/modded/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1201/impl/wrapper/loot/LootConditionCodecProviderImpl.java @@ -0,0 +1,18 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1201.impl.wrapper.loot; + +import com.mojang.serialization.Codec; +import net.minecraft.world.level.storage.loot.Deserializers; +import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootCondition; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootConditionWrapper; +import top.offsetmonkey538.loottablemodifier.modded.v1201.codec.GSONCodec; + +public final class LootConditionCodecProviderImpl implements LootCondition.CodecProvider { + private static final Codec CODEC = new GSONCodec<>(Deserializers.createConditionSerializer(), LootItemCondition.class) + .xmap(LootConditionWrapper::new, wrappedCondition -> ((LootConditionWrapper) wrappedCondition).vanillaCondition()); + + @Override + public Codec get() { + return CODEC; + } +} diff --git a/modded/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1201/impl/wrapper/loot/LootPoolCodecProviderImpl.java b/modded/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1201/impl/wrapper/loot/LootPoolCodecProviderImpl.java new file mode 100644 index 0000000..51d4806 --- /dev/null +++ b/modded/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1201/impl/wrapper/loot/LootPoolCodecProviderImpl.java @@ -0,0 +1,17 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1201.impl.wrapper.loot; + +import com.mojang.serialization.Codec; +import net.minecraft.world.level.storage.loot.Deserializers; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootPool; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootPoolWrapper; +import top.offsetmonkey538.loottablemodifier.modded.v1201.codec.GSONCodec; + +public final class LootPoolCodecProviderImpl implements LootPool.CodecProvider { + private static final Codec CODEC = new GSONCodec<>(Deserializers.createLootTableSerializer(), net.minecraft.world.level.storage.loot.LootPool.class) + .xmap(LootPoolWrapper::new, wrappedPool -> ((LootPoolWrapper) wrappedPool).vanillaPool()); + + @Override + public Codec get() { + return CODEC; + } +} diff --git a/modded/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1201/impl/wrapper/loot/LootTableCodecProviderImpl.java b/modded/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1201/impl/wrapper/loot/LootTableCodecProviderImpl.java new file mode 100644 index 0000000..68216bb --- /dev/null +++ b/modded/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1201/impl/wrapper/loot/LootTableCodecProviderImpl.java @@ -0,0 +1,17 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1201.impl.wrapper.loot; + +import com.mojang.serialization.Codec; +import net.minecraft.world.level.storage.loot.Deserializers; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootTable; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootTableWrapper; +import top.offsetmonkey538.loottablemodifier.modded.v1201.codec.GSONCodec; + +public final class LootTableCodecProviderImpl implements LootTable.CodecProvider { + private static final Codec CODEC = new GSONCodec<>(Deserializers.createLootTableSerializer(), net.minecraft.world.level.storage.loot.LootTable.class) + .xmap(LootTableWrapper::new, wrappedPool -> ((LootTableWrapper) wrappedPool).vanillaTable()); + + @Override + public Codec get() { + return CODEC; + } +} diff --git a/modded/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1201/impl/wrapper/loot/LootTableTypeGetterImpl.java b/modded/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1201/impl/wrapper/loot/LootTableTypeGetterImpl.java new file mode 100644 index 0000000..3603906 --- /dev/null +++ b/modded/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1201/impl/wrapper/loot/LootTableTypeGetterImpl.java @@ -0,0 +1,12 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1201.impl.wrapper.loot; + +import net.minecraft.world.level.storage.loot.LootTable; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootTableWrapper; +import top.offsetmonkey538.loottablemodifier.modded.v1201.mixin.LootContextTypesAccessor; + +public final class LootTableTypeGetterImpl implements LootTableWrapper.TypeGetter { + @Override + public String apply(LootTable lootTable) { + return LootContextTypesAccessor.getMAP().inverse().get(lootTable.getParamSet()).toString(); + } +} diff --git a/modded/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1201/impl/wrapper/loot/entry/LootPoolEntryCodecProviderImpl.java b/modded/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1201/impl/wrapper/loot/entry/LootPoolEntryCodecProviderImpl.java new file mode 100644 index 0000000..bb8682a --- /dev/null +++ b/modded/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1201/impl/wrapper/loot/entry/LootPoolEntryCodecProviderImpl.java @@ -0,0 +1,18 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1201.impl.wrapper.loot.entry; + +import com.mojang.serialization.Codec; +import net.minecraft.world.level.storage.loot.Deserializers; +import net.minecraft.world.level.storage.loot.entries.LootPoolEntryContainer; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.entry.LootPoolEntry; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.entry.LootPoolEntryWrapper; +import top.offsetmonkey538.loottablemodifier.modded.v1201.codec.GSONCodec; + +public final class LootPoolEntryCodecProviderImpl implements LootPoolEntry.CodecProvider { + private static final Codec CODEC = new GSONCodec<>(Deserializers.createFunctionSerializer(), LootPoolEntryContainer.class) + .xmap(LootPoolEntryWrapper::create, wrappedEntry -> ((LootPoolEntryWrapper) wrappedEntry).vanillaEntry); + + @Override + public Codec get() { + return CODEC; + } +} diff --git a/modded/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1201/mixin/ItemEntryMixin.java b/modded/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1201/mixin/ItemEntryMixin.java new file mode 100644 index 0000000..0083c54 --- /dev/null +++ b/modded/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1201/mixin/ItemEntryMixin.java @@ -0,0 +1,29 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1201.mixin; + +import net.minecraft.core.Holder; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.storage.loot.entries.LootItem; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +import org.spongepowered.asm.mixin.Shadow; +import top.offsetmonkey538.loottablemodifier.modded.duck.ItemEntryDuck; + +@Mixin(LootItem.class) +public abstract class ItemEntryMixin implements ItemEntryDuck { + @Shadow + @Mutable + @Final + Item item; + + @Override + public void loot_table_modifier$setItem(Holder itemHolder) { + this.item = itemHolder.value(); + } + + @Override + public String loot_table_modifier$getId() { + return BuiltInRegistries.ITEM.getKey(this.item).toString(); + } +} diff --git a/modded/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1201/mixin/LootContextTypesAccessor.java b/modded/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1201/mixin/LootContextTypesAccessor.java new file mode 100644 index 0000000..708f055 --- /dev/null +++ b/modded/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1201/mixin/LootContextTypesAccessor.java @@ -0,0 +1,16 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1201.mixin; + +import com.google.common.collect.BiMap; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.storage.loot.parameters.LootContextParamSet; +import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(LootContextParamSets.class) +public interface LootContextTypesAccessor { + @Accessor("REGISTRY") + static BiMap getMAP() { + throw new AssertionError(); + } +} diff --git a/modded/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1201/mixin/LootPoolEntryMixin.java b/modded/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1201/mixin/LootPoolEntryMixin.java new file mode 100644 index 0000000..57bc195 --- /dev/null +++ b/modded/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1201/mixin/LootPoolEntryMixin.java @@ -0,0 +1,38 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1201.mixin; + +import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.level.storage.loot.entries.LootPoolEntryContainer; +import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; +import org.spongepowered.asm.mixin.*; +import top.offsetmonkey538.loottablemodifier.common.util.PredicateUtils; +import top.offsetmonkey538.loottablemodifier.modded.duck.LootElementWithConditions; + +import java.util.Arrays; +import java.util.List; +import java.util.function.Predicate; + +@Mixin(LootPoolEntryContainer.class) +public abstract class LootPoolEntryMixin implements LootElementWithConditions { + + @Shadow + @Final + @Mutable + protected LootItemCondition[] conditions; + + @Shadow + @Final + @Mutable + private Predicate compositeCondition; + + @Override + @Unique + public void loot_table_modifier$setConditions(List conditions) { + this.conditions = conditions.toArray(LootItemCondition[]::new); + this.compositeCondition = PredicateUtils.allOf(conditions); + } + + @Override + public List loot_table_modifier$getConditions() { + return Arrays.asList(this.conditions); + } +} diff --git a/modded/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1201/mixin/LootPoolMixin.java b/modded/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1201/mixin/LootPoolMixin.java new file mode 100644 index 0000000..5caf033 --- /dev/null +++ b/modded/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1201/mixin/LootPoolMixin.java @@ -0,0 +1,79 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1201.mixin; + +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.level.storage.loot.LootPool; +import net.minecraft.world.level.storage.loot.entries.LootPoolEntryContainer; +import net.minecraft.world.level.storage.loot.functions.LootItemFunction; +import net.minecraft.world.level.storage.loot.functions.LootItemFunctions; +import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; +import org.spongepowered.asm.mixin.*; +import top.offsetmonkey538.loottablemodifier.common.util.PredicateUtils; +import top.offsetmonkey538.loottablemodifier.modded.duck.LootPoolDuck; + +import java.util.Arrays; +import java.util.List; +import java.util.function.BiFunction; +import java.util.function.Predicate; + +@Mixin(LootPool.class) +public abstract class LootPoolMixin implements LootPoolDuck { + + @Shadow + @Final + @Mutable + LootItemCondition[] conditions; + + @Shadow + @Final + @Mutable + private Predicate compositeCondition; + + @Shadow + @Mutable + @Final + LootPoolEntryContainer[] entries; + + @Shadow + @Mutable + @Final + LootItemFunction[] functions; + + @Shadow + @Mutable + @Final + private BiFunction compositeFunction; + + @Override + @Unique + public void loot_table_modifier$setConditions(List conditions) { + this.conditions = conditions.toArray(LootItemCondition[]::new); + this.compositeCondition = PredicateUtils.allOf(conditions); + } + + @Override + public List loot_table_modifier$getConditions() { + return Arrays.asList(this.conditions); + } + + @Override + public void loot_table_modifier$setEntries(List entries) { + this.entries = entries.toArray(LootPoolEntryContainer[]::new); + } + + @Override + public List loot_table_modifier$getEntries() { + return Arrays.asList(this.entries); + } + + @Override + public void loot_table_modifier$setFunctions(List functions) { + this.functions = functions.toArray(LootItemFunction[]::new); + this.compositeFunction = LootItemFunctions.compose(this.functions); + } + + @Override + public List loot_table_modifier$getFunctions() { + return Arrays.asList(this.functions); + } +} diff --git a/modded/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1201/mixin/LootTableMixin.java b/modded/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1201/mixin/LootTableMixin.java new file mode 100644 index 0000000..20cb001 --- /dev/null +++ b/modded/1.20.1/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1201/mixin/LootTableMixin.java @@ -0,0 +1,57 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1201.mixin; + +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.level.storage.loot.LootPool; +import net.minecraft.world.level.storage.loot.LootTable; +import net.minecraft.world.level.storage.loot.functions.LootItemFunction; +import net.minecraft.world.level.storage.loot.functions.LootItemFunctions; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +import org.spongepowered.asm.mixin.Shadow; +import top.offsetmonkey538.loottablemodifier.modded.duck.LootTableDuck; + +import java.util.Arrays; +import java.util.List; +import java.util.function.BiFunction; + +@Mixin(LootTable.class) +public abstract class LootTableMixin implements LootTableDuck { + + @Shadow + @Mutable + @Final + LootPool[] pools; + + @Shadow + @Mutable + @Final + LootItemFunction[] functions; + + @Shadow + @Mutable + @Final + private BiFunction compositeFunction; + + @Override + public void loot_table_modifier$setPools(List pools) { + this.pools = pools.toArray(LootPool[]::new); + } + + @Override + public List loot_table_modifier$getPools() { + return Arrays.asList(this.pools); + } + + @Override + public void loot_table_modifier$setFunctions(List functions) { + this.functions = functions.toArray(LootItemFunction[]::new); + this.compositeFunction = LootItemFunctions.compose(this.functions); + } + + @Override + public List loot_table_modifier$getFunctions() { + return Arrays.asList(this.functions); + } +} diff --git a/modded/1.20.1/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierActionType$CodecProvider b/modded/1.20.1/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierActionType$CodecProvider new file mode 100644 index 0000000..2e887ec --- /dev/null +++ b/modded/1.20.1/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierActionType$CodecProvider @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v1201.impl.resource.action.LootModifierActionTypeCodecProviderImpl \ No newline at end of file diff --git a/modded/1.20.1/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicateType$CodecProvider b/modded/1.20.1/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicateType$CodecProvider new file mode 100644 index 0000000..652f6cc --- /dev/null +++ b/modded/1.20.1/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicateType$CodecProvider @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v1201.impl.resource.predicate.LootModifierPredicateTypeCodecProviderImpl \ No newline at end of file diff --git a/modded/1.20.1/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.Identifier$Instantiator b/modded/1.20.1/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.Identifier$Instantiator new file mode 100644 index 0000000..c720fd5 --- /dev/null +++ b/modded/1.20.1/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.Identifier$Instantiator @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v1201.impl.wrapper.IdentifierInstantiator \ No newline at end of file diff --git a/modded/1.20.1/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.Item$CodecProvider b/modded/1.20.1/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.Item$CodecProvider new file mode 100644 index 0000000..52136ac --- /dev/null +++ b/modded/1.20.1/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.Item$CodecProvider @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v1201.impl.wrapper.ItemCodecProviderImpl \ No newline at end of file diff --git a/modded/1.20.1/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootCondition$CodecProvider b/modded/1.20.1/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootCondition$CodecProvider new file mode 100644 index 0000000..6141ffa --- /dev/null +++ b/modded/1.20.1/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootCondition$CodecProvider @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v1201.impl.wrapper.loot.LootConditionCodecProviderImpl \ No newline at end of file diff --git a/modded/1.20.1/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootPool$CodecProvider b/modded/1.20.1/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootPool$CodecProvider new file mode 100644 index 0000000..1655e86 --- /dev/null +++ b/modded/1.20.1/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootPool$CodecProvider @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v1201.impl.wrapper.loot.LootPoolCodecProviderImpl \ No newline at end of file diff --git a/modded/1.20.1/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootTable$CodecProvider b/modded/1.20.1/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootTable$CodecProvider new file mode 100644 index 0000000..92b6ac0 --- /dev/null +++ b/modded/1.20.1/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootTable$CodecProvider @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v1201.impl.wrapper.loot.LootTableCodecProviderImpl \ No newline at end of file diff --git a/modded/1.20.1/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.entry.LootPoolEntry$CodecProvider b/modded/1.20.1/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.entry.LootPoolEntry$CodecProvider new file mode 100644 index 0000000..d4dadb3 --- /dev/null +++ b/modded/1.20.1/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.entry.LootPoolEntry$CodecProvider @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v1201.impl.wrapper.loot.entry.LootPoolEntryCodecProviderImpl \ No newline at end of file diff --git a/modded/1.20.1/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootTableWrapper$TypeGetter b/modded/1.20.1/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootTableWrapper$TypeGetter new file mode 100644 index 0000000..21f8df3 --- /dev/null +++ b/modded/1.20.1/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootTableWrapper$TypeGetter @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v1201.impl.wrapper.loot.LootTableTypeGetterImpl \ No newline at end of file diff --git a/modded/1.20.1/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.modded.platform.ModdedPlatformCommandUtils$TableGetterById b/modded/1.20.1/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.modded.platform.ModdedPlatformCommandUtils$TableGetterById new file mode 100644 index 0000000..acdf0f0 --- /dev/null +++ b/modded/1.20.1/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.modded.platform.ModdedPlatformCommandUtils$TableGetterById @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v1201.impl.TableGetterById \ No newline at end of file diff --git a/modded/1.20.1/src/main/resources/loot-table-modifier.version.modded.mixins.json b/modded/1.20.1/src/main/resources/loot-table-modifier.version.modded.mixins.json new file mode 100644 index 0000000..c28e173 --- /dev/null +++ b/modded/1.20.1/src/main/resources/loot-table-modifier.version.modded.mixins.json @@ -0,0 +1,15 @@ +{ + "required": true, + "package": "top.offsetmonkey538.loottablemodifier.modded.v1201.mixin", + "compatibilityLevel": "JAVA_21", + "mixins": [ + "ItemEntryMixin", + "LootContextTypesAccessor", + "LootPoolEntryMixin", + "LootPoolMixin", + "LootTableMixin" + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/modded/1.20.2/gradle.properties b/modded/1.20.2/gradle.properties new file mode 100644 index 0000000..da34419 --- /dev/null +++ b/modded/1.20.2/gradle.properties @@ -0,0 +1,6 @@ +project_name = modded-1.20.2 + +monkeylib538_suffix = 1.20.1 + +# Miminum Minecraft version supported, check at https://fabricmc.net/develop +minecraft_version = 1.20.2 diff --git a/modded/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1202/impl/TableGetterById.java b/modded/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1202/impl/TableGetterById.java new file mode 100644 index 0000000..273c286 --- /dev/null +++ b/modded/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1202/impl/TableGetterById.java @@ -0,0 +1,15 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1202.impl; + +import net.minecraft.commands.CommandSourceStack; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.Identifier; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootTable; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.IdentifierWrapper; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootTableWrapper; +import top.offsetmonkey538.loottablemodifier.modded.platform.ModdedPlatformCommandUtils; + +public final class TableGetterById implements ModdedPlatformCommandUtils.TableGetterById { + @Override + public LootTable getTableForIdImpl(CommandSourceStack source, Identifier id) { + return new LootTableWrapper(source.getServer().getLootData().getLootTable(((IdentifierWrapper) id).vanillaIdentifier())); + } +} diff --git a/modded/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1202/impl/resource/action/LootModifierActionTypeCodecProviderImpl.java b/modded/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1202/impl/resource/action/LootModifierActionTypeCodecProviderImpl.java new file mode 100644 index 0000000..9864cd9 --- /dev/null +++ b/modded/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1202/impl/resource/action/LootModifierActionTypeCodecProviderImpl.java @@ -0,0 +1,15 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1202.impl.resource.action; + +import com.mojang.serialization.Codec; +import top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierAction; +import top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierActionType; +import top.offsetmonkey538.loottablemodifier.modded.impl.resource.action.LootModifierActionTypeRegistryImpl; + +public final class LootModifierActionTypeCodecProviderImpl implements LootModifierActionType.CodecProvider { + private static final Codec CODEC = LootModifierActionTypeRegistryImpl.REGISTRY.byNameCodec().dispatch(LootModifierAction::getType, lootModifierActionType -> lootModifierActionType.codec().codec()); + + @Override + public Codec get() { + return CODEC; + } +} diff --git a/modded/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1202/impl/resource/predicate/LootModifierPredicateTypeCodecProviderImpl.java b/modded/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1202/impl/resource/predicate/LootModifierPredicateTypeCodecProviderImpl.java new file mode 100644 index 0000000..d0f7343 --- /dev/null +++ b/modded/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1202/impl/resource/predicate/LootModifierPredicateTypeCodecProviderImpl.java @@ -0,0 +1,15 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1202.impl.resource.predicate; + +import com.mojang.serialization.Codec; +import top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicate; +import top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicateType; +import top.offsetmonkey538.loottablemodifier.modded.impl.resource.predicate.LootModifierPredicateTypeRegistryImpl; + +public final class LootModifierPredicateTypeCodecProviderImpl implements LootModifierPredicateType.CodecProvider { + private static final Codec CODEC = LootModifierPredicateTypeRegistryImpl.REGISTRY.byNameCodec().dispatch(LootModifierPredicate::getType, lootModifierPredicateType -> lootModifierPredicateType.codec().codec()); + + @Override + public Codec get() { + return CODEC; + } +} diff --git a/modded/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1202/impl/wrapper/IdentifierInstantiator.java b/modded/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1202/impl/wrapper/IdentifierInstantiator.java new file mode 100644 index 0000000..f0050b6 --- /dev/null +++ b/modded/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1202/impl/wrapper/IdentifierInstantiator.java @@ -0,0 +1,12 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1202.impl.wrapper; + +import net.minecraft.resources.ResourceLocation; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.Identifier; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.IdentifierWrapper; + +public final class IdentifierInstantiator implements Identifier.Instantiator { + @Override + public Identifier apply(String s) { + return new IdentifierWrapper(new ResourceLocation(s)); + } +} diff --git a/modded/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1202/impl/wrapper/ItemCodecProviderImpl.java b/modded/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1202/impl/wrapper/ItemCodecProviderImpl.java new file mode 100644 index 0000000..a39eb6f --- /dev/null +++ b/modded/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1202/impl/wrapper/ItemCodecProviderImpl.java @@ -0,0 +1,13 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1202.impl.wrapper; + +import com.mojang.serialization.Codec; +import net.minecraft.core.registries.BuiltInRegistries; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.Item; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.ItemWrapper; + +public final class ItemCodecProviderImpl implements Item.CodecProvider { + @Override + public Codec get() { + return BuiltInRegistries.ITEM.holderByNameCodec().xmap(ItemWrapper::new, wrappedItem -> ((ItemWrapper) wrappedItem).vanillaItem()); + } +} diff --git a/modded/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1202/impl/wrapper/loot/LootConditionCodecProviderImpl.java b/modded/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1202/impl/wrapper/loot/LootConditionCodecProviderImpl.java new file mode 100644 index 0000000..ee65387 --- /dev/null +++ b/modded/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1202/impl/wrapper/loot/LootConditionCodecProviderImpl.java @@ -0,0 +1,13 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1202.impl.wrapper.loot; + +import com.mojang.serialization.Codec; +import net.minecraft.world.level.storage.loot.predicates.LootItemConditions; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootCondition; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootConditionWrapper; + +public final class LootConditionCodecProviderImpl implements LootCondition.CodecProvider { + @Override + public Codec get() { + return LootItemConditions.CODEC.xmap(LootConditionWrapper::new, wrappedCondition -> ((LootConditionWrapper) wrappedCondition).vanillaCondition()); + } +} diff --git a/modded/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1202/impl/wrapper/loot/LootPoolCodecProviderImpl.java b/modded/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1202/impl/wrapper/loot/LootPoolCodecProviderImpl.java new file mode 100644 index 0000000..19b9410 --- /dev/null +++ b/modded/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1202/impl/wrapper/loot/LootPoolCodecProviderImpl.java @@ -0,0 +1,12 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1202.impl.wrapper.loot; + +import com.mojang.serialization.Codec; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootPool; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootPoolWrapper; + +public final class LootPoolCodecProviderImpl implements LootPool.CodecProvider { + @Override + public Codec get() { + return net.minecraft.world.level.storage.loot.LootPool.CODEC.xmap(LootPoolWrapper::new, wrappedPool -> ((LootPoolWrapper) wrappedPool).vanillaPool()); + } +} diff --git a/modded/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1202/impl/wrapper/loot/LootTableCodecProviderImpl.java b/modded/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1202/impl/wrapper/loot/LootTableCodecProviderImpl.java new file mode 100644 index 0000000..f3acc57 --- /dev/null +++ b/modded/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1202/impl/wrapper/loot/LootTableCodecProviderImpl.java @@ -0,0 +1,12 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1202.impl.wrapper.loot; + +import com.mojang.serialization.Codec; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootTable; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootTableWrapper; + +public final class LootTableCodecProviderImpl implements LootTable.CodecProvider { + @Override + public Codec get() { + return net.minecraft.world.level.storage.loot.LootTable.CODEC.xmap(LootTableWrapper::new, wrappedPool -> ((LootTableWrapper) wrappedPool).vanillaTable()); + } +} diff --git a/modded/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1202/impl/wrapper/loot/LootTableTypeGetterImpl.java b/modded/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1202/impl/wrapper/loot/LootTableTypeGetterImpl.java new file mode 100644 index 0000000..72baa3f --- /dev/null +++ b/modded/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1202/impl/wrapper/loot/LootTableTypeGetterImpl.java @@ -0,0 +1,12 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1202.impl.wrapper.loot; + +import net.minecraft.world.level.storage.loot.LootTable; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootTableWrapper; +import top.offsetmonkey538.loottablemodifier.modded.v1202.mixin.LootContextTypesAccessor; + +public final class LootTableTypeGetterImpl implements LootTableWrapper.TypeGetter { + @Override + public String apply(LootTable lootTable) { + return LootContextTypesAccessor.getMAP().inverse().get(lootTable.getParamSet()).toString(); + } +} diff --git a/modded/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1202/impl/wrapper/loot/entry/LootPoolEntryCodecProviderImpl.java b/modded/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1202/impl/wrapper/loot/entry/LootPoolEntryCodecProviderImpl.java new file mode 100644 index 0000000..e4caf5e --- /dev/null +++ b/modded/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1202/impl/wrapper/loot/entry/LootPoolEntryCodecProviderImpl.java @@ -0,0 +1,13 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1202.impl.wrapper.loot.entry; + +import com.mojang.serialization.Codec; +import net.minecraft.world.level.storage.loot.entries.LootPoolEntries; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.entry.LootPoolEntry; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.entry.LootPoolEntryWrapper; + +public final class LootPoolEntryCodecProviderImpl implements LootPoolEntry.CodecProvider { + @Override + public Codec get() { + return LootPoolEntries.CODEC.xmap(LootPoolEntryWrapper::create, wrappedEntry -> ((LootPoolEntryWrapper) wrappedEntry).vanillaEntry); + } +} diff --git a/modded/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1202/mixin/ItemEntryMixin.java b/modded/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1202/mixin/ItemEntryMixin.java new file mode 100644 index 0000000..903a975 --- /dev/null +++ b/modded/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1202/mixin/ItemEntryMixin.java @@ -0,0 +1,28 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1202.mixin; + +import net.minecraft.core.Holder; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.storage.loot.entries.LootItem; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +import org.spongepowered.asm.mixin.Shadow; +import top.offsetmonkey538.loottablemodifier.modded.duck.ItemEntryDuck; + +@Mixin(LootItem.class) +public abstract class ItemEntryMixin implements ItemEntryDuck { + @Shadow + @Mutable + @Final + private Holder item; + + @Override + public void loot_table_modifier$setItem(Holder itemHolder) { + this.item = itemHolder; + } + + @Override + public String loot_table_modifier$getId() { + return this.item.unwrapKey().map(key -> key.location().toString()).orElse("[unregistered]"); + } +} diff --git a/modded/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1202/mixin/LootContextTypesAccessor.java b/modded/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1202/mixin/LootContextTypesAccessor.java new file mode 100644 index 0000000..b02e236 --- /dev/null +++ b/modded/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1202/mixin/LootContextTypesAccessor.java @@ -0,0 +1,16 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1202.mixin; + +import com.google.common.collect.BiMap; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.storage.loot.parameters.LootContextParamSet; +import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(LootContextParamSets.class) +public interface LootContextTypesAccessor { + @Accessor("REGISTRY") + static BiMap getMAP() { + throw new AssertionError(); + } +} diff --git a/modded/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1202/mixin/LootPoolEntryMixin.java b/modded/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1202/mixin/LootPoolEntryMixin.java new file mode 100644 index 0000000..caf887b --- /dev/null +++ b/modded/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1202/mixin/LootPoolEntryMixin.java @@ -0,0 +1,37 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1202.mixin; + +import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.level.storage.loot.entries.LootPoolEntryContainer; +import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; +import org.spongepowered.asm.mixin.*; +import top.offsetmonkey538.loottablemodifier.common.util.PredicateUtils; +import top.offsetmonkey538.loottablemodifier.modded.duck.LootElementWithConditions; + +import java.util.List; +import java.util.function.Predicate; + +@Mixin(LootPoolEntryContainer.class) +public abstract class LootPoolEntryMixin implements LootElementWithConditions { + + @Shadow + @Final + @Mutable + protected List conditions; + + @Shadow + @Final + @Mutable + private Predicate compositeCondition; + + @Override + @Unique + public void loot_table_modifier$setConditions(List conditions) { + this.conditions = conditions; + this.compositeCondition = PredicateUtils.allOf(conditions); + } + + @Override + public List loot_table_modifier$getConditions() { + return this.conditions; + } +} diff --git a/modded/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1202/mixin/LootPoolMixin.java b/modded/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1202/mixin/LootPoolMixin.java new file mode 100644 index 0000000..91a6c2b --- /dev/null +++ b/modded/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1202/mixin/LootPoolMixin.java @@ -0,0 +1,78 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1202.mixin; + +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.level.storage.loot.LootPool; +import net.minecraft.world.level.storage.loot.entries.LootPoolEntryContainer; +import net.minecraft.world.level.storage.loot.functions.LootItemFunction; +import net.minecraft.world.level.storage.loot.functions.LootItemFunctions; +import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; +import org.spongepowered.asm.mixin.*; +import top.offsetmonkey538.loottablemodifier.common.util.PredicateUtils; +import top.offsetmonkey538.loottablemodifier.modded.duck.LootPoolDuck; + +import java.util.List; +import java.util.function.BiFunction; +import java.util.function.Predicate; + +@Mixin(LootPool.class) +public abstract class LootPoolMixin implements LootPoolDuck { + + @Shadow + @Final + @Mutable + private List conditions; + + @Shadow + @Final + @Mutable + private Predicate compositeCondition; + + @Shadow + @Mutable + @Final + private List entries; + + @Shadow + @Mutable + @Final + private List functions; + + @Shadow + @Mutable + @Final + private BiFunction compositeFunction; + + @Override + @Unique + public void loot_table_modifier$setConditions(List conditions) { + this.conditions = conditions; + this.compositeCondition = PredicateUtils.allOf(conditions); + } + + @Override + public List loot_table_modifier$getConditions() { + return this.conditions; + } + + @Override + public void loot_table_modifier$setEntries(List entries) { + this.entries = entries; + } + + @Override + public List loot_table_modifier$getEntries() { + return this.entries; + } + + @Override + public void loot_table_modifier$setFunctions(List functions) { + this.functions = functions; + this.compositeFunction = LootItemFunctions.compose(functions); + } + + @Override + public List loot_table_modifier$getFunctions() { + return this.functions; + } +} diff --git a/modded/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1202/mixin/LootTableMixin.java b/modded/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1202/mixin/LootTableMixin.java new file mode 100644 index 0000000..ae77e69 --- /dev/null +++ b/modded/1.20.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1202/mixin/LootTableMixin.java @@ -0,0 +1,56 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1202.mixin; + +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.level.storage.loot.LootPool; +import net.minecraft.world.level.storage.loot.LootTable; +import net.minecraft.world.level.storage.loot.functions.LootItemFunction; +import net.minecraft.world.level.storage.loot.functions.LootItemFunctions; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +import org.spongepowered.asm.mixin.Shadow; +import top.offsetmonkey538.loottablemodifier.modded.duck.LootTableDuck; + +import java.util.List; +import java.util.function.BiFunction; + +@Mixin(LootTable.class) +public abstract class LootTableMixin implements LootTableDuck { + + @Shadow + @Mutable + @Final + private List pools; + + @Shadow + @Mutable + @Final + private List functions; + + @Shadow + @Mutable + @Final + private BiFunction compositeFunction; + + @Override + public void loot_table_modifier$setPools(List pools) { + this.pools = pools; + } + + @Override + public List loot_table_modifier$getPools() { + return this.pools; + } + + @Override + public void loot_table_modifier$setFunctions(List functions) { + this.functions = functions; + this.compositeFunction = LootItemFunctions.compose(functions); + } + + @Override + public List loot_table_modifier$getFunctions() { + return this.functions; + } +} diff --git a/modded/1.20.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierActionType$CodecProvider b/modded/1.20.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierActionType$CodecProvider new file mode 100644 index 0000000..f2da455 --- /dev/null +++ b/modded/1.20.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierActionType$CodecProvider @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v1202.impl.resource.action.LootModifierActionTypeCodecProviderImpl \ No newline at end of file diff --git a/modded/1.20.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicateType$CodecProvider b/modded/1.20.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicateType$CodecProvider new file mode 100644 index 0000000..b277aeb --- /dev/null +++ b/modded/1.20.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicateType$CodecProvider @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v1202.impl.resource.predicate.LootModifierPredicateTypeCodecProviderImpl \ No newline at end of file diff --git a/modded/1.20.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.Identifier$Instantiator b/modded/1.20.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.Identifier$Instantiator new file mode 100644 index 0000000..318bef0 --- /dev/null +++ b/modded/1.20.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.Identifier$Instantiator @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v1202.impl.wrapper.IdentifierInstantiator \ No newline at end of file diff --git a/modded/1.20.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.Item$CodecProvider b/modded/1.20.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.Item$CodecProvider new file mode 100644 index 0000000..d7a9f7d --- /dev/null +++ b/modded/1.20.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.Item$CodecProvider @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v1202.impl.wrapper.ItemCodecProviderImpl \ No newline at end of file diff --git a/modded/1.20.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootCondition$CodecProvider b/modded/1.20.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootCondition$CodecProvider new file mode 100644 index 0000000..b69bab1 --- /dev/null +++ b/modded/1.20.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootCondition$CodecProvider @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v1202.impl.wrapper.loot.LootConditionCodecProviderImpl \ No newline at end of file diff --git a/modded/1.20.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootPool$CodecProvider b/modded/1.20.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootPool$CodecProvider new file mode 100644 index 0000000..bac55b4 --- /dev/null +++ b/modded/1.20.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootPool$CodecProvider @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v1202.impl.wrapper.loot.LootPoolCodecProviderImpl \ No newline at end of file diff --git a/modded/1.20.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootTable$CodecProvider b/modded/1.20.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootTable$CodecProvider new file mode 100644 index 0000000..ae2a50f --- /dev/null +++ b/modded/1.20.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootTable$CodecProvider @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v1202.impl.wrapper.loot.LootTableCodecProviderImpl \ No newline at end of file diff --git a/modded/1.20.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.entry.LootPoolEntry$CodecProvider b/modded/1.20.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.entry.LootPoolEntry$CodecProvider new file mode 100644 index 0000000..665d7a3 --- /dev/null +++ b/modded/1.20.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.entry.LootPoolEntry$CodecProvider @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v1202.impl.wrapper.loot.entry.LootPoolEntryCodecProviderImpl \ No newline at end of file diff --git a/modded/1.20.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootTableWrapper$TypeGetter b/modded/1.20.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootTableWrapper$TypeGetter new file mode 100644 index 0000000..62c657e --- /dev/null +++ b/modded/1.20.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootTableWrapper$TypeGetter @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v1202.impl.wrapper.loot.LootTableTypeGetterImpl \ No newline at end of file diff --git a/modded/1.20.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.modded.platform.ModdedPlatformCommandUtils$TableGetterById b/modded/1.20.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.modded.platform.ModdedPlatformCommandUtils$TableGetterById new file mode 100644 index 0000000..bf90b97 --- /dev/null +++ b/modded/1.20.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.modded.platform.ModdedPlatformCommandUtils$TableGetterById @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v1202.impl.TableGetterById \ No newline at end of file diff --git a/modded/1.20.2/src/main/resources/loot-table-modifier.version.modded.mixins.json b/modded/1.20.2/src/main/resources/loot-table-modifier.version.modded.mixins.json new file mode 100644 index 0000000..7621c32 --- /dev/null +++ b/modded/1.20.2/src/main/resources/loot-table-modifier.version.modded.mixins.json @@ -0,0 +1,15 @@ +{ + "required": true, + "package": "top.offsetmonkey538.loottablemodifier.modded.v1202.mixin", + "compatibilityLevel": "JAVA_21", + "mixins": [ + "ItemEntryMixin", + "LootContextTypesAccessor", + "LootPoolEntryMixin", + "LootPoolMixin", + "LootTableMixin" + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/modded/1.20.5/gradle.properties b/modded/1.20.5/gradle.properties new file mode 100644 index 0000000..63f2246 --- /dev/null +++ b/modded/1.20.5/gradle.properties @@ -0,0 +1,6 @@ +project_name = modded-1.20.5 + +monkeylib538_suffix = 1.20.1 + +# Miminum Minecraft version supported, check at https://fabricmc.net/develop +minecraft_version = 1.20.5 diff --git a/modded/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1205/impl/TableGetterById.java b/modded/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1205/impl/TableGetterById.java new file mode 100644 index 0000000..c73f14c --- /dev/null +++ b/modded/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1205/impl/TableGetterById.java @@ -0,0 +1,17 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1205.impl; + +import net.minecraft.commands.CommandSourceStack; +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.ResourceKey; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.Identifier; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootTable; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.IdentifierWrapper; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootTableWrapper; +import top.offsetmonkey538.loottablemodifier.modded.platform.ModdedPlatformCommandUtils; + +public final class TableGetterById implements ModdedPlatformCommandUtils.TableGetterById { + @Override + public LootTable getTableForIdImpl(CommandSourceStack source, Identifier id) { + return new LootTableWrapper(source.getServer().reloadableRegistries().getLootTable(ResourceKey.create(Registries.LOOT_TABLE, ((IdentifierWrapper) id).vanillaIdentifier()))); + } +} diff --git a/modded/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1205/impl/resource/action/LootModifierActionTypeCodecProviderImpl.java b/modded/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1205/impl/resource/action/LootModifierActionTypeCodecProviderImpl.java new file mode 100644 index 0000000..29f5a8d --- /dev/null +++ b/modded/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1205/impl/resource/action/LootModifierActionTypeCodecProviderImpl.java @@ -0,0 +1,15 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1205.impl.resource.action; + +import com.mojang.serialization.Codec; +import top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierAction; +import top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierActionType; +import top.offsetmonkey538.loottablemodifier.modded.impl.resource.action.LootModifierActionTypeRegistryImpl; + +public final class LootModifierActionTypeCodecProviderImpl implements LootModifierActionType.CodecProvider { + private static final Codec CODEC = LootModifierActionTypeRegistryImpl.REGISTRY.byNameCodec().dispatch(LootModifierAction::getType, LootModifierActionType::codec); + + @Override + public Codec get() { + return CODEC; + } +} diff --git a/modded/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1205/impl/resource/predicate/LootModifierPredicateTypeCodecProviderImpl.java b/modded/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1205/impl/resource/predicate/LootModifierPredicateTypeCodecProviderImpl.java new file mode 100644 index 0000000..bd1d483 --- /dev/null +++ b/modded/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1205/impl/resource/predicate/LootModifierPredicateTypeCodecProviderImpl.java @@ -0,0 +1,15 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1205.impl.resource.predicate; + +import com.mojang.serialization.Codec; +import top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicate; +import top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicateType; +import top.offsetmonkey538.loottablemodifier.modded.impl.resource.predicate.LootModifierPredicateTypeRegistryImpl; + +public final class LootModifierPredicateTypeCodecProviderImpl implements LootModifierPredicateType.CodecProvider { + private static final Codec CODEC = LootModifierPredicateTypeRegistryImpl.REGISTRY.byNameCodec().dispatch(LootModifierPredicate::getType, LootModifierPredicateType::codec); + + @Override + public Codec get() { + return CODEC; + } +} diff --git a/modded/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1205/impl/wrapper/IdentifierInstantiator.java b/modded/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1205/impl/wrapper/IdentifierInstantiator.java new file mode 100644 index 0000000..30ca31f --- /dev/null +++ b/modded/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1205/impl/wrapper/IdentifierInstantiator.java @@ -0,0 +1,12 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1205.impl.wrapper; + +import net.minecraft.resources.ResourceLocation; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.Identifier; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.IdentifierWrapper; + +public final class IdentifierInstantiator implements Identifier.Instantiator { + @Override + public Identifier apply(String s) { + return new IdentifierWrapper(new ResourceLocation(s)); + } +} diff --git a/modded/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1205/impl/wrapper/ItemCodecProviderImpl.java b/modded/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1205/impl/wrapper/ItemCodecProviderImpl.java new file mode 100644 index 0000000..8ac2b97 --- /dev/null +++ b/modded/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1205/impl/wrapper/ItemCodecProviderImpl.java @@ -0,0 +1,13 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1205.impl.wrapper; + +import com.mojang.serialization.Codec; +import net.minecraft.core.registries.BuiltInRegistries; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.Item; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.ItemWrapper; + +public final class ItemCodecProviderImpl implements Item.CodecProvider { + @Override + public Codec get() { + return BuiltInRegistries.ITEM.holderByNameCodec().xmap(ItemWrapper::new, wrappedItem -> ((ItemWrapper) wrappedItem).vanillaItem()); + } +} diff --git a/modded/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1205/impl/wrapper/loot/LootConditionCodecProviderImpl.java b/modded/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1205/impl/wrapper/loot/LootConditionCodecProviderImpl.java new file mode 100644 index 0000000..2827ab0 --- /dev/null +++ b/modded/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1205/impl/wrapper/loot/LootConditionCodecProviderImpl.java @@ -0,0 +1,13 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1205.impl.wrapper.loot; + +import com.mojang.serialization.Codec; +import net.minecraft.world.level.storage.loot.predicates.LootItemConditions; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootCondition; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootConditionWrapper; + +public final class LootConditionCodecProviderImpl implements LootCondition.CodecProvider { + @Override + public Codec get() { + return LootItemConditions.DIRECT_CODEC.xmap(LootConditionWrapper::new, wrappedCondition -> ((LootConditionWrapper) wrappedCondition).vanillaCondition()); + } +} diff --git a/modded/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1205/impl/wrapper/loot/LootPoolCodecProviderImpl.java b/modded/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1205/impl/wrapper/loot/LootPoolCodecProviderImpl.java new file mode 100644 index 0000000..a03d303 --- /dev/null +++ b/modded/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1205/impl/wrapper/loot/LootPoolCodecProviderImpl.java @@ -0,0 +1,12 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1205.impl.wrapper.loot; + +import com.mojang.serialization.Codec; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootPool; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootPoolWrapper; + +public final class LootPoolCodecProviderImpl implements LootPool.CodecProvider { + @Override + public Codec get() { + return net.minecraft.world.level.storage.loot.LootPool.CODEC.xmap(LootPoolWrapper::new, wrappedPool -> ((LootPoolWrapper) wrappedPool).vanillaPool()); + } +} diff --git a/modded/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1205/impl/wrapper/loot/LootTableCodecProviderImpl.java b/modded/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1205/impl/wrapper/loot/LootTableCodecProviderImpl.java new file mode 100644 index 0000000..829ed04 --- /dev/null +++ b/modded/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1205/impl/wrapper/loot/LootTableCodecProviderImpl.java @@ -0,0 +1,12 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1205.impl.wrapper.loot; + +import com.mojang.serialization.Codec; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootTable; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootTableWrapper; + +public final class LootTableCodecProviderImpl implements LootTable.CodecProvider { + @Override + public Codec get() { + return net.minecraft.world.level.storage.loot.LootTable.DIRECT_CODEC.xmap(LootTableWrapper::new, wrappedPool -> ((LootTableWrapper) wrappedPool).vanillaTable()); + } +} diff --git a/modded/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1205/impl/wrapper/loot/LootTableTypeGetterImpl.java b/modded/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1205/impl/wrapper/loot/LootTableTypeGetterImpl.java new file mode 100644 index 0000000..525ff7d --- /dev/null +++ b/modded/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1205/impl/wrapper/loot/LootTableTypeGetterImpl.java @@ -0,0 +1,12 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1205.impl.wrapper.loot; + +import net.minecraft.world.level.storage.loot.LootTable; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootTableWrapper; +import top.offsetmonkey538.loottablemodifier.modded.v1205.mixin.LootContextTypesAccessor; + +public final class LootTableTypeGetterImpl implements LootTableWrapper.TypeGetter { + @Override + public String apply(LootTable lootTable) { + return LootContextTypesAccessor.getMAP().inverse().get(lootTable.getParamSet()).toString(); + } +} diff --git a/modded/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1205/impl/wrapper/loot/entry/LootPoolEntryCodecProviderImpl.java b/modded/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1205/impl/wrapper/loot/entry/LootPoolEntryCodecProviderImpl.java new file mode 100644 index 0000000..8cb47aa --- /dev/null +++ b/modded/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1205/impl/wrapper/loot/entry/LootPoolEntryCodecProviderImpl.java @@ -0,0 +1,13 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1205.impl.wrapper.loot.entry; + +import com.mojang.serialization.Codec; +import net.minecraft.world.level.storage.loot.entries.LootPoolEntries; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.entry.LootPoolEntry; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.entry.LootPoolEntryWrapper; + +public final class LootPoolEntryCodecProviderImpl implements LootPoolEntry.CodecProvider { + @Override + public Codec get() { + return LootPoolEntries.CODEC.xmap(LootPoolEntryWrapper::create, wrappedEntry -> ((LootPoolEntryWrapper) wrappedEntry).vanillaEntry); + } +} diff --git a/modded/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1205/mixin/ItemEntryMixin.java b/modded/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1205/mixin/ItemEntryMixin.java new file mode 100644 index 0000000..eb31dd3 --- /dev/null +++ b/modded/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1205/mixin/ItemEntryMixin.java @@ -0,0 +1,28 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1205.mixin; + +import net.minecraft.core.Holder; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.storage.loot.entries.LootItem; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +import org.spongepowered.asm.mixin.Shadow; +import top.offsetmonkey538.loottablemodifier.modded.duck.ItemEntryDuck; + +@Mixin(LootItem.class) +public abstract class ItemEntryMixin implements ItemEntryDuck { + @Shadow + @Mutable + @Final + private Holder item; + + @Override + public void loot_table_modifier$setItem(Holder itemHolder) { + this.item = itemHolder; + } + + @Override + public String loot_table_modifier$getId() { + return this.item.unwrapKey().map(key -> key.location().toString()).orElse("[unregistered]"); + } +} diff --git a/modded/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1205/mixin/LootContextTypesAccessor.java b/modded/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1205/mixin/LootContextTypesAccessor.java new file mode 100644 index 0000000..0baaf5e --- /dev/null +++ b/modded/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1205/mixin/LootContextTypesAccessor.java @@ -0,0 +1,16 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1205.mixin; + +import com.google.common.collect.BiMap; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.storage.loot.parameters.LootContextParamSet; +import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(LootContextParamSets.class) +public interface LootContextTypesAccessor { + @Accessor("REGISTRY") + static BiMap getMAP() { + throw new AssertionError(); + } +} diff --git a/modded/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1205/mixin/LootPoolEntryMixin.java b/modded/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1205/mixin/LootPoolEntryMixin.java new file mode 100644 index 0000000..b7f8c9b --- /dev/null +++ b/modded/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1205/mixin/LootPoolEntryMixin.java @@ -0,0 +1,37 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1205.mixin; + +import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.level.storage.loot.entries.LootPoolEntryContainer; +import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; +import org.spongepowered.asm.mixin.*; +import top.offsetmonkey538.loottablemodifier.common.util.PredicateUtils; +import top.offsetmonkey538.loottablemodifier.modded.duck.LootElementWithConditions; + +import java.util.List; +import java.util.function.Predicate; + +@Mixin(LootPoolEntryContainer.class) +public abstract class LootPoolEntryMixin implements LootElementWithConditions { + + @Shadow + @Final + @Mutable + protected List conditions; + + @Shadow + @Final + @Mutable + private Predicate compositeCondition; + + @Override + @Unique + public void loot_table_modifier$setConditions(List conditions) { + this.conditions = conditions; + this.compositeCondition = PredicateUtils.allOf(conditions); + } + + @Override + public List loot_table_modifier$getConditions() { + return this.conditions; + } +} diff --git a/modded/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1205/mixin/LootPoolMixin.java b/modded/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1205/mixin/LootPoolMixin.java new file mode 100644 index 0000000..d9259d0 --- /dev/null +++ b/modded/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1205/mixin/LootPoolMixin.java @@ -0,0 +1,78 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1205.mixin; + +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.level.storage.loot.LootPool; +import net.minecraft.world.level.storage.loot.entries.LootPoolEntryContainer; +import net.minecraft.world.level.storage.loot.functions.LootItemFunction; +import net.minecraft.world.level.storage.loot.functions.LootItemFunctions; +import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; +import org.spongepowered.asm.mixin.*; +import top.offsetmonkey538.loottablemodifier.common.util.PredicateUtils; +import top.offsetmonkey538.loottablemodifier.modded.duck.LootPoolDuck; + +import java.util.List; +import java.util.function.BiFunction; +import java.util.function.Predicate; + +@Mixin(LootPool.class) +public abstract class LootPoolMixin implements LootPoolDuck { + + @Shadow + @Final + @Mutable + private List conditions; + + @Shadow + @Final + @Mutable + private Predicate compositeCondition; + + @Shadow + @Mutable + @Final + private List entries; + + @Shadow + @Mutable + @Final + private List functions; + + @Shadow + @Mutable + @Final + private BiFunction compositeFunction; + + @Override + @Unique + public void loot_table_modifier$setConditions(List conditions) { + this.conditions = conditions; + this.compositeCondition = PredicateUtils.allOf(conditions); + } + + @Override + public List loot_table_modifier$getConditions() { + return this.conditions; + } + + @Override + public void loot_table_modifier$setEntries(List entries) { + this.entries = entries; + } + + @Override + public List loot_table_modifier$getEntries() { + return this.entries; + } + + @Override + public void loot_table_modifier$setFunctions(List functions) { + this.functions = functions; + this.compositeFunction = LootItemFunctions.compose(functions); + } + + @Override + public List loot_table_modifier$getFunctions() { + return this.functions; + } +} diff --git a/modded/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1205/mixin/LootTableMixin.java b/modded/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1205/mixin/LootTableMixin.java new file mode 100644 index 0000000..ec49146 --- /dev/null +++ b/modded/1.20.5/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1205/mixin/LootTableMixin.java @@ -0,0 +1,56 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1205.mixin; + +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.level.storage.loot.LootPool; +import net.minecraft.world.level.storage.loot.LootTable; +import net.minecraft.world.level.storage.loot.functions.LootItemFunction; +import net.minecraft.world.level.storage.loot.functions.LootItemFunctions; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +import org.spongepowered.asm.mixin.Shadow; +import top.offsetmonkey538.loottablemodifier.modded.duck.LootTableDuck; + +import java.util.List; +import java.util.function.BiFunction; + +@Mixin(LootTable.class) +public abstract class LootTableMixin implements LootTableDuck { + + @Shadow + @Mutable + @Final + private List pools; + + @Shadow + @Mutable + @Final + private List functions; + + @Shadow + @Mutable + @Final + private BiFunction compositeFunction; + + @Override + public void loot_table_modifier$setPools(List pools) { + this.pools = pools; + } + + @Override + public List loot_table_modifier$getPools() { + return this.pools; + } + + @Override + public void loot_table_modifier$setFunctions(List functions) { + this.functions = functions; + this.compositeFunction = LootItemFunctions.compose(functions); + } + + @Override + public List loot_table_modifier$getFunctions() { + return this.functions; + } +} diff --git a/modded/1.20.5/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierActionType$CodecProvider b/modded/1.20.5/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierActionType$CodecProvider new file mode 100644 index 0000000..ad0bcd9 --- /dev/null +++ b/modded/1.20.5/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierActionType$CodecProvider @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v1205.impl.resource.action.LootModifierActionTypeCodecProviderImpl \ No newline at end of file diff --git a/modded/1.20.5/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicateType$CodecProvider b/modded/1.20.5/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicateType$CodecProvider new file mode 100644 index 0000000..cc3ba13 --- /dev/null +++ b/modded/1.20.5/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicateType$CodecProvider @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v1205.impl.resource.predicate.LootModifierPredicateTypeCodecProviderImpl \ No newline at end of file diff --git a/modded/1.20.5/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.Identifier$Instantiator b/modded/1.20.5/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.Identifier$Instantiator new file mode 100644 index 0000000..65a22d7 --- /dev/null +++ b/modded/1.20.5/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.Identifier$Instantiator @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v1205.impl.wrapper.IdentifierInstantiator \ No newline at end of file diff --git a/modded/1.20.5/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.Item$CodecProvider b/modded/1.20.5/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.Item$CodecProvider new file mode 100644 index 0000000..7b5e17d --- /dev/null +++ b/modded/1.20.5/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.Item$CodecProvider @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v1205.impl.wrapper.ItemCodecProviderImpl \ No newline at end of file diff --git a/modded/1.20.5/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootCondition$CodecProvider b/modded/1.20.5/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootCondition$CodecProvider new file mode 100644 index 0000000..02d0c1d --- /dev/null +++ b/modded/1.20.5/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootCondition$CodecProvider @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v1205.impl.wrapper.loot.LootConditionCodecProviderImpl \ No newline at end of file diff --git a/modded/1.20.5/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootPool$CodecProvider b/modded/1.20.5/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootPool$CodecProvider new file mode 100644 index 0000000..b6b0e2f --- /dev/null +++ b/modded/1.20.5/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootPool$CodecProvider @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v1205.impl.wrapper.loot.LootPoolCodecProviderImpl \ No newline at end of file diff --git a/modded/1.20.5/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootTable$CodecProvider b/modded/1.20.5/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootTable$CodecProvider new file mode 100644 index 0000000..c44a8c3 --- /dev/null +++ b/modded/1.20.5/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootTable$CodecProvider @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v1205.impl.wrapper.loot.LootTableCodecProviderImpl \ No newline at end of file diff --git a/modded/1.20.5/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.entry.LootPoolEntry$CodecProvider b/modded/1.20.5/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.entry.LootPoolEntry$CodecProvider new file mode 100644 index 0000000..e8eb7f1 --- /dev/null +++ b/modded/1.20.5/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.entry.LootPoolEntry$CodecProvider @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v1205.impl.wrapper.loot.entry.LootPoolEntryCodecProviderImpl \ No newline at end of file diff --git a/modded/1.20.5/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootTableWrapper$TypeGetter b/modded/1.20.5/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootTableWrapper$TypeGetter new file mode 100644 index 0000000..1daefc7 --- /dev/null +++ b/modded/1.20.5/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootTableWrapper$TypeGetter @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v1205.impl.wrapper.loot.LootTableTypeGetterImpl \ No newline at end of file diff --git a/modded/1.20.5/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.modded.platform.ModdedPlatformCommandUtils$TableGetterById b/modded/1.20.5/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.modded.platform.ModdedPlatformCommandUtils$TableGetterById new file mode 100644 index 0000000..093213e --- /dev/null +++ b/modded/1.20.5/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.modded.platform.ModdedPlatformCommandUtils$TableGetterById @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v1205.impl.TableGetterById \ No newline at end of file diff --git a/modded/1.20.5/src/main/resources/loot-table-modifier.version.modded.mixins.json b/modded/1.20.5/src/main/resources/loot-table-modifier.version.modded.mixins.json new file mode 100644 index 0000000..87141e0 --- /dev/null +++ b/modded/1.20.5/src/main/resources/loot-table-modifier.version.modded.mixins.json @@ -0,0 +1,15 @@ +{ + "required": true, + "package": "top.offsetmonkey538.loottablemodifier.modded.v1205.mixin", + "compatibilityLevel": "JAVA_21", + "mixins": [ + "ItemEntryMixin", + "LootContextTypesAccessor", + "LootPoolEntryMixin", + "LootPoolMixin", + "LootTableMixin" + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/modded/1.21.2/gradle.properties b/modded/1.21.2/gradle.properties new file mode 100644 index 0000000..27136e0 --- /dev/null +++ b/modded/1.21.2/gradle.properties @@ -0,0 +1,6 @@ +project_name = modded-1.21.2 + +monkeylib538_suffix = 1.20.1 + +# Miminum Minecraft version supported, check at https://fabricmc.net/develop +minecraft_version = 1.21.2 diff --git a/modded/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1212/impl/TableGetterById.java b/modded/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1212/impl/TableGetterById.java new file mode 100644 index 0000000..e00c878 --- /dev/null +++ b/modded/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1212/impl/TableGetterById.java @@ -0,0 +1,17 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1212.impl; + +import net.minecraft.commands.CommandSourceStack; +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.ResourceKey; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.Identifier; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootTable; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.IdentifierWrapper; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootTableWrapper; +import top.offsetmonkey538.loottablemodifier.modded.platform.ModdedPlatformCommandUtils; + +public final class TableGetterById implements ModdedPlatformCommandUtils.TableGetterById { + @Override + public LootTable getTableForIdImpl(CommandSourceStack source, Identifier id) { + return new LootTableWrapper(source.getServer().reloadableRegistries().getLootTable(ResourceKey.create(Registries.LOOT_TABLE, ((IdentifierWrapper) id).vanillaIdentifier()))); + } +} diff --git a/modded/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1212/impl/resource/action/LootModifierActionTypeCodecProviderImpl.java b/modded/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1212/impl/resource/action/LootModifierActionTypeCodecProviderImpl.java new file mode 100644 index 0000000..fb7c63a --- /dev/null +++ b/modded/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1212/impl/resource/action/LootModifierActionTypeCodecProviderImpl.java @@ -0,0 +1,15 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1212.impl.resource.action; + +import com.mojang.serialization.Codec; +import top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierAction; +import top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierActionType; +import top.offsetmonkey538.loottablemodifier.modded.impl.resource.action.LootModifierActionTypeRegistryImpl; + +public final class LootModifierActionTypeCodecProviderImpl implements LootModifierActionType.CodecProvider { + private static final Codec CODEC = LootModifierActionTypeRegistryImpl.REGISTRY.byNameCodec().dispatch(LootModifierAction::getType, LootModifierActionType::codec); + + @Override + public Codec get() { + return CODEC; + } +} diff --git a/modded/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1212/impl/resource/predicate/LootModifierPredicateTypeCodecProviderImpl.java b/modded/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1212/impl/resource/predicate/LootModifierPredicateTypeCodecProviderImpl.java new file mode 100644 index 0000000..c0743c5 --- /dev/null +++ b/modded/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1212/impl/resource/predicate/LootModifierPredicateTypeCodecProviderImpl.java @@ -0,0 +1,15 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1212.impl.resource.predicate; + +import com.mojang.serialization.Codec; +import top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicate; +import top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicateType; +import top.offsetmonkey538.loottablemodifier.modded.impl.resource.predicate.LootModifierPredicateTypeRegistryImpl; + +public final class LootModifierPredicateTypeCodecProviderImpl implements LootModifierPredicateType.CodecProvider { + private static final Codec CODEC = LootModifierPredicateTypeRegistryImpl.REGISTRY.byNameCodec().dispatch(LootModifierPredicate::getType, LootModifierPredicateType::codec); + + @Override + public Codec get() { + return CODEC; + } +} diff --git a/modded/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1212/impl/wrapper/IdentifierInstantiator.java b/modded/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1212/impl/wrapper/IdentifierInstantiator.java new file mode 100644 index 0000000..4299deb --- /dev/null +++ b/modded/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1212/impl/wrapper/IdentifierInstantiator.java @@ -0,0 +1,11 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1212.impl.wrapper; + +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.Identifier; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.IdentifierWrapper; + +public final class IdentifierInstantiator implements Identifier.Instantiator { + @Override + public Identifier apply(String s) { + return new IdentifierWrapper(net.minecraft.resources.ResourceLocation.parse(s)); + } + } \ No newline at end of file diff --git a/modded/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1212/impl/wrapper/ItemCodecProviderImpl.java b/modded/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1212/impl/wrapper/ItemCodecProviderImpl.java new file mode 100644 index 0000000..c83fcff --- /dev/null +++ b/modded/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1212/impl/wrapper/ItemCodecProviderImpl.java @@ -0,0 +1,12 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1212.impl.wrapper; + +import com.mojang.serialization.Codec; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.Item; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.ItemWrapper; + +public final class ItemCodecProviderImpl implements Item.CodecProvider { + @Override + public Codec get() { + return net.minecraft.world.item.Item.CODEC.xmap(ItemWrapper::new, wrappedItem -> ((ItemWrapper) wrappedItem).vanillaItem()); + } +} diff --git a/modded/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1212/impl/wrapper/loot/LootConditionCodecProviderImpl.java b/modded/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1212/impl/wrapper/loot/LootConditionCodecProviderImpl.java new file mode 100644 index 0000000..6edc59a --- /dev/null +++ b/modded/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1212/impl/wrapper/loot/LootConditionCodecProviderImpl.java @@ -0,0 +1,12 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1212.impl.wrapper.loot; + +import com.mojang.serialization.Codec; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootCondition; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootConditionWrapper; + +public final class LootConditionCodecProviderImpl implements LootCondition.CodecProvider { + @Override + public Codec get() { + return net.minecraft.world.level.storage.loot.predicates.LootItemCondition.DIRECT_CODEC.xmap(LootConditionWrapper::new, wrappedCondition -> ((LootConditionWrapper) wrappedCondition).vanillaCondition()); + } +} diff --git a/modded/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1212/impl/wrapper/loot/LootPoolCodecProviderImpl.java b/modded/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1212/impl/wrapper/loot/LootPoolCodecProviderImpl.java new file mode 100644 index 0000000..40b3411 --- /dev/null +++ b/modded/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1212/impl/wrapper/loot/LootPoolCodecProviderImpl.java @@ -0,0 +1,12 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1212.impl.wrapper.loot; + +import com.mojang.serialization.Codec; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootPool; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootPoolWrapper; + +public final class LootPoolCodecProviderImpl implements LootPool.CodecProvider { + @Override + public Codec get() { + return net.minecraft.world.level.storage.loot.LootPool.CODEC.xmap(LootPoolWrapper::new, wrappedPool -> ((LootPoolWrapper) wrappedPool).vanillaPool()); + } +} diff --git a/modded/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1212/impl/wrapper/loot/LootTableCodecProviderImpl.java b/modded/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1212/impl/wrapper/loot/LootTableCodecProviderImpl.java new file mode 100644 index 0000000..d28c1b2 --- /dev/null +++ b/modded/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1212/impl/wrapper/loot/LootTableCodecProviderImpl.java @@ -0,0 +1,12 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1212.impl.wrapper.loot; + +import com.mojang.serialization.Codec; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootTable; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootTableWrapper; + +public final class LootTableCodecProviderImpl implements LootTable.CodecProvider { + @Override + public Codec get() { + return net.minecraft.world.level.storage.loot.LootTable.DIRECT_CODEC.xmap(LootTableWrapper::new, wrappedPool -> ((LootTableWrapper) wrappedPool).vanillaTable()); + } +} diff --git a/modded/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1212/impl/wrapper/loot/LootTableTypeGetterImpl.java b/modded/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1212/impl/wrapper/loot/LootTableTypeGetterImpl.java new file mode 100644 index 0000000..9708e10 --- /dev/null +++ b/modded/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1212/impl/wrapper/loot/LootTableTypeGetterImpl.java @@ -0,0 +1,12 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1212.impl.wrapper.loot; + +import net.minecraft.world.level.storage.loot.LootTable; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootTableWrapper; +import top.offsetmonkey538.loottablemodifier.modded.v1212.mixin.LootContextTypesAccessor; + +public final class LootTableTypeGetterImpl implements LootTableWrapper.TypeGetter { + @Override + public String apply(LootTable lootTable) { + return LootContextTypesAccessor.getMAP().inverse().get(lootTable.getParamSet()).toString(); + } +} diff --git a/modded/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1212/impl/wrapper/loot/entry/LootPoolEntryCodecProviderImpl.java b/modded/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1212/impl/wrapper/loot/entry/LootPoolEntryCodecProviderImpl.java new file mode 100644 index 0000000..e3ca0d1 --- /dev/null +++ b/modded/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1212/impl/wrapper/loot/entry/LootPoolEntryCodecProviderImpl.java @@ -0,0 +1,13 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1212.impl.wrapper.loot.entry; + +import com.mojang.serialization.Codec; +import net.minecraft.world.level.storage.loot.entries.LootPoolEntries; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.entry.LootPoolEntry; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.entry.LootPoolEntryWrapper; + +public final class LootPoolEntryCodecProviderImpl implements LootPoolEntry.CodecProvider { + @Override + public Codec get() { + return LootPoolEntries.CODEC.xmap(LootPoolEntryWrapper::create, wrappedEntry -> ((LootPoolEntryWrapper) wrappedEntry).vanillaEntry); + } +} diff --git a/modded/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1212/mixin/ItemEntryMixin.java b/modded/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1212/mixin/ItemEntryMixin.java new file mode 100644 index 0000000..843af51 --- /dev/null +++ b/modded/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1212/mixin/ItemEntryMixin.java @@ -0,0 +1,28 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1212.mixin; + +import net.minecraft.core.Holder; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.storage.loot.entries.LootItem; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +import org.spongepowered.asm.mixin.Shadow; +import top.offsetmonkey538.loottablemodifier.modded.duck.ItemEntryDuck; + +@Mixin(LootItem.class) +public abstract class ItemEntryMixin implements ItemEntryDuck { + @Shadow + @Mutable + @Final + private Holder item; + + @Override + public void loot_table_modifier$setItem(Holder itemHolder) { + this.item = itemHolder; + } + + @Override + public String loot_table_modifier$getId() { + return this.item.unwrapKey().map(key -> key.location().toString()).orElse("[unregistered]"); + } +} diff --git a/modded/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1212/mixin/LootContextTypesAccessor.java b/modded/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1212/mixin/LootContextTypesAccessor.java new file mode 100644 index 0000000..586e2c2 --- /dev/null +++ b/modded/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1212/mixin/LootContextTypesAccessor.java @@ -0,0 +1,16 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1212.mixin; + +import com.google.common.collect.BiMap; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.context.ContextKeySet; +import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(LootContextParamSets.class) +public interface LootContextTypesAccessor { + @Accessor("REGISTRY") + static BiMap getMAP() { + throw new AssertionError(); + } +} diff --git a/modded/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1212/mixin/LootPoolEntryMixin.java b/modded/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1212/mixin/LootPoolEntryMixin.java new file mode 100644 index 0000000..f403a1f --- /dev/null +++ b/modded/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1212/mixin/LootPoolEntryMixin.java @@ -0,0 +1,38 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1212.mixin; + +import org.spongepowered.asm.mixin.*; +import top.offsetmonkey538.loottablemodifier.common.util.PredicateUtils; +import top.offsetmonkey538.loottablemodifier.modded.duck.LootElementWithConditions; + +import java.util.List; +import java.util.function.Predicate; + +import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.level.storage.loot.entries.LootPoolEntryContainer; +import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; + +@Mixin(LootPoolEntryContainer.class) +public abstract class LootPoolEntryMixin implements LootElementWithConditions { + + @Shadow + @Final + @Mutable + protected List conditions; + + @Shadow + @Final + @Mutable + private Predicate compositeCondition; + + @Override + @Unique + public void loot_table_modifier$setConditions(List conditions) { + this.conditions = conditions; + this.compositeCondition = PredicateUtils.allOf(conditions); + } + + @Override + public List loot_table_modifier$getConditions() { + return this.conditions; + } +} diff --git a/modded/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1212/mixin/LootPoolMixin.java b/modded/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1212/mixin/LootPoolMixin.java new file mode 100644 index 0000000..0fde3d6 --- /dev/null +++ b/modded/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1212/mixin/LootPoolMixin.java @@ -0,0 +1,79 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1212.mixin; + +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.storage.loot.entries.LootPoolEntryContainer; +import net.minecraft.world.level.storage.loot.functions.LootItemFunction; +import net.minecraft.world.level.storage.loot.functions.LootItemFunctions; +import org.spongepowered.asm.mixin.*; +import top.offsetmonkey538.loottablemodifier.common.util.PredicateUtils; + +import java.util.List; +import java.util.function.BiFunction; +import java.util.function.Predicate; + +import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.level.storage.loot.LootPool; +import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; +import top.offsetmonkey538.loottablemodifier.modded.duck.LootPoolDuck; + +@Mixin(LootPool.class) +public abstract class LootPoolMixin implements LootPoolDuck { + + @Shadow + @Final + @Mutable + private List conditions; + + @Shadow + @Final + @Mutable + private Predicate compositeCondition; + + @Shadow + @Mutable + @Final + private List entries; + + @Shadow + @Mutable + @Final + private List functions; + + @Shadow + @Mutable + @Final + private BiFunction compositeFunction; + + @Override + @Unique + public void loot_table_modifier$setConditions(List conditions) { + this.conditions = conditions; + this.compositeCondition = PredicateUtils.allOf(conditions); + } + + @Override + public List loot_table_modifier$getConditions() { + return this.conditions; + } + + @Override + public void loot_table_modifier$setEntries(List entries) { + this.entries = entries; + } + + @Override + public List loot_table_modifier$getEntries() { + return this.entries; + } + + @Override + public void loot_table_modifier$setFunctions(List functions) { + this.functions = functions; + this.compositeFunction = LootItemFunctions.compose(functions); + } + + @Override + public List loot_table_modifier$getFunctions() { + return this.functions; + } +} diff --git a/modded/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1212/mixin/LootTableMixin.java b/modded/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1212/mixin/LootTableMixin.java new file mode 100644 index 0000000..cac4bab --- /dev/null +++ b/modded/1.21.2/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v1212/mixin/LootTableMixin.java @@ -0,0 +1,53 @@ +package top.offsetmonkey538.loottablemodifier.modded.v1212.mixin; + +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.level.storage.loot.LootPool; +import net.minecraft.world.level.storage.loot.LootTable; +import net.minecraft.world.level.storage.loot.functions.LootItemFunction; +import net.minecraft.world.level.storage.loot.functions.LootItemFunctions; +import org.spongepowered.asm.mixin.*; +import top.offsetmonkey538.loottablemodifier.modded.duck.LootTableDuck; + +import java.util.List; +import java.util.function.BiFunction; + +@Mixin(LootTable.class) +public abstract class LootTableMixin implements LootTableDuck { + + @Shadow + @Mutable + @Final + private List pools; + + @Shadow + @Mutable + @Final + private List functions; + + @Shadow + @Mutable + @Final + private BiFunction compositeFunction; + + @Override + public void loot_table_modifier$setPools(List pools) { + this.pools = pools; + } + + @Override + public List loot_table_modifier$getPools() { + return this.pools; + } + + @Override + public void loot_table_modifier$setFunctions(List functions) { + this.functions = functions; + this.compositeFunction = LootItemFunctions.compose(functions); + } + + @Override + public List loot_table_modifier$getFunctions() { + return this.functions; + } +} diff --git a/modded/1.21.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierActionType$CodecProvider b/modded/1.21.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierActionType$CodecProvider new file mode 100644 index 0000000..6e106b5 --- /dev/null +++ b/modded/1.21.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierActionType$CodecProvider @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v1212.impl.resource.action.LootModifierActionTypeCodecProviderImpl \ No newline at end of file diff --git a/modded/1.21.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicateType$CodecProvider b/modded/1.21.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicateType$CodecProvider new file mode 100644 index 0000000..471904f --- /dev/null +++ b/modded/1.21.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicateType$CodecProvider @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v1212.impl.resource.predicate.LootModifierPredicateTypeCodecProviderImpl \ No newline at end of file diff --git a/modded/1.21.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.Identifier$Instantiator b/modded/1.21.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.Identifier$Instantiator new file mode 100644 index 0000000..2f89704 --- /dev/null +++ b/modded/1.21.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.Identifier$Instantiator @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v1212.impl.wrapper.IdentifierInstantiator \ No newline at end of file diff --git a/modded/1.21.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.Item$CodecProvider b/modded/1.21.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.Item$CodecProvider new file mode 100644 index 0000000..2655ef5 --- /dev/null +++ b/modded/1.21.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.Item$CodecProvider @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v1212.impl.wrapper.ItemCodecProviderImpl \ No newline at end of file diff --git a/modded/1.21.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootCondition$CodecProvider b/modded/1.21.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootCondition$CodecProvider new file mode 100644 index 0000000..708f960 --- /dev/null +++ b/modded/1.21.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootCondition$CodecProvider @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v1212.impl.wrapper.loot.LootConditionCodecProviderImpl \ No newline at end of file diff --git a/modded/1.21.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootPool$CodecProvider b/modded/1.21.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootPool$CodecProvider new file mode 100644 index 0000000..b7d1b04 --- /dev/null +++ b/modded/1.21.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootPool$CodecProvider @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v1212.impl.wrapper.loot.LootPoolCodecProviderImpl \ No newline at end of file diff --git a/modded/1.21.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootTable$CodecProvider b/modded/1.21.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootTable$CodecProvider new file mode 100644 index 0000000..bbc7d36 --- /dev/null +++ b/modded/1.21.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootTable$CodecProvider @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v1212.impl.wrapper.loot.LootTableCodecProviderImpl \ No newline at end of file diff --git a/modded/1.21.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.entry.LootPoolEntry$CodecProvider b/modded/1.21.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.entry.LootPoolEntry$CodecProvider new file mode 100644 index 0000000..b6fff9f --- /dev/null +++ b/modded/1.21.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.entry.LootPoolEntry$CodecProvider @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v1212.impl.wrapper.loot.entry.LootPoolEntryCodecProviderImpl \ No newline at end of file diff --git a/modded/1.21.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootTableWrapper$TypeGetter b/modded/1.21.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootTableWrapper$TypeGetter new file mode 100644 index 0000000..45755df --- /dev/null +++ b/modded/1.21.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootTableWrapper$TypeGetter @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v1212.impl.wrapper.loot.LootTableTypeGetterImpl \ No newline at end of file diff --git a/modded/1.21.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.modded.platform.ModdedPlatformCommandUtils$TableGetterById b/modded/1.21.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.modded.platform.ModdedPlatformCommandUtils$TableGetterById new file mode 100644 index 0000000..b378194 --- /dev/null +++ b/modded/1.21.2/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.modded.platform.ModdedPlatformCommandUtils$TableGetterById @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v1212.impl.TableGetterById \ No newline at end of file diff --git a/modded/1.21.2/src/main/resources/loot-table-modifier.version.modded.mixins.json b/modded/1.21.2/src/main/resources/loot-table-modifier.version.modded.mixins.json new file mode 100644 index 0000000..7909bab --- /dev/null +++ b/modded/1.21.2/src/main/resources/loot-table-modifier.version.modded.mixins.json @@ -0,0 +1,15 @@ +{ + "required": true, + "package": "top.offsetmonkey538.loottablemodifier.modded.v1212.mixin", + "compatibilityLevel": "JAVA_21", + "mixins": [ + "ItemEntryMixin", + "LootContextTypesAccessor", + "LootPoolEntryMixin", + "LootPoolMixin", + "LootTableMixin" + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/modded/1.21/gradle.properties b/modded/1.21/gradle.properties new file mode 100644 index 0000000..40aa28e --- /dev/null +++ b/modded/1.21/gradle.properties @@ -0,0 +1,6 @@ +project_name = modded-1.21 + +monkeylib538_suffix = 1.20.1 + +# Miminum Minecraft version supported, check at https://fabricmc.net/develop +minecraft_version = 1.21 diff --git a/modded/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v121/impl/TableGetterById.java b/modded/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v121/impl/TableGetterById.java new file mode 100644 index 0000000..968ad1f --- /dev/null +++ b/modded/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v121/impl/TableGetterById.java @@ -0,0 +1,17 @@ +package top.offsetmonkey538.loottablemodifier.modded.v121.impl; + +import net.minecraft.commands.CommandSourceStack; +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.ResourceKey; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.Identifier; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootTable; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.IdentifierWrapper; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootTableWrapper; +import top.offsetmonkey538.loottablemodifier.modded.platform.ModdedPlatformCommandUtils; + +public final class TableGetterById implements ModdedPlatformCommandUtils.TableGetterById { + @Override + public LootTable getTableForIdImpl(CommandSourceStack source, Identifier id) { + return new LootTableWrapper(source.getServer().reloadableRegistries().getLootTable(ResourceKey.create(Registries.LOOT_TABLE, ((IdentifierWrapper) id).vanillaIdentifier()))); + } +} diff --git a/modded/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v121/impl/resource/action/LootModifierActionTypeCodecProviderImpl.java b/modded/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v121/impl/resource/action/LootModifierActionTypeCodecProviderImpl.java new file mode 100644 index 0000000..9fee63f --- /dev/null +++ b/modded/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v121/impl/resource/action/LootModifierActionTypeCodecProviderImpl.java @@ -0,0 +1,15 @@ +package top.offsetmonkey538.loottablemodifier.modded.v121.impl.resource.action; + +import com.mojang.serialization.Codec; +import top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierAction; +import top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierActionType; +import top.offsetmonkey538.loottablemodifier.modded.impl.resource.action.LootModifierActionTypeRegistryImpl; + +public final class LootModifierActionTypeCodecProviderImpl implements LootModifierActionType.CodecProvider { + private static final Codec CODEC = LootModifierActionTypeRegistryImpl.REGISTRY.byNameCodec().dispatch(LootModifierAction::getType, LootModifierActionType::codec); + + @Override + public Codec get() { + return CODEC; + } +} diff --git a/modded/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v121/impl/resource/predicate/LootModifierPredicateTypeCodecProviderImpl.java b/modded/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v121/impl/resource/predicate/LootModifierPredicateTypeCodecProviderImpl.java new file mode 100644 index 0000000..96b7c1c --- /dev/null +++ b/modded/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v121/impl/resource/predicate/LootModifierPredicateTypeCodecProviderImpl.java @@ -0,0 +1,15 @@ +package top.offsetmonkey538.loottablemodifier.modded.v121.impl.resource.predicate; + +import com.mojang.serialization.Codec; +import top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicate; +import top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicateType; +import top.offsetmonkey538.loottablemodifier.modded.impl.resource.predicate.LootModifierPredicateTypeRegistryImpl; + +public final class LootModifierPredicateTypeCodecProviderImpl implements LootModifierPredicateType.CodecProvider { + private static final Codec CODEC = LootModifierPredicateTypeRegistryImpl.REGISTRY.byNameCodec().dispatch(LootModifierPredicate::getType, LootModifierPredicateType::codec); + + @Override + public Codec get() { + return CODEC; + } +} diff --git a/modded/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v121/impl/wrapper/IdentifierInstantiator.java b/modded/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v121/impl/wrapper/IdentifierInstantiator.java new file mode 100644 index 0000000..1e745e4 --- /dev/null +++ b/modded/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v121/impl/wrapper/IdentifierInstantiator.java @@ -0,0 +1,12 @@ +package top.offsetmonkey538.loottablemodifier.modded.v121.impl.wrapper; + +import net.minecraft.resources.ResourceLocation; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.Identifier; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.IdentifierWrapper; + +public final class IdentifierInstantiator implements Identifier.Instantiator { + @Override + public Identifier apply(String s) { + return new IdentifierWrapper(ResourceLocation.parse(s)); + } +} \ No newline at end of file diff --git a/modded/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v121/impl/wrapper/ItemCodecProviderImpl.java b/modded/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v121/impl/wrapper/ItemCodecProviderImpl.java new file mode 100644 index 0000000..4cb5c4a --- /dev/null +++ b/modded/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v121/impl/wrapper/ItemCodecProviderImpl.java @@ -0,0 +1,13 @@ +package top.offsetmonkey538.loottablemodifier.modded.v121.impl.wrapper; + +import com.mojang.serialization.Codec; +import net.minecraft.core.registries.BuiltInRegistries; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.Item; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.ItemWrapper; + +public final class ItemCodecProviderImpl implements Item.CodecProvider { + @Override + public Codec get() { + return BuiltInRegistries.ITEM.holderByNameCodec().xmap(ItemWrapper::new, wrappedItem -> ((ItemWrapper) wrappedItem).vanillaItem()); + } +} diff --git a/modded/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v121/impl/wrapper/loot/LootConditionCodecProviderImpl.java b/modded/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v121/impl/wrapper/loot/LootConditionCodecProviderImpl.java new file mode 100644 index 0000000..fef3b71 --- /dev/null +++ b/modded/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v121/impl/wrapper/loot/LootConditionCodecProviderImpl.java @@ -0,0 +1,12 @@ +package top.offsetmonkey538.loottablemodifier.modded.v121.impl.wrapper.loot; + +import com.mojang.serialization.Codec; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootCondition; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootConditionWrapper; + +public final class LootConditionCodecProviderImpl implements LootCondition.CodecProvider { + @Override + public Codec get() { + return net.minecraft.world.level.storage.loot.predicates.LootItemCondition.DIRECT_CODEC.xmap(LootConditionWrapper::new, wrappedCondition -> ((LootConditionWrapper) wrappedCondition).vanillaCondition()); + } +} diff --git a/modded/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v121/impl/wrapper/loot/LootPoolCodecProviderImpl.java b/modded/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v121/impl/wrapper/loot/LootPoolCodecProviderImpl.java new file mode 100644 index 0000000..1867024 --- /dev/null +++ b/modded/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v121/impl/wrapper/loot/LootPoolCodecProviderImpl.java @@ -0,0 +1,12 @@ +package top.offsetmonkey538.loottablemodifier.modded.v121.impl.wrapper.loot; + +import com.mojang.serialization.Codec; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootPool; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootPoolWrapper; + +public final class LootPoolCodecProviderImpl implements LootPool.CodecProvider { + @Override + public Codec get() { + return net.minecraft.world.level.storage.loot.LootPool.CODEC.xmap(LootPoolWrapper::new, wrappedPool -> ((LootPoolWrapper) wrappedPool).vanillaPool()); + } +} diff --git a/modded/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v121/impl/wrapper/loot/LootTableCodecProviderImpl.java b/modded/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v121/impl/wrapper/loot/LootTableCodecProviderImpl.java new file mode 100644 index 0000000..8acb207 --- /dev/null +++ b/modded/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v121/impl/wrapper/loot/LootTableCodecProviderImpl.java @@ -0,0 +1,12 @@ +package top.offsetmonkey538.loottablemodifier.modded.v121.impl.wrapper.loot; + +import com.mojang.serialization.Codec; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootTable; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootTableWrapper; + +public final class LootTableCodecProviderImpl implements LootTable.CodecProvider { + @Override + public Codec get() { + return net.minecraft.world.level.storage.loot.LootTable.DIRECT_CODEC.xmap(LootTableWrapper::new, wrappedPool -> ((LootTableWrapper) wrappedPool).vanillaTable()); + } +} diff --git a/modded/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v121/impl/wrapper/loot/LootTableTypeGetterImpl.java b/modded/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v121/impl/wrapper/loot/LootTableTypeGetterImpl.java new file mode 100644 index 0000000..d9bfb43 --- /dev/null +++ b/modded/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v121/impl/wrapper/loot/LootTableTypeGetterImpl.java @@ -0,0 +1,12 @@ +package top.offsetmonkey538.loottablemodifier.modded.v121.impl.wrapper.loot; + +import net.minecraft.world.level.storage.loot.LootTable; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootTableWrapper; +import top.offsetmonkey538.loottablemodifier.modded.v121.mixin.LootContextTypesAccessor; + +public final class LootTableTypeGetterImpl implements LootTableWrapper.TypeGetter { + @Override + public String apply(LootTable lootTable) { + return LootContextTypesAccessor.getMAP().inverse().get(lootTable.getParamSet()).toString(); + } +} diff --git a/modded/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v121/impl/wrapper/loot/entry/LootPoolEntryCodecProviderImpl.java b/modded/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v121/impl/wrapper/loot/entry/LootPoolEntryCodecProviderImpl.java new file mode 100644 index 0000000..ef5c61f --- /dev/null +++ b/modded/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v121/impl/wrapper/loot/entry/LootPoolEntryCodecProviderImpl.java @@ -0,0 +1,13 @@ +package top.offsetmonkey538.loottablemodifier.modded.v121.impl.wrapper.loot.entry; + +import com.mojang.serialization.Codec; +import net.minecraft.world.level.storage.loot.entries.LootPoolEntries; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.entry.LootPoolEntry; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.entry.LootPoolEntryWrapper; + +public final class LootPoolEntryCodecProviderImpl implements LootPoolEntry.CodecProvider { + @Override + public Codec get() { + return LootPoolEntries.CODEC.xmap(LootPoolEntryWrapper::create, wrappedEntry -> ((LootPoolEntryWrapper) wrappedEntry).vanillaEntry); + } +} diff --git a/modded/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v121/mixin/ItemEntryMixin.java b/modded/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v121/mixin/ItemEntryMixin.java new file mode 100644 index 0000000..24a2017 --- /dev/null +++ b/modded/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v121/mixin/ItemEntryMixin.java @@ -0,0 +1,28 @@ +package top.offsetmonkey538.loottablemodifier.modded.v121.mixin; + +import net.minecraft.core.Holder; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.storage.loot.entries.LootItem; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +import org.spongepowered.asm.mixin.Shadow; +import top.offsetmonkey538.loottablemodifier.modded.duck.ItemEntryDuck; + +@Mixin(LootItem.class) +public abstract class ItemEntryMixin implements ItemEntryDuck { + @Shadow + @Mutable + @Final + private Holder item; + + @Override + public void loot_table_modifier$setItem(Holder itemHolder) { + this.item = itemHolder; + } + + @Override + public String loot_table_modifier$getId() { + return this.item.unwrapKey().map(key -> key.location().toString()).orElse("[unregistered]"); + } +} diff --git a/modded/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v121/mixin/LootContextTypesAccessor.java b/modded/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v121/mixin/LootContextTypesAccessor.java new file mode 100644 index 0000000..8fd86d2 --- /dev/null +++ b/modded/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v121/mixin/LootContextTypesAccessor.java @@ -0,0 +1,16 @@ +package top.offsetmonkey538.loottablemodifier.modded.v121.mixin; + +import com.google.common.collect.BiMap; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.storage.loot.parameters.LootContextParamSet; +import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(LootContextParamSets.class) +public interface LootContextTypesAccessor { + @Accessor("REGISTRY") + static BiMap getMAP() { + throw new AssertionError(); + } +} diff --git a/modded/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v121/mixin/LootPoolEntryMixin.java b/modded/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v121/mixin/LootPoolEntryMixin.java new file mode 100644 index 0000000..11eb7cb --- /dev/null +++ b/modded/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v121/mixin/LootPoolEntryMixin.java @@ -0,0 +1,37 @@ +package top.offsetmonkey538.loottablemodifier.modded.v121.mixin; + +import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.level.storage.loot.entries.LootPoolEntryContainer; +import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; +import org.spongepowered.asm.mixin.*; +import top.offsetmonkey538.loottablemodifier.common.util.PredicateUtils; +import top.offsetmonkey538.loottablemodifier.modded.duck.LootElementWithConditions; + +import java.util.List; +import java.util.function.Predicate; + +@Mixin(LootPoolEntryContainer.class) +public abstract class LootPoolEntryMixin implements LootElementWithConditions { + + @Shadow + @Final + @Mutable + protected List conditions; + + @Shadow + @Final + @Mutable + private Predicate compositeCondition; + + @Override + @Unique + public void loot_table_modifier$setConditions(List conditions) { + this.conditions = conditions; + this.compositeCondition = PredicateUtils.allOf(conditions); + } + + @Override + public List loot_table_modifier$getConditions() { + return this.conditions; + } +} diff --git a/modded/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v121/mixin/LootPoolMixin.java b/modded/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v121/mixin/LootPoolMixin.java new file mode 100644 index 0000000..a4258c6 --- /dev/null +++ b/modded/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v121/mixin/LootPoolMixin.java @@ -0,0 +1,78 @@ +package top.offsetmonkey538.loottablemodifier.modded.v121.mixin; + +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.level.storage.loot.LootPool; +import net.minecraft.world.level.storage.loot.entries.LootPoolEntryContainer; +import net.minecraft.world.level.storage.loot.functions.LootItemFunction; +import net.minecraft.world.level.storage.loot.functions.LootItemFunctions; +import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; +import org.spongepowered.asm.mixin.*; +import top.offsetmonkey538.loottablemodifier.common.util.PredicateUtils; +import top.offsetmonkey538.loottablemodifier.modded.duck.LootPoolDuck; + +import java.util.List; +import java.util.function.BiFunction; +import java.util.function.Predicate; + +@Mixin(LootPool.class) +public abstract class LootPoolMixin implements LootPoolDuck { + + @Shadow + @Final + @Mutable + private List conditions; + + @Shadow + @Final + @Mutable + private Predicate compositeCondition; + + @Shadow + @Mutable + @Final + private List entries; + + @Shadow + @Mutable + @Final + private List functions; + + @Shadow + @Mutable + @Final + private BiFunction compositeFunction; + + @Override + @Unique + public void loot_table_modifier$setConditions(List conditions) { + this.conditions = conditions; + this.compositeCondition = PredicateUtils.allOf(conditions); + } + + @Override + public List loot_table_modifier$getConditions() { + return this.conditions; + } + + @Override + public void loot_table_modifier$setEntries(List entries) { + this.entries = entries; + } + + @Override + public List loot_table_modifier$getEntries() { + return this.entries; + } + + @Override + public void loot_table_modifier$setFunctions(List functions) { + this.functions = functions; + this.compositeFunction = LootItemFunctions.compose(functions); + } + + @Override + public List loot_table_modifier$getFunctions() { + return this.functions; + } +} diff --git a/modded/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v121/mixin/LootTableMixin.java b/modded/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v121/mixin/LootTableMixin.java new file mode 100644 index 0000000..d1c4e42 --- /dev/null +++ b/modded/1.21/src/main/java/top/offsetmonkey538/loottablemodifier/modded/v121/mixin/LootTableMixin.java @@ -0,0 +1,56 @@ +package top.offsetmonkey538.loottablemodifier.modded.v121.mixin; + +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.level.storage.loot.LootPool; +import net.minecraft.world.level.storage.loot.LootTable; +import net.minecraft.world.level.storage.loot.functions.LootItemFunction; +import net.minecraft.world.level.storage.loot.functions.LootItemFunctions; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +import org.spongepowered.asm.mixin.Shadow; +import top.offsetmonkey538.loottablemodifier.modded.duck.LootTableDuck; + +import java.util.List; +import java.util.function.BiFunction; + +@Mixin(LootTable.class) +public abstract class LootTableMixin implements LootTableDuck { + + @Shadow + @Mutable + @Final + private List pools; + + @Shadow + @Mutable + @Final + private List functions; + + @Shadow + @Mutable + @Final + private BiFunction compositeFunction; + + @Override + public void loot_table_modifier$setPools(List pools) { + this.pools = pools; + } + + @Override + public List loot_table_modifier$getPools() { + return this.pools; + } + + @Override + public void loot_table_modifier$setFunctions(List functions) { + this.functions = functions; + this.compositeFunction = LootItemFunctions.compose(functions); + } + + @Override + public List loot_table_modifier$getFunctions() { + return this.functions; + } +} diff --git a/modded/1.21/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierActionType$CodecProvider b/modded/1.21/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierActionType$CodecProvider new file mode 100644 index 0000000..7e57568 --- /dev/null +++ b/modded/1.21/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierActionType$CodecProvider @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v121.impl.resource.action.LootModifierActionTypeCodecProviderImpl \ No newline at end of file diff --git a/modded/1.21/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicateType$CodecProvider b/modded/1.21/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicateType$CodecProvider new file mode 100644 index 0000000..c3128f0 --- /dev/null +++ b/modded/1.21/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicateType$CodecProvider @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v121.impl.resource.predicate.LootModifierPredicateTypeCodecProviderImpl \ No newline at end of file diff --git a/modded/1.21/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.Identifier$Instantiator b/modded/1.21/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.Identifier$Instantiator new file mode 100644 index 0000000..f3a72f9 --- /dev/null +++ b/modded/1.21/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.Identifier$Instantiator @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v121.impl.wrapper.IdentifierInstantiator \ No newline at end of file diff --git a/modded/1.21/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.Item$CodecProvider b/modded/1.21/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.Item$CodecProvider new file mode 100644 index 0000000..0c68828 --- /dev/null +++ b/modded/1.21/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.Item$CodecProvider @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v121.impl.wrapper.ItemCodecProviderImpl \ No newline at end of file diff --git a/modded/1.21/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootCondition$CodecProvider b/modded/1.21/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootCondition$CodecProvider new file mode 100644 index 0000000..3976c4c --- /dev/null +++ b/modded/1.21/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootCondition$CodecProvider @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v121.impl.wrapper.loot.LootConditionCodecProviderImpl \ No newline at end of file diff --git a/modded/1.21/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootPool$CodecProvider b/modded/1.21/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootPool$CodecProvider new file mode 100644 index 0000000..dd4a6ca --- /dev/null +++ b/modded/1.21/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootPool$CodecProvider @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v121.impl.wrapper.loot.LootPoolCodecProviderImpl \ No newline at end of file diff --git a/modded/1.21/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootTable$CodecProvider b/modded/1.21/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootTable$CodecProvider new file mode 100644 index 0000000..8ecb4e4 --- /dev/null +++ b/modded/1.21/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootTable$CodecProvider @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v121.impl.wrapper.loot.LootTableCodecProviderImpl \ No newline at end of file diff --git a/modded/1.21/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.entry.LootPoolEntry$CodecProvider b/modded/1.21/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.entry.LootPoolEntry$CodecProvider new file mode 100644 index 0000000..f3e163c --- /dev/null +++ b/modded/1.21/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.entry.LootPoolEntry$CodecProvider @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v121.impl.wrapper.loot.entry.LootPoolEntryCodecProviderImpl \ No newline at end of file diff --git a/modded/1.21/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootTableWrapper$TypeGetter b/modded/1.21/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootTableWrapper$TypeGetter new file mode 100644 index 0000000..769dc18 --- /dev/null +++ b/modded/1.21/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootTableWrapper$TypeGetter @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v121.impl.wrapper.loot.LootTableTypeGetterImpl \ No newline at end of file diff --git a/modded/1.21/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.modded.platform.ModdedPlatformCommandUtils$TableGetterById b/modded/1.21/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.modded.platform.ModdedPlatformCommandUtils$TableGetterById new file mode 100644 index 0000000..75fa32a --- /dev/null +++ b/modded/1.21/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.modded.platform.ModdedPlatformCommandUtils$TableGetterById @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.v121.impl.TableGetterById \ No newline at end of file diff --git a/modded/1.21/src/main/resources/loot-table-modifier.version.modded.mixins.json b/modded/1.21/src/main/resources/loot-table-modifier.version.modded.mixins.json new file mode 100644 index 0000000..b234daf --- /dev/null +++ b/modded/1.21/src/main/resources/loot-table-modifier.version.modded.mixins.json @@ -0,0 +1,15 @@ +{ + "required": true, + "package": "top.offsetmonkey538.loottablemodifier.modded.v121.mixin", + "compatibilityLevel": "JAVA_21", + "mixins": [ + "ItemEntryMixin", + "LootContextTypesAccessor", + "LootPoolEntryMixin", + "LootPoolMixin", + "LootTableMixin" + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/modded/build.gradle b/modded/build.gradle new file mode 100644 index 0000000..cd590b5 --- /dev/null +++ b/modded/build.gradle @@ -0,0 +1,45 @@ +plugins { + id 'multiloader-modded' + id 'fabric-loom' +} + +allprojects { + apply plugin: "multiloader-modded" + apply plugin: "fabric-loom" + + repositories { + exclusiveContent { + forRepository { + maven { + name = "Sponge" + url = "https://repo.spongepowered.org/repository/maven-public" + } + } + filter { + includeGroupAndSubgroups "org.spongepowered" + } + } + } + + dependencies { + compileOnly project(":common") + commonJava project(path: ":common", configuration: "commonJava") + commonResources project(path: ":common", configuration: "commonResources") + + minecraft "com.mojang:minecraft:${project.minecraft_version}" + mappings loom.officialMojangMappings() + + compileOnly "org.spongepowered:mixin:0.8.5" + compileOnly annotationProcessor("io.github.llamalad7:mixinextras-common:0.3.5") + + modCompileOnly "top.offsetmonkey538.monkeylib538:monkeylib538-modded:${rootProject.monkeylib538_version}+modded" + } +} + +subprojects { + dependencies { + compileOnly project(":modded") + commonJava project(path: ":modded", configuration: "commonJava") + commonResources project(path: ":modded", configuration: "commonResources") + } +} diff --git a/modded/gradle.properties b/modded/gradle.properties new file mode 100644 index 0000000..cd3fb9e --- /dev/null +++ b/modded/gradle.properties @@ -0,0 +1,8 @@ +project_name = modded + + +## "Common" fabric one should depend on the latest version just so it can access Minecraft and Fabric. +## It MUST NOT include version-specific code + +# Minecraft version, check at https://fabricmc.net/develop +minecraft_version = 1.21.8 diff --git a/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/duck/ItemEntryDuck.java b/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/duck/ItemEntryDuck.java new file mode 100644 index 0000000..e2a2dbe --- /dev/null +++ b/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/duck/ItemEntryDuck.java @@ -0,0 +1,9 @@ +package top.offsetmonkey538.loottablemodifier.modded.duck; + +import net.minecraft.core.Holder; +import net.minecraft.world.item.Item; + +public interface ItemEntryDuck { + void loot_table_modifier$setItem(Holder itemHolder); + String loot_table_modifier$getId(); +} \ No newline at end of file diff --git a/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/duck/LootElementWithConditions.java b/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/duck/LootElementWithConditions.java new file mode 100644 index 0000000..2ffa312 --- /dev/null +++ b/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/duck/LootElementWithConditions.java @@ -0,0 +1,9 @@ +package top.offsetmonkey538.loottablemodifier.modded.duck; + +import java.util.List; +import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; + +public interface LootElementWithConditions { + void loot_table_modifier$setConditions(List conditions); + List loot_table_modifier$getConditions(); +} \ No newline at end of file diff --git a/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/duck/LootPoolDuck.java b/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/duck/LootPoolDuck.java new file mode 100644 index 0000000..75c8ab0 --- /dev/null +++ b/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/duck/LootPoolDuck.java @@ -0,0 +1,14 @@ +package top.offsetmonkey538.loottablemodifier.modded.duck; + +import net.minecraft.world.level.storage.loot.entries.LootPoolEntryContainer; +import net.minecraft.world.level.storage.loot.functions.LootItemFunction; + +import java.util.List; + +public interface LootPoolDuck extends LootElementWithConditions { + void loot_table_modifier$setEntries(List entries); + List loot_table_modifier$getEntries(); + + void loot_table_modifier$setFunctions(List functions); + List loot_table_modifier$getFunctions(); +} \ No newline at end of file diff --git a/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/duck/LootTableDuck.java b/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/duck/LootTableDuck.java new file mode 100644 index 0000000..1a6566e --- /dev/null +++ b/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/duck/LootTableDuck.java @@ -0,0 +1,14 @@ +package top.offsetmonkey538.loottablemodifier.modded.duck; + +import net.minecraft.world.level.storage.loot.LootPool; +import net.minecraft.world.level.storage.loot.functions.LootItemFunction; + +import java.util.List; + +public interface LootTableDuck { + void loot_table_modifier$setPools(List pools); + List loot_table_modifier$getPools(); + + void loot_table_modifier$setFunctions(List functions); + List loot_table_modifier$getFunctions(); +} \ No newline at end of file diff --git a/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/impl/resource/action/LootModifierActionTypeRegistryImpl.java b/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/impl/resource/action/LootModifierActionTypeRegistryImpl.java new file mode 100644 index 0000000..46f65b8 --- /dev/null +++ b/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/impl/resource/action/LootModifierActionTypeRegistryImpl.java @@ -0,0 +1,23 @@ +package top.offsetmonkey538.loottablemodifier.modded.impl.resource.action; + +import com.mojang.serialization.Lifecycle; +import net.minecraft.core.MappedRegistry; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceKey; +import org.jetbrains.annotations.NotNull; +import top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierActionType; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.Identifier; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.IdentifierWrapper; + +import static top.offsetmonkey538.loottablemodifier.modded.platform.ModdedPlatformMain.id; + +public final class LootModifierActionTypeRegistryImpl implements LootModifierActionType.Registry { + public static final Registry REGISTRY = new MappedRegistry<>( + ResourceKey.createRegistryKey(id("loot_modifier_action_types")), Lifecycle.stable() + ); + + @Override + public LootModifierActionType register(@NotNull Identifier id, @NotNull LootModifierActionType type) { + return Registry.register(REGISTRY, ((IdentifierWrapper) id).vanillaIdentifier(), type); + } +} diff --git a/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/impl/resource/predicate/LootModifierPredicateTypeRegistryImpl.java b/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/impl/resource/predicate/LootModifierPredicateTypeRegistryImpl.java new file mode 100644 index 0000000..deef6c0 --- /dev/null +++ b/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/impl/resource/predicate/LootModifierPredicateTypeRegistryImpl.java @@ -0,0 +1,23 @@ +package top.offsetmonkey538.loottablemodifier.modded.impl.resource.predicate; + +import com.mojang.serialization.Lifecycle; +import net.minecraft.core.MappedRegistry; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceKey; +import org.jetbrains.annotations.NotNull; +import top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicateType; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.Identifier; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.IdentifierWrapper; + +import static top.offsetmonkey538.loottablemodifier.modded.platform.ModdedPlatformMain.id; + +public final class LootModifierPredicateTypeRegistryImpl implements LootModifierPredicateType.Registry { + public static final Registry REGISTRY = new MappedRegistry<>( + ResourceKey.createRegistryKey(id("loot_modifier_predicate_types")), Lifecycle.stable() + ); + + @Override + public top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicateType register(@NotNull Identifier id, @NotNull top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicateType type) { + return Registry.register(REGISTRY, ((IdentifierWrapper) id).vanillaIdentifier(), type); + } +} diff --git a/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/impl/wrapper/IdentifierWrapper.java b/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/impl/wrapper/IdentifierWrapper.java new file mode 100644 index 0000000..db6e40b --- /dev/null +++ b/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/impl/wrapper/IdentifierWrapper.java @@ -0,0 +1,36 @@ +package top.offsetmonkey538.loottablemodifier.modded.impl.wrapper; + +import com.mojang.serialization.Codec; +import org.jetbrains.annotations.NotNull; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.Identifier; + +public record IdentifierWrapper(net.minecraft.resources.ResourceLocation vanillaIdentifier) implements Identifier { + + @Override + public String asString() { + return vanillaIdentifier.toString(); + } + + @Override + public String getNamespace() { + return vanillaIdentifier.getNamespace(); + } + + @Override + public String getPath() { + return vanillaIdentifier.getPath(); + } + + @Override + public @NotNull String toString() { + return vanillaIdentifier.toString(); + } + + public static final class CodecProviderImpl implements CodecProvider { + @Override + public Codec get() { + return net.minecraft.resources.ResourceLocation.CODEC.xmap(IdentifierWrapper::new, wrappedIdentifier -> ((IdentifierWrapper) wrappedIdentifier).vanillaIdentifier()); + } + } +} + diff --git a/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/impl/wrapper/ItemWrapper.java b/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/impl/wrapper/ItemWrapper.java new file mode 100644 index 0000000..a9968cd --- /dev/null +++ b/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/impl/wrapper/ItemWrapper.java @@ -0,0 +1,14 @@ +package top.offsetmonkey538.loottablemodifier.modded.impl.wrapper; + +import net.minecraft.core.Holder; +import net.minecraft.core.registries.BuiltInRegistries; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.Item; + +public record ItemWrapper(Holder vanillaItem) implements Item { + + @Override + public String getId() { + return BuiltInRegistries.ITEM.getKey(vanillaItem.value()).toString(); + } +} + diff --git a/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/impl/wrapper/ResourceManagerWrapper.java b/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/impl/wrapper/ResourceManagerWrapper.java new file mode 100644 index 0000000..5526a41 --- /dev/null +++ b/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/impl/wrapper/ResourceManagerWrapper.java @@ -0,0 +1,30 @@ +package top.offsetmonkey538.loottablemodifier.modded.impl.wrapper; + +import it.unimi.dsi.fastutil.Pair; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.Identifier; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.ResourceManager; + +import java.io.BufferedReader; +import java.io.IOException; +import java.util.function.Predicate; +import java.util.function.Supplier; +import java.util.stream.Stream; + +public record ResourceManagerWrapper(net.minecraft.server.packs.resources.ResourceManager vanillaIdentifier) implements ResourceManager { + @Override + public Stream>> listResources(String string, Predicate predicate) { + return vanillaIdentifier.listResources(string, id -> predicate.test(id.toString())).entrySet().stream() + .map(entry -> Pair.of( + new IdentifierWrapper(entry.getKey()), + () -> { + try { + return entry.getValue().openAsReader(); + } catch (IOException e) { + // Rethrow as runtime, otherwise can't be a supplier. Will be called in LootTableModifierCommon.loadModifiers which catches all exceptions + throw new RuntimeException(e); + } + } + )); + } +} + diff --git a/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/impl/wrapper/loot/LootConditionWrapper.java b/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/impl/wrapper/loot/LootConditionWrapper.java new file mode 100644 index 0000000..e5007cf --- /dev/null +++ b/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/impl/wrapper/loot/LootConditionWrapper.java @@ -0,0 +1,8 @@ +package top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot; + +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootCondition; + +public record LootConditionWrapper(net.minecraft.world.level.storage.loot.predicates.LootItemCondition vanillaCondition) implements LootCondition { + +} + diff --git a/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/impl/wrapper/loot/LootFunctionWrapper.java b/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/impl/wrapper/loot/LootFunctionWrapper.java new file mode 100644 index 0000000..7491ed0 --- /dev/null +++ b/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/impl/wrapper/loot/LootFunctionWrapper.java @@ -0,0 +1,7 @@ +package top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot; + +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootFunction; + +public record LootFunctionWrapper(net.minecraft.world.level.storage.loot.functions.LootItemFunction vanillaFunction) implements LootFunction { + +} diff --git a/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/impl/wrapper/loot/LootPoolWrapper.java b/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/impl/wrapper/loot/LootPoolWrapper.java new file mode 100644 index 0000000..7bb2951 --- /dev/null +++ b/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/impl/wrapper/loot/LootPoolWrapper.java @@ -0,0 +1,58 @@ +package top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot; + +import com.google.common.collect.ImmutableList; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootCondition; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootFunction; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootPool; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.entry.LootPoolEntry; +import top.offsetmonkey538.loottablemodifier.modded.duck.LootPoolDuck; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.entry.LootPoolEntryWrapper; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +public record LootPoolWrapper(net.minecraft.world.level.storage.loot.LootPool vanillaPool) implements LootPool { + @Override + public ArrayList getEntries() { + return ((LootPoolDuck) vanillaPool).loot_table_modifier$getEntries().stream().map(LootPoolEntryWrapper::create).collect(Collectors.toCollection(ArrayList::new)); + } + + @Override + public void setEntries(List entries) { + final ImmutableList.Builder newEntries = ImmutableList.builder(); + + newEntries.addAll(entries.stream().map(wrapperEntry -> ((LootPoolEntryWrapper) wrapperEntry).vanillaEntry).toList()); + + ((LootPoolDuck) vanillaPool).loot_table_modifier$setEntries(newEntries.build()); + } + + @Override + public ArrayList getConditions() { + return ((LootPoolDuck) vanillaPool).loot_table_modifier$getConditions().stream().map(LootConditionWrapper::new).collect(Collectors.toCollection(ArrayList::new)); + } + + @Override + public void setConditions(List conditions) { + final ImmutableList.Builder newConditions = ImmutableList.builder(); + + newConditions.addAll(conditions.stream().map(wrapperEntry -> ((LootConditionWrapper) wrapperEntry).vanillaCondition()).toList()); + + ((LootPoolDuck) vanillaPool).loot_table_modifier$setConditions(newConditions.build()); + } + + @Override + public ArrayList getFunctions() { + return ((LootPoolDuck) vanillaPool).loot_table_modifier$getFunctions().stream().map(LootFunctionWrapper::new).collect(Collectors.toCollection(ArrayList::new)); + } + + @Override + public void setFunctions(List functions) { + final ImmutableList.Builder newFunctions = ImmutableList.builder(); + + newFunctions.addAll(functions.stream().map(wrapperEntry -> ((LootFunctionWrapper) wrapperEntry).vanillaFunction()).toList()); + + ((LootPoolDuck) vanillaPool).loot_table_modifier$setFunctions(newFunctions.build()); + } +} + diff --git a/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/impl/wrapper/loot/LootTableWrapper.java b/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/impl/wrapper/loot/LootTableWrapper.java new file mode 100644 index 0000000..deeeada --- /dev/null +++ b/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/impl/wrapper/loot/LootTableWrapper.java @@ -0,0 +1,55 @@ +package top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot; + +import com.google.common.collect.ImmutableList; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootFunction; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootPool; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootTable; +import top.offsetmonkey538.loottablemodifier.modded.duck.LootTableDuck; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Function; +import java.util.stream.Collectors; + +import static top.offsetmonkey538.loottablemodifier.common.LootTableModifierCommon.load; + +public record LootTableWrapper(net.minecraft.world.level.storage.loot.LootTable vanillaTable) implements LootTable { + + @Override + public String getType() { + return TypeGetter.INSTANCE.apply(vanillaTable); + } + + @Override + public ArrayList getPools() { + return ((LootTableDuck) vanillaTable).loot_table_modifier$getPools().stream().map(LootPoolWrapper::new).collect(Collectors.toCollection(ArrayList::new)); + } + + @Override + public void setPools(List entries) { + final ImmutableList.Builder newPools = ImmutableList.builder(); + + newPools.addAll(entries.stream().map(wrapperEntry -> ((LootPoolWrapper) wrapperEntry).vanillaPool()).toList()); + + ((LootTableDuck) vanillaTable).loot_table_modifier$setPools(newPools.build()); + } + + @Override + public ArrayList getFunctions() { + return ((LootTableDuck) vanillaTable).loot_table_modifier$getFunctions().stream().map(LootFunctionWrapper::new).collect(Collectors.toCollection(ArrayList::new)); + } + + @Override + public void setFunctions(List functions) { + final ImmutableList.Builder newFunctions = ImmutableList.builder(); + + newFunctions.addAll(functions.stream().map(wrapperEntry -> ((LootFunctionWrapper) wrapperEntry).vanillaFunction()).toList()); + + ((LootTableDuck) vanillaTable).loot_table_modifier$setFunctions(newFunctions.build()); + } + + public interface TypeGetter extends Function { + TypeGetter INSTANCE = load(TypeGetter.class); + } +} + diff --git a/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/impl/wrapper/loot/entry/ItemEntryWrapper.java b/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/impl/wrapper/loot/entry/ItemEntryWrapper.java new file mode 100644 index 0000000..9e546e5 --- /dev/null +++ b/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/impl/wrapper/loot/entry/ItemEntryWrapper.java @@ -0,0 +1,27 @@ +package top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.entry; + +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.Item; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.entry.ItemEntry; +import top.offsetmonkey538.loottablemodifier.modded.duck.ItemEntryDuck; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.ItemWrapper; + +public final class ItemEntryWrapper extends LootPoolEntryWrapper implements ItemEntry { + private final net.minecraft.world.level.storage.loot.entries.LootItem vanillaEntry; + + ItemEntryWrapper(net.minecraft.world.level.storage.loot.entries.LootItem vanillaEntry) { + super(vanillaEntry); + this.vanillaEntry = vanillaEntry; + } + + @Override + public void setItem(Item item) { + ((ItemWrapper) item).vanillaItem().value(); + ((ItemEntryDuck) this.vanillaEntry).loot_table_modifier$setItem(((ItemWrapper) item).vanillaItem()); + } + + @Override + public String getId() { + return ((ItemEntryDuck) this.vanillaEntry).loot_table_modifier$getId(); + } +} + diff --git a/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/impl/wrapper/loot/entry/LootPoolEntryWrapper.java b/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/impl/wrapper/loot/entry/LootPoolEntryWrapper.java new file mode 100644 index 0000000..04021a5 --- /dev/null +++ b/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/impl/wrapper/loot/entry/LootPoolEntryWrapper.java @@ -0,0 +1,55 @@ +package top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.entry; + +import com.google.common.collect.ImmutableList; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootCondition; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.entry.LootPoolEntry; +import top.offsetmonkey538.loottablemodifier.modded.duck.LootElementWithConditions; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.loot.LootConditionWrapper; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; +import net.minecraft.world.level.storage.loot.entries.LootItem; + +/** + * Don't initialize using canonical constructor. Use {@link #create(net.minecraft.world.level.storage.loot.entries.LootPoolEntryContainer)} instead + */ +public class LootPoolEntryWrapper implements LootPoolEntry { + public final net.minecraft.world.level.storage.loot.entries.LootPoolEntryContainer vanillaEntry; + + protected LootPoolEntryWrapper(net.minecraft.world.level.storage.loot.entries.LootPoolEntryContainer vanillaEntry) { + this.vanillaEntry = vanillaEntry; + } + + public static LootPoolEntryWrapper create(net.minecraft.world.level.storage.loot.entries.LootPoolEntryContainer vanillaEntry) { + if (vanillaEntry instanceof LootItem itemEntry) return new ItemEntryWrapper(itemEntry); + return new LootPoolEntryWrapper(vanillaEntry); + } + + @Override + public ArrayList getConditions() { + return ((LootElementWithConditions) vanillaEntry).loot_table_modifier$getConditions().stream().map(LootConditionWrapper::new).collect(Collectors.toCollection(ArrayList::new)); + } + + @Override + public void setConditions(List conditions) { + final ImmutableList.Builder newConditions = ImmutableList.builder(); + + newConditions.addAll(conditions.stream().map(wrapperCondition -> ((LootConditionWrapper) wrapperCondition).vanillaCondition()).toList()); + + ((LootElementWithConditions) vanillaEntry).loot_table_modifier$setConditions(newConditions.build()); + } + + @Override + public final boolean equals(Object o) { + if (!(o instanceof LootPoolEntryWrapper that)) return false; + + return vanillaEntry.equals(that.vanillaEntry); + } + + @Override + public int hashCode() { + return vanillaEntry.hashCode(); + } +} + diff --git a/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/platform/ModdedPlatformCommandUtils.java b/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/platform/ModdedPlatformCommandUtils.java new file mode 100644 index 0000000..9255581 --- /dev/null +++ b/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/platform/ModdedPlatformCommandUtils.java @@ -0,0 +1,31 @@ +package top.offsetmonkey538.loottablemodifier.modded.platform; + +import com.google.gson.JsonElement; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.serialization.DynamicOps; +import com.mojang.serialization.JsonOps; +import net.minecraft.commands.CommandSourceStack; +import net.minecraft.resources.RegistryOps; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.Identifier; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.loot.LootTable; +import top.offsetmonkey538.loottablemodifier.common.platform.PlatformCommandUtils; +import top.offsetmonkey538.monkeylib538.modded.api.command.ModdedCommandAbstractionApi; + +import static top.offsetmonkey538.loottablemodifier.common.LootTableModifierCommon.load; + +public class ModdedPlatformCommandUtils implements PlatformCommandUtils { + @Override + public DynamicOps getRegistryOpsImpl(CommandContext context) { + return RegistryOps.create(JsonOps.INSTANCE, ModdedCommandAbstractionApi.get(context).getServer().registryAccess()); + } + + @Override + public LootTable getTableForIdImpl(CommandContext context, Identifier id) { + return TableGetterById.INSTANCE.getTableForIdImpl(ModdedCommandAbstractionApi.get(context), id); + } + + public interface TableGetterById { + TableGetterById INSTANCE = load(TableGetterById.class); + LootTable getTableForIdImpl(CommandSourceStack source, Identifier id); + } +} diff --git a/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/platform/ModdedPlatformMain.java b/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/platform/ModdedPlatformMain.java new file mode 100644 index 0000000..559ab0c --- /dev/null +++ b/modded/src/main/java/top/offsetmonkey538/loottablemodifier/modded/platform/ModdedPlatformMain.java @@ -0,0 +1,31 @@ +package top.offsetmonkey538.loottablemodifier.modded.platform; + +import com.google.gson.JsonElement; +import com.google.gson.stream.JsonWriter; +import net.minecraft.data.DataProvider; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.GsonHelper; +import top.offsetmonkey538.loottablemodifier.common.api.wrapper.Identifier; +import top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.IdentifierWrapper; +import top.offsetmonkey538.loottablemodifier.common.platform.PlatformMain; + +import java.io.IOException; + +import static top.offsetmonkey538.loottablemodifier.common.LootTableModifierCommon.*; + +public class ModdedPlatformMain implements PlatformMain { + + @Override + public void writeSortedImpl(JsonWriter jsonWriter, JsonElement json) throws IOException { + GsonHelper.writeValue(jsonWriter, json, DataProvider.KEY_COMPARATOR); + } + + @Override + public Identifier idImpl(String path) { + return new IdentifierWrapper(id(path)); + } + + public static ResourceLocation id(String path) { + return ((IdentifierWrapper) Identifier.of(MOD_ID + ":" + path)).vanillaIdentifier(); + } +} diff --git a/modded/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierActionType$Registry b/modded/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierActionType$Registry new file mode 100644 index 0000000..8343d69 --- /dev/null +++ b/modded/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.resource.action.LootModifierActionType$Registry @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.impl.resource.action.LootModifierActionTypeRegistryImpl \ No newline at end of file diff --git a/modded/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicateType$Registry b/modded/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicateType$Registry new file mode 100644 index 0000000..6d921a6 --- /dev/null +++ b/modded/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.resource.predicate.LootModifierPredicateType$Registry @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.impl.resource.predicate.LootModifierPredicateTypeRegistryImpl \ No newline at end of file diff --git a/modded/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.Identifier$CodecProvider b/modded/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.Identifier$CodecProvider new file mode 100644 index 0000000..fcf205a --- /dev/null +++ b/modded/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.api.wrapper.Identifier$CodecProvider @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.impl.wrapper.IdentifierWrapper$CodecProviderImpl \ No newline at end of file diff --git a/modded/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.platform.PlatformCommandUtils b/modded/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.platform.PlatformCommandUtils new file mode 100644 index 0000000..d44cc61 --- /dev/null +++ b/modded/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.platform.PlatformCommandUtils @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.platform.ModdedPlatformCommandUtils \ No newline at end of file diff --git a/modded/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.platform.PlatformMain b/modded/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.platform.PlatformMain new file mode 100644 index 0000000..8523ac0 --- /dev/null +++ b/modded/src/main/resources/META-INF/services/top.offsetmonkey538.loottablemodifier.common.platform.PlatformMain @@ -0,0 +1 @@ +top.offsetmonkey538.loottablemodifier.modded.platform.ModdedPlatformMain \ No newline at end of file diff --git a/modded/src/main/resources/loot-table-modifier.modded.mixins.json b/modded/src/main/resources/loot-table-modifier.modded.mixins.json new file mode 100644 index 0000000..24ccee1 --- /dev/null +++ b/modded/src/main/resources/loot-table-modifier.modded.mixins.json @@ -0,0 +1,11 @@ +{ + "required": true, + "package": "top.offsetmonkey538.loottablemodifier.modded.mixin", + "compatibilityLevel": "JAVA_21", + "mixins": [ + + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/settings.gradle b/settings.gradle index 0fdae2f..5a9f344 100644 --- a/settings.gradle +++ b/settings.gradle @@ -8,3 +8,26 @@ pluginManagement { gradlePluginPortal() } } + +rootProject.name = "Loot-Table-Modifier" + + +include "common" + +include "modded" +include "modded:1.20.1" +include "modded:1.20.2" +include "modded:1.20.5" +include "modded:1.21" +include "modded:1.21.2" + +include "loader:fabric" +include "loader:fabric:1.20.1" +include "loader:fabric:1.20.2" +include "loader:fabric:1.20.5" +include "loader:fabric:1.21" +include "loader:fabric:1.21.2" + +include "loader:neoforge" +include "loader:neoforge:1.21" +include "loader:neoforge:1.21.2" \ No newline at end of file diff --git a/src/client/java/top/offsetmonkey538/loottablemodifier/LootTableModifierClient.java b/src/client/java/top/offsetmonkey538/loottablemodifier/LootTableModifierClient.java deleted file mode 100644 index 7b36f26..0000000 --- a/src/client/java/top/offsetmonkey538/loottablemodifier/LootTableModifierClient.java +++ /dev/null @@ -1,11 +0,0 @@ -package top.offsetmonkey538.loottablemodifier; - -import net.fabricmc.api.ClientModInitializer; - -public class LootTableModifierClient implements ClientModInitializer { - - @Override - public void onInitializeClient() { - // Do stuff - } -} diff --git a/src/client/resources/loot-table-modifier.client.mixins.json b/src/client/resources/loot-table-modifier.client.mixins.json deleted file mode 100644 index cc2571a..0000000 --- a/src/client/resources/loot-table-modifier.client.mixins.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "required": true, - "package": "top.offsetmonkey538.loottablemodifier.mixin.client", - "compatibilityLevel": "JAVA_17", - "client": [ - - ], - "injectors": { - "defaultRequire": 1 - } -} diff --git a/src/main/java/top/offsetmonkey538/loottablemodifier/LootTableModifier.java b/src/main/java/top/offsetmonkey538/loottablemodifier/LootTableModifier.java deleted file mode 100644 index 0d4da6b..0000000 --- a/src/main/java/top/offsetmonkey538/loottablemodifier/LootTableModifier.java +++ /dev/null @@ -1,250 +0,0 @@ -package top.offsetmonkey538.loottablemodifier; - -import com.google.common.base.Stopwatch; -import com.google.gson.JsonElement; -import com.google.gson.JsonParser; -import com.google.gson.stream.JsonWriter; -import com.mojang.brigadier.context.CommandContext; -import com.mojang.serialization.DataResult; -import com.mojang.serialization.DynamicOps; -import com.mojang.serialization.JsonOps; -import net.fabricmc.api.ModInitializer; -import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; -import net.fabricmc.fabric.api.resource.ResourceManagerHelper; -import net.fabricmc.fabric.api.resource.ResourcePackActivationType; -import net.fabricmc.loader.api.FabricLoader; -import net.minecraft.data.DataProvider; -import net.minecraft.loot.LootPool; -import net.minecraft.loot.LootTable; -import net.minecraft.loot.entry.LootPoolEntry; -import net.minecraft.registry.*; -import net.minecraft.registry.entry.RegistryEntry; -import net.minecraft.resource.Resource; -import net.minecraft.resource.ResourceManager; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.command.ServerCommandSource; -import net.minecraft.text.*; -import net.minecraft.util.Formatting; -import net.minecraft.util.Identifier; -import net.minecraft.util.JsonHelper; -import org.apache.commons.io.file.PathUtils; -import org.jetbrains.annotations.NotNull; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import top.offsetmonkey538.loottablemodifier.api.resource.action.LootModifierActionTypes; -import top.offsetmonkey538.loottablemodifier.api.resource.predicate.LootModifierPredicateTypes; -import top.offsetmonkey538.loottablemodifier.api.resource.LootModifier; -import top.offsetmonkey538.loottablemodifier.api.resource.util.LootModifierContext; - -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.*; - -import static net.minecraft.server.command.CommandManager.literal; -import static top.offsetmonkey538.loottablemodifier.api.resource.action.LootModifierAction.*; - -public class LootTableModifier implements ModInitializer { - public static final String MOD_ID = "loot-table-modifier"; - public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); - - public static final boolean IS_DEV; - static { - final String isDev = System.getProperty("lootTableModifierDev", ""); - if (isDev.equalsIgnoreCase("true")) IS_DEV = true; - else if (isDev.equalsIgnoreCase("false")) IS_DEV = false; // This way it can be disabled in devenv too. - else IS_DEV = FabricLoader.getInstance().isDevelopmentEnvironment(); - } - - // Only used when IS_DEV is true - private static final List MODIFIED_TABLE_IDs; - static { - if (IS_DEV) MODIFIED_TABLE_IDs = Collections.synchronizedList(new ArrayList<>(0)); - else MODIFIED_TABLE_IDs = null; - } - - @Override - public void onInitialize() { - LootModifierActionTypes.register(); - LootModifierPredicateTypes.register(); - - if (IS_DEV) enableDebug(); - } - - public static void runModification(ResourceManager resourceManager, Registry lootRegistry, RegistryOps registryOps) { - final Map modifiers = loadModifiers(resourceManager, registryOps); - - final List modifiedTableIds = new ArrayList<>(); // Used for exporting modified ones - int poolsModified = 0, entriesModified = 0; - boolean tableModified, poolModified; - - LOGGER.info("Modifying loot tables..."); - final Stopwatch stopwatch = Stopwatch.createStarted(); - - for (Iterator> it = getRegistryAsWrapper(lootRegistry).streamEntries().iterator(); it.hasNext(); ) { - final RegistryEntry.Reference registryEntry = it.next(); - final RegistryKey key = registryEntry.registryKey(); - - final LootTable table = lootRegistry.get(key); - final Identifier tableId = key.getValue(); - if (table == null) throw new IllegalStateException("Loot table with id '%s' is null!".formatted(key)); - - tableModified = false; - - final LootPool[] poolsCopy = table.pools.toArray(LootPool[]::new); - int poolsSize = Math.max(1, poolsCopy.length); // Run loop at least once - for (int i = 0; i < poolsSize; i++) { - final LootPool pool = poolsCopy.length == 0 ? null : poolsCopy[i]; - poolModified = false; - - final LootPoolEntry[] entriesCopy = pool == null ? new LootPoolEntry[]{} : pool.entries.toArray(LootPoolEntry[]::new); - int entriesSize = Math.max(1, entriesCopy.length); // Run loop at least once - for (int j = 0; j < entriesSize; j++) { - final LootPoolEntry entry = entriesCopy.length == 0 ? null : entriesCopy[j]; - - for (Map.Entry modifierEntry : modifiers.entrySet()) { - final LootModifierContext context = new LootModifierContext(table, tableId, pool, entry, tableModified, poolModified); - - final LootModifier modifier = modifierEntry.getValue(); - if (!modifier.test(context)) continue; - - if (IS_DEV) LOGGER.warn("Modifier {} can modify table {}", modifierEntry.getKey(), tableId); - - - int result = modifier.apply(context); - - if (IS_DEV && result != MODIFIED_NONE) LOGGER.warn("Modifier {} modified table {} with modified mask {}", modifierEntry.getKey(), tableId, Integer.toUnsignedString(result, 2)); - - if ((result & MODIFIED_TABLE) == MODIFIED_TABLE) tableModified = true; - if ((result & MODIFIED_POOL) == MODIFIED_POOL) poolModified = true; - if ((result & MODIFIED_ENTRY) == MODIFIED_ENTRY) entriesModified++; - } - } - - poolsModified += poolModified ? 1 : 0; - } - if (tableModified) modifiedTableIds.add(tableId); - } - - - LOGGER.info("Applied {} modifiers and modified {} entries, {} pools and {} loot tables in {}!", modifiers.size(), entriesModified, poolsModified, modifiedTableIds.size(), stopwatch.stop()); - - if (!IS_DEV) return; - - LOGGER.warn("Dev mode enabled, modified loot tables can be exported using the '/loot-table-modifier debug export' command"); - synchronized (MODIFIED_TABLE_IDs) { - MODIFIED_TABLE_IDs.clear(); - MODIFIED_TABLE_IDs.addAll(modifiedTableIds); - } - } - - private static Map loadModifiers(ResourceManager resourceManager, RegistryOps registryOps) { - LOGGER.info("Loading loot table modifiers..."); - final Stopwatch stopwatch = Stopwatch.createStarted(); - - final Map result = new HashMap<>(); - - for (Map.Entry entry : resourceManager.findResources(MOD_ID + "/loot_modifier", path -> path.toString().endsWith(".json")).entrySet()) { - final Identifier id = entry.getKey(); - - try { - LOGGER.debug("Loading load loot table modifier from '{}'", id); - result.put( - id, - LootModifier.CODEC.decode(registryOps, JsonParser.parseReader(entry.getValue().getReader())).getOrThrow().getFirst() - ); - } catch (Exception e) { - //noinspection StringConcatenationArgumentToLogCall - LOGGER.error("Failed to load loot table modifier from '%s'!".formatted(id), e); - } - } - - LOGGER.info("Loaded {} loot modifiers in {}!", result.size(), stopwatch.stop()); - - return result; - } - - private static void enableDebug() { - ResourceManagerHelper.registerBuiltinResourcePack(id("example_pack"), FabricLoader.getInstance().getModContainer(MOD_ID).orElseThrow(), Text.of("Example Pack"), ResourcePackActivationType.NORMAL); - CommandRegistrationCallback.EVENT.register((dispatcher, commandRegistryAccess, registrationEnvironment) -> dispatcher.register( - literal(MOD_ID) - .then( - literal("debug") - .then( - literal("export") - .executes( - LootTableModifier::executeExportCommand - ) - ) - ) - )); - } - - private static int executeExportCommand(CommandContext context) { - synchronized (MODIFIED_TABLE_IDs) { - final ServerCommandSource source = context.getSource(); - final MinecraftServer server = source.getServer(); - - final DynamicOps ops = RegistryOps.of(JsonOps.INSTANCE, server.getRegistryManager()); - try { - final Path exportDir = FabricLoader.getInstance().getGameDir().resolve(".loot-table-modifier").resolve("export"); - if (Files.exists(exportDir)) PathUtils.deleteDirectory(exportDir); - - source.sendFeedback(() -> Text.literal("Exporting modified tables to ").append(Text.literal(exportDir.toString()).setStyle(Style.EMPTY.withUnderline(true).withColor(Formatting.WHITE).withHoverEvent(new HoverEvent.ShowText(Text.literal("Click to copy"))).withClickEvent(new ClickEvent.CopyToClipboard(exportDir.toAbsolutePath().toString())))), true); - final Stopwatch stopwatch = Stopwatch.createStarted(); - - for (Identifier id : MODIFIED_TABLE_IDs) { - final LootTable table = server.getReloadableRegistries().getLootTable(RegistryKey.of(RegistryKeys.LOOT_TABLE, id)); - final Path file = exportDir.resolve(id.getNamespace()).resolve(id.getPath() + ".json"); - Files.createDirectories(file.getParent()); - - LOGGER.warn("Exporting loot table to {}", file); - DataResult dataResult = LootTable.CODEC.encodeStart(ops, table); - final Optional optionalResult = dataResult.resultOrPartial(LOGGER::error); - final JsonElement result = optionalResult.orElseThrow(); - - LOGGER.warn("Writing loot table to {}", file); - - try (JsonWriter jsonWriter = new JsonWriter(Files.newBufferedWriter(file, StandardCharsets.UTF_8))) { - jsonWriter.setSerializeNulls(false); - jsonWriter.setIndent(" "); - JsonHelper.writeSorted(jsonWriter, result, DataProvider.JSON_KEY_SORTING_COMPARATOR); - } - } - source.sendFeedback(() -> Text.literal("Exported %s modified tables in %s".formatted(MODIFIED_TABLE_IDs.size(), stopwatch.stop())), true); - } catch (IOException e) { - throw new RuntimeException("Failed to export modified tables!", e); - } - - return 1; - } - } - - public static Identifier id(String path) { - return Identifier.of(MOD_ID, path); - } - - /* - In 1.21.4, the 'Registry' class extends 'RegistryWrapper' and inherits the 'streamEntries' method from it. - In 1.20.5, the 'Registry' class *doesn't* extend the 'RegistryWrapper' and implements its own 'streamEntries' method. - Compiling on both versions works, because the names of the methods are the same, but they compile to different intermediary names, thus a jar compiled for 1.20.5 doesn't work on 1.21.4 and vice versa. - Solution: Turn the 'Registry' into a 'RegistryWrapper' as its 'streamEntries' retains the same intermediary on both versions. - If 'Registry' implements 'RegistryWrapper': cast it - Else: call 'getReadOnlyWrapper' on the registry (doesn't exist on 1.21.4, otherwise would've used 'registry.getReadOnlyWrapper().streamEntries()') - */ - private static RegistryWrapper getRegistryAsWrapper(@NotNull Registry registry) { - //noinspection ConstantValue,RedundantSuppression: On lower versions, Registry doesn't extend RegistryWrapper and thus the 'isAssignableFrom' check can be false. The redundant supression is for the unchecked cast below. - if (RegistryWrapper.class.isAssignableFrom(registry.getClass())) - //noinspection unchecked,RedundantCast: I swear it casts 🤞 - return (RegistryWrapper) registry; - - try { - //noinspection unchecked: Seriously I swear 🤞🤞 - return (RegistryWrapper) registry.getClass().getDeclaredMethod(FabricLoader.getInstance().getMappingResolver().mapMethodName("intermediary", "net.minecraft.class_2378", "method_46771", "()Lnet/minecraft/class_7225$class_7226;")).invoke(registry); - } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { - throw new RuntimeException(e); - } - } -} diff --git a/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/action/LootModifierActionType.java b/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/action/LootModifierActionType.java deleted file mode 100644 index 780da7a..0000000 --- a/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/action/LootModifierActionType.java +++ /dev/null @@ -1,23 +0,0 @@ -package top.offsetmonkey538.loottablemodifier.api.resource.action; - -import com.mojang.serialization.Lifecycle; -import com.mojang.serialization.MapCodec; -import net.minecraft.registry.Registry; -import net.minecraft.registry.RegistryKey; -import net.minecraft.registry.SimpleRegistry; -import org.jetbrains.annotations.NotNull; -import top.offsetmonkey538.loottablemodifier.LootTableModifier; - -/** - * The type of a {@link LootModifierAction}, holds the codec. - * - * @param codec the codec for this action. - */ -public record LootModifierActionType(@NotNull MapCodec codec) { - /** - * Registry of {@link LootModifierActionType}s - */ - public static final Registry REGISTRY = new SimpleRegistry<>( - RegistryKey.ofRegistry(LootTableModifier.id("loot_modifier_action_types")), Lifecycle.stable() - ); -} diff --git a/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/action/LootModifierActionTypes.java b/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/action/LootModifierActionTypes.java deleted file mode 100644 index dd00b16..0000000 --- a/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/action/LootModifierActionTypes.java +++ /dev/null @@ -1,67 +0,0 @@ -package top.offsetmonkey538.loottablemodifier.api.resource.action; - -import com.mojang.serialization.MapCodec; -import net.minecraft.registry.Registry; -import net.minecraft.util.Identifier; -import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.NotNull; -import top.offsetmonkey538.loottablemodifier.api.resource.action.condition.ConditionAddAction; -import top.offsetmonkey538.loottablemodifier.api.resource.action.entry.EntryAddAction; -import top.offsetmonkey538.loottablemodifier.api.resource.action.entry.EntryRemoveAction; -import top.offsetmonkey538.loottablemodifier.api.resource.action.pool.PoolAddAction; -import top.offsetmonkey538.loottablemodifier.api.resource.action.entry.EntryItemSetAction; -import top.offsetmonkey538.loottablemodifier.api.resource.action.pool.PoolRemoveAction; - -import static top.offsetmonkey538.loottablemodifier.LootTableModifier.id; - -/** - * Contains all {@link LootModifierAction} types available in Loot Table Modifier. - *
- * Use their builders to create them. - */ -public final class LootModifierActionTypes { - private LootModifierActionTypes() { - - } - - /** - * Type of {@link PoolAddAction} - */ - public static final LootModifierActionType POOL_ADD = register(id("pool_add"), PoolAddAction.CODEC); - /** - * Type of {@link PoolRemoveAction} - */ - public static final LootModifierActionType POOL_REMOVE = register(id("pool_remove"), PoolRemoveAction.CODEC); - - /** - * Type of {@link EntryAddAction} - */ - public static final LootModifierActionType ENTRY_ADD = register(id("entry_add"), EntryAddAction.CODEC); - /** - * Type of {@link EntryRemoveAction} - */ - public static final LootModifierActionType ENTRY_REMOVE = register(id("entry_remove"), EntryRemoveAction.CODEC); - /** - * Type of {@link EntryItemSetAction} - */ - public static final LootModifierActionType ENTRY_ITEM_SET = register(id("entry_item_set"), EntryItemSetAction.CODEC); - - /** - * Type of {@link ConditionAddAction} - */ - public static final LootModifierActionType CONDITION_ADD = register(id("condition_add"), ConditionAddAction.CODEC); - - private static LootModifierActionType register(final @NotNull Identifier id, final @NotNull MapCodec codec) { - return Registry.register(LootModifierActionType.REGISTRY, id, new LootModifierActionType(codec)); - } - - /** - * Registers action types by loading the class. - *
- * Only for the loot table modifier initializer to call, NO TOUCHY >:( - */ - @ApiStatus.Internal - public static void register() { - // Registers action types by loading the class - } -} diff --git a/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/action/entry/EntryItemSetAction.java b/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/action/entry/EntryItemSetAction.java deleted file mode 100644 index ebdd089..0000000 --- a/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/action/entry/EntryItemSetAction.java +++ /dev/null @@ -1,105 +0,0 @@ -package top.offsetmonkey538.loottablemodifier.api.resource.action.entry; - -import com.google.common.collect.ImmutableList; -import com.mojang.serialization.Codec; -import com.mojang.serialization.MapCodec; -import com.mojang.serialization.codecs.RecordCodecBuilder; -import net.minecraft.item.Item; -import net.minecraft.item.ItemConvertible; -import net.minecraft.loot.LootPool; -import net.minecraft.loot.entry.ItemEntry; -import net.minecraft.loot.entry.LootPoolEntry; -import net.minecraft.registry.Registries; -import net.minecraft.registry.entry.RegistryEntry; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import top.offsetmonkey538.loottablemodifier.api.resource.action.LootModifierActionTypes; -import top.offsetmonkey538.loottablemodifier.mixin.ItemEntryAccessor; -import top.offsetmonkey538.loottablemodifier.mixin.LootPoolAccessor; -import top.offsetmonkey538.loottablemodifier.api.resource.util.LootModifierContext; -import top.offsetmonkey538.loottablemodifier.api.resource.action.LootModifierAction; -import top.offsetmonkey538.loottablemodifier.api.resource.action.LootModifierActionType; - -/** - * Sets the item in matched item entries - * - * @param item the new item to replace the existing one with - * @param canReplaceEntry if other types of entries can be replaced with a basic item entry containing the target item - */ -public record EntryItemSetAction(RegistryEntry item, boolean canReplaceEntry) implements LootModifierAction { - public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - Item.ENTRY_CODEC.fieldOf("name").forGetter(EntryItemSetAction::item), - Codec.BOOL.optionalFieldOf("canReplaceEntry", false).forGetter(EntryItemSetAction::canReplaceEntry) - ).apply(instance, EntryItemSetAction::new)); - - @Override - public LootModifierActionType getType() { - return LootModifierActionTypes.ENTRY_ITEM_SET; - } - - @Override - public int apply(@NotNull LootModifierContext context) { - final LootPoolEntry entry = context.entry(); - if (entry == null) return MODIFIED_NONE; - - if (entry instanceof ItemEntry itemEntry) { - ((ItemEntryAccessor) itemEntry).setItem(item); - return MODIFIED_ENTRY; - } - // Matched entry is not an ItemEntry, check if entry replacing is on - if (!canReplaceEntry) return MODIFIED_NONE; - - final LootPool pool = context.pool(); - if (pool == null) return MODIFIED_NONE; - - final ImmutableList.Builder newEntriesBuilder = ImmutableList.builder(); - - for (LootPoolEntry originalEntry : pool.entries) { - if (originalEntry == entry) continue; // I think we do want '==' here as the references should be the same? - newEntriesBuilder.add(originalEntry); - } - ((LootPoolAccessor) pool).setEntries(newEntriesBuilder.build()); - - return MODIFIED_ENTRY; - } - - /** - * Creates a builder for {@link EntryItemSetAction} - * - * @param item the new item to replace the existing one with - * @return a new {@link EntryItemSetAction.Builder} - */ - @Contract("_->new") - public static EntryItemSetAction.Builder builder(@NotNull ItemConvertible item) { - return new EntryItemSetAction.Builder(item); - } - - /** - * Builder for {@link EntryItemSetAction} - */ - public static class Builder implements LootModifierAction.Builder { - private final RegistryEntry item; - private boolean canReplaceEntry; - - private Builder(@NotNull ItemConvertible item) { - this.item = Registries.ITEM.getEntry(item.asItem()); - } - - /** - * Sets if other types of entries can be replaced with a basic item entry containing the target item - * - * @param canReplaceEntry if other types of entries can be replaced with a basic item entry containing the target item - * @return this - */ - @Contract("_->this") - public EntryItemSetAction.Builder setCanReplaceEntry(boolean canReplaceEntry) { - this.canReplaceEntry = canReplaceEntry; - return this; - } - - @Override - public EntryItemSetAction build() { - return new EntryItemSetAction(item, canReplaceEntry); - } - } -} diff --git a/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/predicate/LootModifierPredicateType.java b/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/predicate/LootModifierPredicateType.java deleted file mode 100644 index 709f0aa..0000000 --- a/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/predicate/LootModifierPredicateType.java +++ /dev/null @@ -1,23 +0,0 @@ -package top.offsetmonkey538.loottablemodifier.api.resource.predicate; - -import com.mojang.serialization.Lifecycle; -import com.mojang.serialization.MapCodec; -import net.minecraft.registry.Registry; -import net.minecraft.registry.RegistryKey; -import net.minecraft.registry.SimpleRegistry; -import org.jetbrains.annotations.NotNull; -import top.offsetmonkey538.loottablemodifier.LootTableModifier; - -/** - * They type of a {@link LootModifierPredicate}, holds the codec. - * - * @param codec the codec for this predicate - */ -public record LootModifierPredicateType(@NotNull MapCodec codec) { - /** - * Registry of {@link LootModifierPredicateType}s - */ - public static final Registry REGISTRY = new SimpleRegistry<>( - RegistryKey.ofRegistry(LootTableModifier.id("loot_modifier_predicate_types")), Lifecycle.stable() - ); -} diff --git a/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/predicate/LootModifierPredicateTypes.java b/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/predicate/LootModifierPredicateTypes.java deleted file mode 100644 index 8981466..0000000 --- a/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/predicate/LootModifierPredicateTypes.java +++ /dev/null @@ -1,62 +0,0 @@ -package top.offsetmonkey538.loottablemodifier.api.resource.predicate; - -import com.mojang.serialization.MapCodec; -import net.minecraft.registry.Registry; -import net.minecraft.util.Identifier; -import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.NotNull; -import top.offsetmonkey538.loottablemodifier.api.resource.predicate.entry.EntryItemPredicate; -import top.offsetmonkey538.loottablemodifier.api.resource.predicate.op.AllOfPredicate; -import top.offsetmonkey538.loottablemodifier.api.resource.predicate.op.AnyOfPredicate; -import top.offsetmonkey538.loottablemodifier.api.resource.predicate.op.InvertedPredicate; -import top.offsetmonkey538.loottablemodifier.api.resource.predicate.table.TablePredicate; - -import static top.offsetmonkey538.loottablemodifier.LootTableModifier.id; - -/** - * Contains all {@link LootModifierPredicate} types available in Loot Table Modifier - *
- * Use their builders to create them. - */ -public final class LootModifierPredicateTypes { - private LootModifierPredicateTypes() { - - } - - /** - * Type of {@link InvertedPredicate} - */ - public static final LootModifierPredicateType INVERTED = register(id("inverted"), InvertedPredicate.CODEC); - /** - * Type of {@link AnyOfPredicate} - */ - public static final LootModifierPredicateType ANY_OF = register(id("any_of"), AnyOfPredicate.CODEC); - /** - * Type of {@link AllOfPredicate} - */ - public static final LootModifierPredicateType ALL_OF = register(id("all_of"), AllOfPredicate.CODEC); - - /** - * Type of {@link EntryItemPredicate} - */ - public static final LootModifierPredicateType ENTRY_ITEM = register(id("entry_item"), EntryItemPredicate.CODEC); - - /** - * Type of {@link TablePredicate} - */ - public static final LootModifierPredicateType TABLE = register(id("table"), TablePredicate.CODEC); - - private static LootModifierPredicateType register(final @NotNull Identifier id, final @NotNull MapCodec codec) { - return Registry.register(LootModifierPredicateType.REGISTRY, id, new LootModifierPredicateType(codec)); - } - - /** - * Registers predicate types by loading the class. - *
- * Only for the loot table modifier initializer to call, NO TOUCHY >:( - */ - @ApiStatus.Internal - public static void register() { - // Registers predicate types by loading the class - } -} diff --git a/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/util/LootTableIdGetter.java b/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/util/LootTableIdGetter.java deleted file mode 100644 index a6763f8..0000000 --- a/src/main/java/top/offsetmonkey538/loottablemodifier/api/resource/util/LootTableIdGetter.java +++ /dev/null @@ -1,36 +0,0 @@ -package top.offsetmonkey538.loottablemodifier.api.resource.util; - -import net.minecraft.block.Block; -import net.minecraft.entity.EntityType; -import net.minecraft.util.Identifier; -import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.NotNull; -import top.offsetmonkey538.loottablemodifier.impl.LootTableIdGetterImpl; - -/** - * Provides methods for getting the identifier of loot tables on different versions. - *
- * The implemented methods may compile fine but throw runtime exceptions on newer versions because there's reflection magic going on, but it should be fine as these methods should only be called during data generation afaik. - */ -@ApiStatus.NonExtendable -public interface LootTableIdGetter { - /** - * The instance - */ - LootTableIdGetter INSTANCE = new LootTableIdGetterImpl(); - - /** - * Returns the identifier of an entity's loot table - * - * @param entityType the entity to get the loot table id for - * @return the identifier of the provided entity's loot table - */ - Identifier get(@NotNull EntityType entityType); - /** - * Returns the identifier of a block's loot table - * - * @param block the block to get the loot table id for - * @return the identifier of the provided block's loot table - */ - Identifier get(@NotNull Block block); -} diff --git a/src/main/java/top/offsetmonkey538/loottablemodifier/duck/LootElementWithConditions.java b/src/main/java/top/offsetmonkey538/loottablemodifier/duck/LootElementWithConditions.java deleted file mode 100644 index 147ae35..0000000 --- a/src/main/java/top/offsetmonkey538/loottablemodifier/duck/LootElementWithConditions.java +++ /dev/null @@ -1,9 +0,0 @@ -package top.offsetmonkey538.loottablemodifier.duck; - -import net.minecraft.loot.condition.LootCondition; - -import java.util.List; - -public interface LootElementWithConditions { - void loot_table_modifier$setConditions(List conditions); -} \ No newline at end of file diff --git a/src/main/java/top/offsetmonkey538/loottablemodifier/impl/LootTableIdGetterImpl.java b/src/main/java/top/offsetmonkey538/loottablemodifier/impl/LootTableIdGetterImpl.java deleted file mode 100644 index 05722e4..0000000 --- a/src/main/java/top/offsetmonkey538/loottablemodifier/impl/LootTableIdGetterImpl.java +++ /dev/null @@ -1,138 +0,0 @@ -package top.offsetmonkey538.loottablemodifier.impl; - -import net.fabricmc.loader.api.FabricLoader; -import net.fabricmc.loader.api.MappingResolver; -import net.minecraft.block.AbstractBlock; -import net.minecraft.block.Block; -import net.minecraft.entity.EntityType; -import net.minecraft.loot.LootTable; -import net.minecraft.registry.RegistryKey; -import net.minecraft.util.Identifier; -import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import top.offsetmonkey538.loottablemodifier.api.resource.util.LootTableIdGetter; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.Optional; -import java.util.function.Function; - -import static top.offsetmonkey538.loottablemodifier.LootTableModifier.LOGGER; - -@ApiStatus.Internal -public class LootTableIdGetterImpl implements LootTableIdGetter { - - @Override - public Identifier get(@NotNull EntityType entityType) { - return VersionSpecific.Entity.get.apply(entityType); - } - - @Override - public Identifier get(@NotNull Block block) { - return VersionSpecific.Block.get.apply(block); - } - - - // Should be executed when class is first accessed, which I think should only happen when using action or predicate Builders which are probably only used with datagen so this should only make datagen stuff crash but still work when used by a player? - private static class VersionSpecific { - private static final MappingResolver RESOLVER = FabricLoader.getInstance().getMappingResolver(); - - private static class Entity { - private static final String V1d21d2 = RESOLVER.mapMethodName("intermediary", "net.minecraft.class_1299", "method_16351", "()Ljava/util/Optional;"); - private static final String V1d20d5 = RESOLVER.mapMethodName("intermediary", "net.minecraft.class_1299", "method_16351", "()Lnet/minecraft/class_5321;"); - - // mod only supports down to 1.20.5 soo: private static final String V1d14d0 = RESOLVER.mapMethodName("intermediary", "net.minecraft.class_1299", "method_16351", "()Lnet/minecraft/util/Identifier;"); - - private static final Function, Identifier> get; - - static { - // TODO: I had the below statement commented out, maybe it doesnt work? use this then: final Class entityType = Class.forName(RESOLVER.mapClassName("intermediary", "net.minecraft.class_1299")); - final Class entityType = EntityType.class; - final Method finalMethod; - Method method; - - // 1.21.2 to future:tm: - if ((method = getMethod(entityType, V1d21d2)) != null) { - method.setAccessible(true); - finalMethod = method; - get = entity -> { - try { - @SuppressWarnings("unchecked") final Optional> optional = (Optional>) finalMethod.invoke(entity); - if (optional.isPresent()) return optional.get().getValue(); - throw new IllegalStateException("Entity '" + entity + "' has no loot table! (It is created with 'builder.dropsNothing()')"); - } catch (IllegalAccessException | InvocationTargetException e) { - throw new RuntimeException(e); - } - }; - } - - // 1.20.5 to 1.21.1 - else if ((method = getMethod(entityType, V1d20d5)) != null) { - method.setAccessible(true); - finalMethod = method; - get = entity -> { - try { - return ((RegistryKey) finalMethod.invoke(entity)).getValue(); - } catch (IllegalAccessException | InvocationTargetException e) { - throw new RuntimeException(e); - } - }; - } else { - throw new IllegalStateException("No valid way to get entity loot table id found!"); - } - } - } - private static class Block { - private static final String V1d21d2 = RESOLVER.mapMethodName("intermediary", "net.minecraft.class_4970", "method_26162", "()Ljava/util/Optional;"); - private static final String V1d20d5 = RESOLVER.mapMethodName("intermediary", "net.minecraft.class_4970", "method_26162", "()Lnet/minecraft/class_5321;"); - - private static final Function get; - - static { - final Class abstractBlock = AbstractBlock.class; - final Method finalMethod; - Method method; - - // 1.21.2 to future:tm: - if ((method = getMethod(abstractBlock, V1d21d2)) != null) { - method.setAccessible(true); - finalMethod = method; - get = entity -> { - try { - @SuppressWarnings("unchecked") final Optional> optional = (Optional>) finalMethod.invoke(entity); - if (optional.isPresent()) return optional.get().getValue(); - throw new IllegalStateException("Entity '" + entity + "' has no loot table! (It is created with 'builder.dropsNothing()')"); - } catch (IllegalAccessException | InvocationTargetException e) { - throw new RuntimeException(e); - } - }; - } - - // 1.20.5 to 1.21.1 - else if ((method = getMethod(abstractBlock, V1d20d5)) != null) { - method.setAccessible(true); - finalMethod = method; - get = entity -> { - try { - return ((RegistryKey) finalMethod.invoke(entity)).getValue(); - } catch (IllegalAccessException | InvocationTargetException e) { - throw new RuntimeException(e); - } - }; - } else { - throw new IllegalStateException("No valid way to get entity loot table id found!"); - } - } - } - - private static @Nullable Method getMethod(Class clazz, String method) { - try { - return clazz.getDeclaredMethod(method); - } catch (NoSuchMethodException e) { - LOGGER.warn("Method '%s' not valid for getting loot table id on this version, trying next method...", e); - return null; - } - } - } -} diff --git a/src/main/java/top/offsetmonkey538/loottablemodifier/mixin/ItemEntryAccessor.java b/src/main/java/top/offsetmonkey538/loottablemodifier/mixin/ItemEntryAccessor.java deleted file mode 100644 index f96296f..0000000 --- a/src/main/java/top/offsetmonkey538/loottablemodifier/mixin/ItemEntryAccessor.java +++ /dev/null @@ -1,17 +0,0 @@ -package top.offsetmonkey538.loottablemodifier.mixin; - -import net.minecraft.item.Item; -import net.minecraft.loot.entry.ItemEntry; -import net.minecraft.registry.entry.RegistryEntry; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Mutable; -import org.spongepowered.asm.mixin.gen.Accessor; - -@SuppressWarnings("MissingJavadoc") -@Mixin(ItemEntry.class) -public interface ItemEntryAccessor { - - @Mutable - @Accessor - void setItem(RegistryEntry item); -} diff --git a/src/main/java/top/offsetmonkey538/loottablemodifier/mixin/LootPoolAccessor.java b/src/main/java/top/offsetmonkey538/loottablemodifier/mixin/LootPoolAccessor.java deleted file mode 100644 index 7a8a0ce..0000000 --- a/src/main/java/top/offsetmonkey538/loottablemodifier/mixin/LootPoolAccessor.java +++ /dev/null @@ -1,17 +0,0 @@ -package top.offsetmonkey538.loottablemodifier.mixin; - -import net.minecraft.loot.LootPool; -import net.minecraft.loot.entry.LootPoolEntry; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Mutable; -import org.spongepowered.asm.mixin.gen.Accessor; - -import java.util.List; - -@Mixin(LootPool.class) -public interface LootPoolAccessor { - - @Mutable - @Accessor - void setEntries(List entries); -} diff --git a/src/main/java/top/offsetmonkey538/loottablemodifier/mixin/LootPoolEntryMixin.java b/src/main/java/top/offsetmonkey538/loottablemodifier/mixin/LootPoolEntryMixin.java deleted file mode 100644 index 1e2ae23..0000000 --- a/src/main/java/top/offsetmonkey538/loottablemodifier/mixin/LootPoolEntryMixin.java +++ /dev/null @@ -1,32 +0,0 @@ -package top.offsetmonkey538.loottablemodifier.mixin; - -import net.minecraft.loot.condition.LootCondition; -import net.minecraft.loot.context.LootContext; -import net.minecraft.loot.entry.LootPoolEntry; -import net.minecraft.util.Util; -import org.spongepowered.asm.mixin.*; -import top.offsetmonkey538.loottablemodifier.duck.LootElementWithConditions; - -import java.util.List; -import java.util.function.Predicate; - -@Mixin(LootPoolEntry.class) -public class LootPoolEntryMixin implements LootElementWithConditions { - - @Shadow - @Final - @Mutable - public List conditions; - - @Shadow - @Final - @Mutable - private Predicate conditionPredicate; - - @Override - @Unique - public void loot_table_modifier$setConditions(List conditions) { - this.conditions = conditions; - this.conditionPredicate = Util.allOf(conditions); - } -} diff --git a/src/main/java/top/offsetmonkey538/loottablemodifier/mixin/LootPoolMixin.java b/src/main/java/top/offsetmonkey538/loottablemodifier/mixin/LootPoolMixin.java deleted file mode 100644 index 3efe51a..0000000 --- a/src/main/java/top/offsetmonkey538/loottablemodifier/mixin/LootPoolMixin.java +++ /dev/null @@ -1,32 +0,0 @@ -package top.offsetmonkey538.loottablemodifier.mixin; - -import net.minecraft.loot.LootPool; -import net.minecraft.loot.condition.LootCondition; -import net.minecraft.loot.context.LootContext; -import net.minecraft.util.Util; -import org.spongepowered.asm.mixin.*; -import top.offsetmonkey538.loottablemodifier.duck.LootElementWithConditions; - -import java.util.List; -import java.util.function.Predicate; - -@Mixin(LootPool.class) -public class LootPoolMixin implements LootElementWithConditions { - - @Shadow - @Final - @Mutable - public List conditions; - - @Shadow - @Final - @Mutable - private Predicate predicate; - - @Override - @Unique - public void loot_table_modifier$setConditions(List conditions) { - this.conditions = conditions; - this.predicate = Util.allOf(conditions); - } -} diff --git a/src/main/java/top/offsetmonkey538/loottablemodifier/mixin/LootTableAccessor.java b/src/main/java/top/offsetmonkey538/loottablemodifier/mixin/LootTableAccessor.java deleted file mode 100644 index 65a6051..0000000 --- a/src/main/java/top/offsetmonkey538/loottablemodifier/mixin/LootTableAccessor.java +++ /dev/null @@ -1,17 +0,0 @@ -package top.offsetmonkey538.loottablemodifier.mixin; - -import net.minecraft.loot.LootPool; -import net.minecraft.loot.LootTable; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Mutable; -import org.spongepowered.asm.mixin.gen.Accessor; - -import java.util.List; - -@Mixin(LootTable.class) -public interface LootTableAccessor { - - @Mutable - @Accessor - void setPools(List pools); -} diff --git a/src/main/java/top/offsetmonkey538/loottablemodifier/mixin/ReloadableRegistriesMixin.java b/src/main/java/top/offsetmonkey538/loottablemodifier/mixin/ReloadableRegistriesMixin.java deleted file mode 100644 index cb65664..0000000 --- a/src/main/java/top/offsetmonkey538/loottablemodifier/mixin/ReloadableRegistriesMixin.java +++ /dev/null @@ -1,46 +0,0 @@ -package top.offsetmonkey538.loottablemodifier.mixin; - -import com.google.gson.JsonElement; -import net.minecraft.loot.LootDataType; -import net.minecraft.loot.LootTable; -import net.minecraft.registry.MutableRegistry; -import net.minecraft.registry.Registry; -import net.minecraft.registry.RegistryOps; -import net.minecraft.registry.ReloadableRegistries; -import net.minecraft.resource.ResourceManager; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import top.offsetmonkey538.loottablemodifier.LootTableModifier; - -@Mixin( - value = ReloadableRegistries.class, - priority = 900, - remap = false -) -public abstract class ReloadableRegistriesMixin { - @Inject( - method = { - // 1.21.2 and up: intermediary - "method_61240(Lnet/minecraft/class_8490;Lnet/minecraft/class_3300;Lnet/minecraft/class_6903;)Lnet/minecraft/class_2385;", - // 1.21.2 and up: yarn - "method_61240(Lnet/minecraft/loot/LootDataType;Lnet/minecraft/resource/ResourceManager;Lnet/minecraft/registry/RegistryOps;)Lnet/minecraft/registry/MutableRegistry;", - // 1.21.2 and up: mojmap - "lambda$scheduleRegistryLoad$3(Lnet/minecraft/world/level/storage/loot/LootDataType;Lnet/minecraft/server/packs/resources/ResourceManager;Lnet/minecraft/resources/RegistryOps;)Lnet/minecraft/core/WritableRegistry;", - - // 1.20.5 to 1.21.1: intermediary - "method_58279(Lnet/minecraft/class_8490;Lnet/minecraft/class_3300;Lnet/minecraft/class_6903;)Lnet/minecraft/class_2385;", - // 1.20.5 to 1.21.1: yarn - "method_58279(Lnet/minecraft/loot/LootDataType;Lnet/minecraft/resource/ResourceManager;Lnet/minecraft/registry/RegistryOps;)Lnet/minecraft/registry/MutableRegistry;", - // 1.20.5 to 1.21.1: mojmap - "lambda$scheduleElementParse$4(Lnet/minecraft/world/level/storage/loot/LootDataType;Lnet/minecraft/server/packs/resources/ResourceManager;Lnet/minecraft/resources/RegistryOps;)Lnet/minecraft/core/WritableRegistry;" - }, - at = @At("RETURN") - ) - private static void loottablemodifier$modifyLootTables(LootDataType lootDataType, ResourceManager resourceManager, RegistryOps registryOps, CallbackInfoReturnable> cir) { - if (lootDataType != LootDataType.LOOT_TABLES) return; - //noinspection unchecked - LootTableModifier.runModification(resourceManager, (Registry) cir.getReturnValue(), registryOps); - } -} diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json deleted file mode 100644 index 7712d72..0000000 --- a/src/main/resources/fabric.mod.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "schemaVersion": 1, - "id": "loot-table-modifier", - "version": "${modVersion}", - "name": "Loot Table Modifier", - "description": "Makes it possible to modify instead of replace loot tables through datapacks.", - "authors": [ - "OffsetMonkey538" - ], - "contact": { - "sources": "https://github.com/OffsetMods538/Loot-Table-Modifier", - "issues": "https://github.com/OffsetMods538/Loot-Table-Modifier/issues", - "homepage": "https://modrinth.com/mod/loot-table-modifier" - }, - "license": "MIT", - "icon": "assets/loot-table-modifier/icon.png", - "environment": "*", - "entrypoints": { - "fabric-datagen": [ - "top.offsetmonkey538.loottablemodifier.datagen.LootTableModifierDatagen" - ], - "main": [ - "top.offsetmonkey538.loottablemodifier.LootTableModifier" - ], - "client": [ - "top.offsetmonkey538.loottablemodifier.LootTableModifierClient" - ] - }, - "mixins": [ - "loot-table-modifier.mixins.json", - { - "config": "loot-table-modifier.client.mixins.json", - "environment": "client" - } - ], - "accessWidener": "loot-table-modifier.accesswidener", - "depends": { - "fabric-api": "*", - "minecraft": "${supportedMinecraftVersions}" - } -} diff --git a/src/main/resources/loot-table-modifier.accesswidener b/src/main/resources/loot-table-modifier.accesswidener deleted file mode 100644 index a3ac5f3..0000000 --- a/src/main/resources/loot-table-modifier.accesswidener +++ /dev/null @@ -1,12 +0,0 @@ -accessWidener v1 named - -# TODO: get rid of these and use mixin insteadddd - -accessible field net/minecraft/loot/LootTable pools Ljava/util/List; -accessible field net/minecraft/loot/LootTable functions Ljava/util/List; - -accessible field net/minecraft/loot/context/LootContextTypes MAP Lcom/google/common/collect/BiMap; - -accessible field net/minecraft/loot/entry/LootPoolEntry conditions Ljava/util/List; - -accessible field net/minecraft/loot/entry/ItemEntry item Lnet/minecraft/registry/entry/RegistryEntry; \ No newline at end of file diff --git a/src/main/resources/loot-table-modifier.mixins.json b/src/main/resources/loot-table-modifier.mixins.json deleted file mode 100644 index 48bc9db..0000000 --- a/src/main/resources/loot-table-modifier.mixins.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "required": true, - "package": "top.offsetmonkey538.loottablemodifier.mixin", - "compatibilityLevel": "JAVA_17", - "mixins": [ - "ItemEntryAccessor", - "LootPoolAccessor", - "LootPoolEntryMixin", - "LootPoolMixin", - "LootTableAccessor", - "ReloadableRegistriesMixin" - ], - "injectors": { - "defaultRequire": 1 - } -}