Port to 1.21.1

Co-authored-by: TropheusJ <jverrellijr@icloud.com>
Co-authored-by: techno-sam <77073745+techno-sam@users.noreply.github.com>
Co-authored-by: ryanhcode <42245712+ryanhcode@users.noreply.github.com>
This commit is contained in:
IThundxr 2025-01-03 15:22:41 -05:00
parent 4bd47bea41
commit 15565fab47
Failed to generate hash of commit
1509 changed files with 19983 additions and 19632 deletions

View file

@ -25,5 +25,5 @@ ij_java_blank_lines_before_method_body = 0
ij_java_else_on_new_line = false ij_java_else_on_new_line = false
ij_java_class_count_to_use_import_on_demand = 999 ij_java_class_count_to_use_import_on_demand = 999
ij_java_names_count_to_use_import_on_demand = 999 ij_java_names_count_to_use_import_on_demand = 999
ij_java_imports_layout = $*,|,java.**,|,javax.**,|,org.**,|,com.**,|,*,|,net.minecraftforge.** ij_java_imports_layout = $*,|,java.**,|,javax.**,|,org.**,|,com.**,|,*,|,net.neoforged.**
ij_java_insert_inner_class_imports = true ij_java_insert_inner_class_imports = true

31
.github/workflows/build.yml vendored Normal file
View file

@ -0,0 +1,31 @@
name: Build
on: [ workflow_dispatch, push, pull_request ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Setup Java
run: echo "JAVA_HOME=$JAVA_HOME_17_X64" >> "$GITHUB_ENV"
- name: NeoGradle Cache
uses: actions/cache@v4
with:
path: "**/.gradle/repositories/"
key: "${{ runner.os }}-gradle-${{ hashFiles('**/libs.versions.*', '**/*.gradle*', '**/gradle-wrapper.properties') }}"
restore-keys: "${{ runner.os }}-gradle-"
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
with:
gradle-home-cache-cleanup: true
- name: Validate Gradle Wrapper Integrity
uses: gradle/wrapper-validation-action@v2
- name: Build
run: ./gradlew build

View file

@ -1,23 +1,33 @@
name: gametest name: GameTests
on: [ workflow_dispatch ] on: [ workflow_dispatch ]
jobs: jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: checkout repository - name: Setup Java
uses: actions/checkout@v3 run: echo "JAVA_HOME=$JAVA_HOME_17_X64" >> "$GITHUB_ENV"
- name: setup Java - name: NeoGradle Cache
uses: actions/setup-java@v3 uses: actions/cache@v4
with: if: ${{ !endsWith(github.ref, '/dev') }}
distribution: temurin with:
java-version: 17 path: "**/.gradle/repositories/"
cache: gradle key: "${{ runner.os }}-gradle-${{ hashFiles('**/libs.versions.*', '**/*.gradle*', '**/gradle-wrapper.properties') }}"
restore-keys: "${{ runner.os }}-gradle-"
- name: make gradle wrapper executable - name: Setup Gradle
run: chmod +x ./gradlew uses: gradle/actions/setup-gradle@v3
with:
gradle-home-cache-cleanup: true
cache-read-only: ${{ !endsWith(github.ref, '/dev') }}
- name: run gametests - name: Validate Gradle Wrapper Integrity
run: ./gradlew prepareRunGameTestServer runGameTestServer --no-daemon uses: gradle/wrapper-validation-action@v2
- name: Run GameTest Server
run: ./gradlew runGameTestServer

View file

@ -1,21 +1,21 @@
name: "Label Actions" name: "Label Actions"
on: on:
issues: issues:
types: [labeled, unlabeled] types: [ labeled, unlabeled ]
pull_request_target: pull_request_target:
types: [labeled, unlabeled] types: [ labeled, unlabeled ]
permissions: permissions:
contents: read contents: read
issues: write issues: write
pull-requests: write pull-requests: write
discussions: write discussions: write
jobs: jobs:
action: action:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: dessant/label-actions@102faf474a544be75fbaf4df54e73d3c515a0e65 # Depend on an exact commit - uses: dessant/label-actions@102faf474a544be75fbaf4df54e73d3c515a0e65 # Depend on an exact commit
with: with:
github-token: ${{ secrets.GITHUB_TOKEN }} github-token: ${{ secrets.GITHUB_TOKEN }}
config-path: '.github/config/label-actions.yml' config-path: '.github/config/label-actions.yml'

View file

@ -5,44 +5,44 @@ name: Crowdin Action
# Controls when the action will run. # Controls when the action will run.
on: workflow_dispatch on: workflow_dispatch
# Only run when started manually # Only run when started manually
#: #:
# inputs: # inputs:
# uploadTranslations: # uploadTranslations:
# description: "Set to true to upload (changed) translations to Crowdin" # description: "Set to true to upload (changed) translations to Crowdin"
# type: boolean # type: boolean
# required: true # required: true
# default: false # default: false
#schedule: #schedule:
#- cron: '0 */6 * * *' # Every 6 hours - https://crontab.guru/#0_*/6_*_*_* #- cron: '0 */6 * * *' # Every 6 hours - https://crontab.guru/#0_*/6_*_*_*
jobs: jobs:
synchronize-with-crowdin: synchronize-with-crowdin:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v2
- name: crowdin action - name: crowdin action
uses: crowdin/github-action@1.4.9 uses: crowdin/github-action@1.4.9
with: with:
# Upload sources to Crowdin # Upload sources to Crowdin
upload_sources: true upload_sources: true
# Upload translations to Crowdin, only use true at initial run # Upload translations to Crowdin, only use true at initial run
upload_translations: false upload_translations: false
# Make pull request of Crowdin translations # Make pull request of Crowdin translations
download_translations: true download_translations: true
# To download translations to the specified version branch # To download translations to the specified version branch
localization_branch_name: l10n_crowdin_translations localization_branch_name: l10n_crowdin_translations
# Create pull request after pushing to branch # Create pull request after pushing to branch
create_pull_request: true create_pull_request: true
pull_request_title: 'New Crowdin translations' pull_request_title: 'New Crowdin translations'
pull_request_body: 'New Crowdin pull request with translations' pull_request_body: 'New Crowdin pull request with translations'
pull_request_base_branch_name: 'mc1.20.1/dev' pull_request_base_branch_name: 'mc1.20.1/dev'
env: env:
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }} CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }}
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }} CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}

View file

@ -1,459 +1,230 @@
plugins { plugins {
id 'idea' id 'java-library'
id 'eclipse' id 'eclipse'
id 'idea'
id 'maven-publish' id 'maven-publish'
id 'net.neoforged.moddev' version '2.0.9-beta'
id 'net.minecraftforge.gradle' version "${forgegradle_version}"
id 'org.spongepowered.mixin' version "${mixingradle_version}"
id 'org.parchmentmc.librarian.forgegradle' version "${librarian_version}"
id 'com.matthewprenger.cursegradle' version "${cursegradle_version}"
} }
apply from: './gradle/java.gradle' boolean dev = System.getenv('RELEASE') == null || System.getenv('RELEASE').equals('false');
String buildNumber = System.getenv('BUILD_NUMBER')
jarJar.enable() version = project.mod_version + (dev && buildNumber != null ? "-${buildNumber}" : '')
group = project.maven_group
boolean dev = System.getenv('RELEASE') == null || System.getenv('RELEASE').equals('false') repositories {
ext.buildNumber = System.getenv('BUILD_NUMBER') mavenLocal()
}
base { base {
archivesName = "create-${artifact_minecraft_version}" archivesName = "$mod_id-$minecraft_version"
group = 'com.simibubi.create'
version = mod_version + (dev && buildNumber != null ? "-${buildNumber}" : '')
} }
boolean inMultiModWorkspace = rootProject.hasProperty('multiModWorkspace.enabled') java.toolchain.languageVersion = JavaLanguageVersion.of(21)
boolean catnipInWorkspace = rootProject.hasProperty('multiModWorkspace.catnip')
boolean ponderInWorkspace = rootProject.hasProperty('multiModWorkspace.ponder')
if (catnipInWorkspace) { neoForge {
evaluationDependsOn(":catnip:Forge") version = project.neo_version
}
if (ponderInWorkspace) { parchment {
evaluationDependsOn(":ponder:Forge") minecraftVersion = project.parchment_minecraft_version
} mappingsVersion = project.parchment_version
project.logger.lifecycle("MultiModWorkspace ${inMultiModWorkspace ? 'enabled' : 'disabled'} for project ${project.name}.")
project.logger.lifecycle("Dependencies included in Workspace: [Catnip: ${catnipInWorkspace}], [Ponder: ${ponderInWorkspace}]")
mixin {
add sourceSets.main, 'create.refmap.json'
config 'create.mixins.json'
}
println "Java: ${System.getProperty 'java.version'}, JVM: ${System.getProperty 'java.vm.version'} (${System.getProperty 'java.vendor'}), Arch: ${System.getProperty 'os.arch'}"
mixin {
add sourceSets.main, 'create.refmap.json'
debug.verbose = true
debug.export = true
}
idea {
module {
downloadJavadoc = true
downloadSources = true
}
}
minecraft {
if (Boolean.parseBoolean(use_parchment)) {
mappings channel: 'parchment', version: "${parchment_version}-${minecraft_version}"
} else {
mappings channel: 'official', version: "${minecraft_version}"
} }
// This property allows configuring Gradle's ProcessResources task(s) to run on IDE output locations before launching the game. accessTransformers = project.files('src/main/resources/META-INF/accesstransformer.cfg')
copyIdeResources = true
if (file('src/main/resources/META-INF/accesstransformer.cfg').exists()) {
accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg')
}
runs { runs {
// applies to all the run configs below
configureEach {
if (inMultiModWorkspace)
ideaModule "createmod.Create.main"
else
ideaModule "Create.main"
property 'forge.logging.markers', ''
property 'forge.logging.console.level', 'info'
jvmArgs '-XX:+IgnoreUnrecognizedVMOptions', '-XX:+AllowEnhancedClassRedefinition'
//jvmArgs("-XX:-OmitStackTraceInFastThrow") // uncomment when you get exceptions with null messages etc
//jvmArgs '-XX:+UnlockCommercialFeatures' // uncomment for profiling
property 'mixin.debug.export', 'true'
property 'mixin.env.remapRefMap', 'true'
property 'mixin.env.refMapRemappingFile', "${projectDir}/build/createSrgToMcp/output.srg"
arg '-mixin.config=create.mixins.json'
arg '-mixin.config=catnip.mixins.json'
mods {
create {
source sourceSets.main
}
if (catnipInWorkspace) {
catnip {
source project(":catnip:Common").sourceSets.main
source project(":catnip:Forge").sourceSets.main
}
}
if (ponderInWorkspace) {
ponder {
source project(":ponder:Common").sourceSets.main
source project(":ponder:Forge").sourceSets.main
}
}
}
}
client { client {
workingDirectory project.file('run') client()
// Comma-separated list of namespaces to load gametests from. Empty = all namespaces.
systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id
} }
server { server {
workingDirectory project.file('run/server') server()
gameDirectory = project.file('run/server')
programArgument '--nogui'
systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id
}
// This run config launches GameTestServer and runs all registered gametests, then exits.
// By default, the server will crash when no gametests are provided.
// The gametest system is also enabled by default for other run configs under the /test command.
gameTestServer {
type = "gameTestServer"
systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id
} }
data { data {
workingDirectory project.file('run') data()
property 'forge.logging.markers', 'REGISTRIES,REGISTRYDUMP'
property 'forge.logging.console.level', 'debug' // Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources.
args '--mod', 'create', '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources') programArguments.addAll '--mod', project.mod_id, '--all', '--output', file('src/generated/resources/').getAbsolutePath(), '--existing', file('src/main/resources/').getAbsolutePath()
} }
gameTestServer { configureEach {
workingDirectory project.file('run/gametest') systemProperty 'forge.logging.markers', 'REGISTRIES'
// setForceExit false <- FIXME 1.20
systemProperty 'mixin.debug.verbose', 'true'
systemProperty 'mixin.debug.export', 'true'
// IThundxr ~ I use JBR for enhanced hotswap, this adds the required arg while not affecting other people
jvmArguments = ["-XX:+AllowEnhancedClassRedefinition", "-XX:+IgnoreUnrecognizedVMOptions"]
logLevel = org.slf4j.event.Level.DEBUG
}
}
mods {
"${mod_id}" {
sourceSet(sourceSets.main)
} }
} }
} }
configurations {
runtimeClasspath.extendsFrom localRuntime
}
repositories { repositories {
maven { maven { url = "https://maven.createmod.net" } // Ponder, Catnip
// location of the maven for Registrate and Flywheel maven { url = "https://maven.tterrag.com" } // Flywheel
name = 'tterrag maven' maven { url = "https://maven.ithundxr.dev/snapshots" } // Registrate
url = 'https://maven.tterrag.com' maven { url = "https://maven.blamejared.com" } // JEI, Vazkii's Mods
} maven { url = "https://harleyoconnor.com/maven" } // Dynamic Trees
maven { maven { url = "https://maven.theillusivec4.top/" } // Curios API
// location of the maven that hosts JEI files since January 2023 maven { url = "https://maven.squiddev.cc/" } // CC: Tweaked
// location of the maven for Vazkii's mods maven { url = "https://www.cursemaven.com" }
name = "Jared's maven" maven { url = "https://api.modrinth.com/maven" }
url = "https://maven.blamejared.com/" maven { url = "https://maven.saps.dev/releases" } // FTB Mods
} maven { url = "https://maven.architectury.dev/" } // Arch API
/*maven { maven { url = "https://jm.gserv.me/repository/maven-public/" // JourneyMap
// location of a maven mirror for JEI files, as a fallback
name = "ModMaven"
url = "https://modmaven.dev"
}*/
maven {
// location of the maven for Dynamic Trees
url = 'https://harleyoconnor.com/maven'
}
maven {
// location of the maven for Curios API
url = "https://maven.theillusivec4.top/"
}
maven {
// location of maven for CC: Tweaked
name = "squiddev"
url = "https://squiddev.cc/maven/"
}
maven {
name = "ftb"
url = "https://maven.saps.dev/releases"
}
maven {
name = "architectury"
url = "https://maven.architectury.dev/"
}
maven {
url = "https://jm.gserv.me/repository/maven-public/"
content { content {
includeGroup "info.journeymap" includeGroup "info.journeymap"
includeGroup "mysticdrew" includeGroup "mysticdrew"
} }
} }
maven {
url = 'https://www.cursemaven.com'
content {
includeGroup "curse.maven"
}
}
maven {
// Location of the maven for Ponder, Catnip
name = 'createmod maven'
url 'https://maven.createmod.net'
}
maven {
name = "Modrinth"
url = "https://api.modrinth.com/maven"
content {
includeGroup "maven.modrinth"
}
}
maven { url = "https://raw.githubusercontent.com/Fuzss/modresources/main/maven/" }
// Mirror of maven.createmod.net // Mirror of maven.createmod.net
if (System.getProperty("os.name").contains("Mac") && System.getenv("USER") == "ithundxr") { if (System.getProperty("os.name").contains("Mac") && System.getenv("USER") == "ithundxr") {
maven { url = "https://maven.ithundxr.dev/mirror" } maven { url = "https://maven.ithundxr.dev/mirror" }
} }
mavenCentral() // todo - temp
mavenLocal() maven { url = "https://maven.ithundxr.dev/hidden" } // Flywheel 1.21 PR
flatDir { flatDir {
dirs 'libs' dirs "libs"
}
}
dependencies {
jarJar(implementation("com.tterrag.registrate:Registrate:${registrate_version}"))
compileOnly("dev.engine_room.flywheel:flywheel-neoforge-api-${flywheel_minecraft_version}:${flywheel_version}")
jarJar(runtimeOnly("dev.engine_room.flywheel:flywheel-neoforge-${flywheel_minecraft_version}:${flywheel_version}"))
jarJar(implementation("net.createmod.catnip:Catnip-NeoForge-${catnip_and_ponder_mc_ver}:${catnip_version}"))
jarJar(implementation("net.createmod.ponder:Ponder-NeoForge-${catnip_and_ponder_mc_ver}:${ponder_version}"))
//compileOnly("mezz.jei:jei-${jei_minecraft_version}-common-api:${jei_version}")
//compileOnly("mezz.jei:jei-${jei_minecraft_version}-neoforge-api:${jei_version}")
implementation("mezz.jei:jei-${jei_minecraft_version}-neoforge:${jei_version}")
compileOnly("top.theillusivec4.curios:curios-neoforge:${curios_version}+${curios_minecraft_version}:api")
// FIXME: Look into what to replace this with
//runtimeOnly("top.theillusivec4.curios:curios-neoforge:${curios_version}+${curios_minecraft_version}")
if (cc_tweaked_enable.toBoolean()) {
compileOnly("cc.tweaked:cc-tweaked-${cc_tweaked_minecraft_version}-core-api:${cc_tweaked_version}")
compileOnly("cc.tweaked:cc-tweaked-${cc_tweaked_minecraft_version}-forge-api:${cc_tweaked_version}")
if (!cc_tweaked_disable_runtime.toBoolean())
runtimeOnly("cc.tweaked:cc-tweaked-${cc_tweaked_minecraft_version}-forge:${cc_tweaked_version}")
}
implementation("dev.architectury:architectury-neoforge:13.0.8")
implementation("dev.ftb.mods:ftb-chunks-neoforge:2101.1.1")
implementation("dev.ftb.mods:ftb-teams-neoforge:2101.1.0")
implementation("dev.ftb.mods:ftb-library-neoforge:2101.1.3")
implementation("maven.modrinth:journeymap:1.21.1-6.0.0-beta.32+neoforge")
implementation("info.journeymap:journeymap-api-neoforge:2.0.0-1.21.1-SNAPSHOT")
// implementation("curse.maven:druidcraft-340991:3101903")
// implementation("com.ferreusveritas.dynamictrees:DynamicTrees-1.16.5:0.10.0-Beta25")
// runtimeOnly("vazkii.arl:AutoRegLib:1.4-35.69")
// runtimeOnly("vazkii.quark:Quark:r2.0-212.984")
// runtimeOnly("slimeknights.mantle:Mantle:1.16.5-1.6.115")
// runtimeOnly("slimeknights.tconstruct:TConstruct:1.16.5-3.1.1.252")
// runtimeOnly("maven.modrinth:rubidium:0.5.3")
// implementation("com.railwayteam.railways:railways-1.18.2-1.1.1:all" { transitive = false })
// runtimeOnly("maven.modrinth:aether:1.19.2-1.0.0-beta.1.1-forge")
// runtimeOnly("maven.modrinth:spark:1.10.38-forge")
// runtimeOnly("curse.maven:xycraft-653786:4788862")
// runtimeOnly("curse.maven:xycraft-world-653789:4788863")
}
sourceSets.main.java {
if (!cc_tweaked_enable.toBoolean()) {
exclude "com/simibubi/create/compat/computercraft/implementation/**"
} }
} }
sourceSets.main.resources { sourceSets.main.resources {
srcDir 'src/generated/resources' srcDir "src/generated/resources"
exclude '.cache/' exclude ".cache/"
} }
dependencies { jar {
minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}" from('LICENSE') {
jarJar("com.tterrag.registrate:Registrate:${registrate_version}") {
jarJar.ranged(it, '[MC1.19.3-1.1.10,)')
}
jarJar("dev.engine_room.flywheel:flywheel-forge-${flywheel_minecraft_version}:${flywheel_version}") {
jarJar.ranged(it, '[1.0,2.0)')
}
jarJar("net.createmod.catnip:Catnip-Forge-${minecraft_version}:${catnip_version}") {
jarJar.ranged(it, '[0.7.5,)')
}
jarJar("net.createmod.ponder:Ponder-Forge-${minecraft_version}:${ponder_version}") {
jarJar.ranged(it, '[0.7.5,)')
}
implementation(jarJar("io.github.llamalad7:mixinextras-forge:${mixin_extras_version}")) {
jarJar.ranged(it, "[${mixin_extras_version},)")
}
implementation fg.deobf("com.tterrag.registrate:Registrate:${registrate_version}")
compileOnly fg.deobf("dev.engine_room.flywheel:flywheel-forge-api-${flywheel_minecraft_version}:${flywheel_version}")
runtimeOnly fg.deobf("dev.engine_room.flywheel:flywheel-forge-${flywheel_minecraft_version}:${flywheel_version}")
if (catnipInWorkspace) {
implementation project(":catnip:Common")
implementation project(":catnip:Forge")
} else {
implementation fg.deobf("net.createmod.catnip:Catnip-Forge-${minecraft_version}:${catnip_version}")
}
if (ponderInWorkspace) {
implementation project(":ponder:Common")
implementation project(":ponder:Forge")
} else {
implementation fg.deobf("net.createmod.ponder:Ponder-Forge-${minecraft_version}:${ponder_version}")
}
compileOnly(annotationProcessor("io.github.llamalad7:mixinextras-common:${mixin_extras_version}"))
// compileOnly fg.deobf("mezz.jei:jei-${jei_minecraft_version}-common-api:${jei_version}")
// compileOnly fg.deobf("mezz.jei:jei-${jei_minecraft_version}-forge-api:${jei_version}")
implementation fg.deobf("mezz.jei:jei-${jei_minecraft_version}-forge:${jei_version}")
compileOnly fg.deobf("top.theillusivec4.curios:curios-forge:${curios_version}+${curios_minecraft_version}:api")
runtimeOnly fg.deobf("top.theillusivec4.curios:curios-forge:${curios_version}+${curios_minecraft_version}")
if (cc_tweaked_enable.toBoolean()) {
compileOnly("cc.tweaked:cc-tweaked-${cc_tweaked_minecraft_version}-core-api:${cc_tweaked_version}")
compileOnly fg.deobf("cc.tweaked:cc-tweaked-${cc_tweaked_minecraft_version}-forge-api:${cc_tweaked_version}")
runtimeOnly fg.deobf("cc.tweaked:cc-tweaked-${cc_tweaked_minecraft_version}-forge:${cc_tweaked_version}")
}
if (dynamic_trees_enable.toBoolean()) {
compileOnly fg.deobf("com.ferreusveritas.dynamictrees:DynamicTrees-${dynamic_trees_minecraft_version}:${dynamic_trees_version}")
}
// implementation fg.deobf("curse.maven:ic2-classic-242942:5555152")
// implementation fg.deobf("curse.maven:druidcraft-340991:3101903")
// implementation fg.deobf("com.railwayteam.railways:railways-1.19.2-1.6.4:all") { transitive = false }
implementation fg.deobf("dev.architectury:architectury-forge:9.1.12")
implementation fg.deobf("dev.ftb.mods:ftb-chunks-forge:2001.3.1")
implementation fg.deobf("dev.ftb.mods:ftb-teams-forge:2001.3.0")
implementation fg.deobf("dev.ftb.mods:ftb-library-forge:2001.2.4")
implementation fg.deobf("curse.maven:journeymap-32274:5457831")
// implementation fg.deobf("ignored:journeymap-1.20.1-5.10.1-forge")
// runtimeOnly fg.deobf("curse.maven:framedblocks-441647:5399211")
// runtimeOnly fg.deobf("curse.maven:galosphere-631098:4574834")
// runtimeOnly fg.deobf("curse.maven:elementary-ores-332609:4514276") 1.19.4 only
// runtimeOnly fg.deobf("curse.maven:flib-661261:4479544")
// runtimeOnly fg.deobf("curse.maven:infernal-expansion-395078:4002091")
// runtimeOnly fg.deobf("vazkii.autoreglib:AutoRegLib:1.8.2-58.126")
// runtimeOnly fg.deobf("curse.maven:quark-243121:4812006")
// runtimeOnly fg.deobf("curse.maven:mantle-74924:5339977")
// runtimeOnly fg.deobf("curse.maven:tinkers-construct-74072:5358052")
// runtimeOnly fg.deobf("maven.modrinth:rubidium:0.6.2c")
// runtimeOnly fg.deobf("maven.modrinth:aether:1.19.2-1.4.2-forge")
// runtimeOnly fg.deobf("maven.modrinth:spark:1.10.38-forge")
// runtimeOnly fg.deobf("curse.maven:forbidden-arcanus-309858:4852521")
// runtimeOnly fg.deobf("curse.maven:valhelsia-core-416935:4181245")
// runtimeOnly fg.deobf("curse.maven:modern-ui-352491:5229370")
// runtimeOnly fg.deobf("curse.maven:sophisticated-storage-619320:5194750")
// runtimeOnly fg.deobf("curse.maven:sophisticated-core-618298:5296313")
// runtimeOnly fg.deobf("curse.maven:functional-storage-556861:5499169")
// runtimeOnly fg.deobf("curse.maven:titanium-287342:5356458")
// runtimeOnly fg.deobf("curse.maven:storage-drawers-223852:3884263")
// runtimeOnly fg.deobf("curse.maven:ftb-chunks-forge-314906:5417874")
// runtimeOnly fg.deobf("curse.maven:architectury-api-419699:5137942")
// runtimeOnly fg.deobf("curse.maven:ftb-library-forge-404465:4661834")
// runtimeOnly fg.deobf("curse.maven:ftb-teams-forge-404468:4611938")
// runtimeOnly fg.deobf("curse.maven:citadel-331936:4556677")
// runtimeOnly fg.deobf("curse.maven:ice-and-fire-dragons-264231:5037952")
// runtimeOnly fg.deobf("curse.maven:exnihilosequentia-400012:4993344")
// runtimeOnly fg.deobf("curse.maven:upgrade-aquatic-326895:4777515")
// runtimeOnly fg.deobf("curse.maven:blueprint-382216:4749000")
// runtimeOnly fg.deobf("curse.maven:windsweptmod-636321:4817132")
// runtimeOnly fg.deobf("curse.maven:good-ending-690161:4363719")
// https://discord.com/channels/313125603924639766/725850371834118214/910619168821354497
// Prevent Mixin annotation processor from getting into IntelliJ's annotation processor settings
// This allows 'Settings > Build, Execution, and Deployment > Build Tools > Gradle > Build and run using' set to IntelliJ to work correctly
if (!Boolean.getBoolean('idea.sync.active')) {
annotationProcessor "org.spongepowered:mixin:${mixin_version}:processor"
}
}
sourceSets.main.java {
if (!cc_tweaked_enable.toBoolean()) {
exclude 'com/simibubi/create/compat/computercraft/implementation/**'
}
}
// Workaround for SpongePowered/MixinGradle#38
afterEvaluate {
tasks.configureReobfTaskForReobfJar.mustRunAfter(tasks.compileJava)
tasks.configureReobfTaskForReobfJarJar.mustRunAfter(tasks.compileJava)
}
processResources {
def buildProps = project.properties.clone()
// Replaces FML's magic file.jarVersion string with the correct version at build time.
buildProps.put('file', [jarVersion: project.version])
filesMatching(['META-INF/mods.toml', 'pack.mcmeta']) {
expand buildProps
}
}
compileJava {
options.compilerArgs = ['-Xdiags:verbose']
}
void addLicense(jarTask) {
jarTask.from('LICENSE') {
rename { "${it}_${project.archivesBaseName}" } rename { "${it}_${project.archivesBaseName}" }
} }
} }
tasks.jar { tasks.withType(ProcessResources).configureEach {
archiveClassifier = 'slim' var replaceProperties = [
finalizedBy('reobfJar') mod_version : mod_version,
addLicense it mod_id : mod_id,
} mod_name : mod_name,
mod_author : mod_author,
mod_description : mod_description,
mod_license : mod_license,
minecraft_version_range: minecraft_version_range,
neo_version_range : neo_version_range,
flywheel_version_range : flywheel_version_range,
]
inputs.properties replaceProperties
tasks.jarJar { filesMatching(['META-INF/neoforge.mods.toml']) {
finalizedBy('reobfJarJar') expand replaceProperties
addLicense it
}
task jarJarRelease {
group = 'jarjar'
doLast {
tasks.jarJar {
archiveClassifier = ''
}
} }
finalizedBy tasks.jarJar
} }
project.publishing { java {
withSourcesJar()
}
publishing {
publications { publications {
mavenJava(MavenPublication) { register('mavenJava', MavenPublication) {
artifactId base.archivesName.get()
from components.java from components.java
fg.component(it)
jarJar.component(it)
} }
} }
repositories { repositories {
if (project.hasProperty('mavendir')) { if (project.hasProperty('mavendir')) {
maven { url mavendir } maven { url = mavendir }
} }
} }
} }
String getChangelogText() { tasks.withType(JavaCompile).configureEach {
def changelogFile = file('changelog.txt') options.encoding = 'UTF-8'
String str = ''
int lineCount = 0
boolean done = false
changelogFile.eachLine {
if (done || it == null) {
return
}
if (it.size() > 1) {
def temp = it
if (lineCount == 0) {
temp = "Create ${version}"
temp = "<span style=\"font-size: 18px; color: #333399;\">Create v${mod_version}</span>&nbsp;&nbsp;<em>for Minecraft ${minecraft_version}</em><br/>"
} else if (it.startsWith('-')) {
temp = "&nbsp;&nbsp;&nbsp;$temp<br/>"
temp = temp.replaceAll("(\\S+\\/\\S+)#([0-9]+)\\b", "<a href=\"https://github.com/\$1/issues/\$2\">\$0</a>");
temp = temp.replaceAll("#([0-9]+)\\b(?!<\\/a>)", "<a href=\"https://github.com/$github_project/issues/\$1\">\$0</a>");
} else {
temp = "<h4>$temp</h4>"
}
str += temp
lineCount++
} else {
str += "<p>Please submit any Issues you come across on the&nbsp;<a href=\"https://github.com/${github_project}/issues\" rel=\"nofollow\">Issue Tracker</a>.</p>"
done = true
}
}
return str
} }
// changelog debugging idea {
// new File("changelog.html").write getChangelogText() module {
// tasks.curseforge.enabled = !dev && project.hasProperty('simi_curseforge_key') downloadSources = true
// curseforge { downloadJavadoc = true
// if (project.hasProperty('simi_curseforge_key')) { }
// apiKey = project.simi_curseforge_key }
// }
//
// project {
// id = project.projectId
// changelog = System.getenv('CHANGELOG') == null || System.getenv('CHANGELOG').equals('none') ? getChangelogText() : System.getenv('CHANGELOG')
// changelogType = 'html'
// releaseType = project.curse_type
// mainArtifact(shadowJar) {
// displayName = "Create - ${version}"
// }
// relations {
// optionalDependency 'jei'
// }
// }
// }

View file

@ -1,55 +1,45 @@
# Sets default memory used for gradle commands. Can be overridden by user or command line properties.
# This is required to provide enough memory for the Minecraft decompilation process.
org.gradle.jvmargs = -Xmx3G org.gradle.jvmargs = -Xmx3G
org.gradle.daemon = false org.gradle.daemon = false
org.gradle.caching = true
# mod version info # Mod Info
mod_version = 0.5.2 mod_version = 0.5.2
artifact_minecraft_version = 1.20.1 maven_group = com.simibubi.create
minecraft_version = 1.20.1
forge_version = 47.2.6
# build dependency versions
forgegradle_version = [6.0.16,6.2)
mixingradle_version = 0.7.+
mixin_version = 0.8.5
librarian_version = 1.+
cursegradle_version = 1.4.0
parchment_version = 2023.09.03
use_parchment = true
# dependency versions
registrate_version = MC1.20-1.3.3
flywheel_minecraft_version = 1.20.1
flywheel_version = 1.0.0-beta-177
jei_minecraft_version = 1.20.1
jei_version = 15.10.0.39
curios_minecraft_version = 1.20.1
curios_version = 5.3.1
catnip_version = 0.8.42
ponder_version = 0.8.15
mixin_extras_version = 0.4.1
cc_tweaked_enable = true
cc_tweaked_minecraft_version = 1.20.1
cc_tweaked_version = 1.105.0
dynamic_trees_enable = true
dynamic_trees_minecraft_version = 1.20.1
dynamic_trees_version = 1.3.0-BETA13
# mod options
mod_id = create mod_id = create
mod_name = Create mod_name = Create
mod_author = simibubi mod_author = simibubi
mod_description = Technology that empowers the player. mod_description = Technology that empowers the player.
mod_license = MIT mod_license = MIT
# curseforge information # Mod Dependencies
projectId = 328085 minecraft_version = 1.21.1
curse_type = beta minecraft_version_range=[1.21.1]
# github information neo_version = 21.1.71
github_project = Creators-of-Create/Create neo_version_range=[21.1.71,)
parchment_minecraft_version = 1.21.1
parchment_version = 2024.11.17
# From maven.ithundxr.dev/snapshots
registrate_version = MC1.21-1.3.0+58
# From maven.ithundxr.dev/hidden
flywheel_minecraft_version = 1.21.1
flywheel_version = 1.0.0-beta-fork.10
flywheel_version_range = [1.0.0-alpha,2.0)
# Optional Dependencies
jei_minecraft_version = 1.21
jei_version = 19.5.0.33
curios_minecraft_version = 1.21.1
curios_version = 9.0.15
catnip_version = 0.8.43
ponder_version = 0.8.7
catnip_and_ponder_mc_ver = 1.21.1
cc_tweaked_enable = true
cc_tweaked_disable_runtime = true
cc_tweaked_minecraft_version = 1.21.1
cc_tweaked_version = 1.114.2

Binary file not shown.

View file

@ -1,6 +1,7 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
networkTimeout=10000 networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

24
gradlew vendored
View file

@ -55,7 +55,7 @@
# Darwin, MinGW, and NonStop. # Darwin, MinGW, and NonStop.
# #
# (3) This script is generated from the Groovy template # (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project. # within the Gradle project.
# #
# You can find Gradle at https://github.com/gradle/gradle/. # You can find Gradle at https://github.com/gradle/gradle/.
@ -83,7 +83,8 @@ done
# This is normally unused # This is normally unused
# shellcheck disable=SC2034 # shellcheck disable=SC2034
APP_BASE_NAME=${0##*/} APP_BASE_NAME=${0##*/}
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value. # Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum MAX_FD=maximum
@ -130,10 +131,13 @@ location of your Java installation."
fi fi
else else
JAVACMD=java JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the Please set the JAVA_HOME variable in your environment to match the
location of your Java installation." location of your Java installation."
fi
fi fi
# Increase the maximum file descriptors if we can. # Increase the maximum file descriptors if we can.
@ -141,7 +145,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #( case $MAX_FD in #(
max*) max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045 # shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) || MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit" warn "Could not query maximum file descriptor limit"
esac esac
@ -149,7 +153,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
'' | soft) :;; #( '' | soft) :;; #(
*) *)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045 # shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" || ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD" warn "Could not set maximum file descriptor limit to $MAX_FD"
esac esac
@ -198,11 +202,11 @@ fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command; # Collect all arguments for the java command:
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of # * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# shell script including quotes and variable substitutions, so put them in # and any embedded shellness will be escaped.
# double quotes to make sure that they get re-expanded; and # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# * put everything else in single quotes, so that it's not re-expanded. # treated as '${Hostname}' itself on the command line.
set -- \ set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \ "-Dorg.gradle.appname=$APP_BASE_NAME" \

20
gradlew.bat vendored
View file

@ -43,11 +43,11 @@ set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1 %JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute if %ERRORLEVEL% equ 0 goto execute
echo. echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. echo location of your Java installation. 1>&2
goto fail goto fail
@ -57,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute if exist "%JAVA_EXE%" goto execute
echo. echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. echo location of your Java installation. 1>&2
goto fail goto fail

View file

@ -1,16 +1,9 @@
pluginManagement { pluginManagement {
repositories { repositories {
mavenLocal()
gradlePluginPortal() gradlePluginPortal()
mavenCentral() maven { url = 'https://maven.neoforged.net/releases' }
jcenter()
maven { url = 'https://maven.minecraftforge.net/' }
maven { url = 'https://repo.spongepowered.org/repository/maven-public' }
maven { url = 'https://maven.parchmentmc.org' }
} }
} }
plugins {
id 'org.gradle.toolchains.foojay-resolver-convention' version '0.7.0'
}
rootProject.name = 'Create' rootProject.name = 'Create'

View file

@ -0,0 +1,22 @@
package com.simibubi.create;
import java.util.function.Supplier;
import com.simibubi.create.content.contraptions.minecart.capability.MinecartController;
import net.neoforged.bus.api.IEventBus;
import net.neoforged.neoforge.attachment.AttachmentType;
import net.neoforged.neoforge.registries.DeferredRegister;
import net.neoforged.neoforge.registries.NeoForgeRegistries;
public class AllAttachmentTypes {
private static final DeferredRegister<AttachmentType<?>> ATTACHMENT_TYPES = DeferredRegister.create(NeoForgeRegistries.ATTACHMENT_TYPES, Create.ID);
public static final Supplier<AttachmentType<MinecartController>> MINECART_CONTROLLER = ATTACHMENT_TYPES.register(
"minecart_controller", () -> AttachmentType.builder(MinecartController::empty).serialize(MinecartController.SERIALIZER).build()
);
public static void register(IEventBus modEventBus) {
ATTACHMENT_TYPES.register(modEventBus);
}
}

View file

@ -282,10 +282,10 @@ import com.simibubi.create.foundation.data.ModelGen;
import com.simibubi.create.foundation.data.SharedProperties; import com.simibubi.create.foundation.data.SharedProperties;
import com.simibubi.create.foundation.item.ItemDescription; import com.simibubi.create.foundation.item.ItemDescription;
import com.simibubi.create.foundation.item.UncontainableBlockItem; import com.simibubi.create.foundation.item.UncontainableBlockItem;
import com.simibubi.create.foundation.mixin.accessor.BlockLootSubProviderAccessor;
import com.simibubi.create.foundation.utility.ColorHandlers; import com.simibubi.create.foundation.utility.ColorHandlers;
import com.simibubi.create.foundation.utility.DyeHelper; import com.simibubi.create.foundation.utility.DyeHelper;
import com.tterrag.registrate.providers.RegistrateRecipeProvider; import com.tterrag.registrate.providers.RegistrateRecipeProvider;
import com.tterrag.registrate.providers.loot.RegistrateBlockLootTables;
import com.tterrag.registrate.util.DataIngredient; import com.tterrag.registrate.util.DataIngredient;
import com.tterrag.registrate.util.entry.BlockEntry; import com.tterrag.registrate.util.entry.BlockEntry;
@ -293,6 +293,7 @@ import net.createmod.catnip.utility.Couple;
import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderType;
import net.minecraft.core.Direction.Axis; import net.minecraft.core.Direction.Axis;
import net.minecraft.core.Direction.AxisDirection; import net.minecraft.core.Direction.AxisDirection;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.registries.Registries; import net.minecraft.core.registries.Registries;
import net.minecraft.data.loot.BlockLootSubProvider; import net.minecraft.data.loot.BlockLootSubProvider;
import net.minecraft.data.recipes.RecipeCategory; import net.minecraft.data.recipes.RecipeCategory;
@ -305,6 +306,7 @@ import net.minecraft.tags.ItemTags;
import net.minecraft.world.item.DyeColor; import net.minecraft.world.item.DyeColor;
import net.minecraft.world.item.Items; import net.minecraft.world.item.Items;
import net.minecraft.world.item.Rarity; import net.minecraft.world.item.Rarity;
import net.minecraft.world.item.enchantment.Enchantment;
import net.minecraft.world.item.enchantment.Enchantments; import net.minecraft.world.item.enchantment.Enchantments;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.Blocks;
@ -321,17 +323,17 @@ import net.minecraft.world.level.storage.loot.LootTable;
import net.minecraft.world.level.storage.loot.LootTable.Builder; import net.minecraft.world.level.storage.loot.LootTable.Builder;
import net.minecraft.world.level.storage.loot.entries.LootItem; import net.minecraft.world.level.storage.loot.entries.LootItem;
import net.minecraft.world.level.storage.loot.functions.ApplyBonusCount; import net.minecraft.world.level.storage.loot.functions.ApplyBonusCount;
import net.minecraft.world.level.storage.loot.functions.CopyComponentsFunction;
import net.minecraft.world.level.storage.loot.functions.CopyNameFunction; import net.minecraft.world.level.storage.loot.functions.CopyNameFunction;
import net.minecraft.world.level.storage.loot.functions.CopyNbtFunction;
import net.minecraft.world.level.storage.loot.predicates.ExplosionCondition; import net.minecraft.world.level.storage.loot.predicates.ExplosionCondition;
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; import net.minecraft.world.level.storage.loot.predicates.LootItemCondition;
import net.minecraft.world.level.storage.loot.providers.nbt.ContextNbtProvider;
import net.minecraft.world.level.storage.loot.providers.number.ConstantValue; import net.minecraft.world.level.storage.loot.providers.number.ConstantValue;
import net.minecraftforge.client.model.generators.ConfiguredModel; import net.neoforged.neoforge.client.model.generators.ConfiguredModel;
import net.minecraftforge.client.model.generators.ModelFile; import net.neoforged.neoforge.client.model.generators.ModelFile;
import net.minecraftforge.common.Tags; import net.neoforged.neoforge.common.Tags;
import net.minecraftforge.common.util.ForgeSoundType; import net.neoforged.neoforge.common.util.DeferredSoundType;
@SuppressWarnings("removal")
public class AllBlocks { public class AllBlocks {
static { static {
@ -354,8 +356,9 @@ public class AllBlocks {
.setRolls(ConstantValue.exactly(1)) .setRolls(ConstantValue.exactly(1))
.add(LootItem.lootTableItem(AllBlocks.SCHEMATICANNON.get() .add(LootItem.lootTableItem(AllBlocks.SCHEMATICANNON.get()
.asItem()) .asItem())
.apply(CopyNbtFunction.copyData(ContextNbtProvider.BLOCK_ENTITY) // TODO 1.21: Make sure this works
.copy("Options", "BlockEntityTag.Options"))))); .apply(CopyComponentsFunction.copyComponents(CopyComponentsFunction.Source.BLOCK_ENTITY)
.include(AllDataComponents.SCHEMATICANNON_OPTIONS.value())))));
}) })
.item() .item()
.transform(customItemModel()) .transform(customItemModel())
@ -1768,7 +1771,7 @@ public class AllBlocks {
public static final BlockEntry<BeltTunnelBlock> ANDESITE_TUNNEL = public static final BlockEntry<BeltTunnelBlock> ANDESITE_TUNNEL =
REGISTRATE.block("andesite_tunnel", BeltTunnelBlock::new) REGISTRATE.block("andesite_tunnel", BeltTunnelBlock::new)
.properties(p -> p.mapColor(MapColor.STONE)) .properties(p -> p.mapColor(MapColor.STONE))
.transform(BuilderTransformers.beltTunnel("andesite", new ResourceLocation("block/polished_andesite"))) .transform(BuilderTransformers.beltTunnel("andesite", ResourceLocation.withDefaultNamespace("block/polished_andesite")))
.onRegister(assignDataBehaviour(new AccumulatedItemCountDisplaySource(), "accumulate_items")) .onRegister(assignDataBehaviour(new AccumulatedItemCountDisplaySource(), "accumulate_items"))
.onRegister(assignDataBehaviour(new ItemThroughputDisplaySource(), "item_throughput")) .onRegister(assignDataBehaviour(new ItemThroughputDisplaySource(), "item_throughput"))
.register(); .register();
@ -1996,7 +1999,7 @@ public class AllBlocks {
.transform(BuilderTransformers.tableCloth("brass", SharedProperties::softMetal, false)) .transform(BuilderTransformers.tableCloth("brass", SharedProperties::softMetal, false))
.properties(p -> p.mapColor(MapColor.TERRACOTTA_YELLOW) .properties(p -> p.mapColor(MapColor.TERRACOTTA_YELLOW)
.requiresCorrectToolForDrops()) .requiresCorrectToolForDrops())
.recipe((c, p) -> p.stonecutting(DataIngredient.tag(AllTags.forgeItemTag("ingots/brass")), .recipe((c, p) -> p.stonecutting(DataIngredient.tag(AllTags.commonItemTag("ingots/brass")),
RecipeCategory.DECORATIONS, c::get, 2)) RecipeCategory.DECORATIONS, c::get, 2))
.transform(pickaxeOnly()) .transform(pickaxeOnly())
.register(); .register();
@ -2005,7 +2008,7 @@ public class AllBlocks {
REGISTRATE.block("copper_table_cloth", p -> new TableClothBlock(p, "copper")) REGISTRATE.block("copper_table_cloth", p -> new TableClothBlock(p, "copper"))
.transform(BuilderTransformers.tableCloth("copper", SharedProperties::copperMetal, false)) .transform(BuilderTransformers.tableCloth("copper", SharedProperties::copperMetal, false))
.properties(p -> p.requiresCorrectToolForDrops()) .properties(p -> p.requiresCorrectToolForDrops())
.recipe((c, p) -> p.stonecutting(DataIngredient.tag(AllTags.forgeItemTag("ingots/copper")), .recipe((c, p) -> p.stonecutting(DataIngredient.tag(Tags.Items.INGOTS_COPPER),
RecipeCategory.DECORATIONS, c::get, 2)) RecipeCategory.DECORATIONS, c::get, 2))
.transform(pickaxeOnly()) .transform(pickaxeOnly())
.register(); .register();
@ -2216,17 +2219,17 @@ public class AllBlocks {
.forceSolidOn()) .forceSolidOn())
.addLayer(() -> RenderType::cutoutMipped) .addLayer(() -> RenderType::cutoutMipped)
.loot((lt, block) -> { .loot((lt, block) -> {
Builder builder = LootTable.lootTable(); lt.add(block, LootTable.lootTable().withPool(LootPool.lootPool()
LootItemCondition.Builder survivesExplosion = ExplosionCondition.survivesExplosion(); .when(ExplosionCondition.survivesExplosion())
lt.add(block, builder.withPool(LootPool.lootPool() .setRolls(ConstantValue.exactly(1))
.when(survivesExplosion) .add(LootItem.lootTableItem(block)
.setRolls(ConstantValue.exactly(1)) .apply(CopyNameFunction.copyName(CopyNameFunction.NameSource.BLOCK_ENTITY))
.add(LootItem.lootTableItem(block) .apply(CopyComponentsFunction.copyComponents(CopyComponentsFunction.Source.BLOCK_ENTITY)
.apply(CopyNameFunction.copyName(CopyNameFunction.NameSource.BLOCK_ENTITY)) .include(AllDataComponents.TOOLBOX_UUID.value())
.apply(CopyNbtFunction.copyData(ContextNbtProvider.BLOCK_ENTITY) .include(AllDataComponents.TOOLBOX_INVENTORY.value())
.copy("UniqueId", "UniqueId")) )
.apply(CopyNbtFunction.copyData(ContextNbtProvider.BLOCK_ENTITY) )
.copy("Inventory", "Inventory"))))); ));
}) })
.blockstate((c, p) -> { .blockstate((c, p) -> {
p.horizontalBlock(c.get(), p.models() p.horizontalBlock(c.get(), p.models()
@ -2272,21 +2275,21 @@ public class AllBlocks {
public static final BlockEntry<MetalLadderBlock> BRASS_LADDER = public static final BlockEntry<MetalLadderBlock> BRASS_LADDER =
REGISTRATE.block("brass_ladder", MetalLadderBlock::new) REGISTRATE.block("brass_ladder", MetalLadderBlock::new)
.transform(BuilderTransformers.ladder("brass", .transform(BuilderTransformers.ladder("brass",
() -> DataIngredient.tag(AllTags.forgeItemTag("ingots/brass")), MapColor.TERRACOTTA_YELLOW)) () -> DataIngredient.tag(AllTags.commonItemTag("ingots/brass")), MapColor.TERRACOTTA_YELLOW))
.register(); .register();
public static final BlockEntry<MetalLadderBlock> COPPER_LADDER = public static final BlockEntry<MetalLadderBlock> COPPER_LADDER =
REGISTRATE.block("copper_ladder", MetalLadderBlock::new) REGISTRATE.block("copper_ladder", MetalLadderBlock::new)
.transform(BuilderTransformers.ladder("copper", .transform(BuilderTransformers.ladder("copper",
() -> DataIngredient.tag(AllTags.forgeItemTag("ingots/copper")), MapColor.COLOR_ORANGE)) () -> DataIngredient.tag(Tags.Items.INGOTS_COPPER), MapColor.COLOR_ORANGE))
.register(); .register();
public static final BlockEntry<IronBarsBlock> ANDESITE_BARS = MetalBarsGen.createBars("andesite", true, public static final BlockEntry<IronBarsBlock> ANDESITE_BARS = MetalBarsGen.createBars("andesite", true,
() -> DataIngredient.items(AllItems.ANDESITE_ALLOY.get()), MapColor.STONE); () -> DataIngredient.items(AllItems.ANDESITE_ALLOY.get()), MapColor.STONE);
public static final BlockEntry<IronBarsBlock> BRASS_BARS = MetalBarsGen.createBars("brass", true, public static final BlockEntry<IronBarsBlock> BRASS_BARS = MetalBarsGen.createBars("brass", true,
() -> DataIngredient.tag(AllTags.forgeItemTag("ingots/brass")), MapColor.TERRACOTTA_YELLOW); () -> DataIngredient.tag(AllTags.commonItemTag("ingots/brass")), MapColor.TERRACOTTA_YELLOW);
public static final BlockEntry<IronBarsBlock> COPPER_BARS = MetalBarsGen.createBars("copper", true, public static final BlockEntry<IronBarsBlock> COPPER_BARS = MetalBarsGen.createBars("copper", true,
() -> DataIngredient.tag(AllTags.forgeItemTag("ingots/copper")), MapColor.COLOR_ORANGE); () -> DataIngredient.tag(Tags.Items.INGOTS_COPPER), MapColor.COLOR_ORANGE);
public static final BlockEntry<MetalScaffoldingBlock> ANDESITE_SCAFFOLD = REGISTRATE public static final BlockEntry<MetalScaffoldingBlock> ANDESITE_SCAFFOLD = REGISTRATE
.block("andesite_scaffolding", MetalScaffoldingBlock::new) .block("andesite_scaffolding", MetalScaffoldingBlock::new)
@ -2298,14 +2301,14 @@ public class AllBlocks {
public static final BlockEntry<MetalScaffoldingBlock> BRASS_SCAFFOLD = public static final BlockEntry<MetalScaffoldingBlock> BRASS_SCAFFOLD =
REGISTRATE.block("brass_scaffolding", MetalScaffoldingBlock::new) REGISTRATE.block("brass_scaffolding", MetalScaffoldingBlock::new)
.transform(BuilderTransformers.scaffold("brass", .transform(BuilderTransformers.scaffold("brass",
() -> DataIngredient.tag(AllTags.forgeItemTag("ingots/brass")), MapColor.TERRACOTTA_YELLOW, () -> DataIngredient.tag(AllTags.commonItemTag("ingots/brass")), MapColor.TERRACOTTA_YELLOW,
AllSpriteShifts.BRASS_SCAFFOLD, AllSpriteShifts.BRASS_SCAFFOLD_INSIDE, AllSpriteShifts.BRASS_CASING)) AllSpriteShifts.BRASS_SCAFFOLD, AllSpriteShifts.BRASS_SCAFFOLD_INSIDE, AllSpriteShifts.BRASS_CASING))
.register(); .register();
public static final BlockEntry<MetalScaffoldingBlock> COPPER_SCAFFOLD = public static final BlockEntry<MetalScaffoldingBlock> COPPER_SCAFFOLD =
REGISTRATE.block("copper_scaffolding", MetalScaffoldingBlock::new) REGISTRATE.block("copper_scaffolding", MetalScaffoldingBlock::new)
.transform(BuilderTransformers.scaffold("copper", .transform(BuilderTransformers.scaffold("copper",
() -> DataIngredient.tag(AllTags.forgeItemTag("ingots/copper")), MapColor.COLOR_ORANGE, () -> DataIngredient.tag(Tags.Items.INGOTS_COPPER), MapColor.COLOR_ORANGE,
AllSpriteShifts.COPPER_SCAFFOLD, AllSpriteShifts.COPPER_SCAFFOLD_INSIDE, AllSpriteShifts.COPPER_CASING)) AllSpriteShifts.COPPER_SCAFFOLD, AllSpriteShifts.COPPER_SCAFFOLD_INSIDE, AllSpriteShifts.COPPER_CASING))
.register(); .register();
@ -2349,7 +2352,7 @@ public class AllBlocks {
.transform(BuilderTransformers.copycat()) .transform(BuilderTransformers.copycat())
.onRegister(CreateRegistrate.blockModel(() -> CopycatStepModel::new)) .onRegister(CreateRegistrate.blockModel(() -> CopycatStepModel::new))
.item() .item()
.recipe((c, p) -> p.stonecutting(DataIngredient.tag(AllTags.forgeItemTag("ingots/zinc")), .recipe((c, p) -> p.stonecutting(DataIngredient.tag(AllTags.commonItemTag("ingots/zinc")),
RecipeCategory.BUILDING_BLOCKS, c::get, 4)) RecipeCategory.BUILDING_BLOCKS, c::get, 4))
.transform(customItemModel("copycat_base", "step")) .transform(customItemModel("copycat_base", "step"))
.register(); .register();
@ -2359,7 +2362,7 @@ public class AllBlocks {
.transform(BuilderTransformers.copycat()) .transform(BuilderTransformers.copycat())
.onRegister(CreateRegistrate.blockModel(() -> CopycatPanelModel::new)) .onRegister(CreateRegistrate.blockModel(() -> CopycatPanelModel::new))
.item() .item()
.recipe((c, p) -> p.stonecutting(DataIngredient.tag(AllTags.forgeItemTag("ingots/zinc")), .recipe((c, p) -> p.stonecutting(DataIngredient.tag(AllTags.commonItemTag("ingots/zinc")),
RecipeCategory.BUILDING_BLOCKS, c::get, 4)) RecipeCategory.BUILDING_BLOCKS, c::get, 4))
.transform(customItemModel("copycat_base", "panel")) .transform(customItemModel("copycat_base", "panel"))
.register(); .register();
@ -2472,10 +2475,14 @@ public class AllBlocks {
.requiresCorrectToolForDrops() .requiresCorrectToolForDrops()
.sound(SoundType.STONE)) .sound(SoundType.STONE))
.transform(pickaxeOnly()) .transform(pickaxeOnly())
.loot((lt, b) -> lt.add(b, .loot((lt, b) -> {
RegistrateBlockLootTables.createSilkTouchDispatchTable(b, HolderLookup.RegistryLookup<Enchantment> enchantmentRegistryLookup = ((BlockLootSubProviderAccessor) lt).create$getRegistries().lookupOrThrow(Registries.ENCHANTMENT);
lt.add(b,
lt.createSilkTouchDispatchTable(b,
lt.applyExplosionDecay(b, LootItem.lootTableItem(AllItems.RAW_ZINC.get()) lt.applyExplosionDecay(b, LootItem.lootTableItem(AllItems.RAW_ZINC.get())
.apply(ApplyBonusCount.addOreBonusCount(Enchantments.BLOCK_FORTUNE)))))) .apply(ApplyBonusCount.addOreBonusCount(enchantmentRegistryLookup.getOrThrow(Enchantments.FORTUNE))))));
})
.tag(BlockTags.NEEDS_IRON_TOOL) .tag(BlockTags.NEEDS_IRON_TOOL)
.tag(Tags.Blocks.ORES) .tag(Tags.Blocks.ORES)
.transform(tagBlockAndItem("ores/zinc", "ores_in_ground/stone")) .transform(tagBlockAndItem("ores/zinc", "ores_in_ground/stone"))
@ -2489,10 +2496,15 @@ public class AllBlocks {
.requiresCorrectToolForDrops() .requiresCorrectToolForDrops()
.sound(SoundType.DEEPSLATE)) .sound(SoundType.DEEPSLATE))
.transform(pickaxeOnly()) .transform(pickaxeOnly())
.loot((lt, b) -> lt.add(b, .loot((lt, b) -> {
RegistrateBlockLootTables.createSilkTouchDispatchTable(b, HolderLookup.RegistryLookup<Enchantment> enchantmentRegistryLookup = ((BlockLootSubProviderAccessor) lt).create$getRegistries().lookupOrThrow(Registries.ENCHANTMENT);
lt.applyExplosionDecay(b, LootItem.lootTableItem(AllItems.RAW_ZINC.get())
.apply(ApplyBonusCount.addOreBonusCount(Enchantments.BLOCK_FORTUNE))))))
lt.add(b,
lt.createSilkTouchDispatchTable(b,
lt.applyExplosionDecay(b, LootItem.lootTableItem(AllItems.RAW_ZINC.get())
.apply(ApplyBonusCount.addOreBonusCount(enchantmentRegistryLookup.getOrThrow(Enchantments.FORTUNE))))));
})
.tag(BlockTags.NEEDS_IRON_TOOL) .tag(BlockTags.NEEDS_IRON_TOOL)
.tag(Tags.Blocks.ORES) .tag(Tags.Blocks.ORES)
.transform(tagBlockAndItem("ores/zinc", "ores_in_ground/deepslate")) .transform(tagBlockAndItem("ores/zinc", "ores_in_ground/deepslate"))
@ -2574,9 +2586,9 @@ public class AllBlocks {
.transform(axeOnly()) .transform(axeOnly())
.blockstate(BlockStateGen.horizontalAxisBlockProvider(false)) .blockstate(BlockStateGen.horizontalAxisBlockProvider(false))
.tag(Tags.Blocks.STORAGE_BLOCKS) .tag(Tags.Blocks.STORAGE_BLOCKS)
.tag(AllTags.forgeBlockTag("storage_blocks/cardboard")) .tag(AllTags.commonBlockTag("storage_blocks/cardboard"))
.item(CardboardBlockItem::new) .item(CardboardBlockItem::new)
.tag(AllTags.forgeItemTag("storage_blocks/cardboard")) .tag(AllTags.commonItemTag("storage_blocks/cardboard"))
.tag(Tags.Items.STORAGE_BLOCKS) .tag(Tags.Items.STORAGE_BLOCKS)
.build() .build()
.lang("Block of Cardboard") .lang("Block of Cardboard")
@ -2606,7 +2618,7 @@ public class AllBlocks {
REGISTRATE.block("experience_block", ExperienceBlock::new) REGISTRATE.block("experience_block", ExperienceBlock::new)
.initialProperties(SharedProperties::softMetal) .initialProperties(SharedProperties::softMetal)
.properties(p -> p.mapColor(MapColor.PLANT) .properties(p -> p.mapColor(MapColor.PLANT)
.sound(new ForgeSoundType(1, .5f, () -> SoundEvents.AMETHYST_BLOCK_BREAK, .sound(new DeferredSoundType(1, .5f, () -> SoundEvents.AMETHYST_BLOCK_BREAK,
() -> SoundEvents.AMETHYST_BLOCK_STEP, () -> SoundEvents.AMETHYST_BLOCK_PLACE, () -> SoundEvents.AMETHYST_BLOCK_STEP, () -> SoundEvents.AMETHYST_BLOCK_PLACE,
() -> SoundEvents.AMETHYST_BLOCK_HIT, () -> SoundEvents.AMETHYST_BLOCK_FALL)) () -> SoundEvents.AMETHYST_BLOCK_HIT, () -> SoundEvents.AMETHYST_BLOCK_FALL))
.requiresCorrectToolForDrops() .requiresCorrectToolForDrops()
@ -2662,14 +2674,14 @@ public class AllBlocks {
public static final CopperBlockSet COPPER_SHINGLES = new CopperBlockSet(REGISTRATE, "copper_shingles", public static final CopperBlockSet COPPER_SHINGLES = new CopperBlockSet(REGISTRATE, "copper_shingles",
"copper_roof_top", CopperBlockSet.DEFAULT_VARIANTS, (c, p) -> { "copper_roof_top", CopperBlockSet.DEFAULT_VARIANTS, (c, p) -> {
p.stonecutting(DataIngredient.tag(AllTags.forgeItemTag("ingots/copper")), RecipeCategory.BUILDING_BLOCKS, p.stonecutting(DataIngredient.tag(Tags.Items.INGOTS_COPPER), RecipeCategory.BUILDING_BLOCKS,
c::get, 2); c::get, 2);
}, (ws, block) -> connectedTextures(() -> new RoofBlockCTBehaviour(AllSpriteShifts.COPPER_SHINGLES.get(ws))) }, (ws, block) -> connectedTextures(() -> new RoofBlockCTBehaviour(AllSpriteShifts.COPPER_SHINGLES.get(ws)))
.accept(block)); .accept(block));
public static final CopperBlockSet COPPER_TILES = public static final CopperBlockSet COPPER_TILES =
new CopperBlockSet(REGISTRATE, "copper_tiles", "copper_roof_top", CopperBlockSet.DEFAULT_VARIANTS, (c, p) -> { new CopperBlockSet(REGISTRATE, "copper_tiles", "copper_roof_top", CopperBlockSet.DEFAULT_VARIANTS, (c, p) -> {
p.stonecutting(DataIngredient.tag(AllTags.forgeItemTag("ingots/copper")), RecipeCategory.BUILDING_BLOCKS, p.stonecutting(DataIngredient.tag(Tags.Items.INGOTS_COPPER), RecipeCategory.BUILDING_BLOCKS,
c::get, 2); c::get, 2);
}, (ws, block) -> connectedTextures(() -> new RoofBlockCTBehaviour(AllSpriteShifts.COPPER_TILES.get(ws))) }, (ws, block) -> connectedTextures(() -> new RoofBlockCTBehaviour(AllSpriteShifts.COPPER_TILES.get(ws)))
.accept(block)); .accept(block));

View file

@ -29,6 +29,7 @@ import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap;
import it.unimi.dsi.fastutil.objects.ReferenceArrayList; import it.unimi.dsi.fastutil.objects.ReferenceArrayList;
import it.unimi.dsi.fastutil.objects.ReferenceLinkedOpenHashSet; import it.unimi.dsi.fastutil.objects.ReferenceLinkedOpenHashSet;
import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet;
import net.createmod.catnip.platform.CatnipServices;
import net.createmod.catnip.utility.lang.Components; import net.createmod.catnip.utility.lang.Components;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.entity.ItemRenderer; import net.minecraft.client.renderer.entity.ItemRenderer;
@ -46,21 +47,17 @@ import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items; import net.minecraft.world.item.Items;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraftforge.api.distmarker.Dist; import net.neoforged.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.neoforged.api.distmarker.OnlyIn;
import net.minecraftforge.eventbus.api.IEventBus; import net.neoforged.bus.api.IEventBus;
import net.minecraftforge.fml.DistExecutor; import net.neoforged.neoforge.registries.DeferredHolder;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber; import net.neoforged.neoforge.registries.DeferredRegister;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.RegistryObject;
@EventBusSubscriber(bus = Bus.MOD)
public class AllCreativeModeTabs { public class AllCreativeModeTabs {
private static final DeferredRegister<CreativeModeTab> REGISTER = private static final DeferredRegister<CreativeModeTab> REGISTER =
DeferredRegister.create(Registries.CREATIVE_MODE_TAB, Create.ID); DeferredRegister.create(Registries.CREATIVE_MODE_TAB, Create.ID);
public static final RegistryObject<CreativeModeTab> BASE_CREATIVE_TAB = REGISTER.register("base", public static final DeferredHolder<CreativeModeTab, CreativeModeTab> BASE_CREATIVE_TAB = REGISTER.register("base",
() -> CreativeModeTab.builder() () -> CreativeModeTab.builder()
.title(Components.translatable("itemGroup.create.base")) .title(Components.translatable("itemGroup.create.base"))
.withTabsBefore(CreativeModeTabs.SPAWN_EGGS) .withTabsBefore(CreativeModeTabs.SPAWN_EGGS)
@ -68,7 +65,7 @@ public class AllCreativeModeTabs {
.displayItems(new RegistrateDisplayItemsGenerator(true, AllCreativeModeTabs.BASE_CREATIVE_TAB)) .displayItems(new RegistrateDisplayItemsGenerator(true, AllCreativeModeTabs.BASE_CREATIVE_TAB))
.build()); .build());
public static final RegistryObject<CreativeModeTab> PALETTES_CREATIVE_TAB = REGISTER.register("palettes", public static final DeferredHolder<CreativeModeTab, CreativeModeTab> PALETTES_CREATIVE_TAB = REGISTER.register("palettes",
() -> CreativeModeTab.builder() () -> CreativeModeTab.builder()
.title(Components.translatable("itemGroup.create.palettes")) .title(Components.translatable("itemGroup.create.palettes"))
.withTabsBefore(BASE_CREATIVE_TAB.getKey()) .withTabsBefore(BASE_CREATIVE_TAB.getKey())
@ -85,14 +82,8 @@ public class AllCreativeModeTabs {
static { static {
MutableObject<Predicate<Item>> isItem3d = new MutableObject<>(item -> false); MutableObject<Predicate<Item>> isItem3d = new MutableObject<>(item -> false);
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> { if (CatnipServices.PLATFORM.getEnv().isClient())
isItem3d.setValue(item -> { isItem3d.setValue(makeClient3dItemPredicate());
ItemRenderer itemRenderer = Minecraft.getInstance()
.getItemRenderer();
BakedModel model = itemRenderer.getModel(new ItemStack(item), null, null, 0);
return model.isGui3d();
});
});
IS_ITEM_3D_PREDICATE = isItem3d.getValue(); IS_ITEM_3D_PREDICATE = isItem3d.getValue();
} }
@ -107,9 +98,9 @@ public class AllCreativeModeTabs {
} }
private final boolean addItems; private final boolean addItems;
private final RegistryObject<CreativeModeTab> tabFilter; private final DeferredHolder<CreativeModeTab, CreativeModeTab> tabFilter;
public RegistrateDisplayItemsGenerator(boolean addItems, RegistryObject<CreativeModeTab> tabFilter) { public RegistrateDisplayItemsGenerator(boolean addItems, DeferredHolder<CreativeModeTab, CreativeModeTab> tabFilter) {
this.addItems = addItems; this.addItems = addItems;
this.tabFilter = tabFilter; this.tabFilter = tabFilter;
} }
@ -117,7 +108,7 @@ public class AllCreativeModeTabs {
private static Predicate<Item> makeExclusionPredicate() { private static Predicate<Item> makeExclusionPredicate() {
Set<Item> exclusions = new ReferenceOpenHashSet<>(); Set<Item> exclusions = new ReferenceOpenHashSet<>();
List<ItemProviderEntry<?>> simpleExclusions = List.of( List<ItemProviderEntry<?, ?>> simpleExclusions = List.of(
AllItems.INCOMPLETE_PRECISION_MECHANISM, AllItems.INCOMPLETE_PRECISION_MECHANISM,
AllItems.INCOMPLETE_REINFORCED_SHEET, AllItems.INCOMPLETE_REINFORCED_SHEET,
AllItems.INCOMPLETE_TRACK, AllItems.INCOMPLETE_TRACK,
@ -157,7 +148,7 @@ public class AllCreativeModeTabs {
exclusions.addAll(PackageStyles.RARE_BOXES); exclusions.addAll(PackageStyles.RARE_BOXES);
for (ItemProviderEntry<?> entry : simpleExclusions) { for (ItemProviderEntry<?, ?> entry : simpleExclusions) {
exclusions.add(entry.asItem()); exclusions.add(entry.asItem());
} }
@ -174,12 +165,12 @@ public class AllCreativeModeTabs {
private static List<ItemOrdering> makeOrderings() { private static List<ItemOrdering> makeOrderings() {
List<ItemOrdering> orderings = new ReferenceArrayList<>(); List<ItemOrdering> orderings = new ReferenceArrayList<>();
Map<ItemProviderEntry<?>, ItemProviderEntry<?>> simpleBeforeOrderings = Map.of( Map<ItemProviderEntry<?, ?>, ItemProviderEntry<?, ?>> simpleBeforeOrderings = Map.of(
AllItems.EMPTY_BLAZE_BURNER, AllBlocks.BLAZE_BURNER, AllItems.EMPTY_BLAZE_BURNER, AllBlocks.BLAZE_BURNER,
AllItems.SCHEDULE, AllBlocks.TRACK_STATION AllItems.SCHEDULE, AllBlocks.TRACK_STATION
); );
Map<ItemProviderEntry<?>, ItemProviderEntry<?>> simpleAfterOrderings = Map.of( Map<ItemProviderEntry<?, ?>, ItemProviderEntry<?, ?>> simpleAfterOrderings = Map.of(
AllItems.VERTICAL_GEARBOX, AllBlocks.GEARBOX AllItems.VERTICAL_GEARBOX, AllBlocks.GEARBOX
); );
@ -201,15 +192,15 @@ public class AllCreativeModeTabs {
private static Function<Item, ItemStack> makeStackFunc() { private static Function<Item, ItemStack> makeStackFunc() {
Map<Item, Function<Item, ItemStack>> factories = new Reference2ReferenceOpenHashMap<>(); Map<Item, Function<Item, ItemStack>> factories = new Reference2ReferenceOpenHashMap<>();
Map<ItemProviderEntry<?>, Function<Item, ItemStack>> simpleFactories = Map.of( Map<ItemProviderEntry<?, ?>, Function<Item, ItemStack>> simpleFactories = Map.of(
AllItems.COPPER_BACKTANK, item -> { AllItems.COPPER_BACKTANK, item -> {
ItemStack stack = new ItemStack(item); ItemStack stack = new ItemStack(item);
stack.getOrCreateTag().putInt("Air", BacktankUtil.maxAirWithoutEnchants()); stack.set(AllDataComponents.BACKTANK_AIR, BacktankUtil.maxAirWithoutEnchants());
return stack; return stack;
}, },
AllItems.NETHERITE_BACKTANK, item -> { AllItems.NETHERITE_BACKTANK, item -> {
ItemStack stack = new ItemStack(item); ItemStack stack = new ItemStack(item);
stack.getOrCreateTag().putInt("Air", BacktankUtil.maxAirWithoutEnchants()); stack.set(AllDataComponents.BACKTANK_AIR, BacktankUtil.maxAirWithoutEnchants());
return stack; return stack;
} }
); );
@ -230,7 +221,7 @@ public class AllCreativeModeTabs {
private static Function<Item, TabVisibility> makeVisibilityFunc() { private static Function<Item, TabVisibility> makeVisibilityFunc() {
Map<Item, TabVisibility> visibilities = new Reference2ObjectOpenHashMap<>(); Map<Item, TabVisibility> visibilities = new Reference2ObjectOpenHashMap<>();
Map<ItemProviderEntry<?>, TabVisibility> simpleVisibilities = Map.of( Map<ItemProviderEntry<?, ?>, TabVisibility> simpleVisibilities = Map.of(
AllItems.BLAZE_CAKE_BASE, TabVisibility.SEARCH_TAB_ONLY AllItems.BLAZE_CAKE_BASE, TabVisibility.SEARCH_TAB_ONLY
); );
@ -301,7 +292,7 @@ public class AllCreativeModeTabs {
private List<Item> collectBlocks(Predicate<Item> exclusionPredicate) { private List<Item> collectBlocks(Predicate<Item> exclusionPredicate) {
List<Item> items = new ReferenceArrayList<>(); List<Item> items = new ReferenceArrayList<>();
for (RegistryEntry<Block> entry : Create.REGISTRATE.getAll(Registries.BLOCK)) { for (RegistryEntry<Block, Block> entry : Create.REGISTRATE.getAll(Registries.BLOCK)) {
if (!CreateRegistrate.isInCreativeTab(entry, tabFilter)) if (!CreateRegistrate.isInCreativeTab(entry, tabFilter))
continue; continue;
Item item = entry.get() Item item = entry.get()
@ -317,7 +308,7 @@ public class AllCreativeModeTabs {
private List<Item> collectItems(Predicate<Item> exclusionPredicate) { private List<Item> collectItems(Predicate<Item> exclusionPredicate) {
List<Item> items = new ReferenceArrayList<>(); List<Item> items = new ReferenceArrayList<>();
for (RegistryEntry<Item> entry : Create.REGISTRATE.getAll(Registries.ITEM)) { for (RegistryEntry<Item, Item> entry : Create.REGISTRATE.getAll(Registries.ITEM)) {
if (!CreateRegistrate.isInCreativeTab(entry, tabFilter)) if (!CreateRegistrate.isInCreativeTab(entry, tabFilter))
continue; continue;
Item item = entry.get(); Item item = entry.get();

View file

@ -3,7 +3,7 @@ package com.simibubi.create;
import com.simibubi.create.foundation.damageTypes.DamageTypeBuilder; import com.simibubi.create.foundation.damageTypes.DamageTypeBuilder;
import net.minecraft.core.registries.Registries; import net.minecraft.core.registries.Registries;
import net.minecraft.data.worldgen.BootstapContext; import net.minecraft.data.worldgen.BootstrapContext;
import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceKey;
import net.minecraft.world.damagesource.DamageEffects; import net.minecraft.world.damagesource.DamageEffects;
import net.minecraft.world.damagesource.DamageScaling; import net.minecraft.world.damagesource.DamageScaling;
@ -25,7 +25,7 @@ public class AllDamageTypes {
return ResourceKey.create(Registries.DAMAGE_TYPE, Create.asResource(name)); return ResourceKey.create(Registries.DAMAGE_TYPE, Create.asResource(name));
} }
public static void bootstrap(BootstapContext<DamageType> ctx) { public static void bootstrap(BootstrapContext<DamageType> ctx) {
new DamageTypeBuilder(CRUSH).scaling(DamageScaling.ALWAYS).register(ctx); new DamageTypeBuilder(CRUSH).scaling(DamageScaling.ALWAYS).register(ctx);
new DamageTypeBuilder(CUCKOO_SURPRISE).scaling(DamageScaling.ALWAYS).exhaustion(0.1f).register(ctx); new DamageTypeBuilder(CUCKOO_SURPRISE).scaling(DamageScaling.ALWAYS).exhaustion(0.1f).register(ctx);
new DamageTypeBuilder(FAN_FIRE).effects(DamageEffects.BURNING).register(ctx); new DamageTypeBuilder(FAN_FIRE).effects(DamageEffects.BURNING).register(ctx);

View file

@ -0,0 +1,342 @@
package com.simibubi.create;
import java.util.List;
import java.util.UUID;
import com.mojang.serialization.Codec;
import com.simibubi.create.content.equipment.clipboard.ClipboardEntry;
import com.simibubi.create.content.equipment.clipboard.ClipboardOverrides.ClipboardType;
import com.simibubi.create.content.equipment.symmetryWand.mirror.SymmetryMirror;
import com.simibubi.create.content.equipment.zapper.PlacementPatterns;
import com.simibubi.create.content.equipment.zapper.terrainzapper.PlacementOptions;
import com.simibubi.create.content.equipment.zapper.terrainzapper.TerrainBrushes;
import com.simibubi.create.content.equipment.zapper.terrainzapper.TerrainTools;
import com.simibubi.create.content.fluids.potion.PotionFluid.BottleType;
import com.simibubi.create.content.logistics.box.PackageItem.PackageOrderData;
import com.simibubi.create.content.logistics.filter.AttributeFilterWhitelistMode;
import com.simibubi.create.content.logistics.item.filter.attribute.ItemAttribute.ItemAttributeEntry;
import com.simibubi.create.content.logistics.redstoneRequester.AutoRequestData;
import com.simibubi.create.content.logistics.stockTicker.PackageOrder;
import com.simibubi.create.content.logistics.tableCloth.ShoppingListItem.ShoppingList;
import com.simibubi.create.content.processing.sequenced.SequencedAssemblyRecipe.SequencedAssembly;
import com.simibubi.create.content.redstone.displayLink.ClickToLinkBlockItem.ClickToLinkData;
import com.simibubi.create.content.schematics.cannon.SchematicannonBlockEntity.SchematicannonOptions;
import com.simibubi.create.content.trains.track.BezierTrackPointLocation;
import com.simibubi.create.content.trains.track.TrackPlacement.ConnectingFrom;
import net.createmod.catnip.codecs.stream.CatnipStreamCodecs;
import net.minecraft.core.BlockPos;
import net.minecraft.core.UUIDUtil;
import net.minecraft.core.Vec3i;
import net.minecraft.core.component.DataComponentType;
import net.minecraft.core.registries.Registries;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.util.ExtraCodecs;
import net.minecraft.util.Unit;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.component.ItemContainerContents;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Mirror;
import net.minecraft.world.level.block.Rotation;
import net.minecraft.world.level.block.state.BlockState;
import net.neoforged.bus.api.IEventBus;
import net.neoforged.neoforge.registries.DeferredHolder;
import net.neoforged.neoforge.registries.DeferredRegister;
public class AllDataComponents {
private static final DeferredRegister.DataComponents DATA_COMPONENTS = DeferredRegister.createDataComponents(Registries.DATA_COMPONENT_TYPE, Create.ID);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<Integer>> BACKTANK_AIR = DATA_COMPONENTS.registerComponentType(
"banktank_air",
builder -> builder.persistent(ExtraCodecs.NON_NEGATIVE_INT).networkSynchronized(ByteBufCodecs.VAR_INT)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<BlockPos>> BELT_FIRST_SHAFT = DATA_COMPONENTS.registerComponentType(
"belt_first_shaft",
builder -> builder.persistent(BlockPos.CODEC).networkSynchronized(BlockPos.STREAM_CODEC)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<Boolean>> INFERRED_FROM_RECIPE = DATA_COMPONENTS.registerComponentType(
"inferred_from_recipe",
builder -> builder.persistent(Codec.BOOL).networkSynchronized(ByteBufCodecs.BOOL)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<PlacementPatterns>> PLACEMENT_PATTERN = DATA_COMPONENTS.registerComponentType(
"placement_pattern",
builder -> builder.persistent(PlacementPatterns.CODEC).networkSynchronized(PlacementPatterns.STREAM_CODEC)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<TerrainBrushes>> SHAPER_BRUSH = DATA_COMPONENTS.registerComponentType(
"shaper_brush",
builder -> builder.persistent(TerrainBrushes.CODEC).networkSynchronized(TerrainBrushes.STREAM_CODEC)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<BlockPos>> SHAPER_BRUSH_PARAMS = DATA_COMPONENTS.registerComponentType(
"shaper_brush_params",
builder -> builder.persistent(BlockPos.CODEC).networkSynchronized(BlockPos.STREAM_CODEC)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<PlacementOptions>> SHAPER_PLACEMENT_OPTIONS = DATA_COMPONENTS.registerComponentType(
"shaper_placement_options",
builder -> builder.persistent(PlacementOptions.CODEC).networkSynchronized(PlacementOptions.STREAM_CODEC)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<TerrainTools>> SHAPER_TOOL = DATA_COMPONENTS.registerComponentType(
"shaper_tool",
builder -> builder.persistent(TerrainTools.CODEC).networkSynchronized(TerrainTools.STREAM_CODEC)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<BlockState>> SHAPER_BLOCK_USED = DATA_COMPONENTS.registerComponentType(
"shaper_block_used",
builder -> builder.persistent(BlockState.CODEC).networkSynchronized(ByteBufCodecs.idMapper(Block.BLOCK_STATE_REGISTRY))
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<Boolean>> SHAPER_SWAP = DATA_COMPONENTS.registerComponentType(
"shaper_swap",
builder -> builder.persistent(Codec.BOOL).networkSynchronized(ByteBufCodecs.BOOL)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<CompoundTag>> SHAPER_BLOCK_DATA = DATA_COMPONENTS.registerComponentType(
"shaper_block_data",
builder -> builder.persistent(CompoundTag.CODEC).networkSynchronized(ByteBufCodecs.COMPOUND_TAG)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<ItemContainerContents>> FILTER_ITEMS = DATA_COMPONENTS.registerComponentType(
"filter_items",
builder -> builder.persistent(ItemContainerContents.CODEC).networkSynchronized(ItemContainerContents.STREAM_CODEC)
);
// These 2 are placed on items inside filters and not the filter itself
public static final DeferredHolder<DataComponentType<?>, DataComponentType<Boolean>> FILTER_ITEMS_RESPECT_NBT = DATA_COMPONENTS.registerComponentType(
"filter_items_respect_nbt",
builder -> builder.persistent(Codec.BOOL).networkSynchronized(ByteBufCodecs.BOOL)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<Boolean>> FILTER_ITEMS_BLACKLIST = DATA_COMPONENTS.registerComponentType(
"filter_items_blacklist",
builder -> builder.persistent(Codec.BOOL).networkSynchronized(ByteBufCodecs.BOOL)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<AttributeFilterWhitelistMode>> ATTRIBUTE_FILTER_WHITELIST_MODE = DATA_COMPONENTS.registerComponentType(
"attribute_filter_whitelist_mode",
builder -> builder.persistent(AttributeFilterWhitelistMode.CODEC).networkSynchronized(AttributeFilterWhitelistMode.STREAM_CODEC)
);
// TODO - Make a stream codec for this
public static final DeferredHolder<DataComponentType<?>, DataComponentType<List<ItemAttributeEntry>>> ATTRIBUTE_FILTER_MATCHED_ATTRIBUTES = DATA_COMPONENTS.registerComponentType(
"attribute_filter_matched_attributes",
builder -> builder.persistent(ItemAttributeEntry.CODEC.listOf())
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<ClipboardType>> CLIPBOARD_TYPE = DATA_COMPONENTS.registerComponentType(
"clipboard_type",
builder -> builder.persistent(ClipboardType.CODEC).networkSynchronized(ClipboardType.STREAM_CODEC)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<List<List<ClipboardEntry>>>> CLIPBOARD_PAGES = DATA_COMPONENTS.registerComponentType(
"clipboard_pages",
builder -> builder.persistent(ClipboardEntry.CODEC.listOf().listOf()).networkSynchronized(ClipboardEntry.STREAM_CODEC.apply(ByteBufCodecs.list()).apply(ByteBufCodecs.list()))
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<Unit>> CLIPBOARD_READ_ONLY = DATA_COMPONENTS.registerComponentType(
"clipboard_read_only",
builder -> builder.persistent(Unit.CODEC).networkSynchronized(StreamCodec.unit(Unit.INSTANCE))
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<CompoundTag>> CLIPBOARD_COPIED_VALUES = DATA_COMPONENTS.registerComponentType(
"clipboard_copied_values",
builder -> builder.persistent(CompoundTag.CODEC).networkSynchronized(ByteBufCodecs.COMPOUND_TAG)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<Integer>> CLIPBOARD_PREVIOUSLY_OPENED_PAGE = DATA_COMPONENTS.registerComponentType(
"clipboard_previously_opened_page",
builder -> builder.persistent(Codec.INT).networkSynchronized(ByteBufCodecs.INT)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<ConnectingFrom>> TRACK_CONNECTING_FROM = DATA_COMPONENTS.registerComponentType(
"track_connecting_from",
builder -> builder.persistent(ConnectingFrom.CODEC).networkSynchronized(ConnectingFrom.STREAM_CODEC)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<Boolean>> TRACK_EXTENDED_CURVE = DATA_COMPONENTS.registerComponentType(
"track_extend_curve",
builder -> builder.persistent(Codec.BOOL).networkSynchronized(ByteBufCodecs.BOOL)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<BlockPos>> TRACK_TARGETING_ITEM_SELECTED_POS = DATA_COMPONENTS.registerComponentType(
"track_targeting_item_selected_pos",
builder -> builder.persistent(BlockPos.CODEC).networkSynchronized(BlockPos.STREAM_CODEC)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<Boolean>> TRACK_TARGETING_ITEM_SELECTED_DIRECTION = DATA_COMPONENTS.registerComponentType(
"track_targeting_item_selected_direction",
builder -> builder.persistent(Codec.BOOL).networkSynchronized(ByteBufCodecs.BOOL)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<BezierTrackPointLocation>> TRACK_TARGETING_ITEM_BEZIER = DATA_COMPONENTS.registerComponentType(
"track_targeting_item_bezier",
builder -> builder.persistent(BezierTrackPointLocation.CODEC).networkSynchronized(BezierTrackPointLocation.STREAM_CODEC)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<Boolean>> SCHEMATIC_DEPLOYED = DATA_COMPONENTS.registerComponentType(
"schematic_deployed",
builder -> builder.persistent(Codec.BOOL).networkSynchronized(ByteBufCodecs.BOOL)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<String>> SCHEMATIC_OWNER = DATA_COMPONENTS.registerComponentType(
"schematic_owner",
builder -> builder.persistent(Codec.STRING).networkSynchronized(ByteBufCodecs.STRING_UTF8)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<String>> SCHEMATIC_FILE = DATA_COMPONENTS.registerComponentType(
"schematic_file",
builder -> builder.persistent(Codec.STRING).networkSynchronized(ByteBufCodecs.STRING_UTF8)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<BlockPos>> SCHEMATIC_ANCHOR = DATA_COMPONENTS.registerComponentType(
"schematic_anchor",
builder -> builder.persistent(BlockPos.CODEC).networkSynchronized(BlockPos.STREAM_CODEC)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<Rotation>> SCHEMATIC_ROTATION = DATA_COMPONENTS.registerComponentType(
"schematic_rotation",
builder -> builder.persistent(Rotation.CODEC).networkSynchronized(CatnipStreamCodecs.ROTATION)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<Mirror>> SCHEMATIC_MIRROR = DATA_COMPONENTS.registerComponentType(
"schematic_mirror",
builder -> builder.persistent(Mirror.CODEC).networkSynchronized(CatnipStreamCodecs.MIRROR)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<Vec3i>> SCHEMATIC_BOUNDS = DATA_COMPONENTS.registerComponentType(
"schematic_bounds",
builder -> builder.persistent(Vec3i.CODEC).networkSynchronized(CatnipStreamCodecs.VEC3I)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<Integer>> SCHEMATIC_HASH = DATA_COMPONENTS.registerComponentType(
"schematic_hash",
builder -> builder.persistent(Codec.INT).networkSynchronized(ByteBufCodecs.INT)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<Integer>> CHROMATIC_COMPOUND_COLLECTING_LIGHT = DATA_COMPONENTS.registerComponentType(
"chromatic_compound_collecting_light",
builder -> builder.persistent(Codec.INT).networkSynchronized(ByteBufCodecs.INT)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<ItemStack>> SAND_PAPER_POLISHING = DATA_COMPONENTS.registerComponentType(
"sand_paper_polishing",
builder -> builder.persistent(ItemStack.CODEC).networkSynchronized(ItemStack.STREAM_CODEC)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<Unit>> SAND_PAPER_JEI = DATA_COMPONENTS.registerComponentType(
"sand_paper_jei",
builder -> builder.persistent(Unit.CODEC).networkSynchronized(StreamCodec.unit(Unit.INSTANCE))
);
// Holds contraption data when a minecraft contraption is picked up
public static final DeferredHolder<DataComponentType<?>, DataComponentType<CompoundTag>> MINECRAFT_CONTRAPTION_DATA = DATA_COMPONENTS.registerComponentType(
"minecart_contraption_data",
builder -> builder.persistent(CompoundTag.CODEC).networkSynchronized(ByteBufCodecs.COMPOUND_TAG)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<ItemContainerContents>> LINKED_CONTROLLER_ITEMS = DATA_COMPONENTS.registerComponentType(
"linked_controller_items",
builder -> builder.persistent(ItemContainerContents.CODEC).networkSynchronized(ItemContainerContents.STREAM_CODEC)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<ItemContainerContents>> TOOLBOX_INVENTORY = DATA_COMPONENTS.registerComponentType(
"toolbox_inventory",
builder -> builder.persistent(ItemContainerContents.CODEC).networkSynchronized(ItemContainerContents.STREAM_CODEC)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<UUID>> TOOLBOX_UUID = DATA_COMPONENTS.registerComponentType(
"toolbox_uuid",
builder -> builder.persistent(UUIDUtil.CODEC).networkSynchronized(UUIDUtil.STREAM_CODEC)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<SequencedAssembly>> SEQUENCED_ASSEMBLY = DATA_COMPONENTS.registerComponentType(
"sequenced_assembly",
builder -> builder.persistent(SequencedAssembly.CODEC).networkSynchronized(SequencedAssembly.STREAM_CODEC)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<CompoundTag>> TRAIN_SCHEDULE = DATA_COMPONENTS.registerComponentType(
"train_schedule",
builder -> builder.persistent(CompoundTag.CODEC).networkSynchronized(ByteBufCodecs.COMPOUND_TAG)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<SymmetryMirror>> SYMMETRY_WAND = DATA_COMPONENTS.registerComponentType(
"symmetry_wand",
builder -> builder.persistent(SymmetryMirror.CODEC).networkSynchronized(SymmetryMirror.STREAM_CODEC)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<Boolean>> SYMMETRY_WAND_ENABLE = DATA_COMPONENTS.registerComponentType(
"symmetry_wand_enable",
builder -> builder.persistent(Codec.BOOL).networkSynchronized(ByteBufCodecs.BOOL)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<Boolean>> SYMMETRY_WAND_SIMULATE = DATA_COMPONENTS.registerComponentType(
"symmetry_wand_simulate",
builder -> builder.persistent(Codec.BOOL).networkSynchronized(ByteBufCodecs.BOOL)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<BlockPos>> DISPLAY_LINK_SELECTED_POS = DATA_COMPONENTS.registerComponentType(
"display_link_selected_pos",
builder -> builder.persistent(BlockPos.CODEC).networkSynchronized(BlockPos.STREAM_CODEC)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<BottleType>> POTION_FLUID_BOTTLE_TYPE = DATA_COMPONENTS.registerComponentType(
"potion_fluid_bottle_type",
builder -> builder.persistent(BottleType.CODEC).networkSynchronized(BottleType.STREAM_CODEC)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<SchematicannonOptions>> SCHEMATICANNON_OPTIONS = DATA_COMPONENTS.registerComponentType(
"schematicannon_options",
builder -> builder.persistent(SchematicannonOptions.CODEC).networkSynchronized(SchematicannonOptions.STREAM_CODEC)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<AutoRequestData>> AUTO_REQUEST_DATA = DATA_COMPONENTS.registerComponentType(
"auto_request_data",
builder -> builder.persistent(AutoRequestData.CODEC).networkSynchronized(AutoRequestData.STREAM_CODEC)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<ShoppingList>> SHOPPING_LIST = DATA_COMPONENTS.registerComponentType(
"shopping_list",
builder -> builder.persistent(ShoppingList.CODEC).networkSynchronized(ShoppingList.STREAM_CODEC)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<String>> SHOPPING_LIST_ADDRESS = DATA_COMPONENTS.registerComponentType(
"shopping_list_address",
builder -> builder.persistent(Codec.STRING).networkSynchronized(ByteBufCodecs.STRING_UTF8)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<String>> PACKAGE_ADDRESS = DATA_COMPONENTS.registerComponentType(
"package_address",
builder -> builder.persistent(Codec.STRING).networkSynchronized(ByteBufCodecs.STRING_UTF8)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<ItemContainerContents>> PACKAGE_CONTENTS = DATA_COMPONENTS.registerComponentType(
"package_contents",
builder -> builder.persistent(ItemContainerContents.CODEC).networkSynchronized(ItemContainerContents.STREAM_CODEC)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<PackageOrderData>> PACKAGE_ORDER_DATA = DATA_COMPONENTS.registerComponentType(
"package_order_data",
builder -> builder.persistent(PackageOrderData.CODEC).networkSynchronized(PackageOrderData.STREAM_CODEC)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<PackageOrder>> PACKAGE_ORDER_CONTEXT = DATA_COMPONENTS.registerComponentType(
"package_order_context",
builder -> builder.persistent(PackageOrder.CODEC).networkSynchronized(PackageOrder.STREAM_CODEC)
);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<ClickToLinkData>> CLICK_TO_LINK_DATA = DATA_COMPONENTS.registerComponentType(
"click_to_link_data",
builder -> builder.persistent(ClickToLinkData.CODEC).networkSynchronized(ClickToLinkData.STREAM_CODEC)
);
public static void register(IEventBus modEventBus) {
DATA_COMPONENTS.register(modEventBus);
}
}

View file

@ -1,31 +1,76 @@
package com.simibubi.create; package com.simibubi.create;
import static com.simibubi.create.Create.REGISTRATE; import com.simibubi.create.content.equipment.potatoCannon.PotatoProjectileTypeManager;
import com.simibubi.create.content.equipment.armor.CapacityEnchantment; import net.minecraft.advancements.critereon.ItemPredicate;
import com.simibubi.create.content.equipment.potatoCannon.PotatoRecoveryEnchantment; import net.minecraft.core.HolderGetter;
import com.tterrag.registrate.util.entry.RegistryEntry; import net.minecraft.core.HolderSet;
import net.minecraft.core.registries.Registries;
import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.data.worldgen.BootstrapContext;
import net.minecraft.world.item.enchantment.Enchantment.Rarity; import net.minecraft.resources.ResourceKey;
import net.minecraft.world.item.enchantment.EnchantmentCategory; import net.minecraft.world.entity.EquipmentSlotGroup;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.enchantment.Enchantment;
import net.minecraft.world.item.enchantment.EnchantmentEffectComponents;
import net.minecraft.world.item.enchantment.LevelBasedValue;
import net.minecraft.world.item.enchantment.effects.SetValue;
import net.minecraft.world.level.storage.loot.predicates.MatchTool;
public class AllEnchantments { public class AllEnchantments {
public static final ResourceKey<Enchantment>
POTATO_RECOVERY = key("potato_recovery"),
CAPACITY = key("capacity");
public static final RegistryEntry<PotatoRecoveryEnchantment> POTATO_RECOVERY = REGISTRATE.object("potato_recovery") private static ResourceKey<Enchantment> key(String name) {
.enchantment(EnchantmentCategory.BOW, PotatoRecoveryEnchantment::new) return ResourceKey.create(Registries.ENCHANTMENT, Create.asResource(name));
.addSlots(EquipmentSlot.MAINHAND, EquipmentSlot.OFFHAND) }
.lang("Potato Recovery")
.rarity(Rarity.UNCOMMON)
.register();
public static final RegistryEntry<CapacityEnchantment> CAPACITY = REGISTRATE.object("capacity") public static void bootstrap(BootstrapContext<Enchantment> context) {
.enchantment(EnchantmentCategory.ARMOR_CHEST, CapacityEnchantment::new) HolderGetter<Item> itemHolderGetter = context.lookup(Registries.ITEM);
.addSlots(EquipmentSlot.CHEST)
.lang("Capacity")
.rarity(Rarity.COMMON)
.register();
public static void register() {} register(
context,
POTATO_RECOVERY,
Enchantment.enchantment(
Enchantment.definition(
HolderSet.direct(AllItems.POTATO_CANNON),
10,
3,
Enchantment.dynamicCost(15, 15),
Enchantment.dynamicCost(45, 15),
1,
EquipmentSlotGroup.MAINHAND
)
).withEffect(
EnchantmentEffectComponents.AMMO_USE,
new SetValue(LevelBasedValue.perLevel(0.0F, 33.3333333333F)),
MatchTool.toolMatches(
ItemPredicate.Builder.item().of(
PotatoProjectileTypeManager.getItems().toArray(Item[]::new)
)
)
)
);
register(
context,
CAPACITY,
Enchantment.enchantment(
Enchantment.definition(
itemHolderGetter.getOrThrow(AllTags.AllItemTags.PRESSURIZED_AIR_SOURCES.tag),
10,
3,
Enchantment.dynamicCost(15, 15),
Enchantment.dynamicCost(45, 15),
1,
EquipmentSlotGroup.MAINHAND
)
)
);
}
private static void register(BootstrapContext<Enchantment> context, ResourceKey<Enchantment> key, Enchantment.Builder builder) {
context.register(key, builder.build(key.location()));
}
} }

View file

@ -3,18 +3,17 @@ package com.simibubi.create;
import com.simibubi.create.content.trains.entity.CarriageSyncDataSerializer; import com.simibubi.create.content.trains.entity.CarriageSyncDataSerializer;
import net.minecraft.network.syncher.EntityDataSerializer; import net.minecraft.network.syncher.EntityDataSerializer;
import net.minecraftforge.eventbus.api.IEventBus; import net.neoforged.bus.api.IEventBus;
import net.minecraftforge.registries.DeferredRegister; import net.neoforged.neoforge.registries.DeferredHolder;
import net.minecraftforge.registries.ForgeRegistries; import net.neoforged.neoforge.registries.DeferredRegister;
import net.minecraftforge.registries.RegistryObject; import net.neoforged.neoforge.registries.NeoForgeRegistries;
public class AllEntityDataSerializers { public class AllEntityDataSerializers {
private static final DeferredRegister<EntityDataSerializer<?>> REGISTER = DeferredRegister.create(ForgeRegistries.Keys.ENTITY_DATA_SERIALIZERS, Create.ID); private static final DeferredRegister<EntityDataSerializer<?>> REGISTER = DeferredRegister.create(NeoForgeRegistries.Keys.ENTITY_DATA_SERIALIZERS, Create.ID);
public static final CarriageSyncDataSerializer CARRIAGE_DATA = new CarriageSyncDataSerializer(); public static final CarriageSyncDataSerializer CARRIAGE_DATA = new CarriageSyncDataSerializer();
public static final RegistryObject<CarriageSyncDataSerializer> CARRIAGE_DATA_ENTRY = REGISTER.register("carriage_data", () -> CARRIAGE_DATA); public static final DeferredHolder<EntityDataSerializer<?>, CarriageSyncDataSerializer> CARRIAGE_DATA_ENTRY = REGISTER.register("carriage_data", () -> CARRIAGE_DATA);
public static void register(IEventBus modEventBus) { public static void register(IEventBus modEventBus) {
REGISTER.register(modEventBus); REGISTER.register(modEventBus);

View file

@ -32,7 +32,7 @@ import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.EntityType.EntityFactory; import net.minecraft.world.entity.EntityType.EntityFactory;
import net.minecraft.world.entity.MobCategory; import net.minecraft.world.entity.MobCategory;
import net.minecraftforge.event.entity.EntityAttributeCreationEvent; import net.neoforged.neoforge.event.entity.EntityAttributeCreationEvent;
public class AllEntityTypes { public class AllEntityTypes {

View file

@ -12,7 +12,6 @@ import org.joml.Vector3f;
import com.mojang.blaze3d.shaders.FogShape; import com.mojang.blaze3d.shaders.FogShape;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import com.simibubi.create.AllTags.AllFluidTags;
import com.simibubi.create.content.decoration.palettes.AllPaletteStoneTypes; import com.simibubi.create.content.decoration.palettes.AllPaletteStoneTypes;
import com.simibubi.create.content.fluids.VirtualFluid; import com.simibubi.create.content.fluids.VirtualFluid;
import com.simibubi.create.content.fluids.potion.PotionFluid; import com.simibubi.create.content.fluids.potion.PotionFluid;
@ -32,13 +31,14 @@ import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid; import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.level.material.FluidState; import net.minecraft.world.level.material.FluidState;
import net.minecraftforge.client.extensions.common.IClientFluidTypeExtensions; import net.neoforged.neoforge.client.extensions.common.IClientFluidTypeExtensions;
import net.minecraftforge.common.ForgeMod; import net.neoforged.neoforge.common.NeoForgeMod;
import net.minecraftforge.fluids.FluidInteractionRegistry; import net.neoforged.neoforge.common.Tags;
import net.minecraftforge.fluids.FluidInteractionRegistry.InteractionInformation; import net.neoforged.neoforge.fluids.BaseFlowingFluid;
import net.minecraftforge.fluids.FluidStack; import net.neoforged.neoforge.fluids.FluidInteractionRegistry;
import net.minecraftforge.fluids.FluidType; import net.neoforged.neoforge.fluids.FluidInteractionRegistry.InteractionInformation;
import net.minecraftforge.fluids.ForgeFlowingFluid; import net.neoforged.neoforge.fluids.FluidStack;
import net.neoforged.neoforge.fluids.FluidType;
public class AllFluids { public class AllFluids {
static { static {
@ -52,10 +52,10 @@ public class AllFluids {
public static final FluidEntry<VirtualFluid> TEA = REGISTRATE.virtualFluid("tea") public static final FluidEntry<VirtualFluid> TEA = REGISTRATE.virtualFluid("tea")
.lang("Builder's Tea") .lang("Builder's Tea")
.tag(AllTags.forgeFluidTag("tea")) .tag(AllTags.commonFluidTag("teas"))
.register(); .register();
public static final FluidEntry<ForgeFlowingFluid.Flowing> HONEY = public static final FluidEntry<BaseFlowingFluid.Flowing> HONEY =
REGISTRATE.standardFluid("honey", REGISTRATE.standardFluid("honey",
SolidRenderedPlaceableFluidType.create(0xEAAE2F, SolidRenderedPlaceableFluidType.create(0xEAAE2F,
() -> 1f / 8f * AllConfigs.client().honeyTransparencyMultiplier.getF())) () -> 1f / 8f * AllConfigs.client().honeyTransparencyMultiplier.getF()))
@ -66,19 +66,19 @@ public class AllFluids {
.tickRate(25) .tickRate(25)
.slopeFindDistance(3) .slopeFindDistance(3)
.explosionResistance(100f)) .explosionResistance(100f))
.tag(AllFluidTags.HONEY.tag) .tag(Tags.Fluids.HONEY)
.source(ForgeFlowingFluid.Source::new) // TODO: remove when Registrate fixes FluidBuilder .source(BaseFlowingFluid.Source::new) // TODO: remove when Registrate fixes FluidBuilder
.bucket() .bucket()
.tag(AllTags.forgeItemTag("buckets/honey")) .tag(AllTags.commonItemTag("buckets/honey"))
.build() .build()
.register(); .register();
public static final FluidEntry<ForgeFlowingFluid.Flowing> CHOCOLATE = public static final FluidEntry<BaseFlowingFluid.Flowing> CHOCOLATE =
REGISTRATE.standardFluid("chocolate", REGISTRATE.standardFluid("chocolate",
SolidRenderedPlaceableFluidType.create(0x622020, SolidRenderedPlaceableFluidType.create(0x622020,
() -> 1f / 32f * AllConfigs.client().chocolateTransparencyMultiplier.getF())) () -> 1f / 32f * AllConfigs.client().chocolateTransparencyMultiplier.getF()))
.lang("Chocolate") .lang("Chocolate")
.tag(AllTags.forgeFluidTag("chocolate")) .tag(AllTags.commonFluidTag("chocolates"))
.properties(b -> b.viscosity(1500) .properties(b -> b.viscosity(1500)
.density(1400)) .density(1400))
.fluidProperties(p -> p.levelDecreasePerBlock(2) .fluidProperties(p -> p.levelDecreasePerBlock(2)
@ -92,7 +92,7 @@ public class AllFluids {
public static void register() {} public static void register() {}
public static void registerFluidInteractions() { public static void registerFluidInteractions() {
FluidInteractionRegistry.addInteraction(ForgeMod.LAVA_TYPE.get(), new InteractionInformation( FluidInteractionRegistry.addInteraction(NeoForgeMod.LAVA_TYPE.value(), new InteractionInformation(
HONEY.get().getFluidType(), HONEY.get().getFluidType(),
fluidState -> { fluidState -> {
if (fluidState.isSource()) { if (fluidState.isSource()) {
@ -105,7 +105,7 @@ public class AllFluids {
} }
)); ));
FluidInteractionRegistry.addInteraction(ForgeMod.LAVA_TYPE.get(), new InteractionInformation( FluidInteractionRegistry.addInteraction(NeoForgeMod.LAVA_TYPE.value(), new InteractionInformation(
CHOCOLATE.get().getFluidType(), CHOCOLATE.get().getFluidType(),
fluidState -> { fluidState -> {
if (fluidState.isSource()) { if (fluidState.isSource()) {

View file

@ -13,15 +13,15 @@ import com.simibubi.create.content.contraptions.behaviour.TrapdoorMovingInteract
import com.simibubi.create.foundation.utility.AttachedRegistry; import com.simibubi.create.foundation.utility.AttachedRegistry;
import com.tterrag.registrate.util.nullness.NonNullConsumer; import com.tterrag.registrate.util.nullness.NonNullConsumer;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.BlockTags; import net.minecraft.tags.BlockTags;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.registries.ForgeRegistries;
public class AllInteractionBehaviours { public class AllInteractionBehaviours {
private static final AttachedRegistry<Block, MovingInteractionBehaviour> BLOCK_BEHAVIOURS = new AttachedRegistry<>(ForgeRegistries.BLOCKS); private static final AttachedRegistry<Block, MovingInteractionBehaviour> BLOCK_BEHAVIOURS = new AttachedRegistry<>(BuiltInRegistries.BLOCK);
private static final List<BehaviourProvider> GLOBAL_BEHAVIOURS = new ArrayList<>(); private static final List<BehaviourProvider> GLOBAL_BEHAVIOURS = new ArrayList<>();
public static void registerBehaviour(ResourceLocation block, MovingInteractionBehaviour provider) { public static void registerBehaviour(ResourceLocation block, MovingInteractionBehaviour provider) {

View file

@ -1,9 +1,9 @@
package com.simibubi.create; package com.simibubi.create;
import static com.simibubi.create.AllTags.forgeItemTag;
import static com.simibubi.create.AllTags.AllItemTags.CREATE_INGOTS; import static com.simibubi.create.AllTags.AllItemTags.CREATE_INGOTS;
import static com.simibubi.create.AllTags.AllItemTags.CRUSHED_RAW_MATERIALS; import static com.simibubi.create.AllTags.AllItemTags.CRUSHED_RAW_MATERIALS;
import static com.simibubi.create.AllTags.AllItemTags.PLATES; import static com.simibubi.create.AllTags.AllItemTags.PLATES;
import static com.simibubi.create.AllTags.commonItemTag;
import static com.simibubi.create.Create.REGISTRATE; import static com.simibubi.create.Create.REGISTRATE;
import static com.simibubi.create.foundation.data.recipe.CompatMetals.ALUMINUM; import static com.simibubi.create.foundation.data.recipe.CompatMetals.ALUMINUM;
import static com.simibubi.create.foundation.data.recipe.CompatMetals.LEAD; import static com.simibubi.create.foundation.data.recipe.CompatMetals.LEAD;
@ -26,7 +26,7 @@ import com.simibubi.create.content.equipment.armor.BacktankItem;
import com.simibubi.create.content.equipment.armor.BacktankItem.BacktankBlockItem; import com.simibubi.create.content.equipment.armor.BacktankItem.BacktankBlockItem;
import com.simibubi.create.content.equipment.armor.BaseArmorItem; import com.simibubi.create.content.equipment.armor.BaseArmorItem;
import com.simibubi.create.content.equipment.armor.CardboardArmorItem; import com.simibubi.create.content.equipment.armor.CardboardArmorItem;
import com.simibubi.create.content.equipment.armor.CardboardHelmetItem; import com.simibubi.create.content.equipment.armor.CardboardArmorStealthOverlay;
import com.simibubi.create.content.equipment.armor.DivingBootsItem; import com.simibubi.create.content.equipment.armor.DivingBootsItem;
import com.simibubi.create.content.equipment.armor.DivingHelmetItem; import com.simibubi.create.content.equipment.armor.DivingHelmetItem;
import com.simibubi.create.content.equipment.armor.TrimmableArmorModelGenerator; import com.simibubi.create.content.equipment.armor.TrimmableArmorModelGenerator;
@ -37,6 +37,7 @@ import com.simibubi.create.content.equipment.goggles.GogglesModel;
import com.simibubi.create.content.equipment.potatoCannon.PotatoCannonItem; import com.simibubi.create.content.equipment.potatoCannon.PotatoCannonItem;
import com.simibubi.create.content.equipment.sandPaper.SandPaperItem; import com.simibubi.create.content.equipment.sandPaper.SandPaperItem;
import com.simibubi.create.content.equipment.symmetryWand.SymmetryWandItem; import com.simibubi.create.content.equipment.symmetryWand.SymmetryWandItem;
import com.simibubi.create.content.equipment.tool.AllToolMaterials;
import com.simibubi.create.content.equipment.tool.CardboardSwordItem; import com.simibubi.create.content.equipment.tool.CardboardSwordItem;
import com.simibubi.create.content.equipment.wrench.WrenchItem; import com.simibubi.create.content.equipment.wrench.WrenchItem;
import com.simibubi.create.content.equipment.zapper.terrainzapper.WorldshaperItem; import com.simibubi.create.content.equipment.zapper.terrainzapper.WorldshaperItem;
@ -78,7 +79,8 @@ import net.minecraft.world.item.ArmorItem;
import net.minecraft.world.item.ArmorMaterials; import net.minecraft.world.item.ArmorMaterials;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import net.minecraft.world.item.Rarity; import net.minecraft.world.item.Rarity;
import net.minecraftforge.common.Tags; import net.minecraft.world.item.SwordItem;
import net.neoforged.neoforge.common.Tags;
public class AllItems { public class AllItems {
@ -86,18 +88,18 @@ public class AllItems {
REGISTRATE.setCreativeTab(AllCreativeModeTabs.BASE_CREATIVE_TAB); REGISTRATE.setCreativeTab(AllCreativeModeTabs.BASE_CREATIVE_TAB);
} }
public static final ItemEntry<Item> WHEAT_FLOUR = public static final ItemEntry<Item>
taggedIngredient("wheat_flour", forgeItemTag("flour/wheat"), forgeItemTag("flour")), WHEAT_FLOUR = taggedIngredient("wheat_flour", commonItemTag("flours/wheat"), commonItemTag("flours")),
DOUGH = taggedIngredient("dough", forgeItemTag("dough"), forgeItemTag("dough/wheat")), DOUGH = taggedIngredient("dough", commonItemTag("doughs"), commonItemTag("doughs/wheat")),
CINDER_FLOUR = ingredient("cinder_flour"), ROSE_QUARTZ = ingredient("rose_quartz"), CINDER_FLOUR = ingredient("cinder_flour"), ROSE_QUARTZ = ingredient("rose_quartz"),
POLISHED_ROSE_QUARTZ = ingredient("polished_rose_quartz"), POWDERED_OBSIDIAN = ingredient("powdered_obsidian"), POLISHED_ROSE_QUARTZ = ingredient("polished_rose_quartz"), POWDERED_OBSIDIAN = ingredient("powdered_obsidian"),
STURDY_SHEET = taggedIngredient("sturdy_sheet", forgeItemTag("plates/obsidian"), PLATES.tag), STURDY_SHEET = taggedIngredient("sturdy_sheet", commonItemTag("plates/obsidian"), PLATES.tag),
PROPELLER = ingredient("propeller"), WHISK = ingredient("whisk"), BRASS_HAND = ingredient("brass_hand"), PROPELLER = ingredient("propeller"), WHISK = ingredient("whisk"), BRASS_HAND = ingredient("brass_hand"),
CRAFTER_SLOT_COVER = ingredient("crafter_slot_cover"), ELECTRON_TUBE = ingredient("electron_tube"), CRAFTER_SLOT_COVER = ingredient("crafter_slot_cover"), ELECTRON_TUBE = ingredient("electron_tube"),
TRANSMITTER = ingredient("transmitter"), PULP = ingredient("pulp"); TRANSMITTER = ingredient("transmitter"), PULP = ingredient("pulp");
public static final ItemEntry<CombustibleItem> CARDBOARD = REGISTRATE.item("cardboard", CombustibleItem::new) public static final ItemEntry<CombustibleItem> CARDBOARD = REGISTRATE.item("cardboard", CombustibleItem::new)
.tag(forgeItemTag("plates/cardboard")) .tag(commonItemTag("plates/cardboard"))
.onRegister(i -> i.setBurnTime(1000)) .onRegister(i -> i.setBurnTime(1000))
.register(); .register();
@ -127,26 +129,26 @@ public class AllItems {
public static final ItemEntry<Item> BAR_OF_CHOCOLATE = REGISTRATE.item("bar_of_chocolate", Item::new) public static final ItemEntry<Item> BAR_OF_CHOCOLATE = REGISTRATE.item("bar_of_chocolate", Item::new)
.properties(p -> p.food(new FoodProperties.Builder().nutrition(6) .properties(p -> p.food(new FoodProperties.Builder().nutrition(6)
.saturationMod(0.3F) .saturationModifier(0.3F)
.build())) .build()))
.lang("Bar of Chocolate") .lang("Bar of Chocolate")
.register(); .register();
public static final ItemEntry<Item> SWEET_ROLL = REGISTRATE.item("sweet_roll", Item::new) public static final ItemEntry<Item> SWEET_ROLL = REGISTRATE.item("sweet_roll", Item::new)
.properties(p -> p.food(new FoodProperties.Builder().nutrition(6) .properties(p -> p.food(new FoodProperties.Builder().nutrition(6)
.saturationMod(0.8F) .saturationModifier(0.8F)
.build())) .build()))
.register(); .register();
public static final ItemEntry<Item> CHOCOLATE_BERRIES = REGISTRATE.item("chocolate_glazed_berries", Item::new) public static final ItemEntry<Item> CHOCOLATE_BERRIES = REGISTRATE.item("chocolate_glazed_berries", Item::new)
.properties(p -> p.food(new FoodProperties.Builder().nutrition(7) .properties(p -> p.food(new FoodProperties.Builder().nutrition(7)
.saturationMod(0.8F) .saturationModifier(0.8F)
.build())) .build()))
.register(); .register();
public static final ItemEntry<Item> HONEYED_APPLE = REGISTRATE.item("honeyed_apple", Item::new) public static final ItemEntry<Item> HONEYED_APPLE = REGISTRATE.item("honeyed_apple", Item::new)
.properties(p -> p.food(new FoodProperties.Builder().nutrition(8) .properties(p -> p.food(new FoodProperties.Builder().nutrition(8)
.saturationMod(0.8F) .saturationModifier(0.8F)
.build())) .build()))
.register(); .register();
@ -159,15 +161,16 @@ public class AllItems {
public static final ItemEntry<CardboardSwordItem> CARDBOARD_SWORD = public static final ItemEntry<CardboardSwordItem> CARDBOARD_SWORD =
REGISTRATE.item("cardboard_sword", CardboardSwordItem::new) REGISTRATE.item("cardboard_sword", CardboardSwordItem::new)
.properties(p -> p.stacksTo(1)) .properties(p -> p.stacksTo(1))
.properties(p -> p.attributes(SwordItem.createAttributes(AllToolMaterials.CARDBOARD, 3, 1)))
.model(AssetLookup.itemModelWithPartials()) .model(AssetLookup.itemModelWithPartials())
.register(); .register();
public static final ItemEntry<Item> RAW_ZINC = public static final ItemEntry<Item> RAW_ZINC =
taggedIngredient("raw_zinc", forgeItemTag("raw_materials/zinc"), forgeItemTag("raw_materials")); taggedIngredient("raw_zinc", commonItemTag("raw_materials/zinc"), commonItemTag("raw_materials"));
public static final ItemEntry<Item> ANDESITE_ALLOY = taggedIngredient("andesite_alloy", CREATE_INGOTS.tag), public static final ItemEntry<Item> ANDESITE_ALLOY = taggedIngredient("andesite_alloy", CREATE_INGOTS.tag),
ZINC_INGOT = taggedIngredient("zinc_ingot", forgeItemTag("ingots/zinc"), CREATE_INGOTS.tag), ZINC_INGOT = taggedIngredient("zinc_ingot", commonItemTag("ingots/zinc"), CREATE_INGOTS.tag),
BRASS_INGOT = taggedIngredient("brass_ingot", forgeItemTag("ingots/brass"), CREATE_INGOTS.tag); BRASS_INGOT = taggedIngredient("brass_ingot", commonItemTag("ingots/brass"), CREATE_INGOTS.tag);
public static final ItemEntry<ChromaticCompoundItem> CHROMATIC_COMPOUND = public static final ItemEntry<ChromaticCompoundItem> CHROMATIC_COMPOUND =
REGISTRATE.item("chromatic_compound", ChromaticCompoundItem::new) REGISTRATE.item("chromatic_compound", ChromaticCompoundItem::new)
@ -185,10 +188,10 @@ public class AllItems {
.properties(p -> p.rarity(Rarity.UNCOMMON)) .properties(p -> p.rarity(Rarity.UNCOMMON))
.register(); .register();
public static final ItemEntry<Item> COPPER_NUGGET = public static final ItemEntry<Item>
taggedIngredient("copper_nugget", forgeItemTag("nuggets/copper"), Tags.Items.NUGGETS), COPPER_NUGGET = taggedIngredient("copper_nugget", commonItemTag("nuggets/copper"), Tags.Items.NUGGETS),
ZINC_NUGGET = taggedIngredient("zinc_nugget", forgeItemTag("nuggets/zinc"), Tags.Items.NUGGETS), ZINC_NUGGET = taggedIngredient("zinc_nugget", commonItemTag("nuggets/zinc"), Tags.Items.NUGGETS),
BRASS_NUGGET = taggedIngredient("brass_nugget", forgeItemTag("nuggets/brass"), Tags.Items.NUGGETS); BRASS_NUGGET = taggedIngredient("brass_nugget", commonItemTag("nuggets/brass"), Tags.Items.NUGGETS);
public static final ItemEntry<ExperienceNuggetItem> EXP_NUGGET = public static final ItemEntry<ExperienceNuggetItem> EXP_NUGGET =
REGISTRATE.item("experience_nugget", ExperienceNuggetItem::new) REGISTRATE.item("experience_nugget", ExperienceNuggetItem::new)
@ -197,11 +200,11 @@ public class AllItems {
.lang("Nugget of Experience") .lang("Nugget of Experience")
.register(); .register();
public static final ItemEntry<Item> COPPER_SHEET = public static final ItemEntry<Item>
taggedIngredient("copper_sheet", forgeItemTag("plates/copper"), PLATES.tag), COPPER_SHEET = taggedIngredient("copper_sheet", commonItemTag("plates/copper"), PLATES.tag),
BRASS_SHEET = taggedIngredient("brass_sheet", forgeItemTag("plates/brass"), PLATES.tag), BRASS_SHEET = taggedIngredient("brass_sheet", commonItemTag("plates/brass"), PLATES.tag),
IRON_SHEET = taggedIngredient("iron_sheet", forgeItemTag("plates/iron"), PLATES.tag), IRON_SHEET = taggedIngredient("iron_sheet", commonItemTag("plates/iron"), PLATES.tag),
GOLDEN_SHEET = taggedIngredient("golden_sheet", forgeItemTag("plates/gold"), PLATES.tag, ItemTags.PIGLIN_LOVED), GOLDEN_SHEET = taggedIngredient("golden_sheet", commonItemTag("plates/gold"), PLATES.tag, ItemTags.PIGLIN_LOVED),
CRUSHED_IRON = taggedIngredient("crushed_raw_iron", CRUSHED_RAW_MATERIALS.tag), CRUSHED_IRON = taggedIngredient("crushed_raw_iron", CRUSHED_RAW_MATERIALS.tag),
CRUSHED_GOLD = taggedIngredient("crushed_raw_gold", CRUSHED_RAW_MATERIALS.tag, ItemTags.PIGLIN_LOVED), CRUSHED_GOLD = taggedIngredient("crushed_raw_gold", CRUSHED_RAW_MATERIALS.tag, ItemTags.PIGLIN_LOVED),
@ -275,7 +278,7 @@ public class AllItems {
COPPER_BACKTANK_PLACEABLE)) COPPER_BACKTANK_PLACEABLE))
.model(AssetLookup.customGenericItemModel("_", "item")) .model(AssetLookup.customGenericItemModel("_", "item"))
.tag(AllItemTags.PRESSURIZED_AIR_SOURCES.tag) .tag(AllItemTags.PRESSURIZED_AIR_SOURCES.tag)
.tag(forgeItemTag("armors/chestplates")) .tag(ItemTags.CHEST_ARMOR)
.register(), .register(),
NETHERITE_BACKTANK = REGISTRATE NETHERITE_BACKTANK = REGISTRATE
@ -285,7 +288,7 @@ public class AllItems {
.model(AssetLookup.customGenericItemModel("_", "item")) .model(AssetLookup.customGenericItemModel("_", "item"))
.properties(p -> p.fireResistant()) .properties(p -> p.fireResistant())
.tag(AllItemTags.PRESSURIZED_AIR_SOURCES.tag) .tag(AllItemTags.PRESSURIZED_AIR_SOURCES.tag)
.tag(forgeItemTag("armors/chestplates")) .tag(ItemTags.CHEST_ARMOR)
.register(); .register();
public static final ItemEntry<? extends DivingHelmetItem> public static final ItemEntry<? extends DivingHelmetItem>
@ -294,14 +297,14 @@ public class AllItems {
REGISTRATE REGISTRATE
.item("copper_diving_helmet", .item("copper_diving_helmet",
p -> new DivingHelmetItem(AllArmorMaterials.COPPER, p, Create.asResource("copper_diving"))) p -> new DivingHelmetItem(AllArmorMaterials.COPPER, p, Create.asResource("copper_diving")))
.tag(forgeItemTag("armors/helmets")) .tag(ItemTags.HEAD_ARMOR)
.register(), .register(),
NETHERITE_DIVING_HELMET = REGISTRATE NETHERITE_DIVING_HELMET = REGISTRATE
.item("netherite_diving_helmet", .item("netherite_diving_helmet",
p -> new DivingHelmetItem(ArmorMaterials.NETHERITE, p, Create.asResource("netherite_diving"))) p -> new DivingHelmetItem(ArmorMaterials.NETHERITE, p, Create.asResource("netherite_diving")))
.properties(p -> p.fireResistant()) .properties(p -> p.fireResistant())
.tag(forgeItemTag("armors/helmets")) .tag(ItemTags.HEAD_ARMOR)
.register(); .register();
public static final ItemEntry<? extends DivingBootsItem> public static final ItemEntry<? extends DivingBootsItem>
@ -310,40 +313,41 @@ public class AllItems {
REGISTRATE REGISTRATE
.item("copper_diving_boots", .item("copper_diving_boots",
p -> new DivingBootsItem(AllArmorMaterials.COPPER, p, Create.asResource("copper_diving"))) p -> new DivingBootsItem(AllArmorMaterials.COPPER, p, Create.asResource("copper_diving")))
.tag(forgeItemTag("armors/boots")) .tag(ItemTags.FOOT_ARMOR)
.register(), .register(),
NETHERITE_DIVING_BOOTS = REGISTRATE NETHERITE_DIVING_BOOTS = REGISTRATE
.item("netherite_diving_boots", .item("netherite_diving_boots",
p -> new DivingBootsItem(ArmorMaterials.NETHERITE, p, Create.asResource("netherite_diving"))) p -> new DivingBootsItem(ArmorMaterials.NETHERITE, p, Create.asResource("netherite_diving")))
.properties(p -> p.fireResistant()) .properties(p -> p.fireResistant())
.tag(forgeItemTag("armors/boots")) .tag(ItemTags.FOOT_ARMOR)
.register(); .register();
public static final ItemEntry<? extends BaseArmorItem> public static final ItemEntry<? extends BaseArmorItem>
CARDBOARD_HELMET = REGISTRATE.item("cardboard_helmet", p -> new CardboardHelmetItem(ArmorItem.Type.HELMET, p)) CARDBOARD_HELMET = REGISTRATE.item("cardboard_helmet", p -> new CardboardArmorItem(ArmorItem.Type.HELMET, p))
.tag(forgeItemTag("armors/helmet"), ItemTags.TRIMMABLE_ARMOR) .tag(ItemTags.HEAD_ARMOR, ItemTags.TRIMMABLE_ARMOR)
.onRegisterAfter(Registries.ITEM, v -> ItemDescription.useKey(v, "item.create.cardboard_armor")) .onRegisterAfter(Registries.ITEM, v -> ItemDescription.useKey(v, "item.create.cardboard_armor"))
.model(TrimmableArmorModelGenerator::generate) .model(TrimmableArmorModelGenerator::generate)
.clientExtension(() -> () -> new CardboardArmorStealthOverlay())
.register(), .register(),
CARDBOARD_CHESTPLATE = CARDBOARD_CHESTPLATE =
REGISTRATE.item("cardboard_chestplate", p -> new CardboardArmorItem(ArmorItem.Type.CHESTPLATE, p)) REGISTRATE.item("cardboard_chestplate", p -> new CardboardArmorItem(ArmorItem.Type.CHESTPLATE, p))
.tag(forgeItemTag("armors/chestplate"), ItemTags.TRIMMABLE_ARMOR) .tag(ItemTags.CHEST_ARMOR, ItemTags.TRIMMABLE_ARMOR)
.onRegisterAfter(Registries.ITEM, v -> ItemDescription.useKey(v, "item.create.cardboard_armor")) .onRegisterAfter(Registries.ITEM, v -> ItemDescription.useKey(v, "item.create.cardboard_armor"))
.model(TrimmableArmorModelGenerator::generate) .model(TrimmableArmorModelGenerator::generate)
.register(), .register(),
CARDBOARD_LEGGINGS = CARDBOARD_LEGGINGS =
REGISTRATE.item("cardboard_leggings", p -> new CardboardArmorItem(ArmorItem.Type.LEGGINGS, p)) REGISTRATE.item("cardboard_leggings", p -> new CardboardArmorItem(ArmorItem.Type.LEGGINGS, p))
.tag(forgeItemTag("armors/leggings"), ItemTags.TRIMMABLE_ARMOR) .tag(ItemTags.LEG_ARMOR, ItemTags.TRIMMABLE_ARMOR)
.onRegisterAfter(Registries.ITEM, v -> ItemDescription.useKey(v, "item.create.cardboard_armor")) .onRegisterAfter(Registries.ITEM, v -> ItemDescription.useKey(v, "item.create.cardboard_armor"))
.model(TrimmableArmorModelGenerator::generate) .model(TrimmableArmorModelGenerator::generate)
.register(), .register(),
CARDBOARD_BOOTS = REGISTRATE.item("cardboard_boots", p -> new CardboardArmorItem(ArmorItem.Type.BOOTS, p)) CARDBOARD_BOOTS = REGISTRATE.item("cardboard_boots", p -> new CardboardArmorItem(ArmorItem.Type.BOOTS, p))
.tag(forgeItemTag("armors/boots"), ItemTags.TRIMMABLE_ARMOR) .tag(ItemTags.FOOT_ARMOR, ItemTags.TRIMMABLE_ARMOR)
.onRegisterAfter(Registries.ITEM, v -> ItemDescription.useKey(v, "item.create.cardboard_armor")) .onRegisterAfter(Registries.ITEM, v -> ItemDescription.useKey(v, "item.create.cardboard_armor"))
.model(TrimmableArmorModelGenerator::generate) .model(TrimmableArmorModelGenerator::generate)
.register(); .register();
@ -386,6 +390,7 @@ public class AllItems {
public static final ItemEntry<PotatoCannonItem> POTATO_CANNON = public static final ItemEntry<PotatoCannonItem> POTATO_CANNON =
REGISTRATE.item("potato_cannon", PotatoCannonItem::new) REGISTRATE.item("potato_cannon", PotatoCannonItem::new)
.model(AssetLookup.itemModelWithPartials()) .model(AssetLookup.itemModelWithPartials())
.tag(Tags.Items.ENCHANTABLES)
.register(); .register();
public static final ItemEntry<ExtendoGripItem> EXTENDO_GRIP = REGISTRATE.item("extendo_grip", ExtendoGripItem::new) public static final ItemEntry<ExtendoGripItem> EXTENDO_GRIP = REGISTRATE.item("extendo_grip", ExtendoGripItem::new)
@ -490,7 +495,7 @@ public class AllItems {
String metalName = metal.getName(); String metalName = metal.getName();
return REGISTRATE return REGISTRATE
.item("crushed_raw_" + metalName, .item("crushed_raw_" + metalName,
props -> new TagDependentIngredientItem(props, AllTags.forgeItemTag("ores/" + metalName))) props -> new TagDependentIngredientItem(props, AllTags.commonItemTag("ores/" + metalName)))
.tag(CRUSHED_RAW_MATERIALS.tag) .tag(CRUSHED_RAW_MATERIALS.tag)
.register(); .register();
} }

View file

@ -1,5 +1,7 @@
package com.simibubi.create; package com.simibubi.create;
import net.neoforged.fml.common.EventBusSubscriber;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
import com.mojang.blaze3d.platform.InputConstants; import com.mojang.blaze3d.platform.InputConstants;
@ -7,10 +9,9 @@ import com.mojang.blaze3d.platform.InputConstants;
import net.minecraft.client.KeyMapping; import net.minecraft.client.KeyMapping;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.Screen;
import net.minecraftforge.api.distmarker.Dist; import net.neoforged.api.distmarker.Dist;
import net.minecraftforge.client.event.RegisterKeyMappingsEvent; import net.neoforged.bus.api.SubscribeEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.neoforged.neoforge.client.event.RegisterKeyMappingsEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
@EventBusSubscriber(value = Dist.CLIENT, bus = EventBusSubscriber.Bus.MOD) @EventBusSubscriber(value = Dist.CLIENT, bus = EventBusSubscriber.Bus.MOD)
public enum AllKeys { public enum AllKeys {

View file

@ -0,0 +1,17 @@
package com.simibubi.create;
import net.minecraft.core.Holder;
import net.minecraft.core.registries.Registries;
import net.minecraft.world.level.saveddata.maps.MapDecorationType;
import net.neoforged.bus.api.IEventBus;
import net.neoforged.neoforge.registries.DeferredRegister;
public class AllMapDecorationTypes {
private static final DeferredRegister<MapDecorationType> DECORATION_TYPES = DeferredRegister.create(Registries.MAP_DECORATION_TYPE, Create.ID);
public static final Holder<MapDecorationType> STATION_MAP_DECORATION = DECORATION_TYPES.register("station", () -> new MapDecorationType(Create.asResource("station"), true, -1, false, true));
public static void register(IEventBus modEventBus) {
DECORATION_TYPES.register(modEventBus);
}
}

View file

@ -13,14 +13,15 @@ import com.simibubi.create.content.contraptions.behaviour.dispenser.DropperMovem
import com.simibubi.create.foundation.utility.AttachedRegistry; import com.simibubi.create.foundation.utility.AttachedRegistry;
import com.tterrag.registrate.util.nullness.NonNullConsumer; import com.tterrag.registrate.util.nullness.NonNullConsumer;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.registries.ForgeRegistries;
public class AllMovementBehaviours { public class AllMovementBehaviours {
private static final AttachedRegistry<Block, MovementBehaviour> BLOCK_BEHAVIOURS = new AttachedRegistry<>(ForgeRegistries.BLOCKS); private static final AttachedRegistry<Block, MovementBehaviour> BLOCK_BEHAVIOURS = new AttachedRegistry<>(BuiltInRegistries.BLOCK);
private static final List<BehaviourProvider> GLOBAL_BEHAVIOURS = new ArrayList<>(); private static final List<BehaviourProvider> GLOBAL_BEHAVIOURS = new ArrayList<>();
public static void registerBehaviour(ResourceLocation block, MovementBehaviour behaviour) { public static void registerBehaviour(ResourceLocation block, MovementBehaviour behaviour) {

View file

@ -1,11 +1,6 @@
package com.simibubi.create; package com.simibubi.create;
import static net.minecraftforge.network.NetworkDirection.PLAY_TO_CLIENT; import java.util.Locale;
import static net.minecraftforge.network.NetworkDirection.PLAY_TO_SERVER;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.Supplier;
import com.simibubi.create.compat.computercraft.AttachedComputerPacket; import com.simibubi.create.compat.computercraft.AttachedComputerPacket;
import com.simibubi.create.compat.trainmap.TrainMapSyncPacket; import com.simibubi.create.compat.trainmap.TrainMapSyncPacket;
@ -91,7 +86,8 @@ import com.simibubi.create.content.schematics.packet.SchematicSyncPacket;
import com.simibubi.create.content.schematics.packet.SchematicUploadPacket; import com.simibubi.create.content.schematics.packet.SchematicUploadPacket;
import com.simibubi.create.content.trains.HonkPacket; import com.simibubi.create.content.trains.HonkPacket;
import com.simibubi.create.content.trains.TrainHUDUpdatePacket; import com.simibubi.create.content.trains.TrainHUDUpdatePacket;
import com.simibubi.create.content.trains.entity.TrainPacket; import com.simibubi.create.content.trains.entity.AddTrainPacket;
import com.simibubi.create.content.trains.entity.RemoveTrainPacket;
import com.simibubi.create.content.trains.entity.TrainPromptPacket; import com.simibubi.create.content.trains.entity.TrainPromptPacket;
import com.simibubi.create.content.trains.entity.TrainRelocationPacket; import com.simibubi.create.content.trains.entity.TrainRelocationPacket;
import com.simibubi.create.content.trains.graph.TrackGraphRequestPacket; import com.simibubi.create.content.trains.graph.TrackGraphRequestPacket;
@ -111,153 +107,137 @@ import com.simibubi.create.foundation.gui.menu.ClearMenuPacket;
import com.simibubi.create.foundation.gui.menu.GhostItemSubmitPacket; import com.simibubi.create.foundation.gui.menu.GhostItemSubmitPacket;
import com.simibubi.create.foundation.networking.ISyncPersistentData; import com.simibubi.create.foundation.networking.ISyncPersistentData;
import com.simibubi.create.foundation.networking.LeftClickPacket; import com.simibubi.create.foundation.networking.LeftClickPacket;
import com.simibubi.create.foundation.networking.SimplePacketBase;
import com.simibubi.create.foundation.utility.ServerSpeedProvider; import com.simibubi.create.foundation.utility.ServerSpeedProvider;
import com.simibubi.create.infrastructure.command.HighlightPacket; import com.simibubi.create.infrastructure.command.HighlightPacket;
import com.simibubi.create.infrastructure.command.SimpleCreateActions; import com.simibubi.create.infrastructure.command.SimpleCreateActions;
import com.simibubi.create.infrastructure.debugInfo.ServerDebugInfoPacket; import com.simibubi.create.infrastructure.debugInfo.ServerDebugInfoPacket;
import net.createmod.catnip.net.ClientboundSimpleActionPacket; import net.createmod.catnip.net.base.BasePacketPayload;
import net.minecraft.core.BlockPos; import net.createmod.catnip.net.base.CatnipPacketRegistry;
import net.minecraft.network.FriendlyByteBuf; import net.createmod.catnip.net.packets.ClientboundSimpleActionPacket;
import net.minecraft.resources.ResourceLocation; import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.world.level.Level; import net.minecraft.network.codec.StreamCodec;
import net.minecraftforge.network.NetworkDirection; import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraftforge.network.NetworkEvent.Context;
import net.minecraftforge.network.NetworkRegistry;
import net.minecraftforge.network.PacketDistributor;
import net.minecraftforge.network.PacketDistributor.TargetPoint;
import net.minecraftforge.network.simple.SimpleChannel;
public enum AllPackets {
public enum AllPackets implements BasePacketPayload.PacketTypeProvider {
// Client to Server // Client to Server
CONFIGURE_SCHEMATICANNON(ConfigureSchematicannonPacket.class, ConfigureSchematicannonPacket::new, PLAY_TO_SERVER), CONFIGURE_SCHEMATICANNON(ConfigureSchematicannonPacket.class, ConfigureSchematicannonPacket.STREAM_CODEC),
CONFIGURE_STOCKSWITCH(ConfigureThresholdSwitchPacket.class, ConfigureThresholdSwitchPacket::new, PLAY_TO_SERVER), CONFIGURE_STOCKSWITCH(ConfigureThresholdSwitchPacket.class, ConfigureThresholdSwitchPacket.STREAM_CODEC),
CONFIGURE_SEQUENCER(ConfigureSequencedGearshiftPacket.class, ConfigureSequencedGearshiftPacket::new, CONFIGURE_SEQUENCER(ConfigureSequencedGearshiftPacket.class, ConfigureSequencedGearshiftPacket.STREAM_CODEC),
PLAY_TO_SERVER), PLACE_SCHEMATIC(SchematicPlacePacket.class, SchematicPlacePacket.STREAM_CODEC),
PLACE_SCHEMATIC(SchematicPlacePacket.class, SchematicPlacePacket::new, PLAY_TO_SERVER), UPLOAD_SCHEMATIC(SchematicUploadPacket.class, SchematicUploadPacket.STREAM_CODEC),
UPLOAD_SCHEMATIC(SchematicUploadPacket.class, SchematicUploadPacket::new, PLAY_TO_SERVER), CLEAR_CONTAINER(ClearMenuPacket.class, ClearMenuPacket.STREAM_CODEC),
CLEAR_CONTAINER(ClearMenuPacket.class, ClearMenuPacket::new, PLAY_TO_SERVER), CONFIGURE_FILTER(FilterScreenPacket.class, FilterScreenPacket.STREAM_CODEC),
CONFIGURE_FILTER(FilterScreenPacket.class, FilterScreenPacket::new, PLAY_TO_SERVER), EXTENDO_INTERACT(ExtendoGripInteractionPacket.class, ExtendoGripInteractionPacket.STREAM_CODEC),
EXTENDO_INTERACT(ExtendoGripInteractionPacket.class, ExtendoGripInteractionPacket::new, PLAY_TO_SERVER), CONTRAPTION_INTERACT(ContraptionInteractionPacket.class, ContraptionInteractionPacket.STREAM_CODEC),
CONTRAPTION_INTERACT(ContraptionInteractionPacket.class, ContraptionInteractionPacket::new, PLAY_TO_SERVER), CLIENT_MOTION(ClientMotionPacket.class, ClientMotionPacket.STREAM_CODEC),
CLIENT_MOTION(ClientMotionPacket.class, ClientMotionPacket::new, PLAY_TO_SERVER), PLACE_ARM(ArmPlacementPacket.class, ArmPlacementPacket.STREAM_CODEC),
PLACE_ARM(ArmPlacementPacket.class, ArmPlacementPacket::new, PLAY_TO_SERVER), PLACE_PACKAGE_PORT(PackagePortPlacementPacket.class, PackagePortPlacementPacket.STREAM_CODEC),
PLACE_PACKAGE_PORT(PackagePortPlacementPacket.class, PackagePortPlacementPacket::new, PLAY_TO_SERVER), MINECART_COUPLING_CREATION(CouplingCreationPacket.class, CouplingCreationPacket.STREAM_CODEC),
MINECART_COUPLING_CREATION(CouplingCreationPacket.class, CouplingCreationPacket::new, PLAY_TO_SERVER), INSTANT_SCHEMATIC(InstantSchematicPacket.class, InstantSchematicPacket.STREAM_CODEC),
INSTANT_SCHEMATIC(InstantSchematicPacket.class, InstantSchematicPacket::new, PLAY_TO_SERVER), SYNC_SCHEMATIC(SchematicSyncPacket.class, SchematicSyncPacket.STREAM_CODEC),
SYNC_SCHEMATIC(SchematicSyncPacket.class, SchematicSyncPacket::new, PLAY_TO_SERVER), LEFT_CLICK(LeftClickPacket.class, LeftClickPacket.STREAM_CODEC),
LEFT_CLICK(LeftClickPacket.class, LeftClickPacket::new, PLAY_TO_SERVER), PLACE_EJECTOR(EjectorPlacementPacket.class, EjectorPlacementPacket.STREAM_CODEC),
PLACE_EJECTOR(EjectorPlacementPacket.class, EjectorPlacementPacket::new, PLAY_TO_SERVER), TRIGGER_EJECTOR(EjectorTriggerPacket.class, EjectorTriggerPacket.STREAM_CODEC),
TRIGGER_EJECTOR(EjectorTriggerPacket.class, EjectorTriggerPacket::new, PLAY_TO_SERVER), EJECTOR_ELYTRA(EjectorElytraPacket.class, EjectorElytraPacket.STREAM_CODEC),
EJECTOR_ELYTRA(EjectorElytraPacket.class, EjectorElytraPacket::new, PLAY_TO_SERVER), LINKED_CONTROLLER_INPUT(LinkedControllerInputPacket.class, LinkedControllerInputPacket.STREAM_CODEC),
LINKED_CONTROLLER_INPUT(LinkedControllerInputPacket.class, LinkedControllerInputPacket::new, PLAY_TO_SERVER), LINKED_CONTROLLER_BIND(LinkedControllerBindPacket.class, LinkedControllerBindPacket.STREAM_CODEC),
LINKED_CONTROLLER_BIND(LinkedControllerBindPacket.class, LinkedControllerBindPacket::new, PLAY_TO_SERVER), LINKED_CONTROLLER_USE_LECTERN(LinkedControllerStopLecternPacket.class, LinkedControllerStopLecternPacket.STREAM_CODEC),
LINKED_CONTROLLER_USE_LECTERN(LinkedControllerStopLecternPacket.class, LinkedControllerStopLecternPacket::new, SUBMIT_GHOST_ITEM(GhostItemSubmitPacket.class, GhostItemSubmitPacket.STREAM_CODEC),
PLAY_TO_SERVER), BLUEPRINT_COMPLETE_RECIPE(BlueprintAssignCompleteRecipePacket.class, BlueprintAssignCompleteRecipePacket.STREAM_CODEC),
SUBMIT_GHOST_ITEM(GhostItemSubmitPacket.class, GhostItemSubmitPacket::new, PLAY_TO_SERVER), CONFIGURE_SYMMETRY_WAND(ConfigureSymmetryWandPacket.class, ConfigureSymmetryWandPacket.STREAM_CODEC),
BLUEPRINT_COMPLETE_RECIPE(BlueprintAssignCompleteRecipePacket.class, BlueprintAssignCompleteRecipePacket::new, CONFIGURE_WORLDSHAPER(ConfigureWorldshaperPacket.class, ConfigureWorldshaperPacket.STREAM_CODEC),
PLAY_TO_SERVER), TOOLBOX_EQUIP(ToolboxEquipPacket.class, ToolboxEquipPacket.STREAM_CODEC),
CONFIGURE_SYMMETRY_WAND(ConfigureSymmetryWandPacket.class, ConfigureSymmetryWandPacket::new, PLAY_TO_SERVER), TOOLBOX_DISPOSE_ALL(ToolboxDisposeAllPacket.class, ToolboxDisposeAllPacket.STREAM_CODEC),
CONFIGURE_WORLDSHAPER(ConfigureWorldshaperPacket.class, ConfigureWorldshaperPacket::new, PLAY_TO_SERVER), CONFIGURE_SCHEDULE(ScheduleEditPacket.class, ScheduleEditPacket.STREAM_CODEC),
TOOLBOX_EQUIP(ToolboxEquipPacket.class, ToolboxEquipPacket::new, PLAY_TO_SERVER), CONFIGURE_STATION(StationEditPacket.class, StationEditPacket.STREAM_CODEC),
TOOLBOX_DISPOSE_ALL(ToolboxDisposeAllPacket.class, ToolboxDisposeAllPacket::new, PLAY_TO_SERVER), C_CONFIGURE_TRAIN(TrainEditPacket.Serverbound.class, TrainEditPacket.Serverbound.STREAM_CODEC),
CONFIGURE_SCHEDULE(ScheduleEditPacket.class, ScheduleEditPacket::new, PLAY_TO_SERVER), RELOCATE_TRAIN(TrainRelocationPacket.class, TrainRelocationPacket.STREAM_CODEC),
CONFIGURE_STATION(StationEditPacket.class, StationEditPacket::new, PLAY_TO_SERVER), CONTROLS_INPUT(ControlsInputPacket.class, ControlsInputPacket.STREAM_CODEC),
C_CONFIGURE_TRAIN(TrainEditPacket.class, TrainEditPacket::new, PLAY_TO_SERVER), CONFIGURE_DATA_GATHERER(DisplayLinkConfigurationPacket.class, DisplayLinkConfigurationPacket.STREAM_CODEC),
RELOCATE_TRAIN(TrainRelocationPacket.class, TrainRelocationPacket::new, PLAY_TO_SERVER), DESTROY_CURVED_TRACK(CurvedTrackDestroyPacket.class, CurvedTrackDestroyPacket.STREAM_CODEC),
CONTROLS_INPUT(ControlsInputPacket.class, ControlsInputPacket::new, PLAY_TO_SERVER), SELECT_CURVED_TRACK(CurvedTrackSelectionPacket.class, CurvedTrackSelectionPacket.STREAM_CODEC),
CONFIGURE_DATA_GATHERER(DisplayLinkConfigurationPacket.class, DisplayLinkConfigurationPacket::new, PLAY_TO_SERVER), PLACE_CURVED_TRACK(PlaceExtendedCurvePacket.class, PlaceExtendedCurvePacket.STREAM_CODEC),
DESTROY_CURVED_TRACK(CurvedTrackDestroyPacket.class, CurvedTrackDestroyPacket::new, PLAY_TO_SERVER), GLUE_IN_AREA(SuperGlueSelectionPacket.class, SuperGlueSelectionPacket.STREAM_CODEC),
SELECT_CURVED_TRACK(CurvedTrackSelectionPacket.class, CurvedTrackSelectionPacket::new, PLAY_TO_SERVER), GLUE_REMOVED(SuperGlueRemovalPacket.class, SuperGlueRemovalPacket.STREAM_CODEC),
PLACE_CURVED_TRACK(PlaceExtendedCurvePacket.class, PlaceExtendedCurvePacket::new, PLAY_TO_SERVER), TRAIN_COLLISION(TrainCollisionPacket.class, TrainCollisionPacket.STREAM_CODEC),
GLUE_IN_AREA(SuperGlueSelectionPacket.class, SuperGlueSelectionPacket::new, PLAY_TO_SERVER), C_TRAIN_HUD(TrainHUDUpdatePacket.Serverbound.class, TrainHUDUpdatePacket.Serverbound.STREAM_CODEC),
GLUE_REMOVED(SuperGlueRemovalPacket.class, SuperGlueRemovalPacket::new, PLAY_TO_SERVER), C_TRAIN_HONK(HonkPacket.Serverbound.class, HonkPacket.Serverbound.STREAM_CODEC),
TRAIN_COLLISION(TrainCollisionPacket.class, TrainCollisionPacket::new, PLAY_TO_SERVER), OBSERVER_STRESSOMETER(GaugeObservedPacket.class, GaugeObservedPacket.STREAM_CODEC),
C_TRAIN_HUD(TrainHUDUpdatePacket.Serverbound.class, TrainHUDUpdatePacket.Serverbound::new, PLAY_TO_SERVER), EJECTOR_AWARD(EjectorAwardPacket.class, EjectorAwardPacket.STREAM_CODEC),
C_TRAIN_HONK(HonkPacket.Serverbound.class, HonkPacket.Serverbound::new, PLAY_TO_SERVER), TRACK_GRAPH_REQUEST(TrackGraphRequestPacket.class, TrackGraphRequestPacket.STREAM_CODEC),
OBSERVER_STRESSOMETER(GaugeObservedPacket.class, GaugeObservedPacket::new, PLAY_TO_SERVER), CONFIGURE_ELEVATOR_CONTACT(ElevatorContactEditPacket.class, ElevatorContactEditPacket.STREAM_CODEC),
EJECTOR_AWARD(EjectorAwardPacket.class, EjectorAwardPacket::new, PLAY_TO_SERVER), REQUEST_FLOOR_LIST(ElevatorFloorListPacket.RequestFloorList.class, ElevatorFloorListPacket.RequestFloorList.STREAM_CODEC),
TRACK_GRAPH_REQUEST(TrackGraphRequestPacket.class, TrackGraphRequestPacket::new, PLAY_TO_SERVER), ELEVATOR_SET_FLOOR(ElevatorTargetFloorPacket.class, ElevatorTargetFloorPacket.STREAM_CODEC),
CONFIGURE_ELEVATOR_CONTACT(ElevatorContactEditPacket.class, ElevatorContactEditPacket::new, PLAY_TO_SERVER), VALUE_SETTINGS(ValueSettingsPacket.class, ValueSettingsPacket.STREAM_CODEC),
REQUEST_FLOOR_LIST(ElevatorFloorListPacket.RequestFloorList.class, ElevatorFloorListPacket.RequestFloorList::new, CLIPBOARD_EDIT(ClipboardEditPacket.class, ClipboardEditPacket.STREAM_CODEC),
PLAY_TO_SERVER), CONTRAPTION_COLLIDER_LOCK_REQUEST(ContraptionColliderLockPacketRequest.class, ContraptionColliderLockPacketRequest.STREAM_CODEC),
ELEVATOR_SET_FLOOR(ElevatorTargetFloorPacket.class, ElevatorTargetFloorPacket::new, PLAY_TO_SERVER), RADIAL_WRENCH_MENU_SUBMIT(RadialWrenchMenuSubmitPacket.class, RadialWrenchMenuSubmitPacket.STREAM_CODEC),
VALUE_SETTINGS(ValueSettingsPacket.class, ValueSettingsPacket::new, PLAY_TO_SERVER), LOGISTICS_STOCK_REQUEST(LogisticalStockRequestPacket.class, LogisticalStockRequestPacket.STREAM_CODEC),
CLIPBOARD_EDIT(ClipboardEditPacket.class, ClipboardEditPacket::new, PLAY_TO_SERVER), LOGISTICS_PACKAGE_REQUEST(PackageOrderRequestPacket.class, PackageOrderRequestPacket.STREAM_CODEC),
CONTRAPTION_COLLIDER_LOCK_REQUEST(ContraptionColliderLockPacketRequest.class, CHAIN_CONVEYOR_CONNECT(ChainConveyorConnectionPacket.class, ChainConveyorConnectionPacket.STREAM_CODEC),
ContraptionColliderLockPacketRequest::new, PLAY_TO_SERVER), CHAIN_CONVEYOR_RIDING(ServerboundChainConveyorRidingPacket.class, ServerboundChainConveyorRidingPacket.STREAM_CODEC),
RADIAL_WRENCH_MENU_SUBMIT(RadialWrenchMenuSubmitPacket.class, RadialWrenchMenuSubmitPacket::new, CHAIN_PACKAGE_INTERACTION(ChainPackageInteractionPacket.class, ChainPackageInteractionPacket.STREAM_CODEC),
PLAY_TO_SERVER), PACKAGE_PORT_CONFIGURATION(PackagePortConfigurationPacket.class, PackagePortConfigurationPacket.STREAM_CODEC),
LOGISTICS_STOCK_REQUEST(LogisticalStockRequestPacket.class, LogisticalStockRequestPacket::new, PLAY_TO_SERVER), TRAIN_MAP_REQUEST(TrainMapSyncRequestPacket.class, TrainMapSyncRequestPacket.STREAM_CODEC),
LOGISTICS_PACKAGE_REQUEST(PackageOrderRequestPacket.class, PackageOrderRequestPacket::new, PLAY_TO_SERVER), CONNECT_FACTORY_PANEL(FactoryPanelConnectionPacket.class, FactoryPanelConnectionPacket.STREAM_CODEC),
CHAIN_CONVEYOR_CONNECT(ChainConveyorConnectionPacket.class, ChainConveyorConnectionPacket::new, PLAY_TO_SERVER), CONFIGURE_FACTORY_PANEL(FactoryPanelConfigurationPacket.class, FactoryPanelConfigurationPacket.STREAM_CODEC),
CHAIN_CONVEYOR_RIDING(ServerboundChainConveyorRidingPacket.class, ServerboundChainConveyorRidingPacket::new, PLAY_TO_SERVER), CONFIGURE_REDSTONE_REQUESTER(RedstoneRequesterConfigurationPacket.class, RedstoneRequesterConfigurationPacket.STREAM_CODEC),
CHAIN_PACKAGE_INTERACTION(ChainPackageInteractionPacket.class, ChainPackageInteractionPacket::new, PLAY_TO_SERVER), CONFIGURE_STOCK_KEEPER_CATEGORIES(StockKeeperCategoryEditPacket.class, StockKeeperCategoryEditPacket.STREAM_CODEC),
PACKAGE_PORT_CONFIGURATION(PackagePortConfigurationPacket.class, PackagePortConfigurationPacket::new, PLAY_TO_SERVER), REFUND_STOCK_KEEPER_CATEGORY(StockKeeperCategoryRefundPacket.class, StockKeeperCategoryRefundPacket.STREAM_CODEC),
TRAIN_MAP_REQUEST(TrainMapSyncRequestPacket.class, TrainMapSyncRequestPacket::new, PLAY_TO_SERVER), LOCK_STOCK_KEEPER(StockKeeperLockPacket.class, StockKeeperLockPacket.STREAM_CODEC),
CONNECT_FACTORY_PANEL(FactoryPanelConnectionPacket.class, FactoryPanelConnectionPacket::new, PLAY_TO_SERVER), STOCK_KEEPER_HIDE_CATEGORY(StockKeeperCategoryHidingPacket.class, StockKeeperCategoryHidingPacket.STREAM_CODEC),
CONFIGURE_FACTORY_PANEL(FactoryPanelConfigurationPacket.class, FactoryPanelConfigurationPacket::new, PLAY_TO_SERVER),
CONFIGURE_REDSTONE_REQUESTER(RedstoneRequesterConfigurationPacket.class, RedstoneRequesterConfigurationPacket::new, PLAY_TO_SERVER),
CONFIGURE_STOCK_KEEPER_CATEGORIES(StockKeeperCategoryEditPacket.class, StockKeeperCategoryEditPacket::new, PLAY_TO_SERVER),
REFUND_STOCK_KEEPER_CATEGORY(StockKeeperCategoryRefundPacket.class, StockKeeperCategoryRefundPacket::new, PLAY_TO_SERVER),
LOCK_STOCK_KEEPER(StockKeeperLockPacket.class, StockKeeperLockPacket::new, PLAY_TO_SERVER),
STOCK_KEEPER_HIDE_CATEGORY(StockKeeperCategoryHidingPacket.class, StockKeeperCategoryHidingPacket::new, PLAY_TO_SERVER),
// Server to Client // Server to Client
SYMMETRY_EFFECT(SymmetryEffectPacket.class, SymmetryEffectPacket::new, PLAY_TO_CLIENT), SYMMETRY_EFFECT(SymmetryEffectPacket.class, SymmetryEffectPacket.STREAM_CODEC),
SERVER_SPEED(ServerSpeedProvider.Packet.class, ServerSpeedProvider.Packet::new, PLAY_TO_CLIENT), SERVER_SPEED(ServerSpeedProvider.Packet.class, ServerSpeedProvider.Packet.STREAM_CODEC),
BEAM_EFFECT(ZapperBeamPacket.class, ZapperBeamPacket::new, PLAY_TO_CLIENT), BEAM_EFFECT(ZapperBeamPacket.class, ZapperBeamPacket.STREAM_CODEC),
CONTRAPTION_STALL(ContraptionStallPacket.class, ContraptionStallPacket::new, PLAY_TO_CLIENT), CONTRAPTION_STALL(ContraptionStallPacket.class, ContraptionStallPacket.STREAM_CODEC),
CONTRAPTION_DISASSEMBLE(ContraptionDisassemblyPacket.class, ContraptionDisassemblyPacket::new, PLAY_TO_CLIENT), CONTRAPTION_DISASSEMBLE(ContraptionDisassemblyPacket.class, ContraptionDisassemblyPacket.STREAM_CODEC),
CONTRAPTION_BLOCK_CHANGED(ContraptionBlockChangedPacket.class, ContraptionBlockChangedPacket::new, PLAY_TO_CLIENT), CONTRAPTION_BLOCK_CHANGED(ContraptionBlockChangedPacket.class, ContraptionBlockChangedPacket.STREAM_CODEC),
GLUE_EFFECT(GlueEffectPacket.class, GlueEffectPacket::new, PLAY_TO_CLIENT), GLUE_EFFECT(GlueEffectPacket.class, GlueEffectPacket.STREAM_CODEC),
CONTRAPTION_SEAT_MAPPING(ContraptionSeatMappingPacket.class, ContraptionSeatMappingPacket::new, PLAY_TO_CLIENT), CONTRAPTION_SEAT_MAPPING(ContraptionSeatMappingPacket.class, ContraptionSeatMappingPacket.STREAM_CODEC),
LIMBSWING_UPDATE(LimbSwingUpdatePacket.class, LimbSwingUpdatePacket::new, PLAY_TO_CLIENT), LIMBSWING_UPDATE(LimbSwingUpdatePacket.class, LimbSwingUpdatePacket.STREAM_CODEC),
MINECART_CONTROLLER(MinecartControllerUpdatePacket.class, MinecartControllerUpdatePacket::new, PLAY_TO_CLIENT), MINECART_CONTROLLER(MinecartControllerUpdatePacket.class, MinecartControllerUpdatePacket.STREAM_CODEC),
FLUID_SPLASH(FluidSplashPacket.class, FluidSplashPacket::new, PLAY_TO_CLIENT), FLUID_SPLASH(FluidSplashPacket.class, FluidSplashPacket.STREAM_CODEC),
CONTRAPTION_FLUID(ContraptionFluidPacket.class, ContraptionFluidPacket::new, PLAY_TO_CLIENT), CONTRAPTION_FLUID(ContraptionFluidPacket.class, ContraptionFluidPacket.STREAM_CODEC),
GANTRY_UPDATE(GantryContraptionUpdatePacket.class, GantryContraptionUpdatePacket::new, PLAY_TO_CLIENT), GANTRY_UPDATE(GantryContraptionUpdatePacket.class, GantryContraptionUpdatePacket.STREAM_CODEC),
BLOCK_HIGHLIGHT(HighlightPacket.class, HighlightPacket::new, PLAY_TO_CLIENT), BLOCK_HIGHLIGHT(HighlightPacket.class, HighlightPacket.STREAM_CODEC),
TUNNEL_FLAP(TunnelFlapPacket.class, TunnelFlapPacket::new, PLAY_TO_CLIENT), TUNNEL_FLAP(TunnelFlapPacket.class, TunnelFlapPacket.STREAM_CODEC),
FUNNEL_FLAP(FunnelFlapPacket.class, FunnelFlapPacket::new, PLAY_TO_CLIENT), FUNNEL_FLAP(FunnelFlapPacket.class, FunnelFlapPacket.STREAM_CODEC),
POTATO_CANNON(PotatoCannonPacket.class, PotatoCannonPacket::new, PLAY_TO_CLIENT), POTATO_CANNON(PotatoCannonPacket.class, PotatoCannonPacket.STREAM_CODEC),
SOUL_PULSE(SoulPulseEffectPacket.class, SoulPulseEffectPacket::new, PLAY_TO_CLIENT), SOUL_PULSE(SoulPulseEffectPacket.class, SoulPulseEffectPacket.STREAM_CODEC),
PERSISTENT_DATA(ISyncPersistentData.PersistentDataPacket.class, ISyncPersistentData.PersistentDataPacket::new, PERSISTENT_DATA(ISyncPersistentData.PersistentDataPacket.class, ISyncPersistentData.PersistentDataPacket.STREAM_CODEC),
PLAY_TO_CLIENT), SYNC_POTATO_PROJECTILE_TYPES(PotatoProjectileTypeManager.SyncPacket.class, PotatoProjectileTypeManager.SyncPacket.STREAM_CODEC),
SYNC_POTATO_PROJECTILE_TYPES(PotatoProjectileTypeManager.SyncPacket.class, SYNC_RAIL_GRAPH(TrackGraphSyncPacket.class, TrackGraphSyncPacket.STREAM_CODEC),
PotatoProjectileTypeManager.SyncPacket::new, PLAY_TO_CLIENT), SYNC_EDGE_GROUP(SignalEdgeGroupPacket.class, SignalEdgeGroupPacket.STREAM_CODEC),
SYNC_RAIL_GRAPH(TrackGraphSyncPacket.class, TrackGraphSyncPacket::new, PLAY_TO_CLIENT), ADD_TRAIN(AddTrainPacket.class, AddTrainPacket.STREAM_CODEC),
SYNC_EDGE_GROUP(SignalEdgeGroupPacket.class, SignalEdgeGroupPacket::new, PLAY_TO_CLIENT), REMOVE_TRAIN(RemoveTrainPacket.class, RemoveTrainPacket.STREAM_CODEC),
SYNC_TRAIN(TrainPacket.class, TrainPacket::new, PLAY_TO_CLIENT), REMOVE_TE(RemoveBlockEntityPacket.class, RemoveBlockEntityPacket.STREAM_CODEC),
REMOVE_TE(RemoveBlockEntityPacket.class, RemoveBlockEntityPacket::new, PLAY_TO_CLIENT), S_CONFIGURE_TRAIN(TrainEditReturnPacket.class, TrainEditReturnPacket.STREAM_CODEC),
S_CONFIGURE_TRAIN(TrainEditReturnPacket.class, TrainEditReturnPacket::new, PLAY_TO_CLIENT), CONTROLS_ABORT(ControlsStopControllingPacket.class, ControlsStopControllingPacket.STREAM_CODEC),
CONTROLS_ABORT(ControlsStopControllingPacket.class, ControlsStopControllingPacket::new, PLAY_TO_CLIENT), S_TRAIN_HUD(TrainHUDUpdatePacket.Clientbound.class, TrainHUDUpdatePacket.Clientbound.STREAM_CODEC),
S_TRAIN_HUD(TrainHUDUpdatePacket.class, TrainHUDUpdatePacket::new, PLAY_TO_CLIENT), S_TRAIN_HONK(HonkPacket.Clientbound.class, HonkPacket.Clientbound.STREAM_CODEC),
S_TRAIN_HONK(HonkPacket.class, HonkPacket::new, PLAY_TO_CLIENT), S_TRAIN_PROMPT(TrainPromptPacket.class, TrainPromptPacket.STREAM_CODEC),
S_TRAIN_PROMPT(TrainPromptPacket.class, TrainPromptPacket::new, PLAY_TO_CLIENT), CONTRAPTION_RELOCATION(ContraptionRelocationPacket.class, ContraptionRelocationPacket.STREAM_CODEC),
CONTRAPTION_RELOCATION(ContraptionRelocationPacket.class, ContraptionRelocationPacket::new, PLAY_TO_CLIENT), TRACK_GRAPH_ROLL_CALL(TrackGraphRollCallPacket.class, TrackGraphRollCallPacket.STREAM_CODEC),
TRACK_GRAPH_ROLL_CALL(TrackGraphRollCallPacket.class, TrackGraphRollCallPacket::new, PLAY_TO_CLIENT), S_PLACE_ARM(ArmPlacementPacket.ClientBoundRequest.class, ArmPlacementPacket.ClientBoundRequest.STREAM_CODEC),
S_PLACE_EJECTOR(ArmPlacementPacket.ClientBoundRequest.class, ArmPlacementPacket.ClientBoundRequest::new, S_PLACE_EJECTOR(EjectorPlacementPacket.ClientBoundRequest.class, EjectorPlacementPacket.ClientBoundRequest.STREAM_CODEC),
PLAY_TO_CLIENT), S_PLACE_PACKAGE_PORT(PackagePortPlacementPacket.ClientBoundRequest.class, PackagePortPlacementPacket.ClientBoundRequest.STREAM_CODEC),
S_PLACE_ARM(EjectorPlacementPacket.ClientBoundRequest.class, EjectorPlacementPacket.ClientBoundRequest::new, UPDATE_ELEVATOR_FLOORS(ElevatorFloorListPacket.class, ElevatorFloorListPacket.STREAM_CODEC),
PLAY_TO_CLIENT), CONTRAPTION_ACTOR_TOGGLE(ContraptionDisableActorPacket.class, ContraptionDisableActorPacket.STREAM_CODEC),
S_PLACE_PACKAGE_PORT(PackagePortPlacementPacket.ClientBoundRequest.class, PackagePortPlacementPacket.ClientBoundRequest::new, CONTRAPTION_COLLIDER_LOCK(ContraptionColliderLockPacket.class, ContraptionColliderLockPacket.STREAM_CODEC),
PLAY_TO_CLIENT), ATTACHED_COMPUTER(AttachedComputerPacket.class, AttachedComputerPacket.STREAM_CODEC),
UPDATE_ELEVATOR_FLOORS(ElevatorFloorListPacket.class, ElevatorFloorListPacket::new, PLAY_TO_CLIENT), SERVER_DEBUG_INFO(ServerDebugInfoPacket.class, ServerDebugInfoPacket.STREAM_CODEC),
CONTRAPTION_ACTOR_TOGGLE(ContraptionDisableActorPacket.class, ContraptionDisableActorPacket::new, PLAY_TO_CLIENT), PACKAGE_DESTROYED(PackageDestroyPacket.class, PackageDestroyPacket.STREAM_CODEC),
CONTRAPTION_COLLIDER_LOCK(ContraptionColliderLockPacket.class, ContraptionColliderLockPacket::new, PLAY_TO_CLIENT), LOGISTICS_STOCK_RESPONSE(LogisticalStockResponsePacket.class, LogisticalStockResponsePacket.STREAM_CODEC),
ATTACHED_COMPUTER(AttachedComputerPacket.class, AttachedComputerPacket::new, PLAY_TO_CLIENT), FACTORY_PANEL_EFFECT(FactoryPanelEffectPacket.class, FactoryPanelEffectPacket.STREAM_CODEC),
SERVER_DEBUG_INFO(ServerDebugInfoPacket.class, ServerDebugInfoPacket::new, PLAY_TO_CLIENT), PACKAGER_LINK_EFFECT(PackagerLinkEffectPacket.class, PackagerLinkEffectPacket.STREAM_CODEC),
PACKAGE_DESTROYED(PackageDestroyPacket.class, PackageDestroyPacket::new, PLAY_TO_CLIENT), REDSTONE_REQUESTER_EFFECT(RedstoneRequesterEffectPacket.class, RedstoneRequesterEffectPacket.STREAM_CODEC),
LOGISTICS_STOCK_RESPONSE(LogisticalStockResponsePacket.class, LogisticalStockResponsePacket::new, PLAY_TO_CLIENT), KNOCKBACK(KnockbackPacket.class, KnockbackPacket.STREAM_CODEC),
FACTORY_PANEL_EFFECT(FactoryPanelEffectPacket.class, FactoryPanelEffectPacket::new, PLAY_TO_CLIENT), TRAIN_MAP_SYNC(TrainMapSyncPacket.class, TrainMapSyncPacket.STREAM_CODEC),
PACKAGER_LINK_EFFECT(PackagerLinkEffectPacket.class, PackagerLinkEffectPacket::new, PLAY_TO_CLIENT), CLIENTBOUND_CHAIN_CONVEYOR(ClientboundChainConveyorRidingPacket.class, ClientboundChainConveyorRidingPacket.STREAM_CODEC)
REDSTONE_REQUESTER_EFFECT(RedstoneRequesterEffectPacket.class, RedstoneRequesterEffectPacket::new, PLAY_TO_CLIENT), ;
KNOCKBACK(KnockbackPacket.class, KnockbackPacket::new, PLAY_TO_CLIENT),
TRAIN_MAP_SYNC(TrainMapSyncPacket.class, TrainMapSyncPacket::new, PLAY_TO_CLIENT),
CLIENTBOUND_CHAIN_CONVEYOR(ClientboundChainConveyorRidingPacket.class, ClientboundChainConveyorRidingPacket::new, PLAY_TO_CLIENT);
static { static {
ClientboundSimpleActionPacket.addAction("rainbowDebug", () -> SimpleCreateActions::rainbowDebug); ClientboundSimpleActionPacket.addAction("rainbowDebug", () -> SimpleCreateActions::rainbowDebug);
@ -271,68 +251,27 @@ public enum AllPackets {
ClientboundSimpleActionPacket.addAction("camAngleFunction", () -> SimpleCreateActions::camAngleFunction); ClientboundSimpleActionPacket.addAction("camAngleFunction", () -> SimpleCreateActions::camAngleFunction);
} }
public static final ResourceLocation CHANNEL_NAME = Create.asResource("main"); private final CatnipPacketRegistry.PacketType<?> type;
public static final int NETWORK_VERSION = 3;
public static final String NETWORK_VERSION_STR = String.valueOf(NETWORK_VERSION);
private static SimpleChannel channel;
private PacketType<?> packetType; <T extends BasePacketPayload> AllPackets(Class<T> clazz, StreamCodec<? super RegistryFriendlyByteBuf, T> codec) {
String name = this.name().toLowerCase(Locale.ROOT);
<T extends SimplePacketBase> AllPackets(Class<T> type, Function<FriendlyByteBuf, T> factory, this.type = new CatnipPacketRegistry.PacketType<>(
NetworkDirection direction) { new CustomPacketPayload.Type<>(Create.asResource(name)),
packetType = new PacketType<>(type, factory, direction); clazz, codec
);
} }
public static void registerPackets() { @Override
channel = NetworkRegistry.ChannelBuilder.named(CHANNEL_NAME) @SuppressWarnings("unchecked")
.serverAcceptedVersions(NETWORK_VERSION_STR::equals) public <T extends CustomPacketPayload> CustomPacketPayload.Type<T> getType() {
.clientAcceptedVersions(NETWORK_VERSION_STR::equals) return (CustomPacketPayload.Type<T>) this.type.type();
.networkProtocolVersion(() -> NETWORK_VERSION_STR)
.simpleChannel();
for (AllPackets packet : values())
packet.packetType.register();
} }
public static SimpleChannel getChannel() { public static void register() {
return channel; CatnipPacketRegistry packetRegistry = new CatnipPacketRegistry(Create.ID, 1);
} for (AllPackets packet : AllPackets.values()) {
packetRegistry.registerPacket(packet.type);
public static void sendToNear(Level world, BlockPos pos, int range, Object message) {
getChannel().send(
PacketDistributor.NEAR.with(TargetPoint.p(pos.getX(), pos.getY(), pos.getZ(), range, world.dimension())),
message);
}
private static class PacketType<T extends SimplePacketBase> {
private static int index = 0;
private BiConsumer<T, FriendlyByteBuf> encoder;
private Function<FriendlyByteBuf, T> decoder;
private BiConsumer<T, Supplier<Context>> handler;
private Class<T> type;
private NetworkDirection direction;
private PacketType(Class<T> type, Function<FriendlyByteBuf, T> factory, NetworkDirection direction) {
encoder = T::write;
decoder = factory;
handler = (packet, contextSupplier) -> {
Context context = contextSupplier.get();
if (packet.handle(context)) {
context.setPacketHandled(true);
}
};
this.type = type;
this.direction = direction;
}
private void register() {
getChannel().messageBuilder(type, index++, direction)
.encoder(encoder)
.decoder(decoder)
.consumerNetworkThread(handler)
.add();
} }
packetRegistry.registerAllPackets();
} }
} }

View file

@ -15,16 +15,15 @@ import com.simibubi.create.foundation.particle.ICustomParticleData;
import net.createmod.catnip.utility.lang.Lang; import net.createmod.catnip.utility.lang.Lang;
import net.minecraft.core.particles.ParticleOptions; import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.core.particles.ParticleType; import net.minecraft.core.particles.ParticleType;
import net.minecraftforge.api.distmarker.Dist; import net.minecraft.core.registries.Registries;
import net.minecraftforge.api.distmarker.OnlyIn; import net.neoforged.api.distmarker.Dist;
import net.minecraftforge.client.event.RegisterParticleProvidersEvent; import net.neoforged.api.distmarker.OnlyIn;
import net.minecraftforge.eventbus.api.IEventBus; import net.neoforged.bus.api.IEventBus;
import net.minecraftforge.registries.DeferredRegister; import net.neoforged.neoforge.client.event.RegisterParticleProvidersEvent;
import net.minecraftforge.registries.ForgeRegistries; import net.neoforged.neoforge.registries.DeferredHolder;
import net.minecraftforge.registries.RegistryObject; import net.neoforged.neoforge.registries.DeferredRegister;
public enum AllParticleTypes { public enum AllParticleTypes {
ROTATION_INDICATOR(RotationIndicatorParticleData::new), ROTATION_INDICATOR(RotationIndicatorParticleData::new),
AIR_FLOW(AirFlowParticleData::new), AIR_FLOW(AirFlowParticleData::new),
AIR(AirParticleData::new), AIR(AirParticleData::new),
@ -64,11 +63,11 @@ public enum AllParticleTypes {
} }
private static class ParticleEntry<D extends ParticleOptions> { private static class ParticleEntry<D extends ParticleOptions> {
private static final DeferredRegister<ParticleType<?>> REGISTER = DeferredRegister.create(ForgeRegistries.PARTICLE_TYPES, Create.ID); private static final DeferredRegister<ParticleType<?>> REGISTER = DeferredRegister.create(Registries.PARTICLE_TYPE, Create.ID);
private final String name; private final String name;
private final Supplier<? extends ICustomParticleData<D>> typeFactory; private final Supplier<? extends ICustomParticleData<D>> typeFactory;
private final RegistryObject<ParticleType<D>> object; private final DeferredHolder<ParticleType<?>, ParticleType<D>> object;
public ParticleEntry(String name, Supplier<? extends ICustomParticleData<D>> typeFactory) { public ParticleEntry(String name, Supplier<? extends ICustomParticleData<D>> typeFactory) {
this.name = name; this.name = name;
@ -84,5 +83,4 @@ public enum AllParticleTypes {
} }
} }
} }

View file

@ -4,8 +4,11 @@ import java.util.Optional;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.function.Supplier; import java.util.function.Supplier;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import com.mojang.serialization.Codec;
import com.mojang.serialization.MapCodec;
import com.simibubi.create.compat.jei.ConversionRecipe; import com.simibubi.create.compat.jei.ConversionRecipe;
import com.simibubi.create.content.equipment.sandPaper.SandPaperPolishingRecipe; import com.simibubi.create.content.equipment.sandPaper.SandPaperPolishingRecipe;
import com.simibubi.create.content.equipment.toolbox.ToolboxDyeingRecipe; import com.simibubi.create.content.equipment.toolbox.ToolboxDyeingRecipe;
@ -14,6 +17,7 @@ import com.simibubi.create.content.fluids.transfer.FillingRecipe;
import com.simibubi.create.content.kinetics.crafter.MechanicalCraftingRecipe; import com.simibubi.create.content.kinetics.crafter.MechanicalCraftingRecipe;
import com.simibubi.create.content.kinetics.crusher.CrushingRecipe; import com.simibubi.create.content.kinetics.crusher.CrushingRecipe;
import com.simibubi.create.content.kinetics.deployer.DeployerApplicationRecipe; import com.simibubi.create.content.kinetics.deployer.DeployerApplicationRecipe;
import com.simibubi.create.content.kinetics.deployer.ItemApplicationRecipe;
import com.simibubi.create.content.kinetics.deployer.ManualApplicationRecipe; import com.simibubi.create.content.kinetics.deployer.ManualApplicationRecipe;
import com.simibubi.create.content.kinetics.fan.processing.HauntingRecipe; import com.simibubi.create.content.kinetics.fan.processing.HauntingRecipe;
import com.simibubi.create.content.kinetics.fan.processing.SplashingRecipe; import com.simibubi.create.content.kinetics.fan.processing.SplashingRecipe;
@ -23,27 +27,30 @@ import com.simibubi.create.content.kinetics.mixer.MixingRecipe;
import com.simibubi.create.content.kinetics.press.PressingRecipe; import com.simibubi.create.content.kinetics.press.PressingRecipe;
import com.simibubi.create.content.kinetics.saw.CuttingRecipe; import com.simibubi.create.content.kinetics.saw.CuttingRecipe;
import com.simibubi.create.content.processing.basin.BasinRecipe; import com.simibubi.create.content.processing.basin.BasinRecipe;
import com.simibubi.create.content.processing.recipe.ProcessingRecipe;
import com.simibubi.create.content.processing.recipe.ProcessingRecipeBuilder.ProcessingRecipeFactory; import com.simibubi.create.content.processing.recipe.ProcessingRecipeBuilder.ProcessingRecipeFactory;
import com.simibubi.create.content.processing.recipe.ProcessingRecipeSerializer; import com.simibubi.create.content.processing.recipe.ProcessingRecipeSerializer;
import com.simibubi.create.content.processing.sequenced.SequencedAssemblyRecipeSerializer; import com.simibubi.create.content.processing.sequenced.SequencedAssemblyRecipeSerializer;
import com.simibubi.create.foundation.recipe.IRecipeTypeInfo; import com.simibubi.create.foundation.recipe.IRecipeTypeInfo;
import net.createmod.catnip.utility.lang.Lang; import net.createmod.catnip.utility.lang.Lang;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries; import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.Container; import net.minecraft.util.StringRepresentable;
import net.minecraft.world.item.crafting.Recipe; import net.minecraft.world.item.crafting.Recipe;
import net.minecraft.world.item.crafting.RecipeHolder;
import net.minecraft.world.item.crafting.RecipeInput;
import net.minecraft.world.item.crafting.RecipeSerializer; import net.minecraft.world.item.crafting.RecipeSerializer;
import net.minecraft.world.item.crafting.RecipeType; import net.minecraft.world.item.crafting.RecipeType;
import net.minecraft.world.item.crafting.ShapedRecipe; import net.minecraft.world.item.crafting.ShapedRecipePattern;
import net.minecraft.world.item.crafting.SimpleCraftingRecipeSerializer; import net.minecraft.world.item.crafting.SimpleCraftingRecipeSerializer;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraftforge.eventbus.api.IEventBus; import net.neoforged.bus.api.IEventBus;
import net.minecraftforge.registries.DeferredRegister; import net.neoforged.neoforge.registries.DeferredHolder;
import net.minecraftforge.registries.ForgeRegistries; import net.neoforged.neoforge.registries.DeferredRegister;
import net.minecraftforge.registries.RegistryObject;
public enum AllRecipeTypes implements IRecipeTypeInfo { public enum AllRecipeTypes implements IRecipeTypeInfo, StringRepresentable {
CONVERSION(ConversionRecipe::new), CONVERSION(ConversionRecipe::new),
CRUSHING(CrushingRecipe::new), CRUSHING(CrushingRecipe::new),
@ -66,19 +73,25 @@ public enum AllRecipeTypes implements IRecipeTypeInfo {
TOOLBOX_DYEING(() -> new SimpleCraftingRecipeSerializer<>(ToolboxDyeingRecipe::new), () -> RecipeType.CRAFTING, false); TOOLBOX_DYEING(() -> new SimpleCraftingRecipeSerializer<>(ToolboxDyeingRecipe::new), () -> RecipeType.CRAFTING, false);
public static final Predicate<? super Recipe<?>> CAN_BE_AUTOMATED = r -> !r.getId() public static final Predicate<RecipeHolder<?>> CAN_BE_AUTOMATED = r -> !r.id()
.getPath() .getPath()
.endsWith("_manual_only"); .endsWith("_manual_only");
private final ResourceLocation id; public final ResourceLocation id;
private final RegistryObject<RecipeSerializer<?>> serializerObject; public final Supplier<RecipeSerializer<?>> serializerSupplier;
private final DeferredHolder<RecipeSerializer<?>, RecipeSerializer<?>> serializerObject;
@Nullable @Nullable
private final RegistryObject<RecipeType<?>> typeObject; private final DeferredHolder<RecipeType<?>, RecipeType<?>> typeObject;
private final Supplier<RecipeType<?>> type; private final Supplier<RecipeType<?>> type;
private boolean isProcessingRecipe;
public static final Codec<AllRecipeTypes> CODEC = StringRepresentable.fromEnum(AllRecipeTypes::values);
AllRecipeTypes(Supplier<RecipeSerializer<?>> serializerSupplier, Supplier<RecipeType<?>> typeSupplier, boolean registerType) { AllRecipeTypes(Supplier<RecipeSerializer<?>> serializerSupplier, Supplier<RecipeType<?>> typeSupplier, boolean registerType) {
String name = Lang.asId(name()); String name = Lang.asId(name());
id = Create.asResource(name); id = Create.asResource(name);
this.serializerSupplier = serializerSupplier;
serializerObject = Registers.SERIALIZER_REGISTER.register(name, serializerSupplier); serializerObject = Registers.SERIALIZER_REGISTER.register(name, serializerSupplier);
if (registerType) { if (registerType) {
typeObject = Registers.TYPE_REGISTER.register(name, typeSupplier); typeObject = Registers.TYPE_REGISTER.register(name, typeSupplier);
@ -87,22 +100,26 @@ public enum AllRecipeTypes implements IRecipeTypeInfo {
typeObject = null; typeObject = null;
type = typeSupplier; type = typeSupplier;
} }
isProcessingRecipe = false;
} }
AllRecipeTypes(Supplier<RecipeSerializer<?>> serializerSupplier) { AllRecipeTypes(Supplier<RecipeSerializer<?>> serializerSupplier) {
String name = Lang.asId(name()); String name = Lang.asId(name());
id = Create.asResource(name); id = Create.asResource(name);
this.serializerSupplier = serializerSupplier;
serializerObject = Registers.SERIALIZER_REGISTER.register(name, serializerSupplier); serializerObject = Registers.SERIALIZER_REGISTER.register(name, serializerSupplier);
typeObject = Registers.TYPE_REGISTER.register(name, () -> RecipeType.simple(id)); typeObject = Registers.TYPE_REGISTER.register(name, () -> RecipeType.simple(id));
type = typeObject; type = typeObject;
isProcessingRecipe = false;
} }
AllRecipeTypes(ProcessingRecipeFactory<?> processingFactory) { AllRecipeTypes(ProcessingRecipeFactory<?> processingFactory) {
this(() -> new ProcessingRecipeSerializer<>(processingFactory)); this(() -> new ProcessingRecipeSerializer<>(processingFactory));
isProcessingRecipe = true;
} }
public static void register(IEventBus modEventBus) { public static void register(IEventBus modEventBus) {
ShapedRecipe.setCraftingSize(9, 9); ShapedRecipePattern.setCraftingSize(9, 9);
Registers.SERIALIZER_REGISTER.register(modEventBus); Registers.SERIALIZER_REGISTER.register(modEventBus);
Registers.TYPE_REGISTER.register(modEventBus); Registers.TYPE_REGISTER.register(modEventBus);
} }
@ -120,24 +137,37 @@ public enum AllRecipeTypes implements IRecipeTypeInfo {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public <T extends RecipeType<?>> T getType() { public <I extends RecipeInput, R extends Recipe<I>> RecipeType<R> getType() {
return (T) type.get(); return (RecipeType<R>) type.get();
} }
public <C extends Container, T extends Recipe<C>> Optional<T> find(C inv, Level world) { public <I extends RecipeInput, R extends Recipe<I>> Optional<RecipeHolder<R>> find(I inv, Level world) {
return world.getRecipeManager() return world.getRecipeManager()
.getRecipeFor(getType(), inv, world); .getRecipeFor(getType(), inv, world);
} }
public static boolean shouldIgnoreInAutomation(Recipe<?> recipe) { public static boolean shouldIgnoreInAutomation(RecipeHolder<?> recipe) {
RecipeSerializer<?> serializer = recipe.getSerializer(); RecipeSerializer<?> serializer = recipe.value().getSerializer();
if (serializer != null && AllTags.AllRecipeSerializerTags.AUTOMATION_IGNORE.matches(serializer)) if (serializer != null && AllTags.AllRecipeSerializerTags.AUTOMATION_IGNORE.matches(serializer))
return true; return true;
return !CAN_BE_AUTOMATED.test(recipe); return !CAN_BE_AUTOMATED.test(recipe);
} }
@Override
public @NotNull String getSerializedName() {
return id.toString();
}
public <T extends ProcessingRecipe<?>> MapCodec<T> processingCodec() {
if (!isProcessingRecipe)
throw new AssertionError("AllRecipeTypes#processingCodec called on "+name()+", which is not a processing recipe");
if (this == DEPLOYING || this == ITEM_APPLICATION)
return ItemApplicationRecipe.codec(this);
return ProcessingRecipeSerializer.codec(this);
}
private static class Registers { private static class Registers {
private static final DeferredRegister<RecipeSerializer<?>> SERIALIZER_REGISTER = DeferredRegister.create(ForgeRegistries.RECIPE_SERIALIZERS, Create.ID); private static final DeferredRegister<RecipeSerializer<?>> SERIALIZER_REGISTER = DeferredRegister.create(BuiltInRegistries.RECIPE_SERIALIZER, Create.ID);
private static final DeferredRegister<RecipeType<?>> TYPE_REGISTER = DeferredRegister.create(Registries.RECIPE_TYPE, Create.ID); private static final DeferredRegister<RecipeType<?>> TYPE_REGISTER = DeferredRegister.create(Registries.RECIPE_TYPE, Create.ID);
} }

View file

@ -6,19 +6,18 @@ import com.simibubi.create.content.logistics.item.filter.attribute.ItemAttribute
import net.minecraft.core.Registry; import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceKey;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.neoforged.bus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod; import net.neoforged.fml.common.EventBusSubscriber;
import net.minecraftforge.registries.IForgeRegistry; import net.neoforged.neoforge.registries.NewRegistryEvent;
import net.minecraftforge.registries.NewRegistryEvent; import net.neoforged.neoforge.registries.RegistryBuilder;
import net.minecraftforge.registries.RegistryBuilder;
import java.util.function.Supplier; import java.util.function.Supplier;
@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD) @EventBusSubscriber(bus = EventBusSubscriber.Bus.MOD)
public class AllRegistries { public class AllRegistries {
public static Supplier<IForgeRegistry<ArmInteractionPointType>> ARM_INTERACTION_POINT_TYPES; public static final Registry<ArmInteractionPointType> ARM_INTERACTION_POINT_TYPES = new RegistryBuilder<>(Keys.ARM_INTERACTION_POINT_TYPES).sync(true).create();
public static Supplier<IForgeRegistry<FanProcessingType>> FAN_PROCESSING_TYPES; public static final Registry<FanProcessingType> FAN_PROCESSING_TYPES = new RegistryBuilder<>(Keys.FAN_PROCESSING_TYPES).sync(true).create();
public static Supplier<IForgeRegistry<ItemAttributeType>> ITEM_ATTRIBUTE_TYPES; public static final Registry<ItemAttributeType> ITEM_ATTRIBUTE_TYPES = new RegistryBuilder<>(AllRegistries.Keys.ITEM_ATTRIBUTE_TYPES).sync(true).create();
public static final class Keys { public static final class Keys {
public static final ResourceKey<Registry<ArmInteractionPointType>> ARM_INTERACTION_POINT_TYPES = key("arm_interaction_point_types"); public static final ResourceKey<Registry<ArmInteractionPointType>> ARM_INTERACTION_POINT_TYPES = key("arm_interaction_point_types");
@ -32,16 +31,8 @@ public class AllRegistries {
@SubscribeEvent @SubscribeEvent
public static void registerRegistries(NewRegistryEvent event) { public static void registerRegistries(NewRegistryEvent event) {
ARM_INTERACTION_POINT_TYPES = event.create(new RegistryBuilder<ArmInteractionPointType>() event.register(AllRegistries.ARM_INTERACTION_POINT_TYPES);
.setName(Keys.ARM_INTERACTION_POINT_TYPES.location()) event.register(AllRegistries.FAN_PROCESSING_TYPES);
.disableSaving()); event.register(AllRegistries.ITEM_ATTRIBUTE_TYPES);
FAN_PROCESSING_TYPES = event.create(new RegistryBuilder<FanProcessingType>()
.setName(Keys.FAN_PROCESSING_TYPES.location())
.disableSaving());
ITEM_ATTRIBUTE_TYPES = event.create(new RegistryBuilder<ItemAttributeType>()
.setName(Keys.ITEM_ATTRIBUTE_TYPES.location())
.disableSaving());
} }
} }

View file

@ -27,24 +27,21 @@ import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import net.minecraftforge.registries.ForgeRegistries; import net.neoforged.neoforge.registries.DeferredHolder;
import net.minecraftforge.registries.RegisterEvent; import net.neoforged.neoforge.registries.RegisterEvent;
import net.minecraftforge.registries.RegistryObject;
//@EventBusSubscriber(bus = Bus.FORGE)
public class AllSoundEvents { public class AllSoundEvents {
public static final Map<ResourceLocation, SoundEntry> ALL = new HashMap<>(); public static final Map<ResourceLocation, SoundEntry> ALL = new HashMap<>();
public static final SoundEntry public static final SoundEntry
SCHEMATICANNON_LAUNCH_BLOCK = create("schematicannon_launch_block").subtitle("Schematicannon fires")
SCHEMATICANNON_LAUNCH_BLOCK = create("schematicannon_launch_block").subtitle("Schematicannon fires") .playExisting(SoundEvents.GENERIC_EXPLODE.value(), .1f, 1.1f)
.playExisting(SoundEvents.GENERIC_EXPLODE, .1f, 1.1f) .category(SoundSource.BLOCKS)
.category(SoundSource.BLOCKS) .build(),
.build(),
SCHEMATICANNON_FINISH = create("schematicannon_finish").subtitle("Schematicannon dings") SCHEMATICANNON_FINISH = create("schematicannon_finish").subtitle("Schematicannon dings")
.playExisting(SoundEvents.NOTE_BLOCK_BELL, 1, .7f) .playExisting(SoundEvents.NOTE_BLOCK_BELL::value, 1, .7f)
.category(SoundSource.BLOCKS) .category(SoundSource.BLOCKS)
.build(), .build(),
@ -112,12 +109,12 @@ public class AllSoundEvents {
.build(), .build(),
SCROLL_VALUE = create("scroll_value").subtitle("Scroll-input clicks") SCROLL_VALUE = create("scroll_value").subtitle("Scroll-input clicks")
.playExisting(SoundEvents.NOTE_BLOCK_HAT, .124f, 1f) .playExisting(SoundEvents.NOTE_BLOCK_HAT::value, .124f, 1f)
.category(SoundSource.PLAYERS) .category(SoundSource.PLAYERS)
.build(), .build(),
CONFIRM = create("confirm").subtitle("Affirmative ding") CONFIRM = create("confirm").subtitle("Affirmative ding")
.playExisting(SoundEvents.NOTE_BLOCK_BELL, 0.5f, 0.8f) .playExisting(SoundEvents.NOTE_BLOCK_BELL::value, 0.5f, 0.8f)
.category(SoundSource.PLAYERS) .category(SoundSource.PLAYERS)
.build(), .build(),
@ -126,7 +123,7 @@ public class AllSoundEvents {
.build(), .build(),
DENY = create("deny").subtitle("Declining boop") DENY = create("deny").subtitle("Declining boop")
.playExisting(SoundEvents.NOTE_BLOCK_BASS, 1f, 0.5f) .playExisting(SoundEvents.NOTE_BLOCK_BASS::value, 1f, 0.5f)
.category(SoundSource.PLAYERS) .category(SoundSource.PLAYERS)
.build(), .build(),
@ -222,7 +219,7 @@ public class AllSoundEvents {
.build(), .build(),
COPPER_ARMOR_EQUIP = create("copper_armor_equip").subtitle("Diving equipment clinks") COPPER_ARMOR_EQUIP = create("copper_armor_equip").subtitle("Diving equipment clinks")
.playExisting(SoundEvents.ARMOR_EQUIP_GOLD, 1f, 1f) .playExisting(SoundEvents.ARMOR_EQUIP_GOLD.value(), 1f, 1f)
.category(SoundSource.PLAYERS) .category(SoundSource.PLAYERS)
.build(), .build(),
@ -466,8 +463,7 @@ public class AllSoundEvents {
} }
public record ConfiguredSoundEvent(Supplier<SoundEvent> event, float volume, float pitch) { public record ConfiguredSoundEvent(Supplier<SoundEvent> event, float volume, float pitch) {}
}
public static class SoundEntryBuilder { public static class SoundEntryBuilder {
@ -527,7 +523,7 @@ public class AllSoundEvents {
} }
public SoundEntryBuilder playExisting(Holder<SoundEvent> event) { public SoundEntryBuilder playExisting(Holder<SoundEvent> event) {
return playExisting(event::get, 1, 1); return playExisting(event::value, 1, 1);
} }
public SoundEntry build() { public SoundEntry build() {
@ -560,6 +556,8 @@ public class AllSoundEvents {
public abstract void write(JsonObject json); public abstract void write(JsonObject json);
public abstract Holder<SoundEvent> getMainEventHolder();
public abstract SoundEvent getMainEvent(); public abstract SoundEvent getMainEvent();
public String getSubtitleKey() { public String getSubtitleKey() {
@ -638,7 +636,7 @@ public class AllSoundEvents {
for (int i = 0; i < wrappedEvents.size(); i++) { for (int i = 0; i < wrappedEvents.size(); i++) {
ConfiguredSoundEvent wrapped = wrappedEvents.get(i); ConfiguredSoundEvent wrapped = wrappedEvents.get(i);
ResourceLocation location = getIdOf(i); ResourceLocation location = getIdOf(i);
RegistryObject<SoundEvent> event = RegistryObject.create(location, ForgeRegistries.SOUND_EVENTS); DeferredHolder<SoundEvent, SoundEvent> event = DeferredHolder.create(Registries.SOUND_EVENT, location);
compiledEvents.add(new CompiledSoundEvent(event, wrapped.volume(), wrapped.pitch())); compiledEvents.add(new CompiledSoundEvent(event, wrapped.volume(), wrapped.pitch()));
} }
} }
@ -651,14 +649,18 @@ public class AllSoundEvents {
} }
} }
@Override
public Holder<SoundEvent> getMainEventHolder() {
return compiledEvents.getFirst().event();
}
@Override @Override
public SoundEvent getMainEvent() { public SoundEvent getMainEvent() {
return compiledEvents.get(0) return compiledEvents.getFirst().event().get();
.event().get();
} }
protected ResourceLocation getIdOf(int i) { protected ResourceLocation getIdOf(int i) {
return new ResourceLocation(id.getNamespace(), i == 0 ? id.getPath() : id.getPath() + "_compounded_" + i); return ResourceLocation.fromNamespaceAndPath(id.getNamespace(), i == 0 ? id.getPath() : id.getPath() + "_compounded_" + i);
} }
@Override @Override
@ -699,7 +701,7 @@ public class AllSoundEvents {
} }
} }
private record CompiledSoundEvent(RegistryObject<SoundEvent> event, float volume, float pitch) { private record CompiledSoundEvent(DeferredHolder<SoundEvent, SoundEvent> event, float volume, float pitch) {
} }
} }
@ -707,7 +709,7 @@ public class AllSoundEvents {
private static class CustomSoundEntry extends SoundEntry { private static class CustomSoundEntry extends SoundEntry {
protected List<ResourceLocation> variants; protected List<ResourceLocation> variants;
protected RegistryObject<SoundEvent> event; protected DeferredHolder<SoundEvent, SoundEvent> event;
public CustomSoundEntry(ResourceLocation id, List<ResourceLocation> variants, String subtitle, public CustomSoundEntry(ResourceLocation id, List<ResourceLocation> variants, String subtitle,
SoundSource category, int attenuationDistance) { SoundSource category, int attenuationDistance) {
@ -717,7 +719,7 @@ public class AllSoundEvents {
@Override @Override
public void prepare() { public void prepare() {
event = RegistryObject.create(id, ForgeRegistries.SOUND_EVENTS); event = DeferredHolder.create(Registries.SOUND_EVENT, id);
} }
@Override @Override
@ -726,6 +728,11 @@ public class AllSoundEvents {
helper.register(location, SoundEvent.createVariableRangeEvent(location)); helper.register(location, SoundEvent.createVariableRangeEvent(location));
} }
@Override
public Holder<SoundEvent> getMainEventHolder() {
return event;
}
@Override @Override
public SoundEvent getMainEvent() { public SoundEvent getMainEvent() {
return event.get(); return event.get();

View file

@ -4,14 +4,14 @@ import com.simibubi.create.content.schematics.SchematicProcessor;
import net.minecraft.core.registries.Registries; import net.minecraft.core.registries.Registries;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProcessorType; import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProcessorType;
import net.minecraftforge.eventbus.api.IEventBus; import net.neoforged.bus.api.IEventBus;
import net.minecraftforge.registries.DeferredRegister; import net.neoforged.neoforge.registries.DeferredHolder;
import net.minecraftforge.registries.RegistryObject; import net.neoforged.neoforge.registries.DeferredRegister;
public class AllStructureProcessorTypes { public class AllStructureProcessorTypes {
private static final DeferredRegister<StructureProcessorType<?>> REGISTER = DeferredRegister.create(Registries.STRUCTURE_PROCESSOR, Create.ID); private static final DeferredRegister<StructureProcessorType<?>> REGISTER = DeferredRegister.create(Registries.STRUCTURE_PROCESSOR, Create.ID);
public static final RegistryObject<StructureProcessorType<SchematicProcessor>> SCHEMATIC = REGISTER.register("schematic", () -> () -> SchematicProcessor.CODEC); public static final DeferredHolder<StructureProcessorType<?>, StructureProcessorType<SchematicProcessor>> SCHEMATIC = REGISTER.register("schematic", () -> () -> SchematicProcessor.CODEC);
public static void register(IEventBus modEventBus) { public static void register(IEventBus modEventBus) {
REGISTER.register(modEventBus); REGISTER.register(modEventBus);

View file

@ -1,15 +1,17 @@
package com.simibubi.create; package com.simibubi.create;
import static com.simibubi.create.AllTags.NameSpace.COMMON;
import static com.simibubi.create.AllTags.NameSpace.CURIOS; import static com.simibubi.create.AllTags.NameSpace.CURIOS;
import static com.simibubi.create.AllTags.NameSpace.FORGE;
import static com.simibubi.create.AllTags.NameSpace.MOD; import static com.simibubi.create.AllTags.NameSpace.MOD;
import static com.simibubi.create.AllTags.NameSpace.QUARK; import static com.simibubi.create.AllTags.NameSpace.QUARK;
import static com.simibubi.create.AllTags.NameSpace.TIC; import static com.simibubi.create.AllTags.NameSpace.TIC;
import java.util.Collections;
import net.createmod.catnip.utility.lang.Lang; import net.createmod.catnip.utility.lang.Lang;
import net.minecraft.core.Registry;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries; import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.BlockTags; import net.minecraft.tags.BlockTags;
import net.minecraft.tags.FluidTags; import net.minecraft.tags.FluidTags;
@ -25,36 +27,32 @@ import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid; import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.level.material.FluidState; import net.minecraft.world.level.material.FluidState;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.IForgeRegistry;
public class AllTags { public class AllTags {
public static <T> TagKey<T> optionalTag(IForgeRegistry<T> registry, public static <T> TagKey<T> optionalTag(Registry<T> registry, ResourceLocation id) {
ResourceLocation id) { return TagKey.create(registry.key(), id);
return registry.tags()
.createOptionalTagKey(id, Collections.emptySet());
} }
public static <T> TagKey<T> forgeTag(IForgeRegistry<T> registry, String path) { public static <T> TagKey<T> commonTag(Registry<T> registry, String path) {
return optionalTag(registry, new ResourceLocation("forge", path)); return optionalTag(registry, ResourceLocation.fromNamespaceAndPath("c", path));
} }
public static TagKey<Block> forgeBlockTag(String path) { public static TagKey<Block> commonBlockTag(String path) {
return forgeTag(ForgeRegistries.BLOCKS, path); return commonTag(BuiltInRegistries.BLOCK, path);
} }
public static TagKey<Item> forgeItemTag(String path) { public static TagKey<Item> commonItemTag(String path) {
return forgeTag(ForgeRegistries.ITEMS, path); return commonTag(BuiltInRegistries.ITEM, path);
} }
public static TagKey<Fluid> forgeFluidTag(String path) { public static TagKey<Fluid> commonFluidTag(String path) {
return forgeTag(ForgeRegistries.FLUIDS, path); return commonTag(BuiltInRegistries.FLUID, path);
} }
public enum NameSpace { public enum NameSpace {
MOD(Create.ID, false, true), MOD(Create.ID, false, true),
FORGE("forge"), COMMON("c"),
TIC("tconstruct"), TIC("tconstruct"),
QUARK("quark"), QUARK("quark"),
GS("galosphere"), GS("galosphere"),
@ -108,8 +106,7 @@ public class AllTags {
CORALS, CORALS,
RELOCATION_NOT_SUPPORTED(FORGE), RELOCATION_NOT_SUPPORTED(COMMON),
WG_STONE(FORGE),
SLIMY_LOGS(TIC), SLIMY_LOGS(TIC),
NON_DOUBLE_DOOR(QUARK), NON_DOUBLE_DOOR(QUARK),
@ -136,9 +133,9 @@ public class AllTags {
} }
AllBlockTags(NameSpace namespace, String path, boolean optional, boolean alwaysDatagen) { AllBlockTags(NameSpace namespace, String path, boolean optional, boolean alwaysDatagen) {
ResourceLocation id = new ResourceLocation(namespace.id, path == null ? Lang.asId(name()) : path); ResourceLocation id = ResourceLocation.fromNamespaceAndPath(namespace.id, path == null ? Lang.asId(name()) : path);
if (optional) { if (optional) {
tag = optionalTag(ForgeRegistries.BLOCKS, id); tag = optionalTag(BuiltInRegistries.BLOCK, id);
} else { } else {
tag = BlockTags.create(id); tag = BlockTags.create(id);
} }
@ -172,8 +169,6 @@ public class AllTags {
CREATE_INGOTS, CREATE_INGOTS,
CRUSHED_RAW_MATERIALS, CRUSHED_RAW_MATERIALS,
DEPLOYABLE_DRINK, DEPLOYABLE_DRINK,
MODDED_STRIPPED_LOGS,
MODDED_STRIPPED_WOOD,
PRESSURIZED_AIR_SOURCES, PRESSURIZED_AIR_SOURCES,
SANDPAPER, SANDPAPER,
SEATS, SEATS,
@ -187,14 +182,10 @@ public class AllTags {
TRACKS, TRACKS,
UPRIGHT_ON_BELT, UPRIGHT_ON_BELT,
VALVE_HANDLES, VALVE_HANDLES,
VANILLA_STRIPPED_LOGS,
VANILLA_STRIPPED_WOOD,
STRIPPED_LOGS(FORGE), PLATES(COMMON),
STRIPPED_WOOD(FORGE), OBSIDIAN_DUST(COMMON,"dusts/obsidian"),
PLATES(FORGE), WRENCH(COMMON, "tools/wrench"),
OBSIDIAN_DUST(FORGE,"dusts/obsidian"),
WRENCH(FORGE, "tools/wrench"),
ALLURITE(MOD,"stone_types/galosphere/allurite"), ALLURITE(MOD,"stone_types/galosphere/allurite"),
AMETHYST(MOD,"stone_types/galosphere/amethyst"), AMETHYST(MOD,"stone_types/galosphere/amethyst"),
@ -225,9 +216,9 @@ public class AllTags {
} }
AllItemTags(NameSpace namespace, String path, boolean optional, boolean alwaysDatagen) { AllItemTags(NameSpace namespace, String path, boolean optional, boolean alwaysDatagen) {
ResourceLocation id = new ResourceLocation(namespace.id, path == null ? Lang.asId(name()) : path); ResourceLocation id = ResourceLocation.fromNamespaceAndPath(namespace.id, path == null ? Lang.asId(name()) : path);
if (optional) { if (optional) {
tag = optionalTag(ForgeRegistries.ITEMS, id); tag = optionalTag(BuiltInRegistries.ITEM, id);
} else { } else {
tag = ItemTags.create(id); tag = ItemTags.create(id);
} }
@ -257,8 +248,6 @@ public class AllTags {
FAN_PROCESSING_CATALYSTS_SMOKING(MOD, "fan_processing_catalysts/smoking"), FAN_PROCESSING_CATALYSTS_SMOKING(MOD, "fan_processing_catalysts/smoking"),
FAN_PROCESSING_CATALYSTS_SPLASHING(MOD, "fan_processing_catalysts/splashing"), FAN_PROCESSING_CATALYSTS_SPLASHING(MOD, "fan_processing_catalysts/splashing"),
HONEY(FORGE)
; ;
public final TagKey<Fluid> tag; public final TagKey<Fluid> tag;
@ -281,9 +270,9 @@ public class AllTags {
} }
AllFluidTags(NameSpace namespace, String path, boolean optional, boolean alwaysDatagen) { AllFluidTags(NameSpace namespace, String path, boolean optional, boolean alwaysDatagen) {
ResourceLocation id = new ResourceLocation(namespace.id, path == null ? Lang.asId(name()) : path); ResourceLocation id = ResourceLocation.fromNamespaceAndPath(namespace.id, path == null ? Lang.asId(name()) : path);
if (optional) { if (optional) {
tag = optionalTag(ForgeRegistries.FLUIDS, id); tag = optionalTag(BuiltInRegistries.FLUID, id);
} else { } else {
tag = FluidTags.create(id); tag = FluidTags.create(id);
} }
@ -330,9 +319,9 @@ public class AllTags {
} }
AllEntityTags(NameSpace namespace, String path, boolean optional, boolean alwaysDatagen) { AllEntityTags(NameSpace namespace, String path, boolean optional, boolean alwaysDatagen) {
ResourceLocation id = new ResourceLocation(namespace.id, path == null ? Lang.asId(name()) : path); ResourceLocation id = ResourceLocation.fromNamespaceAndPath(namespace.id, path == null ? Lang.asId(name()) : path);
if (optional) { if (optional) {
tag = optionalTag(ForgeRegistries.ENTITY_TYPES, id); tag = optionalTag(BuiltInRegistries.ENTITY_TYPE, id);
} else { } else {
tag = TagKey.create(Registries.ENTITY_TYPE, id); tag = TagKey.create(Registries.ENTITY_TYPE, id);
} }
@ -377,9 +366,9 @@ public class AllTags {
} }
AllRecipeSerializerTags(NameSpace namespace, String path, boolean optional, boolean alwaysDatagen) { AllRecipeSerializerTags(NameSpace namespace, String path, boolean optional, boolean alwaysDatagen) {
ResourceLocation id = new ResourceLocation(namespace.id, path == null ? Lang.asId(name()) : path); ResourceLocation id = ResourceLocation.fromNamespaceAndPath(namespace.id, path == null ? Lang.asId(name()) : path);
if (optional) { if (optional) {
tag = optionalTag(ForgeRegistries.RECIPE_SERIALIZERS, id); tag = optionalTag(BuiltInRegistries.RECIPE_SERIALIZER, id);
} else { } else {
tag = TagKey.create(Registries.RECIPE_SERIALIZER, id); tag = TagKey.create(Registries.RECIPE_SERIALIZER, id);
} }
@ -387,7 +376,8 @@ public class AllTags {
} }
public boolean matches(RecipeSerializer<?> recipeSerializer) { public boolean matches(RecipeSerializer<?> recipeSerializer) {
return ForgeRegistries.RECIPE_SERIALIZERS.getHolder(recipeSerializer).orElseThrow().is(tag); ResourceKey<RecipeSerializer<?>> key = BuiltInRegistries.RECIPE_SERIALIZER.getResourceKey(recipeSerializer).orElseThrow();
return BuiltInRegistries.RECIPE_SERIALIZER.getHolder(key).orElseThrow().is(tag);
} }
private static void init() {} private static void init() {}

View file

@ -4,8 +4,6 @@ import java.util.Random;
import org.slf4j.Logger; import org.slf4j.Logger;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.mojang.logging.LogUtils; import com.mojang.logging.LogUtils;
import com.simibubi.create.api.behaviour.BlockSpoutingBehaviour; import com.simibubi.create.api.behaviour.BlockSpoutingBehaviour;
import com.simibubi.create.compat.Mods; import com.simibubi.create.compat.Mods;
@ -13,6 +11,7 @@ import com.simibubi.create.compat.computercraft.ComputerCraftProxy;
import com.simibubi.create.compat.curios.Curios; import com.simibubi.create.compat.curios.Curios;
import com.simibubi.create.content.contraptions.ContraptionMovementSetting; import com.simibubi.create.content.contraptions.ContraptionMovementSetting;
import com.simibubi.create.content.decoration.palettes.AllPaletteBlocks; import com.simibubi.create.content.decoration.palettes.AllPaletteBlocks;
import com.simibubi.create.content.equipment.armor.AllArmorMaterials;
import com.simibubi.create.content.equipment.potatoCannon.BuiltinPotatoProjectileTypes; import com.simibubi.create.content.equipment.potatoCannon.BuiltinPotatoProjectileTypes;
import com.simibubi.create.content.fluids.tank.BoilerHeaters; import com.simibubi.create.content.fluids.tank.BoilerHeaters;
import com.simibubi.create.content.kinetics.TorquePropagator; import com.simibubi.create.content.kinetics.TorquePropagator;
@ -28,11 +27,11 @@ import com.simibubi.create.content.trains.bogey.BogeySizes;
import com.simibubi.create.content.trains.track.AllPortalTracks; import com.simibubi.create.content.trains.track.AllPortalTracks;
import com.simibubi.create.foundation.advancement.AllAdvancements; import com.simibubi.create.foundation.advancement.AllAdvancements;
import com.simibubi.create.foundation.advancement.AllTriggers; import com.simibubi.create.foundation.advancement.AllTriggers;
import com.simibubi.create.foundation.block.CopperRegistries;
import com.simibubi.create.foundation.data.CreateRegistrate; import com.simibubi.create.foundation.data.CreateRegistrate;
import com.simibubi.create.foundation.item.ItemDescription; import com.simibubi.create.foundation.item.ItemDescription;
import com.simibubi.create.foundation.item.KineticStats; import com.simibubi.create.foundation.item.KineticStats;
import com.simibubi.create.foundation.item.TooltipModifier; import com.simibubi.create.foundation.item.TooltipModifier;
import com.simibubi.create.foundation.recipe.AllIngredients;
import com.simibubi.create.foundation.utility.AttachedRegistry; import com.simibubi.create.foundation.utility.AttachedRegistry;
import com.simibubi.create.foundation.utility.CreateNBTProcessors; import com.simibubi.create.foundation.utility.CreateNBTProcessors;
import com.simibubi.create.infrastructure.command.ServerLagger; import com.simibubi.create.infrastructure.command.ServerLagger;
@ -43,21 +42,20 @@ import com.simibubi.create.infrastructure.worldgen.AllPlacementModifiers;
import net.createmod.catnip.utility.FontHelper; import net.createmod.catnip.utility.FontHelper;
import net.createmod.catnip.utility.lang.LangBuilder; import net.createmod.catnip.utility.lang.LangBuilder;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.item.CreativeModeTab; import net.minecraft.world.item.CreativeModeTab;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraftforge.api.distmarker.Dist; import net.neoforged.bus.api.EventPriority;
import net.minecraftforge.common.ForgeMod; import net.neoforged.bus.api.IEventBus;
import net.minecraftforge.common.MinecraftForge; import net.neoforged.fml.ModContainer;
import net.minecraftforge.eventbus.api.EventPriority; import net.neoforged.fml.ModLoadingContext;
import net.minecraftforge.eventbus.api.IEventBus; import net.neoforged.fml.common.Mod;
import net.minecraftforge.fml.DistExecutor; import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.ModLoadingContext; import net.neoforged.neoforge.common.NeoForgeMod;
import net.minecraftforge.fml.common.Mod; import net.neoforged.neoforge.registries.RegisterEvent;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
@Mod(Create.ID) @Mod(Create.ID)
public class Create { public class Create {
@ -68,10 +66,6 @@ public class Create {
public static final Logger LOGGER = LogUtils.getLogger(); public static final Logger LOGGER = LogUtils.getLogger();
public static final Gson GSON = new GsonBuilder().setPrettyPrinting()
.disableHtmlEscaping()
.create();
/** Use the {@link Random} of a local {@link Level} or {@link Entity} or create one */ /** Use the {@link Random} of a local {@link Level} or {@link Entity} or create one */
@Deprecated @Deprecated
public static final Random RANDOM = new Random(); public static final Random RANDOM = new Random();
@ -97,22 +91,19 @@ public class Create {
public static final GlobalLogisticsManager LOGISTICS = new GlobalLogisticsManager(); public static final GlobalLogisticsManager LOGISTICS = new GlobalLogisticsManager();
public static final ServerLagger LAGGER = new ServerLagger(); public static final ServerLagger LAGGER = new ServerLagger();
public Create() { public Create(IEventBus eventBus, ModContainer modContainer) {
onCtor(); onCtor(eventBus, modContainer);
} }
public static void onCtor() { public static void onCtor(IEventBus modEventBus, ModContainer modContainer) {
ModLoadingContext modLoadingContext = ModLoadingContext.get(); ModLoadingContext modLoadingContext = ModLoadingContext.get();
IEventBus modEventBus = FMLJavaModLoadingContext.get()
.getModEventBus();
IEventBus forgeEventBus = MinecraftForge.EVENT_BUS;
REGISTRATE.registerEventListeners(modEventBus); REGISTRATE.registerEventListeners(modEventBus);
AllSoundEvents.prepare(); AllSoundEvents.prepare();
AllTags.init(); AllTags.init();
AllCreativeModeTabs.register(modEventBus); AllCreativeModeTabs.register(modEventBus);
AllArmorMaterials.register(modEventBus);
AllBlocks.register(); AllBlocks.register();
AllItems.register(); AllItems.register();
AllFluids.register(); AllFluids.register();
@ -120,16 +111,20 @@ public class Create {
AllMenuTypes.register(); AllMenuTypes.register();
AllEntityTypes.register(); AllEntityTypes.register();
AllBlockEntityTypes.register(); AllBlockEntityTypes.register();
AllEnchantments.register();
AllRecipeTypes.register(modEventBus); AllRecipeTypes.register(modEventBus);
AllParticleTypes.register(modEventBus); AllParticleTypes.register(modEventBus);
AllStructureProcessorTypes.register(modEventBus); AllStructureProcessorTypes.register(modEventBus);
AllEntityDataSerializers.register(modEventBus); AllEntityDataSerializers.register(modEventBus);
AllPackets.registerPackets();
AllFeatures.register(modEventBus); AllFeatures.register(modEventBus);
AllPlacementModifiers.register(modEventBus); AllPlacementModifiers.register(modEventBus);
AllIngredients.register(modEventBus);
AllAttachmentTypes.register(modEventBus);
AllDataComponents.register(modEventBus);
AllMapDecorationTypes.register(modEventBus);
AllConfigs.register(modLoadingContext); AllConfigs.register(modLoadingContext, modContainer);
AllPackets.register();
AllArmInteractionPointTypes.register(modEventBus); AllArmInteractionPointTypes.register(modEventBus);
AllFanProcessingTypes.register(modEventBus); AllFanProcessingTypes.register(modEventBus);
@ -148,18 +143,16 @@ public class Create {
ComputerCraftProxy.register(); ComputerCraftProxy.register();
ForgeMod.enableMilkFluid(); NeoForgeMod.enableMilkFluid();
CopperRegistries.inject();
modEventBus.addListener(Create::init); modEventBus.addListener(Create::init);
modEventBus.addListener(Create::registerAdvancements);
modEventBus.addListener(AllEntityTypes::registerEntityAttributes); modEventBus.addListener(AllEntityTypes::registerEntityAttributes);
modEventBus.addListener(EventPriority.LOWEST, CreateDatagen::gatherData); modEventBus.addListener(EventPriority.LOWEST, CreateDatagen::gatherData);
modEventBus.addListener(AllSoundEvents::register); modEventBus.addListener(AllSoundEvents::register);
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> CreateClient.onCtorClient(modEventBus, forgeEventBus));
// FIXME: this is not thread-safe // FIXME: this is not thread-safe
Mods.CURIOS.executeIfInstalled(() -> () -> Curios.init(modEventBus, forgeEventBus)); Mods.CURIOS.executeIfInstalled(() -> () -> Curios.init(modEventBus));
} }
public static void init(final FMLCommonSetupEvent event) { public static void init(final FMLCommonSetupEvent event) {
@ -175,9 +168,14 @@ public class Create {
// -- // --
AttachedRegistry.unwrapAll(); AttachedRegistry.unwrapAll();
});
}
public static void registerAdvancements(final RegisterEvent event) {
if (event.getRegistry() == BuiltInRegistries.TRIGGER_TYPES) {
AllAdvancements.register(); AllAdvancements.register();
AllTriggers.register(); AllTriggers.register();
}); }
} }
public static LangBuilder lang() { public static LangBuilder lang() {
@ -185,7 +183,7 @@ public class Create {
} }
public static ResourceLocation asResource(String path) { public static ResourceLocation asResource(String path) {
return new ResourceLocation(ID, path); return ResourceLocation.fromNamespaceAndPath(ID, path);
} }
} }

View file

@ -40,9 +40,13 @@ import net.minecraft.network.chat.ClickEvent;
import net.minecraft.network.chat.ComponentUtils; import net.minecraft.network.chat.ComponentUtils;
import net.minecraft.network.chat.HoverEvent; import net.minecraft.network.chat.HoverEvent;
import net.minecraft.network.chat.MutableComponent; import net.minecraft.network.chat.MutableComponent;
import net.minecraftforge.eventbus.api.IEventBus; import net.neoforged.api.distmarker.Dist;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; import net.neoforged.bus.api.IEventBus;
import net.neoforged.fml.common.Mod;
import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent;
import net.neoforged.neoforge.common.NeoForge;
@Mod(value = Create.ID, dist = Dist.CLIENT)
public class CreateClient { public class CreateClient {
public static final ModelSwapper MODEL_SWAPPER = new ModelSwapper(); public static final ModelSwapper MODEL_SWAPPER = new ModelSwapper();
@ -61,7 +65,13 @@ public class CreateClient {
public static final ClientResourceReloadListener RESOURCE_RELOAD_LISTENER = new ClientResourceReloadListener(); public static final ClientResourceReloadListener RESOURCE_RELOAD_LISTENER = new ClientResourceReloadListener();
public static void onCtorClient(IEventBus modEventBus, IEventBus forgeEventBus) { public CreateClient(IEventBus modEventBus) {
onCtorClient(modEventBus);
}
public static void onCtorClient(IEventBus modEventBus) {
IEventBus neoEventBus = NeoForge.EVENT_BUS;
modEventBus.addListener(CreateClient::clientInit); modEventBus.addListener(CreateClient::clientInit);
modEventBus.addListener(AllParticleTypes::registerFactories); modEventBus.addListener(AllParticleTypes::registerFactories);
@ -69,10 +79,10 @@ public class CreateClient {
MODEL_SWAPPER.registerListeners(modEventBus); MODEL_SWAPPER.registerListeners(modEventBus);
ZAPPER_RENDER_HANDLER.registerListeners(forgeEventBus); ZAPPER_RENDER_HANDLER.registerListeners(neoEventBus);
POTATO_CANNON_RENDER_HANDLER.registerListeners(forgeEventBus); POTATO_CANNON_RENDER_HANDLER.registerListeners(neoEventBus);
Mods.FTBLIBRARY.executeIfInstalled(() -> () -> FTBIntegration.init(modEventBus, forgeEventBus)); Mods.FTBLIBRARY.executeIfInstalled(() -> () -> FTBIntegration.init(modEventBus, neoEventBus));
} }
public static void clientInit(final FMLClientSetupEvent event) { public static void clientInit(final FMLClientSetupEvent event) {
@ -102,7 +112,7 @@ public class CreateClient {
private static void setupConfigUIBackground() { private static void setupConfigUIBackground() {
ConfigScreen.backgrounds.put(Create.ID, (screen, graphics, partialTicks) -> { ConfigScreen.backgrounds.put(Create.ID, (screen, graphics, partialTicks) -> {
CreateMainMenuScreen.PANORAMA.render(screen.getMinecraft().getDeltaFrameTime(), 1); CreateMainMenuScreen.PANORAMA.render(graphics, screen.width, screen.height, 1, partialTicks);
//RenderSystem.setShaderTexture(0, CreateMainMenuScreen.PANORAMA_OVERLAY_TEXTURES); //RenderSystem.setShaderTexture(0, CreateMainMenuScreen.PANORAMA_OVERLAY_TEXTURES);
RenderSystem.enableBlend(); RenderSystem.enableBlend();

View file

@ -8,7 +8,7 @@ import com.simibubi.create.impl.behaviour.BlockSpoutingBehaviourImpl;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraftforge.fluids.FluidStack; import net.neoforged.neoforge.fluids.FluidStack;
public abstract class BlockSpoutingBehaviour { public abstract class BlockSpoutingBehaviour {
/** /**

View file

@ -23,10 +23,9 @@ import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraftforge.common.capabilities.ForgeCapabilities; import net.neoforged.neoforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidStack; import net.neoforged.neoforge.fluids.IFluidTank;
import net.minecraftforge.fluids.IFluidTank; import net.neoforged.neoforge.fluids.capability.IFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler;
public class ConnectivityHandler { public class ConnectivityHandler {
@ -215,7 +214,7 @@ public class ConnectivityHandler {
} }
if (controller instanceof IMultiBlockEntityContainer.Fluid ifluidCon && ifluidCon.hasTank()) { if (controller instanceof IMultiBlockEntityContainer.Fluid ifluidCon && ifluidCon.hasTank()) {
FluidStack otherFluid = ifluidCon.getFluid(0); FluidStack otherFluid = ifluidCon.getFluid(0);
if (!fluid.isEmpty() && !otherFluid.isEmpty() && !fluid.isFluidEqual(otherFluid)) if (!fluid.isEmpty() && !otherFluid.isEmpty() && !FluidStack.isSameFluidSameComponents(fluid, otherFluid))
break Search; break Search;
} }
} }
@ -361,11 +360,9 @@ public class ConnectivityHandler {
} }
if (be instanceof IMultiBlockEntityContainer.Inventory inv && inv.hasInventory()) if (be instanceof IMultiBlockEntityContainer.Inventory inv && inv.hasInventory())
be.getCapability(ForgeCapabilities.ITEM_HANDLER) be.getLevel().invalidateCapabilities(be.getBlockPos());
.invalidate();
if (be instanceof IMultiBlockEntityContainer.Fluid fluid && fluid.hasTank()) if (be instanceof IMultiBlockEntityContainer.Fluid fluid && fluid.hasTank())
be.getCapability(ForgeCapabilities.FLUID_HANDLER) be.getLevel().invalidateCapabilities(be.getBlockPos());
.invalidate();
if (tryReconnect) if (tryReconnect)
formMulti(be.getType(), level, cache == null ? new SearchCache<>() : cache, frontier); formMulti(be.getType(), level, cache == null ? new SearchCache<>() : cache, frontier);

View file

@ -9,13 +9,13 @@ import com.simibubi.create.Create;
import com.simibubi.create.content.trains.schedule.hat.TrainHatInfo; import com.simibubi.create.content.trains.schedule.hat.TrainHatInfo;
import com.simibubi.create.content.trains.schedule.hat.TrainHatInfoReloadListener; import com.simibubi.create.content.trains.schedule.hat.TrainHatInfoReloadListener;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.data.CachedOutput; import net.minecraft.data.CachedOutput;
import net.minecraft.data.DataProvider; import net.minecraft.data.DataProvider;
import net.minecraft.data.PackOutput; import net.minecraft.data.PackOutput;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.EntityType;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import net.minecraftforge.registries.ForgeRegistries;
public abstract class TrainHatInfoProvider implements DataProvider { public abstract class TrainHatInfoProvider implements DataProvider {
protected final Map<ResourceLocation, TrainHatInfo> trainHatOffsets = new HashMap<>(); protected final Map<ResourceLocation, TrainHatInfo> trainHatOffsets = new HashMap<>();
@ -44,7 +44,7 @@ public abstract class TrainHatInfoProvider implements DataProvider {
} }
protected void makeInfoFor(EntityType<?> type, Vec3 offset, String part, int cubeIndex, float scale) { protected void makeInfoFor(EntityType<?> type, Vec3 offset, String part, int cubeIndex, float scale) {
this.trainHatOffsets.put(ForgeRegistries.ENTITY_TYPES.getKey(type), new TrainHatInfo(part, cubeIndex, offset, scale)); this.trainHatOffsets.put(BuiltInRegistries.ENTITY_TYPE.getKey(type), new TrainHatInfo(part, cubeIndex, offset, scale));
} }
@Override @Override

View file

@ -1,14 +1,14 @@
package com.simibubi.create.api.event; package com.simibubi.create.api.event;
import java.lang.reflect.Type;
import java.util.Map; import java.util.Map;
import java.util.function.Consumer;
import com.simibubi.create.foundation.blockEntity.SmartBlockEntity; import com.simibubi.create.foundation.blockEntity.SmartBlockEntity;
import com.simibubi.create.foundation.blockEntity.behaviour.BehaviourType; import com.simibubi.create.foundation.blockEntity.behaviour.BehaviourType;
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour; import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraftforge.eventbus.api.GenericEvent; import net.neoforged.bus.api.Event;
/** /**
* Event that is fired just before a SmartBlockEntity is being deserialized<br> * Event that is fired just before a SmartBlockEntity is being deserialized<br>
@ -22,21 +22,29 @@ import net.minecraftforge.eventbus.api.GenericEvent;
* <br> * <br>
* Because of the earliness of this event, the added behaviours will have access * Because of the earliness of this event, the added behaviours will have access
* to the initial NBT read (unless the BE was placed, not loaded), thereby * to the initial NBT read (unless the BE was placed, not loaded), thereby
* allowing block entities to store and retrieve data for injected behaviours. * allowing block entities to store and retrieve data for injected behaviours.<br>
* <br>
* Example: <pre> {@code
* neoForgeEventBus.addListener((BlockEntityBehaviourEvent event) -> {
* event.forType(AllBlockEntityTypes.FUNNEL.get(), be -> {
* event.attach(new FunFunnelBehaviour(be));
* });
* });
* } <pre>
*/ */
public class BlockEntityBehaviourEvent<T extends SmartBlockEntity> extends GenericEvent<T> { public class BlockEntityBehaviourEvent extends Event {
private final SmartBlockEntity smartBlockEntity;
private final T smartBlockEntity;
private final Map<BehaviourType<?>, BlockEntityBehaviour> behaviours; private final Map<BehaviourType<?>, BlockEntityBehaviour> behaviours;
public BlockEntityBehaviourEvent(T blockEntity, Map<BehaviourType<?>, BlockEntityBehaviour> behaviours) { public BlockEntityBehaviourEvent(SmartBlockEntity blockEntity, Map<BehaviourType<?>, BlockEntityBehaviour> behaviours) {
smartBlockEntity = blockEntity; smartBlockEntity = blockEntity;
this.behaviours = behaviours; this.behaviours = behaviours;
} }
@Override public <T extends SmartBlockEntity> void forType(BlockEntityType<T> type, Consumer<T> action) {
public Type getGenericType() { if (smartBlockEntity.getType() == type) {
return smartBlockEntity.getClass(); action.accept((T) smartBlockEntity);
}
} }
public void attach(BlockEntityBehaviour behaviour) { public void attach(BlockEntityBehaviour behaviour) {
@ -47,12 +55,4 @@ public class BlockEntityBehaviourEvent<T extends SmartBlockEntity> extends Gener
return behaviours.remove(type); return behaviours.remove(type);
} }
public T getBlockEntity() {
return smartBlockEntity;
}
public BlockState getBlockState() {
return smartBlockEntity.getBlockState();
}
} }

View file

@ -6,7 +6,7 @@ import net.minecraft.core.BlockPos;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid; import net.minecraft.world.level.material.Fluid;
import net.minecraftforge.eventbus.api.Event; import net.neoforged.bus.api.Event;
/** /**
* This Event is fired when two fluids meet in a pipe ({@link Flow})<br> * This Event is fired when two fluids meet in a pipe ({@link Flow})<br>

View file

@ -2,12 +2,11 @@ package com.simibubi.create.api.event;
import com.simibubi.create.content.trains.graph.TrackGraph; import com.simibubi.create.content.trains.graph.TrackGraph;
import net.minecraftforge.eventbus.api.Event; import net.neoforged.bus.api.Event;
public class TrackGraphMergeEvent extends Event { public class TrackGraphMergeEvent extends Event {
private final TrackGraph mergedInto; private final TrackGraph mergedInto;
private final TrackGraph mergedFrom; private final TrackGraph mergedFrom;
public TrackGraphMergeEvent(TrackGraph from, TrackGraph into) { public TrackGraphMergeEvent(TrackGraph from, TrackGraph into) {
mergedInto = into; mergedInto = into;
mergedFrom = from; mergedFrom = from;

View file

@ -1,10 +1,11 @@
package com.simibubi.create.api.schematic.nbt; package com.simibubi.create.api.schematic.nbt;
import net.minecraft.core.HolderLookup;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
public interface IPartialSafeNBT { public interface IPartialSafeNBT {
/** /**
* This will always be called from the logical server * This will always be called from the logical server
*/ */
void writeSafe(CompoundTag compound); void writeSafe(CompoundTag compound, HolderLookup.Provider registries);
} }

View file

@ -2,6 +2,7 @@ package com.simibubi.create.api.schematic.nbt;
import com.simibubi.create.impl.schematic.nbt.SchematicSafeNBTRegistryImpl; import com.simibubi.create.impl.schematic.nbt.SchematicSafeNBTRegistryImpl;
import net.minecraft.core.HolderLookup;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.entity.BlockEntityType;
@ -17,7 +18,7 @@ public class SchematicSafeNBTRegistry {
* *
* @param blockEntityType The block entity type you would like to register this for * @param blockEntityType The block entity type you would like to register this for
* @param safeNBT The custom PartialSafeNBT provider you would like to register for this blockEntityType, * @param safeNBT The custom PartialSafeNBT provider you would like to register for this blockEntityType,
* your {@link ContextProvidingPartialSafeNBT#writeSafe(BlockEntity, CompoundTag)} method will be * your {@link ContextProvidingPartialSafeNBT#writeSafe(BlockEntity, CompoundTag, HolderLookup.Provider)} method will be
* called on the passed {@link ContextProvidingPartialSafeNBT} * called on the passed {@link ContextProvidingPartialSafeNBT}
* when the block entities data is being prepared for placement. * when the block entities data is being prepared for placement.
*/ */
@ -32,6 +33,6 @@ public class SchematicSafeNBTRegistry {
/** /**
* This will always be called from the logical server * This will always be called from the logical server
*/ */
void writeSafe(BlockEntity blockEntity, CompoundTag tag); void writeSafe(BlockEntity blockEntity, CompoundTag tag, HolderLookup.Provider registries);
} }
} }

View file

@ -3,20 +3,21 @@ package com.simibubi.create.compat;
import java.util.Optional; import java.util.Optional;
import java.util.function.Supplier; import java.util.function.Supplier;
import net.createmod.catnip.platform.CatnipServices; import net.createmod.catnip.utility.RegisteredObjectsHelper;
import net.createmod.catnip.utility.lang.Lang; import net.createmod.catnip.utility.lang.Lang;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import net.minecraft.world.level.ItemLike; import net.minecraft.world.level.ItemLike;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraftforge.fml.ModList; import net.neoforged.fml.ModList;
import net.minecraftforge.registries.ForgeRegistries;
/** /**
* For compatibility with and without another mod present, we have to define load conditions of the specific code * For compatibility with and without another mod present, we have to define load conditions of the specific code
*/ */
public enum Mods { public enum Mods {
AETHER, AETHER,
AETHER_II,
COMPUTERCRAFT, COMPUTERCRAFT,
CONNECTIVITY, CONNECTIVITY,
CURIOS, CURIOS,
@ -49,22 +50,22 @@ public enum Mods {
} }
public ResourceLocation rl(String path) { public ResourceLocation rl(String path) {
return new ResourceLocation(id, path); return ResourceLocation.fromNamespaceAndPath(id, path);
} }
public Block getBlock(String id) { public Block getBlock(String id) {
return ForgeRegistries.BLOCKS.getValue(rl(id)); return BuiltInRegistries.BLOCK.get(rl(id));
} }
public Item getItem(String id) { public Item getItem(String id) {
return ForgeRegistries.ITEMS.getValue(rl(id)); return BuiltInRegistries.ITEM.get(rl(id));
} }
public boolean contains(ItemLike entry) { public boolean contains(ItemLike entry) {
if (!isLoaded()) if (!isLoaded())
return false; return false;
Item asItem = entry.asItem(); Item asItem = entry.asItem();
return asItem != null && CatnipServices.REGISTRIES.getKeyOrThrow(asItem) return asItem != null && RegisteredObjectsHelper.getKeyOrThrow(asItem)
.getNamespace() .getNamespace()
.equals(id); .equals(id);
} }

View file

@ -4,9 +4,9 @@ import com.simibubi.create.foundation.blockEntity.SmartBlockEntity;
import com.simibubi.create.foundation.blockEntity.behaviour.BehaviourType; import com.simibubi.create.foundation.blockEntity.behaviour.BehaviourType;
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour; import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
import dan200.computercraft.api.peripheral.IPeripheral;
import net.minecraft.core.HolderLookup;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.LazyOptional;
public class AbstractComputerBehaviour extends BlockEntityBehaviour { public class AbstractComputerBehaviour extends BlockEntityBehaviour {
@ -20,23 +20,19 @@ public class AbstractComputerBehaviour extends BlockEntityBehaviour {
} }
@Override @Override
public void read(CompoundTag nbt, boolean clientPacket) { public void read(CompoundTag nbt, HolderLookup.Provider registries, boolean clientPacket) {
hasAttachedComputer = nbt.getBoolean("HasAttachedComputer"); hasAttachedComputer = nbt.getBoolean("HasAttachedComputer");
super.read(nbt, clientPacket); super.read(nbt, registries, clientPacket);
} }
@Override @Override
public void write(CompoundTag nbt, boolean clientPacket) { public void write(CompoundTag nbt, HolderLookup.Provider registries, boolean clientPacket) {
nbt.putBoolean("HasAttachedComputer", hasAttachedComputer); nbt.putBoolean("HasAttachedComputer", hasAttachedComputer);
super.write(nbt, clientPacket); super.write(nbt, registries, clientPacket);
} }
public <T> boolean isPeripheralCap(Capability<T> cap) { public IPeripheral getPeripheralCapability() {
return false; return null;
}
public <T> LazyOptional<T> getPeripheralCapability() {
return LazyOptional.empty();
} }
public void removePeripheral() {} public void removePeripheral() {}

View file

@ -1,13 +1,22 @@
package com.simibubi.create.compat.computercraft; package com.simibubi.create.compat.computercraft;
import com.simibubi.create.AllPackets;
import com.simibubi.create.foundation.blockEntity.SmartBlockEntity; import com.simibubi.create.foundation.blockEntity.SmartBlockEntity;
import com.simibubi.create.foundation.blockEntity.SyncedBlockEntity; import com.simibubi.create.foundation.blockEntity.SyncedBlockEntity;
import com.simibubi.create.foundation.networking.BlockEntityDataPacket; import com.simibubi.create.foundation.networking.BlockEntityDataPacket;
import io.netty.buffer.ByteBuf;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
public class AttachedComputerPacket extends BlockEntityDataPacket<SyncedBlockEntity> { public class AttachedComputerPacket extends BlockEntityDataPacket<SyncedBlockEntity> {
public static final StreamCodec<ByteBuf, AttachedComputerPacket> STREAM_CODEC = StreamCodec.composite(
BlockPos.STREAM_CODEC, packet -> packet.pos,
ByteBufCodecs.BOOL, packet -> packet.hasAttachedComputer,
AttachedComputerPacket::new
);
private final boolean hasAttachedComputer; private final boolean hasAttachedComputer;
@ -16,16 +25,6 @@ public class AttachedComputerPacket extends BlockEntityDataPacket<SyncedBlockEnt
this.hasAttachedComputer = hasAttachedComputer; this.hasAttachedComputer = hasAttachedComputer;
} }
public AttachedComputerPacket(FriendlyByteBuf buffer) {
super(buffer);
this.hasAttachedComputer = buffer.readBoolean();
}
@Override
protected void writeData(FriendlyByteBuf buffer) {
buffer.writeBoolean(hasAttachedComputer);
}
@Override @Override
protected void handlePacket(SyncedBlockEntity blockEntity) { protected void handlePacket(SyncedBlockEntity blockEntity) {
if (blockEntity instanceof SmartBlockEntity sbe) { if (blockEntity instanceof SmartBlockEntity sbe) {
@ -34,4 +33,8 @@ public class AttachedComputerPacket extends BlockEntityDataPacket<SyncedBlockEnt
} }
} }
@Override
public PacketTypeProvider getTypeProvider() {
return AllPackets.ATTACHED_COMPUTER;
}
} }

View file

@ -1,5 +1,7 @@
package com.simibubi.create.compat.computercraft.implementation; package com.simibubi.create.compat.computercraft.implementation;
import java.util.function.Supplier;
import com.simibubi.create.compat.computercraft.AbstractComputerBehaviour; import com.simibubi.create.compat.computercraft.AbstractComputerBehaviour;
import com.simibubi.create.compat.computercraft.implementation.peripherals.DisplayLinkPeripheral; import com.simibubi.create.compat.computercraft.implementation.peripherals.DisplayLinkPeripheral;
import com.simibubi.create.compat.computercraft.implementation.peripherals.SequencedGearshiftPeripheral; import com.simibubi.create.compat.computercraft.implementation.peripherals.SequencedGearshiftPeripheral;
@ -16,27 +18,21 @@ import com.simibubi.create.content.trains.station.StationBlockEntity;
import com.simibubi.create.foundation.blockEntity.SmartBlockEntity; import com.simibubi.create.foundation.blockEntity.SmartBlockEntity;
import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.peripheral.IPeripheral;
import net.minecraftforge.common.capabilities.Capability; import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraftforge.common.capabilities.CapabilityManager;
import net.minecraftforge.common.capabilities.CapabilityToken;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.common.util.NonNullSupplier;
import net.minecraftforge.registries.ForgeRegistries;
public class ComputerBehaviour extends AbstractComputerBehaviour { public class ComputerBehaviour extends AbstractComputerBehaviour {
protected static final Capability<IPeripheral> PERIPHERAL_CAPABILITY = IPeripheral peripheral;
CapabilityManager.get(new CapabilityToken<>() { Supplier<IPeripheral> peripheralSupplier;
}); SmartBlockEntity be;
LazyOptional<IPeripheral> peripheral;
NonNullSupplier<IPeripheral> peripheralSupplier;
public ComputerBehaviour(SmartBlockEntity te) { public ComputerBehaviour(SmartBlockEntity be) {
super(te); super(be);
this.peripheralSupplier = getPeripheralFor(te); this.peripheralSupplier = getPeripheralFor(be);
this.be = be;
} }
public static NonNullSupplier<IPeripheral> getPeripheralFor(SmartBlockEntity be) { public static Supplier<IPeripheral> getPeripheralFor(SmartBlockEntity be) {
if (be instanceof SpeedControllerBlockEntity scbe) if (be instanceof SpeedControllerBlockEntity scbe)
return () -> new SpeedControllerPeripheral(scbe, scbe.targetSpeed); return () -> new SpeedControllerPeripheral(scbe, scbe.targetSpeed);
if (be instanceof DisplayLinkBlockEntity dlbe) if (be instanceof DisplayLinkBlockEntity dlbe)
@ -51,25 +47,20 @@ public class ComputerBehaviour extends AbstractComputerBehaviour {
return () -> new StationPeripheral(sbe); return () -> new StationPeripheral(sbe);
throw new IllegalArgumentException( throw new IllegalArgumentException(
"No peripheral available for " + ForgeRegistries.BLOCK_ENTITY_TYPES.getKey(be.getType())); "No peripheral available for " + BuiltInRegistries.BLOCK_ENTITY_TYPE.getKey(be.getType()));
} }
@Override @Override
public <T> boolean isPeripheralCap(Capability<T> cap) { public IPeripheral getPeripheralCapability() {
return cap == PERIPHERAL_CAPABILITY; if (peripheral == null)
} peripheral = peripheralSupplier.get();
return peripheral;
@Override
public <T> LazyOptional<T> getPeripheralCapability() {
if (peripheral == null || !peripheral.isPresent())
peripheral = LazyOptional.of(peripheralSupplier);
return peripheral.cast();
} }
@Override @Override
public void removePeripheral() { public void removePeripheral() {
if (peripheral != null) if (peripheral != null)
peripheral.invalidate(); getWorld().invalidateCapabilities(be.getBlockPos());
} }
} }

View file

@ -6,13 +6,13 @@ import javax.annotation.Nullable;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import com.simibubi.create.AllPackets;
import com.simibubi.create.compat.computercraft.implementation.CreateLuaTable; import com.simibubi.create.compat.computercraft.implementation.CreateLuaTable;
import com.simibubi.create.content.trains.entity.Train; import com.simibubi.create.content.trains.entity.Train;
import com.simibubi.create.content.trains.schedule.Schedule; import com.simibubi.create.content.trains.schedule.Schedule;
import com.simibubi.create.content.trains.station.GlobalStation; import com.simibubi.create.content.trains.station.GlobalStation;
import com.simibubi.create.content.trains.station.StationBlockEntity; import com.simibubi.create.content.trains.station.StationBlockEntity;
import com.simibubi.create.content.trains.station.TrainEditPacket; import com.simibubi.create.content.trains.station.TrainEditPacket;
import net.createmod.catnip.platform.CatnipServices;
import com.simibubi.create.foundation.utility.StringHelper; import com.simibubi.create.foundation.utility.StringHelper;
import dan200.computercraft.api.lua.IArguments; import dan200.computercraft.api.lua.IArguments;
@ -28,7 +28,6 @@ import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.NumericTag; import net.minecraft.nbt.NumericTag;
import net.minecraft.nbt.StringTag; import net.minecraft.nbt.StringTag;
import net.minecraft.nbt.Tag; import net.minecraft.nbt.Tag;
import net.minecraftforge.network.PacketDistributor;
public class StationPeripheral extends SyncedPeripheral<StationBlockEntity> { public class StationPeripheral extends SyncedPeripheral<StationBlockEntity> {
@ -129,7 +128,7 @@ public class StationPeripheral extends SyncedPeripheral<StationBlockEntity> {
public final void setTrainName(String name) throws LuaException { public final void setTrainName(String name) throws LuaException {
Train train = getTrainOrThrow(); Train train = getTrainOrThrow();
train.name = Components.literal(name); train.name = Components.literal(name);
AllPackets.getChannel().send(PacketDistributor.ALL.noArg(), new TrainEditPacket.TrainEditReturnPacket(train.id, name, train.icon.getId(), train.mapColorIndex)); CatnipServices.NETWORK.sendToAllClients(new TrainEditPacket.TrainEditReturnPacket(train.id, name, train.icon.getId(), train.mapColorIndex));
} }
@LuaFunction @LuaFunction
@ -146,7 +145,7 @@ public class StationPeripheral extends SyncedPeripheral<StationBlockEntity> {
if (schedule == null) if (schedule == null)
throw new LuaException("train doesn't have a schedule"); throw new LuaException("train doesn't have a schedule");
return fromCompoundTag(schedule.write()); return fromCompoundTag(schedule.write(blockEntity.getLevel().registryAccess()));
} }
@LuaFunction(mainThread = true) @LuaFunction(mainThread = true)
@ -159,7 +158,7 @@ public class StationPeripheral extends SyncedPeripheral<StationBlockEntity> {
throw new LuaException("Schedule must have at least one entry"); throw new LuaException("Schedule must have at least one entry");
Train train = getTrainOrThrow(); Train train = getTrainOrThrow();
Schedule schedule = Schedule.fromTag(toCompoundTag(new CreateLuaTable(arguments.getTable(0)))); Schedule schedule = Schedule.fromTag(blockEntity.getLevel().registryAccess(), toCompoundTag(new CreateLuaTable(arguments.getTable(0))));
boolean autoSchedule = train.runtime.getSchedule() == null || train.runtime.isAutoSchedule; boolean autoSchedule = train.runtime.getSchedule() == null || train.runtime.isAutoSchedule;
train.runtime.setSchedule(schedule, autoSchedule); train.runtime.setSchedule(schedule, autoSchedule);
} }

View file

@ -5,14 +5,13 @@ import java.util.concurrent.atomic.AtomicInteger;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import com.simibubi.create.AllPackets;
import com.simibubi.create.compat.computercraft.AttachedComputerPacket; import com.simibubi.create.compat.computercraft.AttachedComputerPacket;
import com.simibubi.create.compat.computercraft.implementation.ComputerBehaviour; import com.simibubi.create.compat.computercraft.implementation.ComputerBehaviour;
import com.simibubi.create.foundation.blockEntity.SmartBlockEntity; import com.simibubi.create.foundation.blockEntity.SmartBlockEntity;
import net.createmod.catnip.platform.CatnipServices;
import dan200.computercraft.api.peripheral.IComputerAccess; import dan200.computercraft.api.peripheral.IComputerAccess;
import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.peripheral.IPeripheral;
import net.minecraftforge.network.PacketDistributor;
public abstract class SyncedPeripheral<T extends SmartBlockEntity> implements IPeripheral { public abstract class SyncedPeripheral<T extends SmartBlockEntity> implements IPeripheral {
@ -39,7 +38,7 @@ public abstract class SyncedPeripheral<T extends SmartBlockEntity> implements IP
boolean hasAttachedComputer = computers.get() > 0; boolean hasAttachedComputer = computers.get() > 0;
blockEntity.getBehaviour(ComputerBehaviour.TYPE).setHasAttachedComputer(hasAttachedComputer); blockEntity.getBehaviour(ComputerBehaviour.TYPE).setHasAttachedComputer(hasAttachedComputer);
AllPackets.getChannel().send(PacketDistributor.ALL.noArg(), new AttachedComputerPacket(blockEntity.getBlockPos(), hasAttachedComputer)); CatnipServices.NETWORK.sendToAllClients(new AttachedComputerPacket(blockEntity.getBlockPos(), hasAttachedComputer));
} }
@Override @Override

View file

@ -10,14 +10,13 @@ import com.simibubi.create.AllTags;
import com.simibubi.create.content.equipment.armor.BacktankUtil; import com.simibubi.create.content.equipment.armor.BacktankUtil;
import com.simibubi.create.content.equipment.goggles.GogglesItem; import com.simibubi.create.content.equipment.goggles.GogglesItem;
import net.createmod.catnip.platform.CatnipServices;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraftforge.api.distmarker.Dist; import net.neoforged.bus.api.IEventBus;
import net.minecraftforge.eventbus.api.IEventBus; import net.neoforged.fml.InterModComms;
import net.minecraftforge.fml.DistExecutor; import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.fml.InterModComms; import net.neoforged.fml.event.lifecycle.InterModEnqueueEvent;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.fml.event.lifecycle.InterModEnqueueEvent;
import top.theillusivec4.curios.api.CuriosCapability; import top.theillusivec4.curios.api.CuriosCapability;
import top.theillusivec4.curios.api.SlotTypeMessage; import top.theillusivec4.curios.api.SlotTypeMessage;
import top.theillusivec4.curios.api.SlotTypePreset; import top.theillusivec4.curios.api.SlotTypePreset;
@ -35,10 +34,10 @@ public class Curios {
* @return An optional of the Stacks Handler Map * @return An optional of the Stacks Handler Map
*/ */
private static Optional<Map<String, ICurioStacksHandler>> resolveCuriosMap(LivingEntity entity) { private static Optional<Map<String, ICurioStacksHandler>> resolveCuriosMap(LivingEntity entity) {
return entity.getCapability(CuriosCapability.INVENTORY).map(ICuriosItemHandler::getCurios); return Optional.ofNullable(entity.getCapability(CuriosCapability.INVENTORY)).map(ICuriosItemHandler::getCurios);
} }
public static void init(IEventBus modEventBus, IEventBus forgeEventBus) { public static void init(IEventBus modEventBus) {
modEventBus.addListener(Curios::onInterModEnqueue); modEventBus.addListener(Curios::onInterModEnqueue);
modEventBus.addListener(Curios::onClientSetup); modEventBus.addListener(Curios::onClientSetup);
@ -74,8 +73,7 @@ public class Curios {
return stacks; return stacks;
}).orElse(new ArrayList<>())); }).orElse(new ArrayList<>()));
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, CatnipServices.PLATFORM.executeOnClientOnly(() -> () -> modEventBus.addListener(CuriosRenderers::onLayerRegister));
() -> () -> modEventBus.addListener(CuriosRenderers::onLayerRegister));
} }
private static void onInterModEnqueue(final InterModEnqueueEvent event) { private static void onInterModEnqueue(final InterModEnqueueEvent event) {

View file

@ -4,9 +4,9 @@ import com.simibubi.create.AllItems;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.model.geom.builders.LayerDefinition; import net.minecraft.client.model.geom.builders.LayerDefinition;
import net.minecraftforge.api.distmarker.Dist; import net.neoforged.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.neoforged.api.distmarker.OnlyIn;
import net.minecraftforge.client.event.EntityRenderersEvent; import net.neoforged.neoforge.client.event.EntityRenderersEvent;
import top.theillusivec4.curios.api.client.CuriosRendererRegistry; import top.theillusivec4.curios.api.client.CuriosRendererRegistry;
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)

View file

@ -20,14 +20,14 @@ import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.item.ItemDisplayContext; import net.minecraft.world.item.ItemDisplayContext;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraftforge.api.distmarker.Dist; import net.neoforged.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.neoforged.api.distmarker.OnlyIn;
import top.theillusivec4.curios.api.SlotContext; import top.theillusivec4.curios.api.SlotContext;
import top.theillusivec4.curios.api.client.ICurioRenderer; import top.theillusivec4.curios.api.client.ICurioRenderer;
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public class GogglesCurioRenderer implements ICurioRenderer { public class GogglesCurioRenderer implements ICurioRenderer {
public static final ModelLayerLocation LAYER = new ModelLayerLocation(new ResourceLocation(Create.ID, "goggles"), "goggles"); public static final ModelLayerLocation LAYER = new ModelLayerLocation(Create.asResource("goggles"), "goggles");
private final HumanoidModel<LivingEntity> model; private final HumanoidModel<LivingEntity> model;

View file

@ -4,19 +4,13 @@ import java.util.function.BiConsumer;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import com.ferreusveritas.dynamictrees.api.TreeHelper;
import com.ferreusveritas.dynamictrees.block.branch.BranchBlock;
import com.ferreusveritas.dynamictrees.block.branch.TrunkShellBlock;
import com.ferreusveritas.dynamictrees.util.BranchDestructionData;
import com.simibubi.create.foundation.utility.AbstractBlockBreakQueue; import com.simibubi.create.foundation.utility.AbstractBlockBreakQueue;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
public class DynamicTree extends AbstractBlockBreakQueue { public class DynamicTree extends AbstractBlockBreakQueue {
@ -27,46 +21,47 @@ public class DynamicTree extends AbstractBlockBreakQueue {
} }
public static boolean isDynamicBranch(Block block) { public static boolean isDynamicBranch(Block block) {
return TreeHelper.isBranch(block) || block instanceof TrunkShellBlock; //return TreeHelper.isBranch(block) || block instanceof TrunkShellBlock;
return false;
} }
@Override @Override
public void destroyBlocks(Level world, ItemStack toDamage, @Nullable Player playerEntity, BiConsumer<BlockPos, ItemStack> drop) { public void destroyBlocks(Level world, ItemStack toDamage, @Nullable Player playerEntity, BiConsumer<BlockPos, ItemStack> drop) {
BranchBlock start = TreeHelper.getBranch(world.getBlockState(startCutPos)); // BranchBlock start = TreeHelper.getBranch(world.getBlockState(startCutPos));
if (start == null) //if start is null, it was not a branch // if (start == null) //if start is null, it was not a branch
start = setBranchToShellMuse(world, world.getBlockState(startCutPos)); //we check for a trunk shell instead // start = setBranchToShellMuse(world, world.getBlockState(startCutPos)); //we check for a trunk shell instead
//
if (start == null) //if it is null again, it was neither a branch nor a trunk shell and thus we return // if (start == null) //if it is null again, it was neither a branch nor a trunk shell and thus we return
return; // return;
//
// Play and render block break sound and particles // // Play and render block break sound and particles
world.levelEvent(null, 2001, startCutPos, Block.getId(world.getBlockState(startCutPos))); // world.levelEvent(null, 2001, startCutPos, Block.getId(world.getBlockState(startCutPos)));
//
// Actually breaks the tree // // Actually breaks the tree
BranchDestructionData data = start.destroyBranchFromNode(world, startCutPos, Direction.DOWN, false, playerEntity); // BranchDestructionData data = start.destroyBranchFromNode(world, startCutPos, Direction.DOWN, false, playerEntity);
//
// Feed all the tree drops to drop bi-consumer // // Feed all the tree drops to drop bi-consumer
data.leavesDrops.forEach(stackPos -> drop.accept(stackPos.pos.offset(startCutPos), stackPos.stack)); // data.leavesDrops.forEach(stackPos -> drop.accept(stackPos.pos.offset(startCutPos), stackPos.stack));
start.getFamily().getCommonSpecies().getBranchesDrops(world, data.woodVolume).forEach(stack -> drop.accept(startCutPos, stack)); // start.getFamily().getCommonSpecies().getBranchesDrops(world, data.woodVolume).forEach(stack -> drop.accept(startCutPos, stack));
} }
private BranchBlock setBranchToShellMuse(Level world, BlockState state) { // private BranchBlock setBranchToShellMuse(Level world, BlockState state) {
//
Block block = state.getBlock(); // Block block = state.getBlock();
if (block instanceof TrunkShellBlock){ // if (block instanceof TrunkShellBlock){
TrunkShellBlock.ShellMuse muse = ((TrunkShellBlock)block).getMuse(world, startCutPos); // TrunkShellBlock.ShellMuse muse = ((TrunkShellBlock)block).getMuse(world, startCutPos);
if (muse != null){ // if (muse != null){
startCutPos = muse.pos; //the cut pos is moved to the center of the trunk // startCutPos = muse.pos; //the cut pos is moved to the center of the trunk
return TreeHelper.getBranch(muse.state); // return TreeHelper.getBranch(muse.state);
} // }
} // }
//
return null; // return null;
} // }
} }

View file

@ -28,7 +28,7 @@ public class FramedBlocksInSchematics {
if (blockEntity == null) if (blockEntity == null)
return data; return data;
data = blockEntity.saveWithFullMetadata(); data = blockEntity.saveWithFullMetadata(blockEntity.getLevel().registryAccess());
List<String> keysToRemove = new ArrayList<>(); List<String> keysToRemove = new ArrayList<>();
for (String key : data.getAllKeys()) for (String key : data.getAllKeys())
@ -52,7 +52,7 @@ public class FramedBlocksInSchematics {
if (blockEntity == null) if (blockEntity == null)
return ItemRequirement.NONE; return ItemRequirement.NONE;
CompoundTag data = blockEntity.saveWithFullMetadata(); CompoundTag data = blockEntity.saveWithFullMetadata(blockEntity.getLevel().registryAccess());
List<StackRequirement> list = new ArrayList<>(); List<StackRequirement> list = new ArrayList<>();
if (data.getBoolean("intangible")) if (data.getBoolean("intangible"))

View file

@ -2,16 +2,16 @@ package com.simibubi.create.compat.ftb;
import com.simibubi.create.foundation.gui.menu.AbstractSimiContainerScreen; import com.simibubi.create.foundation.gui.menu.AbstractSimiContainerScreen;
import dev.ftb.mods.ftblibrary.FTBLibraryClient; import dev.ftb.mods.ftblibrary.config.FTBLibraryClientConfig;
import net.createmod.catnip.gui.AbstractSimiScreen; import net.createmod.catnip.gui.AbstractSimiScreen;
import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.Screen;
import net.minecraftforge.client.event.ScreenEvent; import net.neoforged.bus.api.EventPriority;
import net.minecraftforge.eventbus.api.EventPriority; import net.neoforged.bus.api.IEventBus;
import net.minecraftforge.eventbus.api.IEventBus; import net.neoforged.neoforge.client.event.ScreenEvent;
public class FTBIntegration { public class FTBIntegration {
private static int buttonStatePreviously = 0; private static boolean buttonStatePreviously;
public static void init(IEventBus modEventBus, IEventBus forgeEventBus) { public static void init(IEventBus modEventBus, IEventBus forgeEventBus) {
forgeEventBus.addListener(EventPriority.HIGH, FTBIntegration::removeGUIClutterOpen); forgeEventBus.addListener(EventPriority.HIGH, FTBIntegration::removeGUIClutterOpen);
@ -23,14 +23,14 @@ public class FTBIntegration {
return; return;
if (!isCreate(event.getNewScreen())) if (!isCreate(event.getNewScreen()))
return; return;
buttonStatePreviously = FTBLibraryClient.showButtons; buttonStatePreviously = FTBLibraryClientConfig.SIDEBAR_ENABLED.get();
FTBLibraryClient.showButtons = 0; FTBLibraryClientConfig.SIDEBAR_ENABLED.set(false);
} }
private static void removeGUIClutterClose(ScreenEvent.Closing event) { private static void removeGUIClutterClose(ScreenEvent.Closing event) {
if (!isCreate(event.getScreen())) if (!isCreate(event.getScreen()))
return; return;
FTBLibraryClient.showButtons = buttonStatePreviously; FTBLibraryClientConfig.SIDEBAR_ENABLED.set(buttonStatePreviously);
} }
private static boolean isCreate(Screen screen) { private static boolean isCreate(Screen screen) {

View file

@ -6,9 +6,9 @@ import javax.annotation.ParametersAreNonnullByDefault;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import com.simibubi.create.AllPackets;
import com.simibubi.create.content.equipment.blueprint.BlueprintAssignCompleteRecipePacket; import com.simibubi.create.content.equipment.blueprint.BlueprintAssignCompleteRecipePacket;
import com.simibubi.create.content.equipment.blueprint.BlueprintMenu; import com.simibubi.create.content.equipment.blueprint.BlueprintMenu;
import net.createmod.catnip.platform.CatnipServices;
import mezz.jei.api.constants.RecipeTypes; import mezz.jei.api.constants.RecipeTypes;
import mezz.jei.api.gui.ingredient.IRecipeSlotsView; import mezz.jei.api.gui.ingredient.IRecipeSlotsView;
@ -19,13 +19,14 @@ import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.MenuType; import net.minecraft.world.inventory.MenuType;
import net.minecraft.world.item.crafting.CraftingRecipe; import net.minecraft.world.item.crafting.CraftingRecipe;
import net.minecraft.world.item.crafting.RecipeHolder;
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault @MethodsReturnNonnullByDefault
public class BlueprintTransferHandler implements IRecipeTransferHandler<BlueprintMenu, CraftingRecipe> { public class BlueprintTransferHandler implements IRecipeTransferHandler<BlueprintMenu, RecipeHolder<CraftingRecipe>> {
@Override @Override
public Class<BlueprintMenu> getContainerClass() { public Class<? extends BlueprintMenu> getContainerClass() {
return BlueprintMenu.class; return BlueprintMenu.class;
} }
@ -35,16 +36,16 @@ public class BlueprintTransferHandler implements IRecipeTransferHandler<Blueprin
} }
@Override @Override
public RecipeType<CraftingRecipe> getRecipeType() { public RecipeType<RecipeHolder<CraftingRecipe>> getRecipeType() {
return RecipeTypes.CRAFTING; return RecipeTypes.CRAFTING;
} }
@Override @Override
public @Nullable IRecipeTransferError transferRecipe(BlueprintMenu menu, CraftingRecipe craftingRecipe, IRecipeSlotsView recipeSlots, Player player, boolean maxTransfer, boolean doTransfer) { public @Nullable IRecipeTransferError transferRecipe(BlueprintMenu menu, RecipeHolder<CraftingRecipe> craftingRecipe, IRecipeSlotsView recipeSlots, Player player, boolean maxTransfer, boolean doTransfer) {
if (!doTransfer) if (!doTransfer)
return null; return null;
AllPackets.getChannel().sendToServer(new BlueprintAssignCompleteRecipePacket(craftingRecipe.getId())); CatnipServices.NETWORK.sendToServer(new BlueprintAssignCompleteRecipePacket(craftingRecipe.id()));
return null; return null;
} }

View file

@ -11,8 +11,9 @@ import com.simibubi.create.content.processing.recipe.ProcessingRecipeBuilder.Pro
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.item.crafting.RecipeHolder;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraftforge.items.wrapper.RecipeWrapper; import net.neoforged.neoforge.items.wrapper.RecipeWrapper;
/** /**
* Helper recipe type for displaying an item relationship in JEI * Helper recipe type for displaying an item relationship in JEI
@ -22,12 +23,13 @@ public class ConversionRecipe extends ProcessingRecipe<RecipeWrapper> {
static int counter = 0; static int counter = 0;
public static ConversionRecipe create(ItemStack from, ItemStack to) { public static RecipeHolder<ConversionRecipe> create(ItemStack from, ItemStack to) {
ResourceLocation recipeId = Create.asResource("conversion_" + counter++); ResourceLocation recipeId = Create.asResource("conversion_" + counter++);
return new ProcessingRecipeBuilder<>(ConversionRecipe::new, recipeId) ConversionRecipe recipe = new ProcessingRecipeBuilder<>(ConversionRecipe::new, recipeId)
.withItemIngredients(Ingredient.of(from)) .withItemIngredients(Ingredient.of(from))
.withSingleItemOutput(to) .withSingleItemOutput(to)
.build(); .build();
return new RecipeHolder<>(recipeId, recipe);
} }
public ConversionRecipe(ProcessingRecipeParams params) { public ConversionRecipe(ProcessingRecipeParams params) {

View file

@ -4,7 +4,6 @@ import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Predicate; import java.util.function.Predicate;
@ -68,15 +67,16 @@ import com.simibubi.create.foundation.gui.menu.AbstractSimiContainerScreen;
import com.simibubi.create.foundation.item.ItemHelper; import com.simibubi.create.foundation.item.ItemHelper;
import com.simibubi.create.foundation.recipe.IRecipeTypeInfo; import com.simibubi.create.foundation.recipe.IRecipeTypeInfo;
import com.simibubi.create.foundation.utility.CreateLang; import com.simibubi.create.foundation.utility.CreateLang;
import com.simibubi.create.foundation.utility.RecipeGenericsUtil;
import com.simibubi.create.infrastructure.config.AllConfigs; import com.simibubi.create.infrastructure.config.AllConfigs;
import com.simibubi.create.infrastructure.config.CRecipes; import com.simibubi.create.infrastructure.config.CRecipes;
import mezz.jei.api.IModPlugin; import mezz.jei.api.IModPlugin;
import mezz.jei.api.JeiPlugin; import mezz.jei.api.JeiPlugin;
import mezz.jei.api.constants.RecipeTypes; import mezz.jei.api.constants.RecipeTypes;
import mezz.jei.api.forge.ForgeTypes;
import mezz.jei.api.gui.drawable.IDrawable; import mezz.jei.api.gui.drawable.IDrawable;
import mezz.jei.api.helpers.IPlatformFluidHelper; import mezz.jei.api.helpers.IPlatformFluidHelper;
import mezz.jei.api.neoforge.NeoForgeTypes;
import mezz.jei.api.recipe.category.IRecipeCategory; import mezz.jei.api.recipe.category.IRecipeCategory;
import mezz.jei.api.registration.IGuiHandlerRegistration; import mezz.jei.api.registration.IGuiHandlerRegistration;
import mezz.jei.api.registration.IRecipeCatalystRegistration; import mezz.jei.api.registration.IRecipeCatalystRegistration;
@ -94,12 +94,14 @@ import net.minecraft.world.item.Items;
import net.minecraft.world.item.crafting.AbstractCookingRecipe; import net.minecraft.world.item.crafting.AbstractCookingRecipe;
import net.minecraft.world.item.crafting.CraftingRecipe; import net.minecraft.world.item.crafting.CraftingRecipe;
import net.minecraft.world.item.crafting.Recipe; import net.minecraft.world.item.crafting.Recipe;
import net.minecraft.world.item.crafting.RecipeHolder;
import net.minecraft.world.item.crafting.RecipeInput;
import net.minecraft.world.item.crafting.RecipeType; import net.minecraft.world.item.crafting.RecipeType;
import net.minecraft.world.item.crafting.ShapedRecipe;
import net.minecraft.world.item.crafting.SmokingRecipe; import net.minecraft.world.item.crafting.SmokingRecipe;
import net.minecraft.world.level.ItemLike; import net.minecraft.world.level.ItemLike;
import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.Blocks;
import net.minecraftforge.common.crafting.IShapedRecipe; import net.neoforged.fml.ModList;
import net.minecraftforge.fml.ModList;
@JeiPlugin @JeiPlugin
@SuppressWarnings("unused") @SuppressWarnings("unused")
@ -180,10 +182,10 @@ public class CreateJEI implements IModPlugin {
autoShapeless = builder(BasinRecipe.class) autoShapeless = builder(BasinRecipe.class)
.enableWhen(c -> c.allowShapelessInMixer) .enableWhen(c -> c.allowShapelessInMixer)
.addAllRecipesIf(r -> r instanceof CraftingRecipe && !(r instanceof IShapedRecipe<?>) .addAllRecipesIf(r -> r.value() instanceof CraftingRecipe && !(r.value() instanceof ShapedRecipe)
&& r.getIngredients() && r.value().getIngredients()
.size() > 1 .size() > 1
&& !MechanicalPressBlockEntity.canCompress(r) && !AllRecipeTypes.shouldIgnoreInAutomation(r), && !MechanicalPressBlockEntity.canCompress(r.value()) && !AllRecipeTypes.shouldIgnoreInAutomation(r),
BasinRecipe::convertShapeless) BasinRecipe::convertShapeless)
.catalyst(AllBlocks.MECHANICAL_MIXER::get) .catalyst(AllBlocks.MECHANICAL_MIXER::get)
.catalyst(AllBlocks.BASIN::get) .catalyst(AllBlocks.BASIN::get)
@ -193,7 +195,7 @@ public class CreateJEI implements IModPlugin {
brewing = builder(BasinRecipe.class) brewing = builder(BasinRecipe.class)
.enableWhen(c -> c.allowBrewingInMixer) .enableWhen(c -> c.allowBrewingInMixer)
.addRecipes(() -> PotionMixingRecipes.ALL) .addRecipes(() -> RecipeGenericsUtil.cast(PotionMixingRecipes.createRecipes(Minecraft.getInstance().level)))
.catalyst(AllBlocks.MECHANICAL_MIXER::get) .catalyst(AllBlocks.MECHANICAL_MIXER::get)
.catalyst(AllBlocks.BASIN::get) .catalyst(AllBlocks.BASIN::get)
.doubleItemIcon(AllBlocks.MECHANICAL_MIXER.get(), Blocks.BREWING_STAND) .doubleItemIcon(AllBlocks.MECHANICAL_MIXER.get(), Blocks.BREWING_STAND)
@ -211,8 +213,8 @@ public class CreateJEI implements IModPlugin {
autoSquare = builder(BasinRecipe.class) autoSquare = builder(BasinRecipe.class)
.enableWhen(c -> c.allowShapedSquareInPress) .enableWhen(c -> c.allowShapedSquareInPress)
.addAllRecipesIf( .addAllRecipesIf(
r -> (r instanceof CraftingRecipe) && !(r instanceof MechanicalCraftingRecipe) r -> (r.value() instanceof CraftingRecipe) && !(r.value() instanceof MechanicalCraftingRecipe)
&& MechanicalPressBlockEntity.canCompress(r) && !AllRecipeTypes.shouldIgnoreInAutomation(r), && MechanicalPressBlockEntity.canCompress(r.value()) && !AllRecipeTypes.shouldIgnoreInAutomation(r),
BasinRecipe::convertShapeless) BasinRecipe::convertShapeless)
.catalyst(AllBlocks.MECHANICAL_PRESS::get) .catalyst(AllBlocks.MECHANICAL_PRESS::get)
.catalyst(AllBlocks.BASIN::get) .catalyst(AllBlocks.BASIN::get)
@ -254,7 +256,7 @@ public class CreateJEI implements IModPlugin {
item_application = builder(ItemApplicationRecipe.class) item_application = builder(ItemApplicationRecipe.class)
.addTypedRecipes(AllRecipeTypes.ITEM_APPLICATION) .addTypedRecipes(AllRecipeTypes.ITEM_APPLICATION)
.addRecipes(LogStrippingFakeRecipes::createRecipes) .addRecipes(() -> RecipeGenericsUtil.cast(LogStrippingFakeRecipes.createRecipes()))
.itemIcon(AllItems.BRASS_HAND.get()) .itemIcon(AllItems.BRASS_HAND.get())
.emptyBackground(177, 60) .emptyBackground(177, 60)
.build("item_application", ItemApplicationCategory::new), .build("item_application", ItemApplicationCategory::new),
@ -289,12 +291,12 @@ public class CreateJEI implements IModPlugin {
autoShaped = builder(CraftingRecipe.class) autoShaped = builder(CraftingRecipe.class)
.enableWhen(c -> c.allowRegularCraftingInCrafter) .enableWhen(c -> c.allowRegularCraftingInCrafter)
.addAllRecipesIf(r -> r instanceof CraftingRecipe && !(r instanceof IShapedRecipe<?>) .addAllRecipesIf(r -> r.value() instanceof CraftingRecipe && !(r.value() instanceof ShapedRecipe)
&& r.getIngredients() && r.value().getIngredients()
.size() == 1 .size() == 1
&& !AllRecipeTypes.shouldIgnoreInAutomation(r)) && !AllRecipeTypes.shouldIgnoreInAutomation(r))
.addTypedRecipesIf(() -> RecipeType.CRAFTING, .addTypedRecipesIf(() -> RecipeType.CRAFTING,
recipe -> recipe instanceof IShapedRecipe<?> && !AllRecipeTypes.shouldIgnoreInAutomation(recipe)) recipe -> recipe.value() instanceof ShapedRecipe && !AllRecipeTypes.shouldIgnoreInAutomation(recipe))
.catalyst(AllBlocks.MECHANICAL_CRAFTER::get) .catalyst(AllBlocks.MECHANICAL_CRAFTER::get)
.itemIcon(AllBlocks.MECHANICAL_CRAFTER.get()) .itemIcon(AllBlocks.MECHANICAL_CRAFTER.get())
.emptyBackground(177, 107) .emptyBackground(177, 107)
@ -321,7 +323,7 @@ public class CreateJEI implements IModPlugin {
} }
private <T extends Recipe<?>> CategoryBuilder<T> builder(Class<? extends T> recipeClass) { private <T extends Recipe<? extends RecipeInput>> CategoryBuilder<T> builder(Class<T> recipeClass) {
return new CategoryBuilder<>(recipeClass); return new CategoryBuilder<>(recipeClass);
} }
@ -361,8 +363,8 @@ public class CreateJEI implements IModPlugin {
public <T> void registerFluidSubtypes(ISubtypeRegistration registration, IPlatformFluidHelper<T> platformFluidHelper) { public <T> void registerFluidSubtypes(ISubtypeRegistration registration, IPlatformFluidHelper<T> platformFluidHelper) {
PotionFluidSubtypeInterpreter interpreter = new PotionFluidSubtypeInterpreter(); PotionFluidSubtypeInterpreter interpreter = new PotionFluidSubtypeInterpreter();
PotionFluid potionFluid = AllFluids.POTION.get(); PotionFluid potionFluid = AllFluids.POTION.get();
registration.registerSubtypeInterpreter(ForgeTypes.FLUID_STACK, potionFluid.getSource(), interpreter); registration.registerSubtypeInterpreter(NeoForgeTypes.FLUID_STACK, potionFluid.getSource(), interpreter);
registration.registerSubtypeInterpreter(ForgeTypes.FLUID_STACK, potionFluid.getFlowing(), interpreter); registration.registerSubtypeInterpreter(NeoForgeTypes.FLUID_STACK, potionFluid.getFlowing(), interpreter);
} }
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })
@ -377,14 +379,14 @@ public class CreateJEI implements IModPlugin {
registration.addGhostIngredientHandler(RedstoneRequesterScreen.class, new GhostIngredientHandler()); registration.addGhostIngredientHandler(RedstoneRequesterScreen.class, new GhostIngredientHandler());
} }
private class CategoryBuilder<T extends Recipe<?>> { private class CategoryBuilder<T extends Recipe<? extends RecipeInput>> {
private final Class<? extends T> recipeClass; private final Class<? extends T> recipeClass;
private Predicate<CRecipes> predicate = cRecipes -> true; private Predicate<CRecipes> predicate = cRecipes -> true;
private IDrawable background; private IDrawable background;
private IDrawable icon; private IDrawable icon;
private final List<Consumer<List<T>>> recipeListConsumers = new ArrayList<>(); private final List<Consumer<List<RecipeHolder<T>>>> recipeListConsumers = new ArrayList<>();
private final List<Supplier<? extends ItemStack>> catalysts = new ArrayList<>(); private final List<Supplier<? extends ItemStack>> catalysts = new ArrayList<>();
public CategoryBuilder(Class<? extends T> recipeClass) { public CategoryBuilder(Class<? extends T> recipeClass) {
@ -401,24 +403,24 @@ public class CreateJEI implements IModPlugin {
return this; return this;
} }
public CategoryBuilder<T> addRecipeListConsumer(Consumer<List<T>> consumer) { public CategoryBuilder<T> addRecipeListConsumer(Consumer<List<RecipeHolder<T>>> consumer) {
recipeListConsumers.add(consumer); recipeListConsumers.add(consumer);
return this; return this;
} }
public CategoryBuilder<T> addRecipes(Supplier<Collection<? extends T>> collection) { public CategoryBuilder<T> addRecipes(Supplier<Collection<? extends RecipeHolder<T>>> collection) {
return addRecipeListConsumer(recipes -> recipes.addAll(collection.get())); return addRecipeListConsumer(recipes -> recipes.addAll(collection.get()));
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public CategoryBuilder<T> addAllRecipesIf(Predicate<Recipe<?>> pred) { public CategoryBuilder<T> addAllRecipesIf(Predicate<RecipeHolder<T>> pred) {
return addRecipeListConsumer(recipes -> consumeAllRecipes(recipe -> { return addRecipeListConsumer(recipes -> consumeAllRecipesOfType(recipe -> {
if (pred.test(recipe)) if (pred.test(recipe))
recipes.add((T) recipe); recipes.add(recipe);
})); }));
} }
public CategoryBuilder<T> addAllRecipesIf(Predicate<Recipe<?>> pred, Function<Recipe<?>, T> converter) { public CategoryBuilder<T> addAllRecipesIf(Predicate<RecipeHolder<?>> pred, Function<RecipeHolder<?>, RecipeHolder<T>> converter) {
return addRecipeListConsumer(recipes -> consumeAllRecipes(recipe -> { return addRecipeListConsumer(recipes -> consumeAllRecipes(recipe -> {
if (pred.test(recipe)) { if (pred.test(recipe)) {
recipes.add(converter.apply(recipe)); recipes.add(converter.apply(recipe));
@ -429,17 +431,20 @@ public class CreateJEI implements IModPlugin {
public CategoryBuilder<T> addTypedRecipes(IRecipeTypeInfo recipeTypeEntry) { public CategoryBuilder<T> addTypedRecipes(IRecipeTypeInfo recipeTypeEntry) {
return addTypedRecipes(recipeTypeEntry::getType); return addTypedRecipes(recipeTypeEntry::getType);
} }
public <I extends RecipeInput, R extends Recipe<I>> CategoryBuilder<T> addTypedRecipes(Supplier<RecipeType<R>> recipeType) {
public CategoryBuilder<T> addTypedRecipes(Supplier<RecipeType<? extends T>> recipeType) { return addRecipeListConsumer(recipes -> CreateJEI.<T>consumeTypedRecipes(recipe -> {
return addRecipeListConsumer(recipes -> CreateJEI.<T>consumeTypedRecipes(recipes::add, recipeType.get())); if (recipeClass.isInstance(recipe.value()))
//noinspection unchecked - checked by if statement above
recipes.add((RecipeHolder<T>) recipe);
}, recipeType.get()));
} }
public CategoryBuilder<T> addTypedRecipes(Supplier<RecipeType<? extends T>> recipeType, Function<Recipe<?>, T> converter) { public CategoryBuilder<T> addTypedRecipes(Supplier<RecipeType<T>> recipeType, Function<RecipeHolder<?>, RecipeHolder<T>> converter) {
return addRecipeListConsumer(recipes -> CreateJEI.<T>consumeTypedRecipes(recipe -> recipes.add(converter.apply(recipe)), recipeType.get())); return addRecipeListConsumer(recipes -> CreateJEI.<T>consumeTypedRecipes(recipe -> recipes.add(converter.apply(recipe)), recipeType.get()));
} }
public CategoryBuilder<T> addTypedRecipesIf(Supplier<RecipeType<? extends T>> recipeType, Predicate<Recipe<?>> pred) { public CategoryBuilder<T> addTypedRecipesIf(Supplier<RecipeType<? extends T>> recipeType, Predicate<RecipeHolder<?>> pred) {
return addRecipeListConsumer(recipes -> CreateJEI.<T>consumeTypedRecipes(recipe -> { return addRecipeListConsumer(recipes -> consumeTypedRecipesTyped(recipe -> {
if (pred.test(recipe)) { if (pred.test(recipe)) {
recipes.add(recipe); recipes.add(recipe);
} }
@ -449,10 +454,10 @@ public class CreateJEI implements IModPlugin {
public CategoryBuilder<T> addTypedRecipesExcluding(Supplier<RecipeType<? extends T>> recipeType, public CategoryBuilder<T> addTypedRecipesExcluding(Supplier<RecipeType<? extends T>> recipeType,
Supplier<RecipeType<? extends T>> excluded) { Supplier<RecipeType<? extends T>> excluded) {
return addRecipeListConsumer(recipes -> { return addRecipeListConsumer(recipes -> {
List<Recipe<?>> excludedRecipes = getTypedRecipes(excluded.get()); List<RecipeHolder<?>> excludedRecipes = getTypedRecipes(excluded.get());
CreateJEI.<T>consumeTypedRecipes(recipe -> { consumeTypedRecipesTyped(recipe -> {
for (Recipe<?> excludedRecipe : excludedRecipes) { for (RecipeHolder<?> excludedRecipe : excludedRecipes) {
if (doInputsMatch(recipe, excludedRecipe)) { if (doInputsMatch(recipe.value(), excludedRecipe.value())) {
return; return;
} }
} }
@ -463,10 +468,10 @@ public class CreateJEI implements IModPlugin {
public CategoryBuilder<T> removeRecipes(Supplier<RecipeType<? extends T>> recipeType) { public CategoryBuilder<T> removeRecipes(Supplier<RecipeType<? extends T>> recipeType) {
return addRecipeListConsumer(recipes -> { return addRecipeListConsumer(recipes -> {
List<Recipe<?>> excludedRecipes = getTypedRecipes(recipeType.get()); List<RecipeHolder<?>> excludedRecipes = getTypedRecipes(recipeType.get());
recipes.removeIf(recipe -> { recipes.removeIf(recipe -> {
for (Recipe<?> excludedRecipe : excludedRecipes) for (RecipeHolder<?> excludedRecipe : excludedRecipes)
if (doInputsMatch(recipe, excludedRecipe) && doOutputsMatch(recipe, excludedRecipe)) if (doInputsMatch(recipe.value(), excludedRecipe.value()) && doOutputsMatch(recipe.value(), excludedRecipe.value()))
return true; return true;
return false; return false;
}); });
@ -513,16 +518,16 @@ public class CreateJEI implements IModPlugin {
} }
public CreateRecipeCategory<T> build(String name, CreateRecipeCategory.Factory<T> factory) { public CreateRecipeCategory<T> build(String name, CreateRecipeCategory.Factory<T> factory) {
Supplier<List<T>> recipesSupplier; Supplier<List<RecipeHolder<T>>> recipesSupplier;
if (predicate.test(AllConfigs.server().recipes)) { if (predicate.test(AllConfigs.server().recipes)) {
recipesSupplier = () -> { recipesSupplier = () -> {
List<T> recipes = new ArrayList<>(); List<RecipeHolder<T>> recipes = new ArrayList<>();
for (Consumer<List<T>> consumer : recipeListConsumers) for (Consumer<List<RecipeHolder<T>>> consumer : recipeListConsumers)
consumer.accept(recipes); consumer.accept(recipes);
return recipes; return recipes;
}; };
} else { } else {
recipesSupplier = () -> Collections.emptyList(); recipesSupplier = Collections::emptyList;
} }
CreateRecipeCategory.Info<T> info = new CreateRecipeCategory.Info<>( CreateRecipeCategory.Info<T> info = new CreateRecipeCategory.Info<>(
@ -532,9 +537,27 @@ public class CreateJEI implements IModPlugin {
allCategories.add(category); allCategories.add(category);
return category; return category;
} }
private void consumeAllRecipesOfType(Consumer<RecipeHolder<T>> consumer) {
consumeAllRecipes(recipeHolder -> {
if (recipeClass.isInstance(recipeHolder.value())) {
//noinspection unchecked - this is checked by the if statement
consumer.accept((RecipeHolder<T>) recipeHolder);
}
});
}
private void consumeTypedRecipesTyped(Consumer<RecipeHolder<T>> consumer, RecipeType<?> type) {
consumeTypedRecipes(recipeHolder -> {
if (recipeClass.isInstance(recipeHolder.value())) {
//noinspection unchecked - this is checked by the if statement
consumer.accept((RecipeHolder<T>) recipeHolder);
}
}, type);
}
} }
public static void consumeAllRecipes(Consumer<Recipe<?>> consumer) { public static void consumeAllRecipes(Consumer<? super RecipeHolder<?>> consumer) {
Minecraft.getInstance() Minecraft.getInstance()
.getConnection() .getConnection()
.getRecipeManager() .getRecipeManager()
@ -542,23 +565,23 @@ public class CreateJEI implements IModPlugin {
.forEach(consumer); .forEach(consumer);
} }
@SuppressWarnings("unchecked") @SuppressWarnings({"unchecked", "rawtypes"})
public static <T extends Recipe<?>> void consumeTypedRecipes(Consumer<T> consumer, RecipeType<?> type) { public static <T extends Recipe<?>> void consumeTypedRecipes(Consumer<RecipeHolder<?>> consumer, RecipeType<?> type) {
Map<ResourceLocation, Recipe<?>> map = Minecraft.getInstance() List<? extends RecipeHolder<?>> map = Minecraft.getInstance()
.getConnection() .getConnection()
.getRecipeManager().recipes.get(type); .getRecipeManager().getAllRecipesFor((RecipeType) type);
if (map != null) if (!map.isEmpty())
map.values().forEach(recipe -> consumer.accept((T) recipe)); map.forEach(consumer);
} }
public static List<Recipe<?>> getTypedRecipes(RecipeType<?> type) { public static List<RecipeHolder<?>> getTypedRecipes(RecipeType<?> type) {
List<Recipe<?>> recipes = new ArrayList<>(); List<RecipeHolder<?>> recipes = new ArrayList<>();
consumeTypedRecipes(recipes::add, type); consumeTypedRecipes(recipes::add, type);
return recipes; return recipes;
} }
public static List<Recipe<?>> getTypedRecipesExcluding(RecipeType<?> type, Predicate<Recipe<?>> exclusionPred) { public static List<RecipeHolder<?>> getTypedRecipesExcluding(RecipeType<?> type, Predicate<RecipeHolder<?>> exclusionPred) {
List<Recipe<?>> recipes = getTypedRecipes(type); List<RecipeHolder<?>> recipes = getTypedRecipes(type);
recipes.removeIf(exclusionPred); recipes.removeIf(exclusionPred);
return recipes; return recipes;
} }
@ -571,13 +594,13 @@ public class CreateJEI implements IModPlugin {
return false; return false;
} }
ItemStack[] matchingStacks = recipe1.getIngredients() ItemStack[] matchingStacks = recipe1.getIngredients()
.get(0) .getFirst()
.getItems(); .getItems();
if (matchingStacks.length == 0) { if (matchingStacks.length == 0) {
return false; return false;
} }
return recipe2.getIngredients() return recipe2.getIngredients()
.get(0) .getFirst()
.test(matchingStacks[0]); .test(matchingStacks[0]);
} }

View file

@ -1,22 +1,24 @@
package com.simibubi.create.compat.jei; package com.simibubi.create.compat.jei;
import com.simibubi.create.AllPackets; import java.util.LinkedList;
import java.util.List;
import javax.annotation.ParametersAreNonnullByDefault;
import com.simibubi.create.content.logistics.filter.AttributeFilterScreen; import com.simibubi.create.content.logistics.filter.AttributeFilterScreen;
import com.simibubi.create.foundation.gui.menu.AbstractSimiContainerScreen; import com.simibubi.create.foundation.gui.menu.AbstractSimiContainerScreen;
import com.simibubi.create.foundation.gui.menu.GhostItemMenu; import com.simibubi.create.foundation.gui.menu.GhostItemMenu;
import com.simibubi.create.foundation.gui.menu.GhostItemSubmitPacket; import com.simibubi.create.foundation.gui.menu.GhostItemSubmitPacket;
import mezz.jei.api.constants.VanillaTypes; import mezz.jei.api.constants.VanillaTypes;
import mezz.jei.api.gui.handlers.IGhostIngredientHandler; import mezz.jei.api.gui.handlers.IGhostIngredientHandler;
import mezz.jei.api.ingredients.ITypedIngredient; import mezz.jei.api.ingredients.ITypedIngredient;
import net.createmod.catnip.platform.CatnipServices;
import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.client.renderer.Rect2i; import net.minecraft.client.renderer.Rect2i;
import net.minecraft.world.inventory.Slot; import net.minecraft.world.inventory.Slot;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.LinkedList;
import java.util.List;
@MethodsReturnNonnullByDefault @MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
public class GhostIngredientHandler<T extends GhostItemMenu<?>> public class GhostIngredientHandler<T extends GhostItemMenu<?>>
@ -83,7 +85,7 @@ public class GhostIngredientHandler<T extends GhostItemMenu<?>>
return; return;
// sync new filter contents with server // sync new filter contents with server
AllPackets.getChannel().sendToServer(new GhostItemSubmitPacket(stack, slotIndex)); CatnipServices.NETWORK.sendToServer(new GhostItemSubmitPacket(stack, slotIndex));
} }
} }
} }

View file

@ -2,43 +2,40 @@ package com.simibubi.create.compat.jei;
import java.util.List; import java.util.List;
import com.simibubi.create.AllDataComponents;
import com.simibubi.create.content.fluids.potion.PotionFluid.BottleType; import com.simibubi.create.content.fluids.potion.PotionFluid.BottleType;
import mezz.jei.api.ingredients.subtypes.IIngredientSubtypeInterpreter; import mezz.jei.api.ingredients.subtypes.IIngredientSubtypeInterpreter;
import mezz.jei.api.ingredients.subtypes.UidContext; import mezz.jei.api.ingredients.subtypes.UidContext;
import net.createmod.catnip.utility.NBTHelper; import net.minecraft.core.component.DataComponents;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.item.alchemy.Potion; import net.minecraft.world.item.alchemy.PotionContents;
import net.minecraft.world.item.alchemy.PotionUtils; import net.neoforged.neoforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidStack;
/* From JEI's Potion item subtype interpreter */ /* From JEI's Potion item subtype interpreter */
public class PotionFluidSubtypeInterpreter implements IIngredientSubtypeInterpreter<FluidStack> { public class PotionFluidSubtypeInterpreter implements IIngredientSubtypeInterpreter<FluidStack> {
@Override @Override
public String apply(FluidStack ingredient, UidContext context) { public String apply(FluidStack ingredient, UidContext context) {
if (!ingredient.hasTag()) if (ingredient.getComponentsPatch().isEmpty())
return IIngredientSubtypeInterpreter.NONE; return IIngredientSubtypeInterpreter.NONE;
CompoundTag tag = ingredient.getOrCreateTag(); PotionContents contents = ingredient.getOrDefault(DataComponents.POTION_CONTENTS, PotionContents.EMPTY);
Potion potionType = PotionUtils.getPotion(tag); String potionTypeString = ingredient.getDescriptionId();
String potionTypeString = potionType.getName(""); String bottleType = ingredient.getOrDefault(AllDataComponents.POTION_FLUID_BOTTLE_TYPE, BottleType.REGULAR).name();
String bottleType = NBTHelper.readEnum(tag, "Bottle", BottleType.class)
.toString();
StringBuilder stringBuilder = new StringBuilder(potionTypeString); StringBuilder stringBuilder = new StringBuilder(potionTypeString);
List<MobEffectInstance> effects = PotionUtils.getCustomEffects(tag); List<MobEffectInstance> effects = contents.customEffects();
stringBuilder.append(";") stringBuilder.append(";")
.append(bottleType); .append(bottleType);
for (MobEffectInstance effect : potionType.getEffects()) contents.potion().ifPresent(p -> {
stringBuilder.append(";") for (MobEffectInstance effect : p.value().getEffects())
.append(effect); stringBuilder.append(";")
.append(effect);
});
for (MobEffectInstance effect : effects) for (MobEffectInstance effect : effects)
stringBuilder.append(";") stringBuilder.append(";")
.append(effect); .append(effect);
return stringBuilder.toString(); return stringBuilder.toString();
} }
} }

View file

@ -17,6 +17,7 @@ import com.simibubi.create.content.logistics.packager.InventorySummary;
import com.simibubi.create.content.logistics.stockTicker.CraftableBigItemStack; import com.simibubi.create.content.logistics.stockTicker.CraftableBigItemStack;
import com.simibubi.create.content.logistics.stockTicker.StockKeeperRequestMenu; import com.simibubi.create.content.logistics.stockTicker.StockKeeperRequestMenu;
import com.simibubi.create.content.logistics.stockTicker.StockKeeperRequestScreen; import com.simibubi.create.content.logistics.stockTicker.StockKeeperRequestScreen;
import com.simibubi.create.foundation.blockEntity.LegacyRecipeWrapper;
import com.simibubi.create.foundation.utility.CreateLang; import com.simibubi.create.foundation.utility.CreateLang;
import mezz.jei.api.gui.ingredient.IRecipeSlotsView; import mezz.jei.api.gui.ingredient.IRecipeSlotsView;
@ -29,6 +30,7 @@ import mezz.jei.common.transfer.RecipeTransferOperationsResult;
import mezz.jei.common.transfer.RecipeTransferUtil; import mezz.jei.common.transfer.RecipeTransferUtil;
import mezz.jei.library.transfer.RecipeTransferErrorMissingSlots; import mezz.jei.library.transfer.RecipeTransferErrorMissingSlots;
import mezz.jei.library.transfer.RecipeTransferErrorTooltip; import mezz.jei.library.transfer.RecipeTransferErrorTooltip;
import net.createmod.catnip.platform.CatnipServices;
import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.world.Container; import net.minecraft.world.Container;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
@ -37,10 +39,7 @@ import net.minecraft.world.inventory.Slot;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Recipe; import net.minecraft.world.item.crafting.Recipe;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraftforge.api.distmarker.Dist; import net.neoforged.neoforge.items.ItemStackHandler;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.items.ItemStackHandler;
import net.minecraftforge.items.wrapper.RecipeWrapper;
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault @MethodsReturnNonnullByDefault
@ -75,7 +74,7 @@ public class StockKeeperTransferHandler implements IRecipeTransferHandler<StockK
return null; return null;
MutableObject<IRecipeTransferError> result = new MutableObject<>(); MutableObject<IRecipeTransferError> result = new MutableObject<>();
if (level.isClientSide()) if (level.isClientSide())
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> result CatnipServices.PLATFORM.executeOnClientOnly(() -> () -> result
.setValue(transferRecipeOnClient(container, recipe, recipeSlots, player, maxTransfer, doTransfer))); .setValue(transferRecipeOnClient(container, recipe, recipeSlots, player, maxTransfer, doTransfer)));
return result.getValue(); return result.getValue();
} }
@ -98,13 +97,13 @@ public class StockKeeperTransferHandler implements IRecipeTransferHandler<StockK
if (summary == null) if (summary == null)
return null; return null;
Container outputDummy = new RecipeWrapper(new ItemStackHandler(9)); Container outputDummy = new LegacyRecipeWrapper(new ItemStackHandler(9));
List<Slot> craftingSlots = new ArrayList<>(); List<Slot> craftingSlots = new ArrayList<>();
for (int i = 0; i < outputDummy.getContainerSize(); i++) for (int i = 0; i < outputDummy.getContainerSize(); i++)
craftingSlots.add(new Slot(outputDummy, i, 0, 0)); craftingSlots.add(new Slot(outputDummy, i, 0, 0));
List<BigItemStack> stacksByCount = summary.getStacksByCount(); List<BigItemStack> stacksByCount = summary.getStacksByCount();
Container inputDummy = new RecipeWrapper(new ItemStackHandler(stacksByCount.size())); Container inputDummy = new LegacyRecipeWrapper(new ItemStackHandler(stacksByCount.size()));
Map<Slot, ItemStack> availableItemStacks = new HashMap<>(); Map<Slot, ItemStack> availableItemStacks = new HashMap<>();
for (int j = 0; j < stacksByCount.size(); j++) { for (int j = 0; j < stacksByCount.size(); j++) {
BigItemStack bigItemStack = stacksByCount.get(j); BigItemStack bigItemStack = stacksByCount.get(j);

View file

@ -3,7 +3,6 @@ package com.simibubi.create.compat.jei;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import net.minecraft.core.NonNullList; import net.minecraft.core.NonNullList;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.TagKey; import net.minecraft.tags.TagKey;
import net.minecraft.world.item.DyeColor; import net.minecraft.world.item.DyeColor;
import net.minecraft.world.item.DyeItem; import net.minecraft.world.item.DyeItem;
@ -12,6 +11,7 @@ import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.CraftingBookCategory; import net.minecraft.world.item.crafting.CraftingBookCategory;
import net.minecraft.world.item.crafting.CraftingRecipe; import net.minecraft.world.item.crafting.CraftingRecipe;
import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.item.crafting.RecipeHolder;
import net.minecraft.world.item.crafting.ShapelessRecipe; import net.minecraft.world.item.crafting.ShapelessRecipe;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
@ -21,7 +21,7 @@ import java.util.stream.Stream;
public final class ToolboxColoringRecipeMaker { public final class ToolboxColoringRecipeMaker {
// From JEI's ShulkerBoxColoringRecipeMaker // From JEI's ShulkerBoxColoringRecipeMaker
public static Stream<CraftingRecipe> createRecipes() { public static Stream<RecipeHolder<CraftingRecipe>> createRecipes() {
String group = "create.toolbox.color"; String group = "create.toolbox.color";
ItemStack baseShulkerStack = AllBlocks.TOOLBOXES.get(DyeColor.BROWN) ItemStack baseShulkerStack = AllBlocks.TOOLBOXES.get(DyeColor.BROWN)
.asStack(); .asStack();
@ -42,8 +42,8 @@ public final class ToolboxColoringRecipeMaker {
Block coloredShulkerBox = AllBlocks.TOOLBOXES.get(color) Block coloredShulkerBox = AllBlocks.TOOLBOXES.get(color)
.get(); .get();
ItemStack output = new ItemStack(coloredShulkerBox); ItemStack output = new ItemStack(coloredShulkerBox);
ResourceLocation id = Create.asResource(group + "." + output.getDescriptionId()); ShapelessRecipe recipe = new ShapelessRecipe(group, CraftingBookCategory.MISC, output, inputs);
return new ShapelessRecipe(id, group, CraftingBookCategory.MISC, output, inputs); return new RecipeHolder<>(Create.asResource(group + "/" + color), recipe);
}); });
} }

View file

@ -10,9 +10,10 @@ import com.simibubi.create.foundation.fluid.FluidIngredient;
import com.simibubi.create.foundation.gui.AllGuiTextures; import com.simibubi.create.foundation.gui.AllGuiTextures;
import com.simibubi.create.foundation.item.ItemHelper; import com.simibubi.create.foundation.item.ItemHelper;
import com.simibubi.create.foundation.utility.CreateLang; import com.simibubi.create.foundation.utility.CreateLang;
import mezz.jei.api.forge.ForgeTypes;
import mezz.jei.api.gui.builder.IRecipeLayoutBuilder; import mezz.jei.api.gui.builder.IRecipeLayoutBuilder;
import mezz.jei.api.gui.ingredient.IRecipeSlotsView; import mezz.jei.api.gui.ingredient.IRecipeSlotsView;
import mezz.jei.api.neoforge.NeoForgeTypes;
import mezz.jei.api.recipe.IFocusGroup; import mezz.jei.api.recipe.IFocusGroup;
import mezz.jei.api.recipe.RecipeIngredientRole; import mezz.jei.api.recipe.RecipeIngredientRole;
import net.createmod.catnip.utility.Pair; import net.createmod.catnip.utility.Pair;
@ -20,7 +21,7 @@ import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.world.item.crafting.Ingredient;
import net.minecraftforge.fluids.FluidStack; import net.neoforged.neoforge.fluids.FluidStack;
import org.apache.commons.lang3.mutable.MutableInt; import org.apache.commons.lang3.mutable.MutableInt;
import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.ParametersAreNonnullByDefault;
@ -63,7 +64,7 @@ public class BasinCategory extends CreateRecipeCategory<BasinRecipe> {
builder builder
.addSlot(RecipeIngredientRole.INPUT, 17 + xOffset + (i % 3) * 19, 51 - (i / 3) * 19) .addSlot(RecipeIngredientRole.INPUT, 17 + xOffset + (i % 3) * 19, 51 - (i / 3) * 19)
.setBackground(getRenderedSlot(), -1, -1) .setBackground(getRenderedSlot(), -1, -1)
.addIngredients(ForgeTypes.FLUID_STACK, withImprovedVisibility(fluidIngredient.getMatchingFluidStacks())) .addIngredients(NeoForgeTypes.FLUID_STACK, withImprovedVisibility(fluidIngredient.getMatchingFluidStacks()))
.addTooltipCallback(addFluidTooltip(fluidIngredient.getRequiredAmount())); .addTooltipCallback(addFluidTooltip(fluidIngredient.getRequiredAmount()));
i++; i++;
} }
@ -90,7 +91,7 @@ public class BasinCategory extends CreateRecipeCategory<BasinRecipe> {
builder builder
.addSlot(RecipeIngredientRole.OUTPUT, xPosition, yPosition) .addSlot(RecipeIngredientRole.OUTPUT, xPosition, yPosition)
.setBackground(getRenderedSlot(), -1, -1) .setBackground(getRenderedSlot(), -1, -1)
.addIngredient(ForgeTypes.FLUID_STACK, withImprovedVisibility(fluidResult)) .addIngredient(NeoForgeTypes.FLUID_STACK, withImprovedVisibility(fluidResult))
.addTooltipCallback(addFluidTooltip(fluidResult.getAmount())); .addTooltipCallback(addFluidTooltip(fluidResult.getAmount()));
i++; i++;
} }

View file

@ -9,10 +9,9 @@ import mezz.jei.api.gui.ingredient.IRecipeSlotsView;
import mezz.jei.api.recipe.IFocusGroup; import mezz.jei.api.recipe.IFocusGroup;
import mezz.jei.api.recipe.RecipeIngredientRole; import mezz.jei.api.recipe.RecipeIngredientRole;
import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.item.crafting.Recipe; import net.minecraft.world.item.crafting.RecipeHolder;
import net.minecraft.world.item.crafting.StonecutterRecipe; import net.minecraft.world.item.crafting.StonecutterRecipe;
import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.ParametersAreNonnullByDefault;
@ -63,7 +62,7 @@ public class BlockCuttingCategory extends CreateRecipeCategory<CondensedBlockCut
List<ItemStack> outputs = new ArrayList<>(); List<ItemStack> outputs = new ArrayList<>();
public CondensedBlockCuttingRecipe(Ingredient ingredient) { public CondensedBlockCuttingRecipe(Ingredient ingredient) {
super(new ResourceLocation(""), "", ingredient, ItemStack.EMPTY); super("", ingredient, ItemStack.EMPTY);
} }
public void addOutput(ItemStack stack) { public void addOutput(ItemStack stack) {
@ -98,19 +97,19 @@ public class BlockCuttingCategory extends CreateRecipeCategory<CondensedBlockCut
} }
public static List<CondensedBlockCuttingRecipe> condenseRecipes(List<Recipe<?>> stoneCuttingRecipes) { public static List<RecipeHolder<CondensedBlockCuttingRecipe>> condenseRecipes(List<RecipeHolder<?>> stoneCuttingRecipes) {
List<CondensedBlockCuttingRecipe> condensed = new ArrayList<>(); List<RecipeHolder<CondensedBlockCuttingRecipe>> condensed = new ArrayList<>();
Recipes: for (Recipe<?> recipe : stoneCuttingRecipes) { Recipes: for (RecipeHolder<?> recipe : stoneCuttingRecipes) {
Ingredient i1 = recipe.getIngredients().get(0); Ingredient i1 = recipe.value().getIngredients().get(0);
for (CondensedBlockCuttingRecipe condensedRecipe : condensed) { for (RecipeHolder<CondensedBlockCuttingRecipe> condensedRecipe : condensed) {
if (ItemHelper.matchIngredients(i1, condensedRecipe.getIngredients().get(0))) { if (ItemHelper.matchIngredients(i1, condensedRecipe.value().getIngredients().get(0))) {
condensedRecipe.addOutput(getResultItem(recipe)); condensedRecipe.value().addOutput(getResultItem(recipe.value()));
continue Recipes; continue Recipes;
} }
} }
CondensedBlockCuttingRecipe cr = new CondensedBlockCuttingRecipe(i1); CondensedBlockCuttingRecipe cr = new CondensedBlockCuttingRecipe(i1);
cr.addOutput(getResultItem(recipe)); cr.addOutput(getResultItem(recipe.value()));
condensed.add(cr); condensed.add(new RecipeHolder<>(recipe.id(), cr));
} }
return condensed; return condensed;
} }

View file

@ -5,9 +5,10 @@ import com.simibubi.create.content.fluids.potion.PotionFluidHandler;
import com.simibubi.create.content.processing.recipe.ProcessingOutput; import com.simibubi.create.content.processing.recipe.ProcessingOutput;
import com.simibubi.create.foundation.gui.AllGuiTextures; import com.simibubi.create.foundation.gui.AllGuiTextures;
import com.simibubi.create.foundation.utility.CreateLang; import com.simibubi.create.foundation.utility.CreateLang;
import mezz.jei.api.forge.ForgeTypes;
import mezz.jei.api.gui.drawable.IDrawable; import mezz.jei.api.gui.drawable.IDrawable;
import mezz.jei.api.gui.ingredient.IRecipeSlotTooltipCallback; import mezz.jei.api.gui.ingredient.IRecipeSlotTooltipCallback;
import mezz.jei.api.neoforge.NeoForgeTypes;
import mezz.jei.api.recipe.RecipeType; import mezz.jei.api.recipe.RecipeType;
import mezz.jei.api.recipe.category.IRecipeCategory; import mezz.jei.api.recipe.category.IRecipeCategory;
import mezz.jei.api.registration.IRecipeCatalystRegistration; import mezz.jei.api.registration.IRecipeCatalystRegistration;
@ -21,7 +22,8 @@ import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Recipe; import net.minecraft.world.item.crafting.Recipe;
import net.minecraftforge.fluids.FluidStack; import net.minecraft.world.item.crafting.RecipeHolder;
import net.neoforged.neoforge.fluids.FluidStack;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.ParametersAreNonnullByDefault;
@ -42,7 +44,7 @@ public abstract class CreateRecipeCategory<T extends Recipe<?>> implements IReci
protected final IDrawable background; protected final IDrawable background;
protected final IDrawable icon; protected final IDrawable icon;
private final Supplier<List<T>> recipes; private final Supplier<List<RecipeHolder<T>>> recipes;
private final List<Supplier<? extends ItemStack>> catalysts; private final List<Supplier<? extends ItemStack>> catalysts;
public CreateRecipeCategory(Info<T> info) { public CreateRecipeCategory(Info<T> info) {
@ -76,7 +78,7 @@ public abstract class CreateRecipeCategory<T extends Recipe<?>> implements IReci
} }
public void registerRecipes(IRecipeRegistration registration) { public void registerRecipes(IRecipeRegistration registration) {
registration.addRecipes(type, recipes.get()); registration.addRecipes(type, recipes.get().stream().map(RecipeHolder::value).toList());
} }
public void registerCatalysts(IRecipeCatalystRegistration registration) { public void registerCatalysts(IRecipeCatalystRegistration registration) {
@ -133,14 +135,14 @@ public abstract class CreateRecipeCategory<T extends Recipe<?>> implements IReci
public static IRecipeSlotTooltipCallback addFluidTooltip(int mbAmount) { public static IRecipeSlotTooltipCallback addFluidTooltip(int mbAmount) {
return (view, tooltip) -> { return (view, tooltip) -> {
Optional<FluidStack> displayed = view.getDisplayedIngredient(ForgeTypes.FLUID_STACK); Optional<FluidStack> displayed = view.getDisplayedIngredient(NeoForgeTypes.FLUID_STACK);
if (displayed.isEmpty()) if (displayed.isEmpty())
return; return;
FluidStack fluidStack = displayed.get(); FluidStack fluidStack = displayed.get();
if (fluidStack.getFluid().isSame(AllFluids.POTION.get())) { if (fluidStack.getFluid().isSame(AllFluids.POTION.get())) {
Component name = fluidStack.getDisplayName(); Component name = fluidStack.getHoverName();
if (tooltip.isEmpty()) if (tooltip.isEmpty())
tooltip.add(0, name); tooltip.add(0, name);
else else
@ -182,7 +184,7 @@ public abstract class CreateRecipeCategory<T extends Recipe<?>> implements IReci
}; };
} }
public record Info<T extends Recipe<?>>(RecipeType<T> recipeType, Component title, IDrawable background, IDrawable icon, Supplier<List<T>> recipes, List<Supplier<? extends ItemStack>> catalysts) { public record Info<T extends Recipe<?>>(RecipeType<T> recipeType, Component title, IDrawable background, IDrawable icon, Supplier<List<RecipeHolder<T>>> recipes, List<Supplier<? extends ItemStack>> catalysts) {
} }
public interface Factory<T extends Recipe<?>> { public interface Factory<T extends Recipe<?>> {

View file

@ -12,23 +12,23 @@ import com.simibubi.create.content.processing.recipe.ProcessingRecipeBuilder;
import com.simibubi.create.foundation.gui.AllGuiTextures; import com.simibubi.create.foundation.gui.AllGuiTextures;
import mezz.jei.api.constants.VanillaTypes; import mezz.jei.api.constants.VanillaTypes;
import mezz.jei.api.forge.ForgeTypes;
import mezz.jei.api.gui.builder.IRecipeLayoutBuilder; import mezz.jei.api.gui.builder.IRecipeLayoutBuilder;
import mezz.jei.api.gui.ingredient.IRecipeSlotsView; import mezz.jei.api.gui.ingredient.IRecipeSlotsView;
import mezz.jei.api.neoforge.NeoForgeTypes;
import mezz.jei.api.recipe.IFocusGroup; import mezz.jei.api.recipe.IFocusGroup;
import mezz.jei.api.recipe.RecipeIngredientRole; import mezz.jei.api.recipe.RecipeIngredientRole;
import mezz.jei.api.runtime.IIngredientManager; import mezz.jei.api.runtime.IIngredientManager;
import net.createmod.catnip.platform.CatnipServices; import net.createmod.catnip.utility.RegisteredObjectsHelper;
import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items; import net.minecraft.world.item.Items;
import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.world.item.crafting.Ingredient;
import net.minecraftforge.common.capabilities.ForgeCapabilities; import net.minecraft.world.item.crafting.RecipeHolder;
import net.minecraftforge.common.util.LazyOptional; import net.neoforged.neoforge.capabilities.Capabilities;
import net.minecraftforge.fluids.FluidStack; import net.neoforged.neoforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.IFluidHandler.FluidAction; import net.neoforged.neoforge.fluids.capability.IFluidHandler.FluidAction;
import net.minecraftforge.fluids.capability.IFluidHandlerItem; import net.neoforged.neoforge.fluids.capability.IFluidHandlerItem;
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
public class ItemDrainCategory extends CreateRecipeCategory<EmptyingRecipe> { public class ItemDrainCategory extends CreateRecipeCategory<EmptyingRecipe> {
@ -39,44 +39,46 @@ public class ItemDrainCategory extends CreateRecipeCategory<EmptyingRecipe> {
super(info); super(info);
} }
public static void consumeRecipes(Consumer<EmptyingRecipe> consumer, IIngredientManager ingredientManager) { public static void consumeRecipes(Consumer<RecipeHolder<EmptyingRecipe>> consumer, IIngredientManager ingredientManager) {
for (ItemStack stack : ingredientManager.getAllIngredients(VanillaTypes.ITEM_STACK)) { for (ItemStack stack : ingredientManager.getAllIngredients(VanillaTypes.ITEM_STACK)) {
if (PotionFluidHandler.isPotionItem(stack)) { if (PotionFluidHandler.isPotionItem(stack)) {
FluidStack fluidFromPotionItem = PotionFluidHandler.getFluidFromPotionItem(stack); FluidStack fluidFromPotionItem = PotionFluidHandler.getFluidFromPotionItem(stack);
Ingredient potion = Ingredient.of(stack); Ingredient potion = Ingredient.of(stack);
consumer.accept(new ProcessingRecipeBuilder<>(EmptyingRecipe::new, Create.asResource("potions")) ResourceLocation id = Create.asResource("potions");
.withItemIngredients(potion) EmptyingRecipe recipe = new ProcessingRecipeBuilder<>(EmptyingRecipe::new, id)
.withFluidOutputs(fluidFromPotionItem) .withItemIngredients(potion)
.withSingleItemOutput(new ItemStack(Items.GLASS_BOTTLE)) .withFluidOutputs(fluidFromPotionItem)
.build()); .withSingleItemOutput(new ItemStack(Items.GLASS_BOTTLE))
.build();
consumer.accept(new RecipeHolder<>(id, recipe));
continue; continue;
} }
LazyOptional<IFluidHandlerItem> capability = IFluidHandlerItem capability = stack.getCapability(Capabilities.FluidHandler.ITEM);
stack.getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM); if (capability == null)
if (!capability.isPresent())
continue; continue;
ItemStack copy = stack.copy(); ItemStack copy = stack.copy();
capability = copy.getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM); capability = copy.getCapability(Capabilities.FluidHandler.ITEM);
IFluidHandlerItem handler = capability.orElse(null); FluidStack extracted = capability.drain(1000, FluidAction.EXECUTE);
FluidStack extracted = handler.drain(1000, FluidAction.EXECUTE); ItemStack result = capability.getContainer();
ItemStack result = handler.getContainer();
if (extracted.isEmpty()) if (extracted.isEmpty())
continue; continue;
if (result.isEmpty()) if (result.isEmpty())
continue; continue;
Ingredient ingredient = Ingredient.of(stack); Ingredient ingredient = Ingredient.of(stack);
ResourceLocation itemName = CatnipServices.REGISTRIES.getKeyOrThrow(stack.getItem()); ResourceLocation itemName = RegisteredObjectsHelper.getKeyOrThrow(stack.getItem());
ResourceLocation fluidName = CatnipServices.REGISTRIES.getKeyOrThrow(extracted.getFluid()); ResourceLocation fluidName = RegisteredObjectsHelper.getKeyOrThrow(extracted.getFluid());
consumer.accept(new ProcessingRecipeBuilder<>(EmptyingRecipe::new, ResourceLocation id = Create.asResource("empty_" + itemName.getNamespace() + "_" + itemName.getPath() + "_of_"
Create.asResource("empty_" + itemName.getNamespace() + "_" + itemName.getPath() + "_of_" + fluidName.getNamespace() + "_" + fluidName.getPath());
+ fluidName.getNamespace() + "_" + fluidName.getPath())).withItemIngredients(ingredient) EmptyingRecipe recipe = new ProcessingRecipeBuilder<>(EmptyingRecipe::new, id)
.withFluidOutputs(extracted) .withItemIngredients(ingredient)
.withSingleItemOutput(result) .withFluidOutputs(extracted)
.build()); .withSingleItemOutput(result)
.build();
consumer.accept(new RecipeHolder<>(id, recipe));
} }
} }
@ -89,7 +91,7 @@ public class ItemDrainCategory extends CreateRecipeCategory<EmptyingRecipe> {
builder builder
.addSlot(RecipeIngredientRole.OUTPUT, 132, 8) .addSlot(RecipeIngredientRole.OUTPUT, 132, 8)
.setBackground(getRenderedSlot(), -1, -1) .setBackground(getRenderedSlot(), -1, -1)
.addIngredient(ForgeTypes.FLUID_STACK, withImprovedVisibility(recipe.getResultingFluid())) .addIngredient(NeoForgeTypes.FLUID_STACK, withImprovedVisibility(recipe.getResultingFluid()))
.addTooltipCallback(addFluidTooltip(recipe.getResultingFluid().getAmount())); .addTooltipCallback(addFluidTooltip(recipe.getResultingFluid().getAmount()));
builder builder
.addSlot(RecipeIngredientRole.OUTPUT, 132, 27) .addSlot(RecipeIngredientRole.OUTPUT, 132, 27)

View file

@ -5,6 +5,10 @@ import java.util.List;
import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.ParametersAreNonnullByDefault;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.crafting.ShapedRecipe;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
@ -30,7 +34,8 @@ import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.TooltipFlag; import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.item.crafting.CraftingRecipe; import net.minecraft.world.item.crafting.CraftingRecipe;
import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.world.item.crafting.Ingredient;
import net.minecraftforge.common.crafting.IShapedRecipe;
import org.joml.Matrix4fStack;
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
public class MechanicalCraftingCategory extends CreateRecipeCategory<CraftingRecipe> { public class MechanicalCraftingCategory extends CreateRecipeCategory<CraftingRecipe> {
@ -84,11 +89,11 @@ public class MechanicalCraftingCategory extends CreateRecipeCategory<CraftingRec
} }
private static int getWidth(CraftingRecipe recipe) { private static int getWidth(CraftingRecipe recipe) {
return recipe instanceof IShapedRecipe<?> ? ((IShapedRecipe<?>) recipe).getRecipeWidth() : 1; return recipe instanceof ShapedRecipe ? ((ShapedRecipe) recipe).getWidth() : 1;
} }
private static int getHeight(CraftingRecipe recipe) { private static int getHeight(CraftingRecipe recipe) {
return recipe instanceof IShapedRecipe<?> ? ((IShapedRecipe<?>) recipe).getRecipeHeight() : 1; return recipe instanceof ShapedRecipe ? ((ShapedRecipe) recipe).getHeight() : 1;
} }
@Override @Override
@ -154,8 +159,8 @@ public class MechanicalCraftingCategory extends CreateRecipeCategory<CraftingRec
matrixStack.scale(scale, scale, scale); matrixStack.scale(scale, scale, scale);
if (ingredient != null) { if (ingredient != null) {
PoseStack modelViewStack = RenderSystem.getModelViewStack(); Matrix4fStack modelViewStack = RenderSystem.getModelViewStack();
modelViewStack.pushPose(); modelViewStack.pushMatrix();
RenderSystem.applyModelViewMatrix(); RenderSystem.applyModelViewMatrix();
RenderSystem.enableDepthTest(); RenderSystem.enableDepthTest();
Minecraft minecraft = Minecraft.getInstance(); Minecraft minecraft = Minecraft.getInstance();
@ -163,7 +168,7 @@ public class MechanicalCraftingCategory extends CreateRecipeCategory<CraftingRec
graphics.renderItem(ingredient, 0, 0); graphics.renderItem(ingredient, 0, 0);
graphics.renderItemDecorations(font, ingredient, 0, 0, null); graphics.renderItemDecorations(font, ingredient, 0, 0, null);
RenderSystem.disableBlend(); RenderSystem.disableBlend();
modelViewStack.popPose(); modelViewStack.popMatrix();
RenderSystem.applyModelViewMatrix(); RenderSystem.applyModelViewMatrix();
} }
@ -185,7 +190,7 @@ public class MechanicalCraftingCategory extends CreateRecipeCategory<CraftingRec
Minecraft minecraft = Minecraft.getInstance(); Minecraft minecraft = Minecraft.getInstance();
Player player = minecraft.player; Player player = minecraft.player;
try { try {
return ingredient.getTooltipLines(player, tooltipFlag); return ingredient.getTooltipLines(Item.TooltipContext.of(minecraft.level), player, tooltipFlag);
} catch (RuntimeException | LinkageError e) { } catch (RuntimeException | LinkageError e) {
List<Component> list = new ArrayList<>(); List<Component> list = new ArrayList<>();
MutableComponent crash = Components.translatable("jei.tooltip.error.crash"); MutableComponent crash = Components.translatable("jei.tooltip.error.crash");

View file

@ -9,6 +9,7 @@ import mezz.jei.api.gui.ingredient.IRecipeSlotsView;
import mezz.jei.api.recipe.IFocusGroup; import mezz.jei.api.recipe.IFocusGroup;
import mezz.jei.api.recipe.RecipeIngredientRole; import mezz.jei.api.recipe.RecipeIngredientRole;
import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.world.item.crafting.RecipeHolder;
import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.ParametersAreNonnullByDefault;
import java.util.ArrayList; import java.util.ArrayList;
@ -17,7 +18,7 @@ import java.util.List;
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
public class MysteriousItemConversionCategory extends CreateRecipeCategory<ConversionRecipe> { public class MysteriousItemConversionCategory extends CreateRecipeCategory<ConversionRecipe> {
public static final List<ConversionRecipe> RECIPES = new ArrayList<>(); public static final List<RecipeHolder<ConversionRecipe>> RECIPES = new ArrayList<>();
static { static {
RECIPES.add(ConversionRecipe.create(AllItems.EMPTY_BLAZE_BURNER.asStack(), AllBlocks.BLAZE_BURNER.asStack())); RECIPES.add(ConversionRecipe.create(AllItems.EMPTY_BLAZE_BURNER.asStack(), AllBlocks.BLAZE_BURNER.asStack()));

View file

@ -1,5 +1,6 @@
package com.simibubi.create.compat.jei.category; package com.simibubi.create.compat.jei.category;
import com.simibubi.create.AllDataComponents;
import com.simibubi.create.AllItems; import com.simibubi.create.AllItems;
import com.simibubi.create.content.equipment.sandPaper.SandPaperPolishingRecipe; import com.simibubi.create.content.equipment.sandPaper.SandPaperPolishingRecipe;
import com.simibubi.create.content.processing.recipe.ProcessingOutput; import com.simibubi.create.content.processing.recipe.ProcessingOutput;
@ -11,7 +12,7 @@ import mezz.jei.api.recipe.RecipeIngredientRole;
import net.createmod.catnip.gui.element.GuiGameElement; import net.createmod.catnip.gui.element.GuiGameElement;
import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.core.NonNullList; import net.minecraft.core.NonNullList;
import net.minecraft.nbt.CompoundTag; import net.minecraft.util.Unit;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.world.item.crafting.Ingredient;
@ -53,10 +54,8 @@ public class PolishingCategory extends CreateRecipeCategory<SandPaperPolishingRe
if (matchingStacks.length == 0) if (matchingStacks.length == 0)
return; return;
renderedSandpaper.set(AllDataComponents.SAND_PAPER_POLISHING, matchingStacks[0]);
CompoundTag tag = renderedSandpaper.getOrCreateTag(); renderedSandpaper.set(AllDataComponents.SAND_PAPER_JEI, Unit.INSTANCE);
tag.put("Polishing", matchingStacks[0].serializeNBT());
tag.putBoolean("JEI", true);
GuiGameElement.of(renderedSandpaper) GuiGameElement.of(renderedSandpaper)
.<GuiGameElement.GuiRenderBuilder>at(getBackground().getWidth() / 2 - 16, 0, 0) .<GuiGameElement.GuiRenderBuilder>at(getBackground().getWidth() / 2 - 16, 0, 0)
.scale(2) .scale(2)

View file

@ -14,6 +14,7 @@ import mezz.jei.api.gui.ingredient.IRecipeSlotsView;
import mezz.jei.api.recipe.IFocusGroup; import mezz.jei.api.recipe.IFocusGroup;
import mezz.jei.api.recipe.RecipeIngredientRole; import mezz.jei.api.recipe.RecipeIngredientRole;
import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.core.component.DataComponents;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Recipe; import net.minecraft.world.item.crafting.Recipe;
@ -31,8 +32,9 @@ public abstract class ProcessingViaFanCategory<T extends Recipe<?>> extends Crea
} }
public static Supplier<ItemStack> getFan(String name) { public static Supplier<ItemStack> getFan(String name) {
return () -> AllBlocks.ENCASED_FAN.asStack() ItemStack stack = AllBlocks.ENCASED_FAN.asStack();
.setHoverName(CreateLang.translateDirect("recipe." + name + ".fan").withStyle(style -> style.withItalic(false))); stack.set(DataComponents.CUSTOM_NAME, CreateLang.translateDirect("recipe." + name + ".fan").withStyle(style -> style.withItalic(false)));
return () -> stack;
} }
@Override @Override

View file

@ -1,5 +1,14 @@
package com.simibubi.create.compat.jei.category; package com.simibubi.create.compat.jei.category;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.ParametersAreNonnullByDefault;
import org.jetbrains.annotations.NotNull;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.compat.jei.category.sequencedAssembly.SequencedAssemblySubCategory; import com.simibubi.create.compat.jei.category.sequencedAssembly.SequencedAssemblySubCategory;
import com.simibubi.create.content.processing.sequenced.SequencedAssemblyRecipe; import com.simibubi.create.content.processing.sequenced.SequencedAssemblyRecipe;
@ -7,11 +16,12 @@ import com.simibubi.create.content.processing.sequenced.SequencedRecipe;
import com.simibubi.create.foundation.gui.AllGuiTextures; import com.simibubi.create.foundation.gui.AllGuiTextures;
import com.simibubi.create.foundation.gui.AllIcons; import com.simibubi.create.foundation.gui.AllIcons;
import com.simibubi.create.foundation.utility.CreateLang; import com.simibubi.create.foundation.utility.CreateLang;
import mezz.jei.api.gui.builder.IRecipeLayoutBuilder; import mezz.jei.api.gui.builder.IRecipeLayoutBuilder;
import mezz.jei.api.gui.ingredient.IRecipeSlotsView; import mezz.jei.api.gui.ingredient.IRecipeSlotsView;
import mezz.jei.api.recipe.IFocusGroup; import mezz.jei.api.recipe.IFocusGroup;
import mezz.jei.api.recipe.RecipeIngredientRole; import mezz.jei.api.recipe.RecipeIngredientRole;
import net.createmod.catnip.platform.CatnipServices; import net.createmod.catnip.utility.RegisteredObjectsHelper;
import net.createmod.catnip.utility.lang.Components; import net.createmod.catnip.utility.lang.Components;
import net.minecraft.ChatFormatting; import net.minecraft.ChatFormatting;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
@ -20,13 +30,6 @@ import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent; import net.minecraft.network.chat.MutableComponent;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import org.jetbrains.annotations.NotNull;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
public class SequencedAssemblyCategory extends CreateRecipeCategory<SequencedAssemblyRecipe> { public class SequencedAssemblyCategory extends CreateRecipeCategory<SequencedAssemblyRecipe> {
@ -73,7 +76,7 @@ public class SequencedAssemblyCategory extends CreateRecipeCategory<SequencedAss
} }
private SequencedAssemblySubCategory getSubCategory(SequencedRecipe<?> sequencedRecipe) { private SequencedAssemblySubCategory getSubCategory(SequencedRecipe<?> sequencedRecipe) {
return subCategories.computeIfAbsent(CatnipServices.REGISTRIES.getKeyOrThrow(sequencedRecipe.getRecipe() return subCategories.computeIfAbsent(RegisteredObjectsHelper.getKeyOrThrow(sequencedRecipe.getRecipe()
.getSerializer()), .getSerializer()),
rl -> sequencedRecipe.getAsAssemblyRecipe() rl -> sequencedRecipe.getAsAssemblyRecipe()
.getJEISubCategory() .getJEISubCategory()

View file

@ -16,23 +16,23 @@ import com.simibubi.create.foundation.gui.AllGuiTextures;
import com.simibubi.create.foundation.item.ItemHelper; import com.simibubi.create.foundation.item.ItemHelper;
import mezz.jei.api.constants.VanillaTypes; import mezz.jei.api.constants.VanillaTypes;
import mezz.jei.api.forge.ForgeTypes;
import mezz.jei.api.gui.builder.IRecipeLayoutBuilder; import mezz.jei.api.gui.builder.IRecipeLayoutBuilder;
import mezz.jei.api.gui.ingredient.IRecipeSlotsView; import mezz.jei.api.gui.ingredient.IRecipeSlotsView;
import mezz.jei.api.neoforge.NeoForgeTypes;
import mezz.jei.api.recipe.IFocusGroup; import mezz.jei.api.recipe.IFocusGroup;
import mezz.jei.api.recipe.RecipeIngredientRole; import mezz.jei.api.recipe.RecipeIngredientRole;
import mezz.jei.api.runtime.IIngredientManager; import mezz.jei.api.runtime.IIngredientManager;
import net.createmod.catnip.platform.CatnipServices; import net.createmod.catnip.utility.RegisteredObjectsHelper;
import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items; import net.minecraft.world.item.Items;
import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.world.item.crafting.Ingredient;
import net.minecraftforge.common.capabilities.ForgeCapabilities; import net.minecraft.world.item.crafting.RecipeHolder;
import net.minecraftforge.common.util.LazyOptional; import net.neoforged.neoforge.capabilities.Capabilities;
import net.minecraftforge.fluids.FluidStack; import net.neoforged.neoforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.IFluidHandler.FluidAction; import net.neoforged.neoforge.fluids.capability.IFluidHandler.FluidAction;
import net.minecraftforge.fluids.capability.IFluidHandlerItem; import net.neoforged.neoforge.fluids.capability.IFluidHandlerItem;
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
public class SpoutCategory extends CreateRecipeCategory<FillingRecipe> { public class SpoutCategory extends CreateRecipeCategory<FillingRecipe> {
@ -43,51 +43,53 @@ public class SpoutCategory extends CreateRecipeCategory<FillingRecipe> {
super(info); super(info);
} }
public static void consumeRecipes(Consumer<FillingRecipe> consumer, IIngredientManager ingredientManager) { public static void consumeRecipes(Consumer<RecipeHolder<FillingRecipe>> consumer, IIngredientManager ingredientManager) {
Collection<FluidStack> fluidStacks = ingredientManager.getAllIngredients(ForgeTypes.FLUID_STACK); Collection<FluidStack> fluidStacks = ingredientManager.getAllIngredients(NeoForgeTypes.FLUID_STACK);
for (ItemStack stack : ingredientManager.getAllIngredients(VanillaTypes.ITEM_STACK)) { for (ItemStack stack : ingredientManager.getAllIngredients(VanillaTypes.ITEM_STACK)) {
if (PotionFluidHandler.isPotionItem(stack)) { if (PotionFluidHandler.isPotionItem(stack)) {
FluidStack fluidFromPotionItem = PotionFluidHandler.getFluidFromPotionItem(stack); FluidStack fluidFromPotionItem = PotionFluidHandler.getFluidFromPotionItem(stack);
Ingredient bottle = Ingredient.of(Items.GLASS_BOTTLE); Ingredient bottle = Ingredient.of(Items.GLASS_BOTTLE);
consumer.accept(new ProcessingRecipeBuilder<>(FillingRecipe::new, Create.asResource("potions")) ResourceLocation id = Create.asResource("potions");
.withItemIngredients(bottle) FillingRecipe recipe = new ProcessingRecipeBuilder<>(FillingRecipe::new, id)
.withFluidIngredients(FluidIngredient.fromFluidStack(fluidFromPotionItem)) .withItemIngredients(bottle)
.withSingleItemOutput(stack) .withFluidIngredients(FluidIngredient.fromFluidStack(fluidFromPotionItem))
.build()); .withSingleItemOutput(stack)
.build();
consumer.accept(new RecipeHolder<>(id, recipe));
continue; continue;
} }
LazyOptional<IFluidHandlerItem> capability = IFluidHandlerItem capability = stack.getCapability(Capabilities.FluidHandler.ITEM);
stack.getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM); if (capability == null)
if (!capability.isPresent())
continue; continue;
for (FluidStack fluidStack : fluidStacks) { for (FluidStack fluidStack : fluidStacks) {
ItemStack copy = stack.copy(); ItemStack copy = stack.copy();
copy.getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM) IFluidHandlerItem fhi = copy.getCapability(Capabilities.FluidHandler.ITEM);
.ifPresent(fhi -> { if (fhi != null) {
if (!GenericItemFilling.isFluidHandlerValid(copy, fhi)) if (!GenericItemFilling.isFluidHandlerValid(copy, fhi))
return; return;
FluidStack fluidCopy = fluidStack.copy(); FluidStack fluidCopy = fluidStack.copy();
fluidCopy.setAmount(1000); fluidCopy.setAmount(1000);
fhi.fill(fluidCopy, FluidAction.EXECUTE); fhi.fill(fluidCopy, FluidAction.EXECUTE);
ItemStack container = fhi.getContainer(); ItemStack container = fhi.getContainer();
if (ItemHelper.sameItem(container, copy)) if (ItemHelper.sameItem(container, copy))
return; return;
if (container.isEmpty()) if (container.isEmpty())
return; return;
Ingredient bucket = Ingredient.of(stack); Ingredient bucket = Ingredient.of(stack);
ResourceLocation itemName = CatnipServices.REGISTRIES.getKeyOrThrow(stack.getItem()); ResourceLocation itemName = RegisteredObjectsHelper.getKeyOrThrow(stack.getItem());
ResourceLocation fluidName = CatnipServices.REGISTRIES.getKeyOrThrow(fluidCopy.getFluid()); ResourceLocation fluidName = RegisteredObjectsHelper.getKeyOrThrow(fluidCopy.getFluid());
consumer.accept(new ProcessingRecipeBuilder<>(FillingRecipe::new, ResourceLocation id = Create.asResource("fill_" + itemName.getNamespace() + "_" + itemName.getPath()
Create.asResource("fill_" + itemName.getNamespace() + "_" + itemName.getPath() + "_with_" + fluidName.getNamespace() + "_" + fluidName.getPath());
+ "_with_" + fluidName.getNamespace() + "_" + fluidName.getPath())) FillingRecipe recipe = new ProcessingRecipeBuilder<>(FillingRecipe::new, id)
.withItemIngredients(bucket) .withItemIngredients(bucket)
.withFluidIngredients(FluidIngredient.fromFluidStack(fluidCopy)) .withFluidIngredients(FluidIngredient.fromFluidStack(fluidCopy))
.withSingleItemOutput(container) .withSingleItemOutput(container)
.build()); .build();
}); consumer.accept(new RecipeHolder<>(id, recipe));
}
} }
} }
} }
@ -101,7 +103,7 @@ public class SpoutCategory extends CreateRecipeCategory<FillingRecipe> {
builder builder
.addSlot(RecipeIngredientRole.INPUT, 27, 32) .addSlot(RecipeIngredientRole.INPUT, 27, 32)
.setBackground(getRenderedSlot(), -1, -1) .setBackground(getRenderedSlot(), -1, -1)
.addIngredients(ForgeTypes.FLUID_STACK, withImprovedVisibility(recipe.getRequiredFluid().getMatchingFluidStacks())) .addIngredients(NeoForgeTypes.FLUID_STACK, withImprovedVisibility(recipe.getRequiredFluid().getMatchingFluidStacks()))
.addTooltipCallback(addFluidTooltip(recipe.getRequiredFluid().getRequiredAmount())); .addTooltipCallback(addFluidTooltip(recipe.getRequiredFluid().getRequiredAmount()));
builder builder
.addSlot(RecipeIngredientRole.OUTPUT, 132, 51) .addSlot(RecipeIngredientRole.OUTPUT, 132, 51)

View file

@ -1,16 +1,13 @@
package com.simibubi.create.compat.jei.category.animations; package com.simibubi.create.compat.jei.category.animations;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.Tesselator;
import com.mojang.math.Axis; import com.mojang.math.Axis;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.foundation.fluid.FluidRenderer; import com.simibubi.create.foundation.fluid.FluidRenderer;
import net.createmod.catnip.gui.UIRenderHelper; import net.createmod.catnip.gui.UIRenderHelper;
import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.renderer.LightTexture; import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.renderer.MultiBufferSource; import net.neoforged.neoforge.fluids.FluidStack;
import net.minecraft.client.renderer.MultiBufferSource.BufferSource;
import net.minecraftforge.fluids.FluidStack;
public class AnimatedItemDrain extends AnimatedKinetics { public class AnimatedItemDrain extends AnimatedKinetics {
@ -34,14 +31,12 @@ public class AnimatedItemDrain extends AnimatedKinetics {
.scale(scale) .scale(scale)
.render(graphics); .render(graphics);
BufferSource buffer = MultiBufferSource.immediate(Tesselator.getInstance()
.getBuilder());
UIRenderHelper.flipForGuiRender(matrixStack); UIRenderHelper.flipForGuiRender(matrixStack);
matrixStack.scale(scale, scale, scale); matrixStack.scale(scale, scale, scale);
float from = 2/16f; float from = 2/16f;
float to = 1f - from; float to = 1f - from;
FluidRenderer.renderFluidBox(fluid.getFluid(), fluid.getAmount(), from, from, from, to, 3/4f, to, buffer, matrixStack, LightTexture.FULL_BRIGHT, false, true, fluid.getTag()); FluidRenderer.renderFluidBox(fluid.getFluid(), fluid.getAmount(), from, from, from, to, 3/4f, to, graphics.bufferSource(), matrixStack, LightTexture.FULL_BRIGHT, false, true, fluid.getComponents());
buffer.endBatch(); graphics.flush();
matrixStack.popPose(); matrixStack.popPose();
} }

View file

@ -18,8 +18,8 @@ public abstract class AnimatedKinetics implements IDrawable {
public int offset = 0; public int offset = 0;
public static final ILightingSettings DEFAULT_LIGHTING = CustomLightingSettings.builder() public static final ILightingSettings DEFAULT_LIGHTING = CustomLightingSettings.builder()
.firstLightRotation(12.5f, 45.0f) .firstLightRotation(12.5f, -45.0f)
.secondLightRotation(-20.0f, 50.0f) .secondLightRotation(-20.0f, -50.0f)
.build(); .build();
/** /**

View file

@ -1,22 +1,21 @@
package com.simibubi.create.compat.jei.category.animations; package com.simibubi.create.compat.jei.category.animations;
import java.util.List;
import com.mojang.blaze3d.platform.Lighting; import com.mojang.blaze3d.platform.Lighting;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.Tesselator;
import com.mojang.math.Axis; import com.mojang.math.Axis;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllPartialModels; import com.simibubi.create.AllPartialModels;
import com.simibubi.create.foundation.fluid.FluidRenderer; import com.simibubi.create.foundation.fluid.FluidRenderer;
import net.createmod.catnip.gui.UIRenderHelper; import net.createmod.catnip.gui.UIRenderHelper;
import net.createmod.catnip.utility.AnimationTickHolder; import net.createmod.catnip.utility.AnimationTickHolder;
import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.renderer.LightTexture; import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.MultiBufferSource.BufferSource;
import net.minecraft.util.Mth; import net.minecraft.util.Mth;
import net.minecraftforge.fluids.FluidStack;
import java.util.List; import net.neoforged.neoforge.fluids.FluidStack;
public class AnimatedSpout extends AnimatedKinetics { public class AnimatedSpout extends AnimatedKinetics {
@ -67,15 +66,13 @@ public class AnimatedSpout extends AnimatedKinetics {
.render(graphics); .render(graphics);
AnimatedKinetics.DEFAULT_LIGHTING.applyLighting(); AnimatedKinetics.DEFAULT_LIGHTING.applyLighting();
BufferSource buffer = MultiBufferSource.immediate(Tesselator.getInstance()
.getBuilder());
matrixStack.pushPose(); matrixStack.pushPose();
UIRenderHelper.flipForGuiRender(matrixStack); UIRenderHelper.flipForGuiRender(matrixStack);
matrixStack.scale(16, 16, 16); matrixStack.scale(16, 16, 16);
float from = 3f / 16f; float from = 3f / 16f;
float to = 17f / 16f; float to = 17f / 16f;
FluidStack fluidStack = fluids.get(0); FluidStack fluidStack = fluids.get(0);
FluidRenderer.renderFluidBox(fluidStack.getFluid(), fluidStack.getAmount(), from, from, from, to, to, to, buffer, matrixStack, LightTexture.FULL_BRIGHT, false, true, fluidStack.getTag()); FluidRenderer.renderFluidBox(fluidStack.getFluid(), fluidStack.getAmount(), from, from, from, to, to, to, graphics.bufferSource(), matrixStack, LightTexture.FULL_BRIGHT, false, true, fluidStack.getComponents());
matrixStack.popPose(); matrixStack.popPose();
float width = 1 / 128f * squeeze; float width = 1 / 128f * squeeze;
@ -85,8 +82,8 @@ public class AnimatedSpout extends AnimatedKinetics {
matrixStack.translate(-0.5f, 0, -0.5f); matrixStack.translate(-0.5f, 0, -0.5f);
from = -width / 2 + 0.5f; from = -width / 2 + 0.5f;
to = width / 2 + 0.5f; to = width / 2 + 0.5f;
FluidRenderer.renderFluidBox(fluidStack.getFluid(), fluidStack.getAmount(), from, 0, from, to, 2, to, buffer, matrixStack, LightTexture.FULL_BRIGHT, false, true, fluidStack.getTag()); FluidRenderer.renderFluidBox(fluidStack.getFluid(), fluidStack.getAmount(), from, 0, from, to, 2, to, graphics.bufferSource(), matrixStack, LightTexture.FULL_BRIGHT, false, true, fluidStack.getComponents());
buffer.endBatch(); graphics.flush();
Lighting.setupFor3DItems(); Lighting.setupFor3DItems();
matrixStack.popPose(); matrixStack.popPose();

View file

@ -10,9 +10,10 @@ import com.simibubi.create.content.kinetics.deployer.DeployerApplicationRecipe;
import com.simibubi.create.content.processing.sequenced.SequencedRecipe; import com.simibubi.create.content.processing.sequenced.SequencedRecipe;
import com.simibubi.create.foundation.fluid.FluidIngredient; import com.simibubi.create.foundation.fluid.FluidIngredient;
import com.simibubi.create.foundation.utility.CreateLang; import com.simibubi.create.foundation.utility.CreateLang;
import mezz.jei.api.forge.ForgeTypes;
import mezz.jei.api.gui.builder.IRecipeLayoutBuilder; import mezz.jei.api.gui.builder.IRecipeLayoutBuilder;
import mezz.jei.api.gui.builder.IRecipeSlotBuilder; import mezz.jei.api.gui.builder.IRecipeSlotBuilder;
import mezz.jei.api.neoforge.NeoForgeTypes;
import mezz.jei.api.recipe.IFocusGroup; import mezz.jei.api.recipe.IFocusGroup;
import mezz.jei.api.recipe.RecipeIngredientRole; import mezz.jei.api.recipe.RecipeIngredientRole;
import net.minecraft.ChatFormatting; import net.minecraft.ChatFormatting;
@ -74,7 +75,7 @@ public abstract class SequencedAssemblySubCategory {
builder builder
.addSlot(RecipeIngredientRole.INPUT, x + 4, 15) .addSlot(RecipeIngredientRole.INPUT, x + 4, 15)
.setBackground(CreateRecipeCategory.getRenderedSlot(), -1, -1) .setBackground(CreateRecipeCategory.getRenderedSlot(), -1, -1)
.addIngredients(ForgeTypes.FLUID_STACK, CreateRecipeCategory.withImprovedVisibility(fluidIngredient.getMatchingFluidStacks())) .addIngredients(NeoForgeTypes.FLUID_STACK, CreateRecipeCategory.withImprovedVisibility(fluidIngredient.getMatchingFluidStacks()))
.addTooltipCallback(CreateRecipeCategory.addFluidTooltip(fluidIngredient.getRequiredAmount())); .addTooltipCallback(CreateRecipeCategory.addFluidTooltip(fluidIngredient.getRequiredAmount()));
} }

View file

@ -5,23 +5,24 @@ import com.simibubi.create.compat.Mods;
import com.simibubi.create.content.fluids.spout.SpoutBlockEntity; import com.simibubi.create.content.fluids.spout.SpoutBlockEntity;
import com.simibubi.create.foundation.fluid.FluidHelper; import com.simibubi.create.foundation.fluid.FluidHelper;
import com.simibubi.create.infrastructure.config.AllConfigs; import com.simibubi.create.infrastructure.config.AllConfigs;
import net.createmod.catnip.platform.CatnipServices;
import net.createmod.catnip.utility.RegisteredObjectsHelper;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraftforge.common.capabilities.ForgeCapabilities; import net.neoforged.neoforge.capabilities.Capabilities;
import net.minecraftforge.fluids.FluidStack; import net.neoforged.neoforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.IFluidHandler; import net.neoforged.neoforge.fluids.capability.IFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler.FluidAction; import net.neoforged.neoforge.fluids.capability.IFluidHandler.FluidAction;
public class SpoutCasting extends BlockSpoutingBehaviour { public class SpoutCasting extends BlockSpoutingBehaviour {
private static final boolean TICON_PRESENT = Mods.TCONSTRUCT.isLoaded(); private static final boolean TICON_PRESENT = Mods.TCONSTRUCT.isLoaded();
ResourceLocation TABLE = new ResourceLocation("tconstruct", "table"); ResourceLocation TABLE = ResourceLocation.fromNamespaceAndPath("tconstruct", "table");
ResourceLocation BASIN = new ResourceLocation("tconstruct", "basin"); ResourceLocation BASIN = ResourceLocation.fromNamespaceAndPath("tconstruct", "basin");
@Override @Override
public int fillBlock(Level level, BlockPos pos, SpoutBlockEntity spout, FluidStack availableFluid, public int fillBlock(Level level, BlockPos pos, SpoutBlockEntity spout, FluidStack availableFluid,
@ -33,21 +34,20 @@ public class SpoutCasting extends BlockSpoutingBehaviour {
if (blockEntity == null) if (blockEntity == null)
return 0; return 0;
IFluidHandler handler = blockEntity.getCapability(ForgeCapabilities.FLUID_HANDLER, Direction.UP) IFluidHandler handler = level.getCapability(Capabilities.FluidHandler.BLOCK, blockEntity.getBlockPos(), Direction.UP);
.orElse(null);
if (handler == null) if (handler == null)
return 0; return 0;
if (handler.getTanks() != 1) if (handler.getTanks() != 1)
return 0; return 0;
ResourceLocation registryName = CatnipServices.REGISTRIES.getKeyOrThrow(blockEntity.getType()); ResourceLocation registryName = RegisteredObjectsHelper.getKeyOrThrow(blockEntity.getType());
if (!registryName.equals(TABLE) && !registryName.equals(BASIN)) if (!registryName.equals(TABLE) && !registryName.equals(BASIN))
return 0; return 0;
if (!handler.isFluidValid(0, availableFluid)) if (!handler.isFluidValid(0, availableFluid))
return 0; return 0;
FluidStack containedFluid = handler.getFluidInTank(0); FluidStack containedFluid = handler.getFluidInTank(0);
if (!(containedFluid.isEmpty() || containedFluid.isFluidEqual(availableFluid))) if (!(containedFluid.isEmpty() || FluidStack.isSameFluidSameComponents(containedFluid, availableFluid)))
return 0; return 0;
// Do not fill if it would only partially fill the table (unless > 1000mb) // Do not fill if it would only partially fill the table (unless > 1000mb)

View file

@ -2,16 +2,16 @@ package com.simibubi.create.compat.thresholdSwitch;
import com.simibubi.create.compat.Mods; import com.simibubi.create.compat.Mods;
import net.createmod.catnip.platform.CatnipServices; import net.createmod.catnip.utility.RegisteredObjectsHelper;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraftforge.items.IItemHandler; import net.neoforged.neoforge.items.IItemHandler;
public class FunctionalStorage implements ThresholdSwitchCompat { public class FunctionalStorage implements ThresholdSwitchCompat {
@Override @Override
public boolean isFromThisMod(BlockEntity blockEntity) { public boolean isFromThisMod(BlockEntity blockEntity) {
return blockEntity != null && Mods.FUNCTIONALSTORAGE.id() return blockEntity != null && Mods.FUNCTIONALSTORAGE.id()
.equals(CatnipServices.REGISTRIES.getKeyOrThrow(blockEntity.getType()) .equals(RegisteredObjectsHelper.getKeyOrThrow(blockEntity.getType())
.getNamespace()); .getNamespace());
} }

View file

@ -2,9 +2,10 @@ package com.simibubi.create.compat.thresholdSwitch;
import com.simibubi.create.compat.Mods; import com.simibubi.create.compat.Mods;
import net.createmod.catnip.platform.CatnipServices; import net.createmod.catnip.utility.RegisteredObjectsHelper;
import net.minecraft.core.component.DataComponents;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraftforge.items.IItemHandler; import net.neoforged.neoforge.items.IItemHandler;
public class SophisticatedStorage implements ThresholdSwitchCompat { public class SophisticatedStorage implements ThresholdSwitchCompat {
@ -13,7 +14,7 @@ public class SophisticatedStorage implements ThresholdSwitchCompat {
if (be == null) if (be == null)
return false; return false;
String namespace = CatnipServices.REGISTRIES.getKeyOrThrow(be.getType()) String namespace = RegisteredObjectsHelper.getKeyOrThrow(be.getType())
.getNamespace(); .getNamespace();
return return
@ -23,7 +24,7 @@ public class SophisticatedStorage implements ThresholdSwitchCompat {
@Override @Override
public long getSpaceInSlot(IItemHandler inv, int slot) { public long getSpaceInSlot(IItemHandler inv, int slot) {
return ((long) inv.getSlotLimit(slot) * inv.getStackInSlot(slot).getMaxStackSize()) / 64; return ((long) inv.getSlotLimit(slot) * inv.getStackInSlot(slot).getOrDefault(DataComponents.MAX_STACK_SIZE, 64)) / 64;
} }
} }

View file

@ -2,16 +2,16 @@ package com.simibubi.create.compat.thresholdSwitch;
import com.simibubi.create.compat.Mods; import com.simibubi.create.compat.Mods;
import net.createmod.catnip.platform.CatnipServices; import net.createmod.catnip.utility.RegisteredObjectsHelper;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraftforge.items.IItemHandler; import net.neoforged.neoforge.items.IItemHandler;
public class StorageDrawers implements ThresholdSwitchCompat { public class StorageDrawers implements ThresholdSwitchCompat {
@Override @Override
public boolean isFromThisMod(BlockEntity blockEntity) { public boolean isFromThisMod(BlockEntity blockEntity) {
return blockEntity != null && Mods.STORAGEDRAWERS.id() return blockEntity != null && Mods.STORAGEDRAWERS.id()
.equals(CatnipServices.REGISTRIES.getKeyOrThrow(blockEntity.getType()) .equals(RegisteredObjectsHelper.getKeyOrThrow(blockEntity.getType())
.getNamespace()); .getNamespace());
} }

View file

@ -1,7 +1,7 @@
package com.simibubi.create.compat.thresholdSwitch; package com.simibubi.create.compat.thresholdSwitch;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraftforge.items.IItemHandler; import net.neoforged.neoforge.items.IItemHandler;
public interface ThresholdSwitchCompat { public interface ThresholdSwitchCompat {

View file

@ -17,10 +17,10 @@ import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.renderer.Rect2i; import net.minecraft.client.renderer.Rect2i;
import net.minecraft.network.chat.FormattedText; import net.minecraft.network.chat.FormattedText;
import net.minecraft.util.Mth; import net.minecraft.util.Mth;
import net.minecraftforge.client.event.InputEvent; import net.neoforged.fml.util.ObfuscationReflectionHelper;
import net.minecraftforge.client.event.RenderTooltipEvent; import net.neoforged.neoforge.client.event.InputEvent;
import net.minecraftforge.client.event.ScreenEvent; import net.neoforged.neoforge.client.event.RenderTooltipEvent;
import net.minecraftforge.fml.util.ObfuscationReflectionHelper; import net.neoforged.neoforge.client.event.ScreenEvent;
public class FTBChunksTrainMap { public class FTBChunksTrainMap {

View file

@ -8,15 +8,15 @@ import com.simibubi.create.foundation.gui.RemovedGuiUtils;
import com.simibubi.create.foundation.utility.CreateLang; import com.simibubi.create.foundation.utility.CreateLang;
import com.simibubi.create.infrastructure.config.AllConfigs; import com.simibubi.create.infrastructure.config.AllConfigs;
import journeymap.client.api.display.Context.UI; import journeymap.api.v2.client.display.Context;
import journeymap.client.api.util.UIState; import journeymap.api.v2.client.util.UIState;
import journeymap.client.ui.fullscreen.Fullscreen; import journeymap.client.ui.fullscreen.Fullscreen;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.renderer.Rect2i; import net.minecraft.client.renderer.Rect2i;
import net.minecraft.network.chat.FormattedText; import net.minecraft.network.chat.FormattedText;
import net.minecraft.util.Mth; import net.minecraft.util.Mth;
import net.minecraftforge.client.event.InputEvent; import net.neoforged.neoforge.client.event.InputEvent;
public class JourneyTrainMap { public class JourneyTrainMap {
@ -52,7 +52,7 @@ public class JourneyTrainMap {
UIState state = screen.getUiState(); UIState state = screen.getUiState();
if (state == null) if (state == null)
return; return;
if (state.ui != UI.Fullscreen) if (state.ui != Context.UI.Fullscreen)
return; return;
if (!state.active) if (!state.active)
return; return;

View file

@ -4,22 +4,19 @@ import com.mojang.blaze3d.platform.InputConstants;
import com.simibubi.create.compat.Mods; import com.simibubi.create.compat.Mods;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraftforge.api.distmarker.Dist; import net.neoforged.api.distmarker.Dist;
import net.minecraftforge.client.event.InputEvent; import net.neoforged.bus.api.SubscribeEvent;
import net.minecraftforge.client.event.RenderTooltipEvent; import net.neoforged.fml.common.EventBusSubscriber;
import net.minecraftforge.client.event.ScreenEvent; import net.neoforged.neoforge.client.event.ClientTickEvent;
import net.minecraftforge.event.TickEvent.ClientTickEvent; import net.neoforged.neoforge.client.event.InputEvent;
import net.minecraftforge.event.TickEvent.Phase; import net.neoforged.neoforge.client.event.RenderTooltipEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.neoforged.neoforge.client.event.ScreenEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
@EventBusSubscriber(value = Dist.CLIENT) @EventBusSubscriber(value = Dist.CLIENT)
public class TrainMapEvents { public class TrainMapEvents {
@SubscribeEvent @SubscribeEvent
public static void tick(ClientTickEvent event) { public static void tick(ClientTickEvent.Post event) {
if (event.phase == Phase.START)
return;
Minecraft mc = Minecraft.getInstance(); Minecraft mc = Minecraft.getInstance();
if (mc.level == null) if (mc.level == null)
return; return;

View file

@ -136,8 +136,8 @@ public class TrainMapManager {
if (!trainEntry.ownerName.isBlank()) if (!trainEntry.ownerName.isBlank())
CreateLang.translate("train_map.train_owned_by", trainEntry.ownerName) CreateLang.translate("train_map.train_owned_by", trainEntry.ownerName)
.color(blue) .color(blue)
.addTo(output); .addTo(output);
switch (state) { switch (state) {
@ -178,12 +178,12 @@ public class TrainMapManager {
if (!currentStation.isBlank()) { if (!currentStation.isBlank()) {
if (targetStationDistance == 0) if (targetStationDistance == 0)
CreateLang.translate("train_map.train_at_station", currentStation) CreateLang.translate("train_map.train_at_station", currentStation)
.color(darkBlue) .color(darkBlue)
.addTo(output); .addTo(output);
else else
CreateLang.translate("train_map.train_moving_to_station", currentStation, targetStationDistance) CreateLang.translate("train_map.train_moving_to_station", currentStation, targetStationDistance)
.color(darkBlue) .color(darkBlue)
.addTo(output); .addTo(output);
} }
if (signalState != SignalState.NOT_WAITING) { if (signalState != SignalState.NOT_WAITING) {
@ -204,12 +204,13 @@ public class TrainMapManager {
Train trainWaitingFor = CreateClient.RAILWAYS.trains.get(waitingFor); Train trainWaitingFor = CreateClient.RAILWAYS.trains.get(waitingFor);
if (trainWaitingFor != null) { if (trainWaitingFor != null) {
CreateLang.translate("train_map.for_other_train", trainWaitingFor.name.getString()) CreateLang.translate("train_map.for_other_train", trainWaitingFor.name.getString())
.color(blue) .color(blue)
.addTo(output); .addTo(output);
trainFound = true; trainFound = true;
} }
} }
if (!trainFound) { if (!trainFound) {
if (chainSignal) if (chainSignal)
CreateLang.translate("train_map.cannot_traverse_section") CreateLang.translate("train_map.cannot_traverse_section")

View file

@ -229,26 +229,22 @@ public class TrainMapRenderer implements AutoCloseable {
Matrix4f matrix4f = pPoseStack.last() Matrix4f matrix4f = pPoseStack.last()
.pose(); .pose();
VertexConsumer vertexconsumer = pBufferSource.getBuffer(renderType); VertexConsumer vertexconsumer = pBufferSource.getBuffer(renderType);
vertexconsumer.vertex(matrix4f, 0.0F, HEIGHT, 0) vertexconsumer.addVertex(matrix4f, 0.0F, HEIGHT, 0)
.color(255, 255, 255, 255) .setColor(255, 255, 255, 255)
.uv(0.0F, 1.0F) .setUv(0.0F, 1.0F)
.uv2(pPackedLight) .setLight(pPackedLight);
.endVertex(); vertexconsumer.addVertex(matrix4f, WIDTH, HEIGHT, 0)
vertexconsumer.vertex(matrix4f, WIDTH, HEIGHT, 0) .setColor(255, 255, 255, 255)
.color(255, 255, 255, 255) .setUv(1.0F, 1.0F)
.uv(1.0F, 1.0F) .setLight(pPackedLight);
.uv2(pPackedLight) vertexconsumer.addVertex(matrix4f, WIDTH, 0.0F, 0)
.endVertex(); .setColor(255, 255, 255, 255)
vertexconsumer.vertex(matrix4f, WIDTH, 0.0F, 0) .setUv(1.0F, 0.0F)
.color(255, 255, 255, 255) .setLight(pPackedLight);
.uv(1.0F, 0.0F) vertexconsumer.addVertex(matrix4f, 0.0F, 0.0F, 0)
.uv2(pPackedLight) .setColor(255, 255, 255, 255)
.endVertex(); .setUv(0.0F, 0.0F)
vertexconsumer.vertex(matrix4f, 0.0F, 0.0F, 0) .setLight(pPackedLight);
.color(255, 255, 255, 255)
.uv(0.0F, 0.0F)
.uv2(pPackedLight)
.endVertex();
} }
public void close() { public void close() {

View file

@ -6,13 +6,12 @@ import java.util.List;
import java.util.UUID; import java.util.UUID;
import com.google.common.cache.Cache; import com.google.common.cache.Cache;
import com.simibubi.create.AllPackets; import com.google.common.cache.CacheBuilder;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.content.trains.entity.Carriage; import com.simibubi.create.content.trains.entity.Carriage;
import com.simibubi.create.content.trains.entity.Carriage.DimensionalCarriageEntity; import com.simibubi.create.content.trains.entity.Carriage.DimensionalCarriageEntity;
import com.simibubi.create.content.trains.entity.Train; import com.simibubi.create.content.trains.entity.Train;
import com.simibubi.create.content.trains.entity.TravellingPoint; import com.simibubi.create.content.trains.entity.TravellingPoint;
import com.simibubi.create.content.trains.graph.DimensionPalette;
import com.simibubi.create.content.trains.graph.EdgePointType; import com.simibubi.create.content.trains.graph.EdgePointType;
import com.simibubi.create.content.trains.schedule.ScheduleRuntime; import com.simibubi.create.content.trains.schedule.ScheduleRuntime;
import com.simibubi.create.content.trains.signal.SignalBlock.SignalType; import com.simibubi.create.content.trains.signal.SignalBlock.SignalType;
@ -21,16 +20,23 @@ import com.simibubi.create.content.trains.signal.SignalEdgeGroup;
import com.simibubi.create.content.trains.station.GlobalStation; import com.simibubi.create.content.trains.station.GlobalStation;
import com.simibubi.create.foundation.utility.TickBasedCache; import com.simibubi.create.foundation.utility.TickBasedCache;
import io.netty.buffer.ByteBuf;
import net.createmod.catnip.codecs.stream.CatnipLargerStreamCodecs;
import net.createmod.catnip.codecs.stream.CatnipStreamCodecBuilders;
import net.createmod.catnip.platform.CatnipServices;
import net.createmod.catnip.utility.Pair; import net.createmod.catnip.utility.Pair;
import net.minecraft.core.UUIDUtil;
import net.minecraft.core.registries.Registries;
import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceKey;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.util.Mth; import net.minecraft.util.Mth;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import net.minecraftforge.event.TickEvent.ServerTickEvent; import net.neoforged.neoforge.event.tick.ServerTickEvent;
import net.minecraftforge.network.PacketDistributor;
public class TrainMapSync { public class TrainMapSync {
@ -40,21 +46,38 @@ public class TrainMapSync {
public static int ticks; public static int ticks;
public enum TrainState { public enum TrainState {
RUNNING, RUNNING_MANUALLY, DERAILED, SCHEDULE_INTERRUPTED, CONDUCTOR_MISSING, NAVIGATION_FAILED RUNNING, RUNNING_MANUALLY, DERAILED, SCHEDULE_INTERRUPTED, CONDUCTOR_MISSING, NAVIGATION_FAILED;
public static StreamCodec<ByteBuf, TrainState> STREAM_CODEC = CatnipStreamCodecBuilders.ofEnum(TrainState.class);
} }
public enum SignalState { public enum SignalState {
NOT_WAITING, WAITING_FOR_REDSTONE, BLOCK_SIGNAL, CHAIN_SIGNAL NOT_WAITING, WAITING_FOR_REDSTONE, BLOCK_SIGNAL, CHAIN_SIGNAL;
public static StreamCodec<ByteBuf, SignalState> STREAM_CODEC = CatnipStreamCodecBuilders.ofEnum(SignalState.class);
} }
public static class TrainMapSyncEntry { public static class TrainMapSyncEntry {
public static StreamCodec<FriendlyByteBuf, TrainMapSyncEntry> STREAM_CODEC = CatnipLargerStreamCodecs.composite(
CatnipStreamCodecBuilders.array(ByteBufCodecs.FLOAT, Float.class), packet -> packet.positions,
CatnipStreamCodecBuilders.list(ResourceKey.streamCodec(Registries.DIMENSION)), packet -> packet.dimensions,
TrainState.STREAM_CODEC, packet -> packet.state,
SignalState.STREAM_CODEC, packet -> packet.signalState,
ByteBufCodecs.BOOL, packet -> packet.fueled,
ByteBufCodecs.BOOL, packet -> packet.backwards,
ByteBufCodecs.VAR_INT, packet -> packet.targetStationDistance,
ByteBufCodecs.STRING_UTF8, packet -> packet.ownerName,
ByteBufCodecs.STRING_UTF8, packet -> packet.targetStationName,
CatnipStreamCodecBuilders.nullable(UUIDUtil.STREAM_CODEC), packet -> packet.waitingForTrain,
TrainMapSyncEntry::new
);
// Clientside // Clientside
public float[] prevPositions; public Float[] prevPositions;
public List<ResourceKey<Level>> prevDims; public List<ResourceKey<Level>> prevDims;
// Updated every 5 ticks // Updated every 5 ticks
public float[] positions; public Float[] positions;
public List<ResourceKey<Level>> dimensions; public List<ResourceKey<Level>> dimensions;
public TrainState state = TrainState.RUNNING; public TrainState state = TrainState.RUNNING;
public SignalState signalState = SignalState.NOT_WAITING; public SignalState signalState = SignalState.NOT_WAITING;
@ -67,65 +90,22 @@ public class TrainMapSync {
public String targetStationName = ""; public String targetStationName = "";
public UUID waitingForTrain = null; public UUID waitingForTrain = null;
public void gatherDimensions(DimensionPalette dimensionPalette) { public TrainMapSyncEntry() {}
for (ResourceKey<Level> resourceKey : dimensions)
if (resourceKey != null)
dimensionPalette.encode(resourceKey);
}
public void send(FriendlyByteBuf buffer, DimensionPalette dimensionPalette, boolean light) { public TrainMapSyncEntry(Float[] positions, List<ResourceKey<Level>> dimensions, TrainState state,
buffer.writeVarInt(positions.length); SignalState signalState, boolean fueled, boolean backwards, int targetStationDistance,
for (float f : positions) String ownerName, String targetStationName,
buffer.writeFloat(f); UUID waitingForTrain) {
this.positions = positions;
buffer.writeVarInt(dimensions.size()); this.dimensions = dimensions;
for (ResourceKey<Level> resourceKey : dimensions) this.state = state;
buffer.writeVarInt(resourceKey == null ? -1 : dimensionPalette.encode(resourceKey)); this.signalState = signalState;
this.fueled = fueled;
buffer.writeVarInt(state.ordinal()); this.backwards = backwards;
buffer.writeVarInt(signalState.ordinal()); this.targetStationDistance = targetStationDistance;
buffer.writeBoolean(fueled); this.ownerName = ownerName;
buffer.writeBoolean(backwards); this.targetStationName = targetStationName;
buffer.writeVarInt(targetStationDistance); this.waitingForTrain = waitingForTrain;
if (light)
return;
buffer.writeUtf(ownerName);
buffer.writeUtf(targetStationName);
buffer.writeBoolean(waitingForTrain != null);
if (waitingForTrain != null)
buffer.writeUUID(waitingForTrain);
}
public void receive(FriendlyByteBuf buffer, DimensionPalette dimensionPalette, boolean light) {
positions = new float[buffer.readVarInt()];
for (int i = 0; i < positions.length; i++)
positions[i] = buffer.readFloat();
dimensions = new ArrayList<>();
int dimensionsSize = buffer.readVarInt();
for (int i = 0; i < dimensionsSize; i++) {
int index = buffer.readVarInt();
dimensions.add(index == -1 ? null : dimensionPalette.decode(index));
}
state = TrainState.values()[buffer.readVarInt()];
signalState = SignalState.values()[buffer.readVarInt()];
fueled = buffer.readBoolean();
backwards = buffer.readBoolean();
targetStationDistance = buffer.readVarInt();
if (light)
return;
ownerName = buffer.readUtf();
targetStationName = buffer.readUtf();
waitingForTrain = null;
if (buffer.readBoolean())
waitingForTrain = buffer.readUUID();
} }
public void updateFrom(TrainMapSyncEntry other, boolean light) { public void updateFrom(TrainMapSyncEntry other, boolean light) {
@ -143,8 +123,7 @@ public class TrainMapSync {
if (prevDims != null) if (prevDims != null)
for (int i = 0; i < Math.min(prevDims.size(), dimensions.size()); i++) for (int i = 0; i < Math.min(prevDims.size(), dimensions.size()); i++)
if (prevDims.get(i) != dimensions.get(i)) if (prevDims.get(i) != dimensions.get(i))
for (int j = 0; j < 6; j++) System.arraycopy(positions, i * 6, prevPositions, i * 6, 6);
prevPositions[i * 6 + j] = positions[i * 6 + j];
if (light) if (light)
return; return;
@ -198,8 +177,7 @@ public class TrainMapSync {
ServerPlayer player = weakReference.get(); ServerPlayer player = weakReference.get();
if (player == null) if (player == null)
continue; continue;
AllPackets.getChannel() CatnipServices.NETWORK.sendToClient(player, packet);
.send(PacketDistributor.PLAYER.with(() -> player), packet);
} }
} }
@ -207,7 +185,7 @@ public class TrainMapSync {
TrainMapSyncEntry entry = new TrainMapSyncEntry(); TrainMapSyncEntry entry = new TrainMapSyncEntry();
boolean stopped = Math.abs(train.speed) < 0.05; boolean stopped = Math.abs(train.speed) < 0.05;
entry.positions = new float[train.carriages.size() * 6]; entry.positions = new Float[train.carriages.size() * 6];
entry.dimensions = new ArrayList<>(); entry.dimensions = new ArrayList<>();
List<Carriage> carriages = train.carriages; List<Carriage> carriages = train.carriages;
@ -279,7 +257,7 @@ public class TrainMapSync {
.getPlayer(train.owner); .getPlayer(train.owner);
if (owner != null) if (owner != null)
entry.ownerName = owner.getName() entry.ownerName = owner.getName()
.getString(); .getString();
} }
if (train.derailed) { if (train.derailed) {

View file

@ -6,9 +6,9 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import com.simibubi.create.AllPackets;
import com.simibubi.create.compat.trainmap.TrainMapSync.TrainMapSyncEntry; import com.simibubi.create.compat.trainmap.TrainMapSync.TrainMapSyncEntry;
import net.createmod.catnip.platform.CatnipServices;
import net.createmod.catnip.utility.AnimationTickHolder; import net.createmod.catnip.utility.AnimationTickHolder;
import net.createmod.catnip.utility.Pair; import net.createmod.catnip.utility.Pair;
@ -23,8 +23,7 @@ public class TrainMapSyncClient {
public static void requestData() { public static void requestData() {
ticks++; ticks++;
if (ticks % 5 == 0) if (ticks % 5 == 0)
AllPackets.getChannel() CatnipServices.NETWORK.sendToServer(TrainMapSyncRequestPacket.INSTANCE);
.sendToServer(new TrainMapSyncRequestPacket());
} }
public static void stopRequesting() { public static void stopRequesting() {
@ -39,8 +38,7 @@ public class TrainMapSyncClient {
lastPacket = AnimationTickHolder.getTicks(); lastPacket = AnimationTickHolder.getTicks();
lastPacket += AnimationTickHolder.getPartialTicks(); lastPacket += AnimationTickHolder.getPartialTicks();
Set<UUID> staleEntries = new HashSet<>(); Set<UUID> staleEntries = new HashSet<>(currentData.keySet());
staleEntries.addAll(currentData.keySet());
for (Pair<UUID, TrainMapSyncEntry> pair : packet.entries) { for (Pair<UUID, TrainMapSyncEntry> pair : packet.entries) {
UUID id = pair.getFirst(); UUID id = pair.getFirst();

View file

@ -4,62 +4,49 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import com.simibubi.create.AllPackets;
import com.simibubi.create.compat.trainmap.TrainMapSync.TrainMapSyncEntry; import com.simibubi.create.compat.trainmap.TrainMapSync.TrainMapSyncEntry;
import com.simibubi.create.content.trains.graph.DimensionPalette; import net.createmod.catnip.net.base.ClientboundPacketPayload;
import com.simibubi.create.foundation.networking.SimplePacketBase;
import net.createmod.catnip.codecs.stream.CatnipStreamCodecBuilders;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.core.UUIDUtil;
import net.createmod.catnip.utility.Pair; import net.createmod.catnip.utility.Pair;
import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.FriendlyByteBuf;
import net.minecraftforge.network.NetworkEvent.Context; import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.neoforged.neoforge.network.handling.IPayloadContext;
public class TrainMapSyncPacket extends SimplePacketBase { public class TrainMapSyncPacket implements ClientboundPacketPayload {
public static final StreamCodec<FriendlyByteBuf, TrainMapSyncPacket> STREAM_CODEC = StreamCodec.composite(
ByteBufCodecs.BOOL, packet -> packet.light,
CatnipStreamCodecBuilders.list(Pair.streamCodec(UUIDUtil.STREAM_CODEC, TrainMapSyncEntry.STREAM_CODEC)), packet -> packet.entries,
TrainMapSyncPacket::new
);
public List<Pair<UUID, TrainMapSyncEntry>> entries = new ArrayList<>();
public boolean light; public boolean light;
public List<Pair<UUID, TrainMapSyncEntry>> entries = new ArrayList<>();
public TrainMapSyncPacket(boolean light) { public TrainMapSyncPacket(boolean light) {
this.light = light; this.light = light;
} }
public TrainMapSyncPacket(boolean light, List<Pair<UUID, TrainMapSyncEntry>> entries) {
this.light = light;
this.entries = entries;
}
public void add(UUID trainId, TrainMapSyncEntry data) { public void add(UUID trainId, TrainMapSyncEntry data) {
entries.add(Pair.of(trainId, data)); entries.add(Pair.of(trainId, data));
} }
public TrainMapSyncPacket(FriendlyByteBuf buffer) { @Override
DimensionPalette dimensionPalette = DimensionPalette.receive(buffer); public void handle(LocalPlayer player) {
light = buffer.readBoolean(); TrainMapSyncClient.receive(this);
int size = buffer.readVarInt();
for (int i = 0; i < size; i++) {
UUID id = buffer.readUUID();
TrainMapSyncEntry entry = new TrainMapSyncEntry();
entry.receive(buffer, dimensionPalette, light);
entries.add(Pair.of(id, entry));
}
} }
@Override @Override
public void write(FriendlyByteBuf buffer) { public PacketTypeProvider getTypeProvider() {
DimensionPalette dimensionPalette = new DimensionPalette(); return AllPackets.TRAIN_MAP_SYNC;
for (Pair<UUID, TrainMapSyncEntry> pair : entries)
pair.getSecond()
.gatherDimensions(dimensionPalette);
dimensionPalette.send(buffer);
buffer.writeBoolean(light);
buffer.writeVarInt(entries.size());
for (Pair<UUID, TrainMapSyncEntry> pair : entries) {
buffer.writeUUID(pair.getFirst());
pair.getSecond()
.send(buffer, dimensionPalette, light);
}
} }
@Override
public boolean handle(Context context) {
context.enqueueWork(() -> TrainMapSyncClient.receive(this));
return true;
}
} }

View file

@ -1,23 +1,24 @@
package com.simibubi.create.compat.trainmap; package com.simibubi.create.compat.trainmap;
import com.simibubi.create.foundation.networking.SimplePacketBase; import com.simibubi.create.AllPackets;
import net.createmod.catnip.net.base.ServerboundPacketPayload;
import net.minecraft.network.FriendlyByteBuf; import io.netty.buffer.ByteBuf;
import net.minecraftforge.network.NetworkEvent.Context; import net.minecraft.network.codec.StreamCodec;
import net.minecraft.server.level.ServerPlayer;
import net.neoforged.neoforge.network.handling.IPayloadContext;
public class TrainMapSyncRequestPacket extends SimplePacketBase { public class TrainMapSyncRequestPacket implements ServerboundPacketPayload {
public static final TrainMapSyncRequestPacket INSTANCE = new TrainMapSyncRequestPacket();
public TrainMapSyncRequestPacket() {} public static final StreamCodec<ByteBuf, TrainMapSyncRequestPacket> STREAM_CODEC = StreamCodec.unit(INSTANCE);
public TrainMapSyncRequestPacket(FriendlyByteBuf buffer) {}
@Override @Override
public void write(FriendlyByteBuf buffer) {} public void handle(ServerPlayer player) {
TrainMapSync.requestReceived(player);
@Override
public boolean handle(Context context) {
context.enqueueWork(() -> TrainMapSync.requestReceived(context.getSender()));
return true;
} }
@Override
public PacketTypeProvider getTypeProvider() {
return AllPackets.TRAIN_MAP_REQUEST;
}
} }

View file

@ -12,11 +12,11 @@ import javax.annotation.Nullable;
import org.apache.commons.lang3.mutable.MutableInt; import org.apache.commons.lang3.mutable.MutableInt;
import org.apache.commons.lang3.tuple.MutablePair; import org.apache.commons.lang3.tuple.MutablePair;
import org.jetbrains.annotations.NotNull;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllItems; import com.simibubi.create.AllItems;
import com.simibubi.create.AllMovementBehaviours; import com.simibubi.create.AllMovementBehaviours;
import com.simibubi.create.AllPackets;
import com.simibubi.create.AllSoundEvents; import com.simibubi.create.AllSoundEvents;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.content.contraptions.actors.psi.PortableStorageInterfaceMovement; import com.simibubi.create.content.contraptions.actors.psi.PortableStorageInterfaceMovement;
@ -37,19 +37,21 @@ import com.simibubi.create.content.trains.entity.Train;
import com.simibubi.create.foundation.advancement.AllAdvancements; import com.simibubi.create.foundation.advancement.AllAdvancements;
import com.simibubi.create.foundation.collision.Matrix3d; import com.simibubi.create.foundation.collision.Matrix3d;
import com.simibubi.create.foundation.mixin.accessor.ServerLevelAccessor; import com.simibubi.create.foundation.mixin.accessor.ServerLevelAccessor;
import net.createmod.catnip.platform.CatnipServices;
import dev.engine_room.flywheel.api.backend.BackendManager; import dev.engine_room.flywheel.api.backend.BackendManager;
import io.netty.handler.codec.DecoderException;
import net.createmod.catnip.utility.VecHelper; import net.createmod.catnip.utility.VecHelper;
import net.createmod.catnip.utility.math.AngleHelper; import net.createmod.catnip.utility.math.AngleHelper;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.core.HolderLookup;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtAccounter;
import net.minecraft.nbt.Tag; import net.minecraft.nbt.Tag;
import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.ClientGamePacketListener;
import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers; import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.network.syncher.SynchedEntityData; import net.minecraft.network.syncher.SynchedEntityData;
@ -73,14 +75,11 @@ import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemp
import net.minecraft.world.level.material.PushReaction; import net.minecraft.world.level.material.PushReaction;
import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import net.minecraftforge.api.distmarker.Dist; import net.neoforged.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.neoforged.api.distmarker.OnlyIn;
import net.minecraftforge.entity.IEntityAdditionalSpawnData; import net.neoforged.neoforge.entity.IEntityWithComplexSpawn;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.network.NetworkHooks;
import net.minecraftforge.network.PacketDistributor;
public abstract class AbstractContraptionEntity extends Entity implements IEntityAdditionalSpawnData { public abstract class AbstractContraptionEntity extends Entity implements IEntityWithComplexSpawn {
private static final EntityDataAccessor<Boolean> STALLED = private static final EntityDataAccessor<Boolean> STALLED =
SynchedEntityData.defineId(AbstractContraptionEntity.class, EntityDataSerializers.BOOLEAN); SynchedEntityData.defineId(AbstractContraptionEntity.class, EntityDataSerializers.BOOLEAN);
@ -93,6 +92,8 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
protected boolean initialized; protected boolean initialized;
protected boolean prevPosInvalid; protected boolean prevPosInvalid;
private boolean skipActorStop; private boolean skipActorStop;
// temporary debug thing
private boolean receivedSpawnData;
/* /*
* staleTicks are a band-aid to prevent a frame or two of missing blocks between * staleTicks are a band-aid to prevent a frame or two of missing blocks between
@ -109,6 +110,10 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
collidingEntities = new IdentityHashMap<>(); collidingEntities = new IdentityHashMap<>();
} }
public boolean hasReceivedSpawnData() {
return receivedSpawnData;
}
protected void setContraption(Contraption contraption) { protected void setContraption(Contraption contraption) {
this.contraption = contraption; this.contraption = contraption;
if (contraption == null) if (contraption == null)
@ -165,8 +170,8 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
return; return;
contraption.getSeatMapping() contraption.getSeatMapping()
.put(passenger.getUUID(), seatIndex); .put(passenger.getUUID(), seatIndex);
AllPackets.getChannel().send(PacketDistributor.TRACKING_ENTITY.with(() -> this),
new ContraptionSeatMappingPacket(getId(), contraption.getSeatMapping())); CatnipServices.NETWORK.sendToClientsTrackingEntity(this, new ContraptionSeatMappingPacket(getId(), contraption.getSeatMapping()));
} }
@Override @Override
@ -182,8 +187,9 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
.put("ContraptionDismountLocation", VecHelper.writeNBT(transformedVector)); .put("ContraptionDismountLocation", VecHelper.writeNBT(transformedVector));
contraption.getSeatMapping() contraption.getSeatMapping()
.remove(passenger.getUUID()); .remove(passenger.getUUID());
AllPackets.getChannel().send(PacketDistributor.TRACKING_ENTITY.with(() -> this),
new ContraptionSeatMappingPacket(getId(), contraption.getSeatMapping(), passenger.getId())); CatnipServices.NETWORK.sendToClientsTrackingEntity(this,
new ContraptionSeatMappingPacket(getId(), contraption.getSeatMapping(), passenger.getId()));
} }
@Override @Override
@ -242,15 +248,15 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
return null; return null;
Vec3 transformedVector = toGlobalVector(Vec3.atLowerCornerOf(seat) Vec3 transformedVector = toGlobalVector(Vec3.atLowerCornerOf(seat)
.add(.5, passenger.getMyRidingOffset() + ySize - .15f, .5), partialTicks) .add(.5, passenger.getVehicleAttachmentPoint(this).y + ySize - .15f, .5), partialTicks)
.add(VecHelper.getCenterOf(BlockPos.ZERO)) .add(VecHelper.getCenterOf(BlockPos.ZERO))
.subtract(0.5, ySize, 0.5); .subtract(0.5, ySize, 0.5);
return transformedVector; return transformedVector;
} }
@Override @Override
protected boolean canAddPassenger(Entity p_184219_1_) { protected boolean canAddPassenger(@NotNull Entity pPassenger) {
if (p_184219_1_ instanceof OrientedContraptionEntity) if (pPassenger instanceof OrientedContraptionEntity)
return true; return true;
return contraption.getSeatMapping() return contraption.getSeatMapping()
.size() < contraption.getSeats() .size() < contraption.getSeats()
@ -280,8 +286,7 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
public void stopControlling(BlockPos controlsLocalPos) { public void stopControlling(BlockPos controlsLocalPos) {
getControllingPlayer().map(level()::getPlayerByUUID) getControllingPlayer().map(level()::getPlayerByUUID)
.map(p -> (p instanceof ServerPlayer) ? ((ServerPlayer) p) : null) .map(p -> (p instanceof ServerPlayer) ? ((ServerPlayer) p) : null)
.ifPresent(p -> AllPackets.getChannel().send(PacketDistributor.PLAYER.with(() -> p), .ifPresent(p -> CatnipServices.NETWORK.sendToClient(p, ControlsStopControllingPacket.INSTANCE));
new ControlsStopControllingPacket()));
setControllingPlayer(null); setControllingPlayer(null);
} }
@ -379,14 +384,9 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
tickContraption(); tickContraption();
super.tick(); super.tick();
if (level().isClientSide()) if (level().isClientSide()) {
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> { AbstractContraptionEntityClient.invalidate(contraption);
// The visual will handle this with flywheel on. }
if (!contraption.deferInvalidate || BackendManager.isBackendOn())
return;
contraption.deferInvalidate = false;
ContraptionRenderInfo.invalidate(contraption);
});
if (!(level() instanceof ServerLevelAccessor sl)) if (!(level() instanceof ServerLevelAccessor sl))
return; return;
@ -415,7 +415,7 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
float angle = AngleHelper.deg(-Mth.atan2(motion.x, motion.z)); float angle = AngleHelper.deg(-Mth.atan2(motion.x, motion.z));
angle = AngleHelper.angleLerp(0.4f, prevAngle, angle); angle = AngleHelper.angleLerp(0.4f, prevAngle, angle);
if (level().isClientSide) { if (level().isClientSide) {
living.lerpTo(0, 0, 0, 0, 0, 0, false); living.lerpTo(0, 0, 0, 0, 0, 0);
living.lerpHeadTo(0, 0); living.lerpHeadTo(0, 0);
living.setYRot(angle); living.setYRot(angle);
living.setXRot(0); living.setXRot(0);
@ -427,8 +427,7 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
public void setBlock(BlockPos localPos, StructureBlockInfo newInfo) { public void setBlock(BlockPos localPos, StructureBlockInfo newInfo) {
contraption.blocks.put(localPos, newInfo); contraption.blocks.put(localPos, newInfo);
AllPackets.getChannel().send(PacketDistributor.TRACKING_ENTITY.with(() -> this), CatnipServices.NETWORK.sendToClientsTrackingEntity(this, new ContraptionBlockChangedPacket(getId(), localPos, newInfo.state()));
new ContraptionBlockChangedPacket(getId(), localPos, newInfo.state()));
} }
protected abstract void tickContraption(); protected abstract void tickContraption();
@ -523,8 +522,7 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
} }
protected void onContraptionStalled() { protected void onContraptionStalled() {
AllPackets.getChannel().send(PacketDistributor.TRACKING_ENTITY.with(() -> this), CatnipServices.NETWORK.sendToClientsTrackingEntity(this, new ContraptionStallPacket(getId(), getX(), getY(), getZ(), getStalledAngle()));
new ContraptionStallPacket(getId(), getX(), getY(), getZ(), getStalledAngle()));
} }
protected boolean shouldActorTrigger(MovementContext context, StructureBlockInfo blockInfo, MovementBehaviour actor, protected boolean shouldActorTrigger(MovementContext context, StructureBlockInfo blockInfo, MovementBehaviour actor,
@ -599,20 +597,15 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
} }
@Override @Override
protected void defineSynchedData() { protected void defineSynchedData(SynchedEntityData.Builder builder) {
this.entityData.define(STALLED, false); builder.define(STALLED, false);
this.entityData.define(CONTROLLED_BY, Optional.empty()); builder.define(CONTROLLED_BY, Optional.empty());
} }
@Override @Override
public Packet<ClientGamePacketListener> getAddEntityPacket() { public void writeSpawnData(RegistryFriendlyByteBuf registryFriendlyByteBuf) {
return NetworkHooks.getEntitySpawningPacket(this);
}
@Override
public void writeSpawnData(FriendlyByteBuf buffer) {
CompoundTag compound = new CompoundTag(); CompoundTag compound = new CompoundTag();
writeAdditional(compound, true); writeAdditional(compound, registryFriendlyByteBuf.registryAccess(), true);
if (ContraptionData.isTooLargeForSync(compound)) { if (ContraptionData.isTooLargeForSync(compound)) {
String info = getContraption().getType().id + " @" + position() + " (" + getStringUUID() + ")"; String info = getContraption().getType().id + " @" + position() + " (" + getStringUUID() + ")";
@ -620,27 +613,30 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
compound = null; compound = null;
} }
buffer.writeNbt(compound); registryFriendlyByteBuf.writeNbt(compound);
} }
@Override @Override
protected final void addAdditionalSaveData(CompoundTag compound) { protected final void addAdditionalSaveData(CompoundTag compound) {
writeAdditional(compound, false); writeAdditional(compound, registryAccess(), false);
} }
protected void writeAdditional(CompoundTag compound, boolean spawnPacket) { protected void writeAdditional(CompoundTag compound, HolderLookup.Provider registries, boolean spawnPacket) {
if (contraption != null) if (contraption != null)
compound.put("Contraption", contraption.writeNBT(spawnPacket)); compound.put("Contraption", contraption.writeNBT(registries, spawnPacket));
compound.putBoolean("Stalled", isStalled()); compound.putBoolean("Stalled", isStalled());
compound.putBoolean("Initialized", initialized); compound.putBoolean("Initialized", initialized);
} }
@Override @Override
public void readSpawnData(FriendlyByteBuf additionalData) { public void readSpawnData(RegistryFriendlyByteBuf registryFriendlyByteBuf) {
CompoundTag nbt = additionalData.readAnySizeNbt(); CompoundTag nbt = readAnySizeNbt(registryFriendlyByteBuf);
if (nbt != null) { if (nbt != null) {
readAdditional(nbt, true); readAdditional(nbt, true);
} else {
Create.LOGGER.warn("Null spawn data for AbstractContraptionEntity");
} }
receivedSpawnData = true;
} }
@Override @Override
@ -648,6 +644,16 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
readAdditional(compound, false); readAdditional(compound, false);
} }
@Nullable
private static CompoundTag readAnySizeNbt(RegistryFriendlyByteBuf buf) {
Tag tag = buf.readNbt(NbtAccounter.unlimitedHeap());
if (tag != null && !(tag instanceof CompoundTag)) {
throw new DecoderException("Not a compound tag: " + tag);
} else {
return (CompoundTag) tag;
}
}
protected void readAdditional(CompoundTag compound, boolean spawnData) { protected void readAdditional(CompoundTag compound, boolean spawnData) {
if (compound.isEmpty()) if (compound.isEmpty())
return; return;
@ -667,8 +673,7 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
StructureTransform transform = makeStructureTransform(); StructureTransform transform = makeStructureTransform();
contraption.stop(level()); contraption.stop(level());
AllPackets.getChannel().send(PacketDistributor.TRACKING_ENTITY.with(() -> this), CatnipServices.NETWORK.sendToClientsTrackingEntity(this, new ContraptionDisassemblyPacket(this.getId(), transform));
new ContraptionDisassemblyPacket(this.getId(), transform));
contraption.addBlocksToWorld(level(), transform); contraption.addBlocksToWorld(level(), transform);
contraption.addPassengersToWorld(level(), transform, getPassengers()); contraption.addPassengersToWorld(level(), transform, getPassengers());
@ -728,8 +733,8 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
} }
@Override @Override
public void onRemovedFromWorld() { public void onRemovedFromLevel() {
super.onRemovedFromWorld(); super.onRemovedFromLevel();
} }
@Override @Override
@ -745,20 +750,20 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
static void handleStallPacket(ContraptionStallPacket packet) { static void handleStallPacket(ContraptionStallPacket packet) {
if (Minecraft.getInstance().level.getEntity(packet.entityID) instanceof AbstractContraptionEntity ce) if (Minecraft.getInstance().level.getEntity(packet.entityId()) instanceof AbstractContraptionEntity ce)
ce.handleStallInformation(packet.x, packet.y, packet.z, packet.angle); ce.handleStallInformation(packet.x(), packet.y(), packet.z(), packet.angle());
} }
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
static void handleBlockChangedPacket(ContraptionBlockChangedPacket packet) { static void handleBlockChangedPacket(ContraptionBlockChangedPacket packet) {
if (Minecraft.getInstance().level.getEntity(packet.entityID) instanceof AbstractContraptionEntity ce) if (Minecraft.getInstance().level.getEntity(packet.entityId()) instanceof AbstractContraptionEntity ce)
ce.handleBlockChange(packet.localPos, packet.newState); ce.handleBlockChange(packet.localPos(), packet.newState());
} }
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
static void handleDisassemblyPacket(ContraptionDisassemblyPacket packet) { static void handleDisassemblyPacket(ContraptionDisassemblyPacket packet) {
if (Minecraft.getInstance().level.getEntity(packet.entityID) instanceof AbstractContraptionEntity ce) if (Minecraft.getInstance().level.getEntity(packet.entityId()) instanceof AbstractContraptionEntity ce)
ce.moveCollidedEntitiesOnDisassembly(packet.transform); ce.moveCollidedEntitiesOnDisassembly(packet.transform());
} }
protected abstract float getStalledAngle(); protected abstract float getStalledAngle();
@ -923,10 +928,15 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
} }
@Override @Override
public void setSecondsOnFire(int p_70015_1_) { public void igniteForTicks(int ticks) {
// Contraptions no longer catch fire // Contraptions no longer catch fire
} }
@Override
public boolean fireImmune() {
return true;
}
// Contraptions shouldn't activate pressure plates and tripwires // Contraptions shouldn't activate pressure plates and tripwires
@Override @Override
public boolean isIgnoringBlockTriggers() { public boolean isIgnoringBlockTriggers() {
@ -944,4 +954,14 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
public boolean isPrevPosInvalid() { public boolean isPrevPosInvalid() {
return prevPosInvalid; return prevPosInvalid;
} }
private static class AbstractContraptionEntityClient {
private static void invalidate(Contraption contraption) {
// The visual will handle this with flywheel on.
if (!contraption.deferInvalidate || BackendManager.isBackendOn())
return;
contraption.deferInvalidate = false;
ContraptionRenderInfo.invalidate(contraption);
}
}
} }

View file

@ -4,6 +4,7 @@ import com.simibubi.create.foundation.utility.CreateLang;
import com.simibubi.create.infrastructure.config.AllConfigs; import com.simibubi.create.infrastructure.config.AllConfigs;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.HolderLookup;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
@ -14,12 +15,12 @@ public class AssemblyException extends Exception {
public final Component component; public final Component component;
private BlockPos position = null; private BlockPos position = null;
public static void write(CompoundTag compound, AssemblyException exception) { public static void write(CompoundTag compound, HolderLookup.Provider registries, AssemblyException exception) {
if (exception == null) if (exception == null)
return; return;
CompoundTag nbt = new CompoundTag(); CompoundTag nbt = new CompoundTag();
nbt.putString("Component", Component.Serializer.toJson(exception.component)); nbt.putString("Component", Component.Serializer.toJson(exception.component, registries));
if (exception.hasPosition()) if (exception.hasPosition())
nbt.putLong("Position", exception.getPosition() nbt.putLong("Position", exception.getPosition()
.asLong()); .asLong());
@ -27,13 +28,13 @@ public class AssemblyException extends Exception {
compound.put("LastException", nbt); compound.put("LastException", nbt);
} }
public static AssemblyException read(CompoundTag compound) { public static AssemblyException read(CompoundTag compound, HolderLookup.Provider registries) {
if (!compound.contains("LastException")) if (!compound.contains("LastException"))
return null; return null;
CompoundTag nbt = compound.getCompound("LastException"); CompoundTag nbt = compound.getCompound("LastException");
String string = nbt.getString("Component"); String string = nbt.getString("Component");
AssemblyException exception = new AssemblyException(Component.Serializer.fromJson(string)); AssemblyException exception = new AssemblyException(Component.Serializer.fromJson(string, registries));
if (nbt.contains("Position")) if (nbt.contains("Position"))
exception.position = BlockPos.of(nbt.getLong("Position")); exception.position = BlockPos.of(nbt.getLong("Position"));

View file

@ -85,6 +85,7 @@ import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.core.Direction.Axis; import net.minecraft.core.Direction.Axis;
import net.minecraft.core.HolderGetter; import net.minecraft.core.HolderGetter;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.registries.Registries; import net.minecraft.core.registries.Registries;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag; import net.minecraft.nbt.ListTag;
@ -122,12 +123,12 @@ import net.minecraft.world.phys.shapes.BooleanOp;
import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.Shapes; import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape; import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraftforge.client.model.data.ModelData; import net.neoforged.neoforge.client.model.data.ModelData;
import net.minecraftforge.fluids.FluidStack; import net.neoforged.neoforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.IFluidHandler; import net.neoforged.neoforge.fluids.capability.IFluidHandler;
import net.minecraftforge.items.IItemHandlerModifiable; import net.neoforged.neoforge.items.IItemHandlerModifiable;
import net.minecraftforge.items.wrapper.CombinedInvWrapper; import net.neoforged.neoforge.items.wrapper.CombinedInvWrapper;
import net.minecraftforge.registries.GameData; import net.neoforged.neoforge.registries.GameData;
public abstract class Contraption { public abstract class Contraption {
@ -632,7 +633,7 @@ public abstract class Contraption {
if (blockEntity instanceof PoweredShaftBlockEntity) if (blockEntity instanceof PoweredShaftBlockEntity)
blockEntity = AllBlockEntityTypes.BRACKETED_KINETIC.create(pos, blockstate); blockEntity = AllBlockEntityTypes.BRACKETED_KINETIC.create(pos, blockstate);
if (blockEntity instanceof FactoryPanelBlockEntity fpbe) if (blockEntity instanceof FactoryPanelBlockEntity fpbe)
fpbe.writeSafe(compoundnbt); fpbe.writeSafe(compoundnbt, world.registryAccess());
return Pair.of(new StructureBlockInfo(pos, blockstate, compoundnbt), blockEntity); return Pair.of(new StructureBlockInfo(pos, blockstate, compoundnbt), blockEntity);
} }
@ -670,9 +671,9 @@ public abstract class Contraption {
return; return;
CompoundTag nbt = structureBlockInfo.nbt(); CompoundTag nbt = structureBlockInfo.nbt();
BlockPos controllerPos = nbt.contains("Controller") ? BlockPos controllerPos = NbtUtils.readBlockPos(nbt,"Controller")
toLocalPos(NbtUtils.readBlockPos(nbt.getCompound("Controller"))) : .map(this::toLocalPos)
localPos; .orElse(localPos);
nbt.put("Controller", NbtUtils.writeBlockPos(controllerPos)); nbt.put("Controller", NbtUtils.writeBlockPos(controllerPos));
if (multiBlockBE.isController() && multiBlockBE.getHeight() <= 1 && multiBlockBE.getWidth() <= 1) { if (multiBlockBE.isController() && multiBlockBE.getHeight() <= 1 && multiBlockBE.getWidth() <= 1) {
@ -689,7 +690,7 @@ public abstract class Contraption {
BlockEntity blockEntity = world.getBlockEntity(pos); BlockEntity blockEntity = world.getBlockEntity(pos);
if (blockEntity == null) if (blockEntity == null)
return null; return null;
CompoundTag nbt = blockEntity.saveWithFullMetadata(); CompoundTag nbt = blockEntity.saveWithFullMetadata(world.registryAccess());
nbt.remove("x"); nbt.remove("x");
nbt.remove("y"); nbt.remove("y");
nbt.remove("z"); nbt.remove("z");
@ -726,9 +727,9 @@ public abstract class Contraption {
if (!tag.contains("Controller", Tag.TAG_COMPOUND) && !tag.contains("Parts", Tag.TAG_LIST)) if (!tag.contains("Controller", Tag.TAG_COMPOUND) && !tag.contains("Parts", Tag.TAG_LIST))
return; return;
BlockPos controllerPos = NbtUtils.readBlockPos(tag.getCompound("Controller")); BlockPos controllerPos = NbtUtils.readBlockPos(tag, "Controller").orElseThrow();
tag.getList("Parts", Tag.TAG_COMPOUND).forEach(part -> { tag.getList("Parts", Tag.TAG_COMPOUND).forEach(part -> {
BlockPos partPos = NbtUtils.readBlockPos((CompoundTag) part); BlockPos partPos = NbtUtils.readBlockPos((CompoundTag) part, "Pos").orElseThrow();
StructureBlockInfo partInfo = this.blocks.get(partPos); StructureBlockInfo partInfo = this.blocks.get(partPos);
capturedMultiblocks.put(controllerPos, partInfo); capturedMultiblocks.put(controllerPos, partInfo);
}); });
@ -738,14 +739,14 @@ public abstract class Contraption {
nbt.getList("Actors", Tag.TAG_COMPOUND) nbt.getList("Actors", Tag.TAG_COMPOUND)
.forEach(c -> { .forEach(c -> {
CompoundTag comp = (CompoundTag) c; CompoundTag comp = (CompoundTag) c;
StructureBlockInfo info = this.blocks.get(NbtUtils.readBlockPos(comp.getCompound("Pos"))); StructureBlockInfo info = this.blocks.get(NbtUtils.readBlockPos(comp, "Pos").orElseThrow());
if (info == null) if (info == null)
return; return;
MovementContext context = MovementContext.readNBT(world, info, comp, this); MovementContext context = MovementContext.readNBT(world, info, comp, this);
getActors().add(MutablePair.of(info, context)); getActors().add(MutablePair.of(info, context));
}); });
disabledActors = NBTHelper.readItemList(nbt.getList("DisabledActors", Tag.TAG_COMPOUND)); disabledActors = NBTHelper.readItemList(nbt.getList("DisabledActors", Tag.TAG_COMPOUND), world.registryAccess());
for (ItemStack stack : disabledActors) for (ItemStack stack : disabledActors)
setActorsActive(stack, false); setActorsActive(stack, false);
@ -754,7 +755,7 @@ public abstract class Contraption {
c -> superglue.add(SuperGlueEntity.readBoundingBox(c))); c -> superglue.add(SuperGlueEntity.readBoundingBox(c)));
seats.clear(); seats.clear();
NBTHelper.iterateCompoundList(nbt.getList("Seats", Tag.TAG_COMPOUND), c -> seats.add(NbtUtils.readBlockPos(c))); NBTHelper.iterateCompoundList(nbt.getList("Seats", Tag.TAG_COMPOUND), c -> seats.add(NbtUtils.readBlockPos(c, "Pos").orElseThrow()));
seatMapping.clear(); seatMapping.clear();
NBTHelper.iterateCompoundList(nbt.getList("Passengers", Tag.TAG_COMPOUND), NBTHelper.iterateCompoundList(nbt.getList("Passengers", Tag.TAG_COMPOUND),
@ -766,7 +767,7 @@ public abstract class Contraption {
interactors.clear(); interactors.clear();
NBTHelper.iterateCompoundList(nbt.getList("Interactors", Tag.TAG_COMPOUND), c -> { NBTHelper.iterateCompoundList(nbt.getList("Interactors", Tag.TAG_COMPOUND), c -> {
BlockPos pos = NbtUtils.readBlockPos(c.getCompound("Pos")); BlockPos pos = NbtUtils.readBlockPos(c, "Pos").orElseThrow();
StructureBlockInfo structureBlockInfo = getBlocks().get(pos); StructureBlockInfo structureBlockInfo = getBlocks().get(pos);
if (structureBlockInfo == null) if (structureBlockInfo == null)
return; return;
@ -775,17 +776,17 @@ public abstract class Contraption {
interactors.put(pos, behaviour); interactors.put(pos, behaviour);
}); });
storage.read(nbt, presentBlockEntities, spawnData); storage.read(nbt, world.registryAccess(), presentBlockEntities, spawnData);
if (nbt.contains("BoundsFront")) if (nbt.contains("BoundsFront"))
bounds = NBTHelper.readAABB(nbt.getList("BoundsFront", Tag.TAG_FLOAT)); bounds = NBTHelper.readAABB(nbt.getList("BoundsFront", Tag.TAG_FLOAT));
stalled = nbt.getBoolean("Stalled"); stalled = nbt.getBoolean("Stalled");
hasUniversalCreativeCrate = nbt.getBoolean("BottomlessSupply"); hasUniversalCreativeCrate = nbt.getBoolean("BottomlessSupply");
anchor = NbtUtils.readBlockPos(nbt.getCompound("Anchor")); anchor = NbtUtils.readBlockPos(nbt, "Anchor").orElseThrow();
} }
public CompoundTag writeNBT(boolean spawnPacket) { public CompoundTag writeNBT(HolderLookup.Provider registries, boolean spawnPacket) {
CompoundTag nbt = new CompoundTag(); CompoundTag nbt = new CompoundTag();
nbt.putString("Type", getType().id); nbt.putString("Type", getType().id);
@ -798,7 +799,10 @@ public abstract class Contraption {
Collection<StructureBlockInfo> multiblockParts = capturedMultiblocks.get(controllerPos); Collection<StructureBlockInfo> multiblockParts = capturedMultiblocks.get(controllerPos);
ListTag partsNBT = new ListTag(); ListTag partsNBT = new ListTag();
multiblockParts.forEach(info -> partsNBT.add(NbtUtils.writeBlockPos(info.pos()))); multiblockParts.forEach(info -> {
CompoundTag c = new CompoundTag();
partsNBT.add(c.put("Pos", NbtUtils.writeBlockPos(info.pos())));
});
tag.put("Parts", partsNBT); tag.put("Parts", partsNBT);
multiblocksNBT.add(tag); multiblocksNBT.add(tag);
@ -816,7 +820,7 @@ public abstract class Contraption {
actorsNBT.add(compound); actorsNBT.add(compound);
} }
ListTag disabledActorsNBT = NBTHelper.writeItemList(disabledActors); ListTag disabledActorsNBT = NBTHelper.writeItemList(disabledActors, registries);
ListTag superglueNBT = new ListTag(); ListTag superglueNBT = new ListTag();
if (!spawnPacket) { if (!spawnPacket) {
@ -827,7 +831,7 @@ public abstract class Contraption {
} }
} }
(spawnPacket ? getStorageForSpawnPacket() : storage).write(nbt, spawnPacket); (spawnPacket ? getStorageForSpawnPacket() : storage).write(nbt, registries, spawnPacket);
ListTag interactorNBT = new ListTag(); ListTag interactorNBT = new ListTag();
for (BlockPos pos : interactors.keySet()) { for (BlockPos pos : interactors.keySet()) {
@ -836,7 +840,11 @@ public abstract class Contraption {
interactorNBT.add(c); interactorNBT.add(c);
} }
nbt.put("Seats", NBTHelper.writeCompoundList(getSeats(), NbtUtils::writeBlockPos)); nbt.put("Seats", NBTHelper.writeCompoundList(getSeats(), pos -> {
CompoundTag c = new CompoundTag();
c.put("Pos", NbtUtils.writeBlockPos(pos));
return c;
}));
nbt.put("Passengers", NBTHelper.writeCompoundList(getSeatMapping().entrySet(), e -> { nbt.put("Passengers", NBTHelper.writeCompoundList(getSeatMapping().entrySet(), e -> {
CompoundTag tag = new CompoundTag(); CompoundTag tag = new CompoundTag();
tag.put("Id", NbtUtils.createUUID(e.getKey())); tag.put("Id", NbtUtils.createUUID(e.getKey()));
@ -941,7 +949,7 @@ public abstract class Contraption {
tag.putInt("y", info.pos().getY()); tag.putInt("y", info.pos().getY());
tag.putInt("z", info.pos().getZ()); tag.putInt("z", info.pos().getZ());
BlockEntity be = BlockEntity.loadStatic(info.pos(), info.state(), tag); BlockEntity be = BlockEntity.loadStatic(info.pos(), info.state(), tag, world.registryAccess());
if (be == null) if (be == null)
return; return;
be.setLevel(world); be.setLevel(world);
@ -967,7 +975,7 @@ public abstract class Contraption {
} }
private static StructureBlockInfo legacyReadStructureBlockInfo(CompoundTag blockListEntry, HolderGetter<Block> holderGetter) { private static StructureBlockInfo legacyReadStructureBlockInfo(CompoundTag blockListEntry, HolderGetter<Block> holderGetter) {
return new StructureBlockInfo(NbtUtils.readBlockPos(blockListEntry.getCompound("Pos")), return new StructureBlockInfo(NbtUtils.readBlockPos(blockListEntry, "Pos").orElseThrow(),
NbtUtils.readBlockState(holderGetter, blockListEntry.getCompound("Block")), NbtUtils.readBlockState(holderGetter, blockListEntry.getCompound("Block")),
blockListEntry.contains("Data") ? blockListEntry.getCompound("Data") : null); blockListEntry.contains("Data") ? blockListEntry.getCompound("Data") : null);
} }
@ -1155,7 +1163,7 @@ public abstract class Contraption {
} }
} }
blockEntity.load(tag); blockEntity.loadWithComponents(tag, world.registryAccess());
storage.addStorageToWorld(block, blockEntity); storage.addStorageToWorld(block, blockEntity);
} }

View file

@ -1,46 +1,35 @@
package com.simibubi.create.content.contraptions; package com.simibubi.create.content.contraptions;
import com.simibubi.create.foundation.networking.SimplePacketBase; import com.simibubi.create.AllPackets;
import net.createmod.catnip.net.base.ClientboundPacketPayload;
import net.createmod.catnip.codecs.stream.CatnipStreamCodecs;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.nbt.NbtUtils; import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.api.distmarker.Dist; import io.netty.buffer.ByteBuf;
import net.minecraftforge.fml.DistExecutor; import net.neoforged.api.distmarker.Dist;
import net.minecraftforge.network.NetworkEvent.Context; import net.neoforged.api.distmarker.OnlyIn;
import net.neoforged.neoforge.network.handling.IPayloadContext;
public class ContraptionBlockChangedPacket extends SimplePacketBase { public record ContraptionBlockChangedPacket(int entityId, BlockPos localPos, BlockState newState) implements ClientboundPacketPayload {
public static final StreamCodec<ByteBuf, ContraptionBlockChangedPacket> STREAM_CODEC = StreamCodec.composite(
ByteBufCodecs.INT, ContraptionBlockChangedPacket::entityId,
BlockPos.STREAM_CODEC, ContraptionBlockChangedPacket::localPos,
CatnipStreamCodecs.BLOCK_STATE, ContraptionBlockChangedPacket::newState,
ContraptionBlockChangedPacket::new
);
int entityID; @Override
BlockPos localPos; @OnlyIn(Dist.CLIENT)
BlockState newState; public void handle(LocalPlayer player) {
AbstractContraptionEntity.handleBlockChangedPacket(this);
public ContraptionBlockChangedPacket(int id, BlockPos pos, BlockState state) {
entityID = id;
localPos = pos;
newState = state;
} }
@Override @Override
public void write(FriendlyByteBuf buffer) { public PacketTypeProvider getTypeProvider() {
buffer.writeInt(entityID); return AllPackets.CONTRAPTION_BLOCK_CHANGED;
buffer.writeBlockPos(localPos);
buffer.writeNbt(NbtUtils.writeBlockState(newState));
} }
@SuppressWarnings("deprecation")
public ContraptionBlockChangedPacket(FriendlyByteBuf buffer) {
entityID = buffer.readInt();
localPos = buffer.readBlockPos();
newState = NbtUtils.readBlockState(BuiltInRegistries.BLOCK.asLookup(), buffer.readNbt());
}
@Override
public boolean handle(Context context) {
context.enqueueWork(() -> DistExecutor.unsafeRunWhenOn(Dist.CLIENT,
() -> () -> AbstractContraptionEntity.handleBlockChangedPacket(this)));
return true;
}
} }

View file

@ -1,9 +1,22 @@
package com.simibubi.create.content.contraptions; package com.simibubi.create.content.contraptions;
import static net.minecraft.world.entity.Entity.collideBoundingBox;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
import org.apache.commons.lang3.mutable.MutableBoolean;
import org.apache.commons.lang3.mutable.MutableFloat;
import org.apache.commons.lang3.mutable.MutableObject;
import org.apache.commons.lang3.tuple.MutablePair;
import com.google.common.base.Predicates; import com.google.common.base.Predicates;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllMovementBehaviours; import com.simibubi.create.AllMovementBehaviours;
import com.simibubi.create.AllPackets;
import com.simibubi.create.content.contraptions.AbstractContraptionEntity.ContraptionRotationState; import com.simibubi.create.content.contraptions.AbstractContraptionEntity.ContraptionRotationState;
import com.simibubi.create.content.contraptions.ContraptionColliderLockPacket.ContraptionColliderLockPacketRequest; import com.simibubi.create.content.contraptions.ContraptionColliderLockPacket.ContraptionColliderLockPacketRequest;
import com.simibubi.create.content.contraptions.actors.harvester.HarvesterMovementBehaviour; import com.simibubi.create.content.contraptions.actors.harvester.HarvesterMovementBehaviour;
@ -19,6 +32,8 @@ import com.simibubi.create.foundation.collision.OrientedBB;
import com.simibubi.create.foundation.damageTypes.CreateDamageSources; import com.simibubi.create.foundation.damageTypes.CreateDamageSources;
import com.simibubi.create.foundation.utility.BlockHelper; import com.simibubi.create.foundation.utility.BlockHelper;
import com.simibubi.create.infrastructure.config.AllConfigs; import com.simibubi.create.infrastructure.config.AllConfigs;
import net.createmod.catnip.platform.CatnipServices;
import net.createmod.catnip.utility.Iterate; import net.createmod.catnip.utility.Iterate;
import net.createmod.catnip.utility.VecHelper; import net.createmod.catnip.utility.VecHelper;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
@ -49,22 +64,8 @@ import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import net.minecraft.world.phys.shapes.VoxelShape; import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraftforge.api.distmarker.Dist; import net.neoforged.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.neoforged.api.distmarker.OnlyIn;
import net.minecraftforge.fml.DistExecutor;
import org.apache.commons.lang3.mutable.MutableBoolean;
import org.apache.commons.lang3.mutable.MutableFloat;
import org.apache.commons.lang3.mutable.MutableObject;
import org.apache.commons.lang3.tuple.MutablePair;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
import static net.minecraft.world.entity.Entity.collideBoundingBox;
public class ContraptionCollider { public class ContraptionCollider {
@ -91,8 +92,7 @@ public class ContraptionCollider {
ContraptionRotationState rotation = null; ContraptionRotationState rotation = null;
if (world.isClientSide() && safetyLock.left != null && safetyLock.left.get() == contraptionEntity) if (world.isClientSide() && safetyLock.left != null && safetyLock.left.get() == contraptionEntity)
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, CatnipServices.PLATFORM.executeOnClientOnly(() -> () -> saveClientPlayerFromClipping(contraptionEntity, contraptionMotion));
() -> () -> saveClientPlayerFromClipping(contraptionEntity, contraptionMotion));
// After death, multiple refs to the client player may show up in the area // After death, multiple refs to the client player may show up in the area
boolean skipClientPlayer = false; boolean skipClientPlayer = false;
@ -107,8 +107,7 @@ public class ContraptionCollider {
if (playerType == PlayerType.REMOTE) { if (playerType == PlayerType.REMOTE) {
if (!(contraption instanceof TranslatingContraption)) if (!(contraption instanceof TranslatingContraption))
continue; continue;
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, CatnipServices.PLATFORM.executeOnClientOnly(() -> () -> saveRemotePlayerFromClipping((Player) entity, contraptionEntity, contraptionMotion));
() -> () -> saveRemotePlayerFromClipping((Player) entity, contraptionEntity, contraptionMotion));
continue; continue;
} }
@ -203,7 +202,7 @@ public class ContraptionCollider {
Vec3 collisionPosition = intersect.getCollisionPosition(); Vec3 collisionPosition = intersect.getCollisionPosition();
if (!isTemporal) { if (!isTemporal) {
Vec3 separation = intersect.asSeparationVec(entity.getStepHeight()); Vec3 separation = intersect.asSeparationVec(entity.maxUpStep());
if (separation != null && !separation.equals(Vec3.ZERO)) { if (separation != null && !separation.equals(Vec3.ZERO)) {
collisionResponse.setValue(currentResponse.add(separation)); collisionResponse.setValue(currentResponse.add(separation));
timeOfImpact = 0; timeOfImpact = 0;
@ -368,8 +367,7 @@ public class ContraptionCollider {
entity.fallDistance = 0; entity.fallDistance = 0;
for (Entity rider : entity.getIndirectPassengers()) for (Entity rider : entity.getIndirectPassengers())
if (getPlayerType(rider) == PlayerType.CLIENT) if (getPlayerType(rider) == PlayerType.CLIENT)
AllPackets.getChannel() CatnipServices.NETWORK.sendToServer(new ClientMotionPacket(rider.getDeltaMovement(), true, 0));
.sendToServer(new ClientMotionPacket(rider.getDeltaMovement(), true, 0));
boolean canWalk = bounce != 0 || slide == 0; boolean canWalk = bounce != 0 || slide == 0;
if (canWalk || !rotation.hasVerticalRotation()) { if (canWalk || !rotation.hasVerticalRotation()) {
if (canWalk) if (canWalk)
@ -393,8 +391,7 @@ public class ContraptionCollider {
float limbSwing = Mth.sqrt((float) (d0 * d0 + d1 * d1)) * 4.0F; float limbSwing = Mth.sqrt((float) (d0 * d0 + d1 * d1)) * 4.0F;
if (limbSwing > 1.0F) if (limbSwing > 1.0F)
limbSwing = 1.0F; limbSwing = 1.0F;
AllPackets.getChannel() CatnipServices.NETWORK.sendToServer(new ClientMotionPacket(entityMotion, true, limbSwing));
.sendToServer(new ClientMotionPacket(entityMotion, true, limbSwing));
if (entity.onGround() && contraption instanceof TranslatingContraption) { if (entity.onGround() && contraption instanceof TranslatingContraption) {
safetyLock.setLeft(new WeakReference<>(contraptionEntity)); safetyLock.setLeft(new WeakReference<>(contraptionEntity));
@ -424,8 +421,7 @@ public class ContraptionCollider {
if (packetCooldown > 0) if (packetCooldown > 0)
packetCooldown--; packetCooldown--;
if (packetCooldown == 0) { if (packetCooldown == 0) {
AllPackets.getChannel() CatnipServices.NETWORK.sendToServer(new ContraptionColliderLockPacketRequest(contraptionEntity.getId(), currentDiff));
.sendToServer(new ContraptionColliderLockPacketRequest(contraptionEntity.getId(), currentDiff));
packetCooldown = 3; packetCooldown = 3;
} }
} }
@ -477,7 +473,7 @@ public class ContraptionCollider {
AABB bb = entity.getBoundingBox() AABB bb = entity.getBoundingBox()
.deflate(1 / 4f, 0, 1 / 4f); .deflate(1 / 4f, 0, 1 / 4f);
double shortestDistance = Double.MAX_VALUE; double shortestDistance = Double.MAX_VALUE;
double yStart = entity.getStepHeight() + contraptionEntity.getY() + yStartOffset; double yStart = entity.maxUpStep() + contraptionEntity.getY() + yStartOffset;
double rayLength = Math.max(5, Math.abs(entity.getY() - yStart)); double rayLength = Math.max(5, Math.abs(entity.getY() - yStart));
for (int rayIndex = 0; rayIndex < 4; rayIndex++) { for (int rayIndex = 0; rayIndex < 4; rayIndex++) {
@ -537,8 +533,7 @@ public class ContraptionCollider {
return entityMotion; return entityMotion;
if (playerType == PlayerType.CLIENT) { if (playerType == PlayerType.CLIENT) {
AllPackets.getChannel() CatnipServices.NETWORK.sendToServer(new TrainCollisionPacket((int) (damage * 16), contraptionEntity.getId()));
.sendToServer(new TrainCollisionPacket((int) (damage * 16), contraptionEntity.getId()));
world.playSound((Player) entity, entity.blockPosition(), SoundEvents.PLAYER_ATTACK_CRIT, world.playSound((Player) entity, entity.blockPosition(), SoundEvents.PLAYER_ATTACK_CRIT,
SoundSource.NEUTRAL, 1, .75f); SoundSource.NEUTRAL, 1, .75f);
} else { } else {
@ -617,12 +612,12 @@ public class ContraptionCollider {
boolean flag1 = p_20273_.y != vec3.y; boolean flag1 = p_20273_.y != vec3.y;
boolean flag2 = p_20273_.z != vec3.z; boolean flag2 = p_20273_.z != vec3.z;
boolean flag3 = flag1 && p_20273_.y < 0.0D; boolean flag3 = flag1 && p_20273_.y < 0.0D;
if (e.getStepHeight() > 0.0F && flag3 && (flag || flag2)) { if (e.maxUpStep() > 0.0F && flag3 && (flag || flag2)) {
Vec3 vec31 = collideBoundingBox(e, new Vec3(p_20273_.x, (double) e.getStepHeight(), p_20273_.z), aabb, Vec3 vec31 = collideBoundingBox(e, new Vec3(p_20273_.x, (double) e.maxUpStep(), p_20273_.z), aabb,
e.level(), list); e.level(), list);
Vec3 vec32 = collideBoundingBox(e, new Vec3(0.0D, (double) e.getStepHeight(), 0.0D), Vec3 vec32 = collideBoundingBox(e, new Vec3(0.0D, (double) e.maxUpStep(), 0.0D),
aabb.expandTowards(p_20273_.x, 0.0D, p_20273_.z), e.level(), list); aabb.expandTowards(p_20273_.x, 0.0D, p_20273_.z), e.level(), list);
if (vec32.y < (double) e.getStepHeight()) { if (vec32.y < (double) e.maxUpStep()) {
Vec3 vec33 = Vec3 vec33 =
collideBoundingBox(e, new Vec3(p_20273_.x, 0.0D, p_20273_.z), aabb.move(vec32), e.level(), list) collideBoundingBox(e, new Vec3(p_20273_.x, 0.0D, p_20273_.z), aabb.move(vec32), e.level(), list)
.add(vec32); .add(vec32);
@ -646,7 +641,7 @@ public class ContraptionCollider {
if (!entity.level().isClientSide) if (!entity.level().isClientSide)
return PlayerType.SERVER; return PlayerType.SERVER;
MutableBoolean isClient = new MutableBoolean(false); MutableBoolean isClient = new MutableBoolean(false);
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> isClient.setValue(isClientPlayerEntity(entity))); CatnipServices.PLATFORM.executeOnClientOnly(() -> () -> isClient.setValue(isClientPlayerEntity(entity)));
return isClient.booleanValue() ? PlayerType.CLIENT : PlayerType.REMOTE; return isClient.booleanValue() ? PlayerType.CLIENT : PlayerType.REMOTE;
} }

View file

@ -1,78 +1,54 @@
package com.simibubi.create.content.contraptions; package com.simibubi.create.content.contraptions;
import com.simibubi.create.AllPackets; import com.simibubi.create.AllPackets;
import com.simibubi.create.foundation.networking.SimplePacketBase; import net.createmod.catnip.net.base.ClientboundPacketPayload;
import net.createmod.catnip.platform.CatnipServices;
import net.createmod.catnip.net.base.ServerboundPacketPayload;
import net.minecraft.network.FriendlyByteBuf; import io.netty.buffer.ByteBuf;
import net.minecraftforge.api.distmarker.Dist; import net.minecraft.client.player.LocalPlayer;
import net.minecraftforge.fml.DistExecutor; import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraftforge.network.NetworkEvent.Context; import net.minecraft.network.codec.StreamCodec;
import net.minecraftforge.network.PacketDistributor; import net.minecraft.server.level.ServerPlayer;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.api.distmarker.OnlyIn;
import net.neoforged.neoforge.network.handling.IPayloadContext;
public class ContraptionColliderLockPacket extends SimplePacketBase { public record ContraptionColliderLockPacket(int contraption, double offset, int sender) implements ClientboundPacketPayload {
public static final StreamCodec<ByteBuf, ContraptionColliderLockPacket> STREAM_CODEC = StreamCodec.composite(
ByteBufCodecs.VAR_INT, ContraptionColliderLockPacket::contraption,
ByteBufCodecs.DOUBLE, ContraptionColliderLockPacket::offset,
ByteBufCodecs.VAR_INT, ContraptionColliderLockPacket::sender,
ContraptionColliderLockPacket::new
);
protected int contraption; @Override
protected double offset; @OnlyIn(Dist.CLIENT)
private int sender; public void handle(LocalPlayer player) {
ContraptionCollider.lockPacketReceived(contraption, sender, offset);
public ContraptionColliderLockPacket(int contraption, double offset, int sender) {
this.contraption = contraption;
this.offset = offset;
this.sender = sender;
}
public ContraptionColliderLockPacket(FriendlyByteBuf buffer) {
contraption = buffer.readVarInt();
offset = buffer.readDouble();
sender = buffer.readVarInt();
} }
@Override @Override
public void write(FriendlyByteBuf buffer) { public PacketTypeProvider getTypeProvider() {
buffer.writeVarInt(contraption); return AllPackets.CONTRAPTION_COLLIDER_LOCK;
buffer.writeDouble(offset);
buffer.writeVarInt(sender);
} }
@Override public record ContraptionColliderLockPacketRequest(int contraption, double offset) implements ServerboundPacketPayload {
public boolean handle(Context context) { public static final StreamCodec<ByteBuf, ContraptionColliderLockPacketRequest> STREAM_CODEC = StreamCodec.composite(
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, ByteBufCodecs.VAR_INT, ContraptionColliderLockPacketRequest::contraption,
() -> () -> ContraptionCollider.lockPacketReceived(contraption, sender, offset)); ByteBufCodecs.DOUBLE, ContraptionColliderLockPacketRequest::offset,
return true; ContraptionColliderLockPacketRequest::new
} );
public static class ContraptionColliderLockPacketRequest extends SimplePacketBase { @Override
public void handle(ServerPlayer player) {
protected int contraption; CatnipServices.NETWORK.sendToClientsTrackingEntity(player, new ContraptionColliderLockPacket(contraption, offset, player.getId()));
protected double offset;
public ContraptionColliderLockPacketRequest(int contraption, double offset) {
this.contraption = contraption;
this.offset = offset;
}
public ContraptionColliderLockPacketRequest(FriendlyByteBuf buffer) {
contraption = buffer.readVarInt();
offset = buffer.readDouble();
} }
@Override @Override
public void write(FriendlyByteBuf buffer) { public PacketTypeProvider getTypeProvider() {
buffer.writeVarInt(contraption); return AllPackets.CONTRAPTION_COLLIDER_LOCK_REQUEST;
buffer.writeDouble(offset);
} }
@Override
public boolean handle(Context context) {
context.enqueueWork(() -> {
AllPackets.getChannel()
.send(PacketDistributor.TRACKING_ENTITY.with(context::getSender),
new ContraptionColliderLockPacket(contraption, offset, context.getSender()
.getId()));
});
return true;
}
} }
} }

View file

@ -7,6 +7,7 @@ import com.simibubi.create.infrastructure.config.AllConfigs;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtAccounter; import net.minecraft.nbt.NbtAccounter;
import net.minecraft.nbt.Tag;
import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket; import net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket;
@ -66,17 +67,17 @@ public class ContraptionData {
/** /**
* @return true if the given NBT is too large for a contraption to be picked up with a wrench. * @return true if the given NBT is too large for a contraption to be picked up with a wrench.
*/ */
public static boolean isTooLargeForPickup(CompoundTag data) { public static boolean isTooLargeForPickup(Tag data) {
return packetSize(data) > PICKUP_LIMIT; return packetSize(data) > PICKUP_LIMIT;
} }
/** /**
* @return the size of the given NBT when put through a packet, in bytes. * @return the size of the given NBT when put through a packet, in bytes.
*/ */
public static long packetSize(CompoundTag data) { public static long packetSize(Tag data) {
FriendlyByteBuf test = new FriendlyByteBuf(Unpooled.buffer()); FriendlyByteBuf test = new FriendlyByteBuf(Unpooled.buffer());
test.writeNbt(data); test.writeNbt(data);
NbtAccounter sizeTracker = new NbtAccounter(Long.MAX_VALUE); NbtAccounter sizeTracker = NbtAccounter.unlimitedHeap();
test.readNbt(sizeTracker); test.readNbt(sizeTracker);
long size = ((NbtAccounterAccessor) sizeTracker).create$getUsage(); long size = ((NbtAccounterAccessor) sizeTracker).create$getUsage();
test.release(); test.release();

View file

@ -1,38 +1,31 @@
package com.simibubi.create.content.contraptions; package com.simibubi.create.content.contraptions;
import com.simibubi.create.foundation.networking.SimplePacketBase; import com.simibubi.create.AllPackets;
import net.createmod.catnip.net.base.ClientboundPacketPayload;
import net.minecraft.network.FriendlyByteBuf; import net.minecraft.client.player.LocalPlayer;
import net.minecraftforge.api.distmarker.Dist; import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraftforge.fml.DistExecutor; import net.minecraft.network.codec.StreamCodec;
import net.minecraftforge.network.NetworkEvent.Context; import io.netty.buffer.ByteBuf;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.api.distmarker.OnlyIn;
import net.neoforged.neoforge.network.handling.IPayloadContext;
public class ContraptionDisassemblyPacket extends SimplePacketBase { public record ContraptionDisassemblyPacket(int entityId, StructureTransform transform) implements ClientboundPacketPayload {
public static final StreamCodec<ByteBuf, ContraptionDisassemblyPacket> STREAM_CODEC = StreamCodec.composite(
ByteBufCodecs.INT, ContraptionDisassemblyPacket::entityId,
StructureTransform.STREAM_CODEC, ContraptionDisassemblyPacket::transform,
ContraptionDisassemblyPacket::new
);
int entityID; @Override
StructureTransform transform; @OnlyIn(Dist.CLIENT)
public void handle(LocalPlayer player) {
public ContraptionDisassemblyPacket(int entityID, StructureTransform transform) { AbstractContraptionEntity.handleDisassemblyPacket(this);
this.entityID = entityID;
this.transform = transform;
}
public ContraptionDisassemblyPacket(FriendlyByteBuf buffer) {
entityID = buffer.readInt();
transform = StructureTransform.fromBuffer(buffer);
} }
@Override @Override
public void write(FriendlyByteBuf buffer) { public PacketTypeProvider getTypeProvider() {
buffer.writeInt(entityID); return AllPackets.CONTRAPTION_DISASSEMBLE;
transform.writeToBuffer(buffer);
} }
@Override
public boolean handle(Context context) {
context.enqueueWork(() -> DistExecutor.unsafeRunWhenOn(Dist.CLIENT,
() -> () -> AbstractContraptionEntity.handleDisassemblyPacket(this)));
return true;
}
} }

View file

@ -1,12 +1,20 @@
package com.simibubi.create.content.contraptions; package com.simibubi.create.content.contraptions;
import java.lang.ref.WeakReference;
import java.util.Collection;
import javax.annotation.Nullable;
import org.apache.commons.lang3.mutable.MutableObject;
import com.simibubi.create.AllItems; import com.simibubi.create.AllItems;
import com.simibubi.create.AllPackets;
import com.simibubi.create.content.contraptions.sync.ContraptionInteractionPacket; import com.simibubi.create.content.contraptions.sync.ContraptionInteractionPacket;
import com.simibubi.create.content.trains.entity.CarriageContraptionEntity; import com.simibubi.create.content.trains.entity.CarriageContraptionEntity;
import com.simibubi.create.content.trains.entity.TrainRelocator; import com.simibubi.create.content.trains.entity.TrainRelocator;
import com.simibubi.create.foundation.utility.RaycastHelper; import com.simibubi.create.foundation.utility.RaycastHelper;
import com.simibubi.create.foundation.utility.RaycastHelper.PredicateTraceResult; import com.simibubi.create.foundation.utility.RaycastHelper.PredicateTraceResult;
import net.createmod.catnip.platform.CatnipServices;
import net.createmod.catnip.utility.Couple; import net.createmod.catnip.utility.Couple;
import net.createmod.catnip.utility.Iterate; import net.createmod.catnip.utility.Iterate;
import net.createmod.catnip.utility.VecHelper; import net.createmod.catnip.utility.VecHelper;
@ -24,30 +32,22 @@ import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import net.minecraft.world.phys.shapes.VoxelShape; import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraftforge.api.distmarker.Dist; import net.neoforged.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.neoforged.api.distmarker.OnlyIn;
import net.minecraftforge.client.event.InputEvent; import net.neoforged.bus.api.SubscribeEvent;
import net.minecraftforge.event.TickEvent.Phase; import net.neoforged.fml.common.EventBusSubscriber;
import net.minecraftforge.event.TickEvent.PlayerTickEvent; import net.neoforged.neoforge.client.event.InputEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.neoforged.neoforge.event.tick.PlayerTickEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
import org.apache.commons.lang3.mutable.MutableObject;
import javax.annotation.Nullable; @EventBusSubscriber(Dist.CLIENT)
import java.lang.ref.WeakReference;
import java.util.Collection;
@EventBusSubscriber
public class ContraptionHandlerClient { public class ContraptionHandlerClient {
@SubscribeEvent @SubscribeEvent
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public static void preventRemotePlayersWalkingAnimations(PlayerTickEvent event) { public static void preventRemotePlayersWalkingAnimations(PlayerTickEvent.Post event) {
if (event.phase == Phase.START) if (!(event.getEntity() instanceof RemotePlayer remotePlayer))
return; return;
if (!(event.player instanceof RemotePlayer))
return;
RemotePlayer remotePlayer = (RemotePlayer) event.player;
CompoundTag data = remotePlayer.getPersistentData(); CompoundTag data = remotePlayer.getPersistentData();
if (!data.contains("LastOverrideLimbSwingUpdate")) if (!data.contains("LastOverrideLimbSwingUpdate"))
return; return;
@ -106,7 +106,7 @@ public class ContraptionHandlerClient {
BlockPos pos = rayTraceResult.getBlockPos(); BlockPos pos = rayTraceResult.getBlockPos();
if (contraptionEntity.handlePlayerInteraction(player, pos, face, hand)) { if (contraptionEntity.handlePlayerInteraction(player, pos, face, hand)) {
AllPackets.getChannel().sendToServer(new ContraptionInteractionPacket(contraptionEntity, hand, pos, face)); CatnipServices.NETWORK.sendToServer(new ContraptionInteractionPacket(contraptionEntity, hand, pos, face));
} else if (handleSpecialInteractions(contraptionEntity, player, pos, face, hand)) { } else if (handleSpecialInteractions(contraptionEntity, player, pos, face, hand)) {
} else } else
continue; continue;
@ -128,7 +128,7 @@ public class ContraptionHandlerClient {
public static Couple<Vec3> getRayInputs(LocalPlayer player) { public static Couple<Vec3> getRayInputs(LocalPlayer player) {
Minecraft mc = Minecraft.getInstance(); Minecraft mc = Minecraft.getInstance();
Vec3 origin = RaycastHelper.getTraceOrigin(player); Vec3 origin = RaycastHelper.getTraceOrigin(player);
double reach = mc.gameMode.getPickRange(); double reach = player.blockInteractionRange();
if (mc.hitResult != null && mc.hitResult.getLocation() != null) if (mc.hitResult != null && mc.hitResult.getLocation() != null)
reach = Math.min(mc.hitResult.getLocation() reach = Math.min(mc.hitResult.getLocation()
.distanceTo(origin), reach); .distanceTo(origin), reach);

View file

@ -2,12 +2,13 @@ package com.simibubi.create.content.contraptions;
import com.simibubi.create.foundation.utility.AttachedRegistry; import com.simibubi.create.foundation.utility.AttachedRegistry;
import com.simibubi.create.infrastructure.config.AllConfigs; import com.simibubi.create.infrastructure.config.AllConfigs;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate; import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
import net.minecraftforge.common.extensions.IForgeBlock; import net.neoforged.neoforge.common.extensions.IBlockExtension;
import net.minecraftforge.registries.ForgeRegistries;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.Collection; import java.util.Collection;
@ -16,7 +17,7 @@ import java.util.function.Supplier;
public enum ContraptionMovementSetting { public enum ContraptionMovementSetting {
MOVABLE, NO_PICKUP, UNMOVABLE; MOVABLE, NO_PICKUP, UNMOVABLE;
private static final AttachedRegistry<Block, Supplier<ContraptionMovementSetting>> SETTING_SUPPLIERS = new AttachedRegistry<>(ForgeRegistries.BLOCKS); private static final AttachedRegistry<Block, Supplier<ContraptionMovementSetting>> SETTING_SUPPLIERS = new AttachedRegistry<>(BuiltInRegistries.BLOCK);
public static void register(ResourceLocation block, Supplier<ContraptionMovementSetting> settingSupplier) { public static void register(ResourceLocation block, Supplier<ContraptionMovementSetting> settingSupplier) {
SETTING_SUPPLIERS.register(block, settingSupplier); SETTING_SUPPLIERS.register(block, settingSupplier);
@ -53,7 +54,7 @@ public enum ContraptionMovementSetting {
register(Blocks.REINFORCED_DEEPSLATE, () -> AllConfigs.server().kinetics.reinforcedDeepslateMovement.get()); register(Blocks.REINFORCED_DEEPSLATE, () -> AllConfigs.server().kinetics.reinforcedDeepslateMovement.get());
} }
public interface IMovementSettingProvider extends IForgeBlock { public interface IMovementSettingProvider extends IBlockExtension {
ContraptionMovementSetting getContraptionMovementSetting(); ContraptionMovementSetting getContraptionMovementSetting();
} }
} }

Some files were not shown because too many files have changed in this diff Show more