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_class_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

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

View file

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

View file

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

View file

@ -1,459 +1,230 @@
plugins {
id 'idea'
id 'java-library'
id 'eclipse'
id 'idea'
id 'maven-publish'
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}"
id 'net.neoforged.moddev' version '2.0.9-beta'
}
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')
ext.buildNumber = System.getenv('BUILD_NUMBER')
repositories {
mavenLocal()
}
base {
archivesName = "create-${artifact_minecraft_version}"
group = 'com.simibubi.create'
version = mod_version + (dev && buildNumber != null ? "-${buildNumber}" : '')
archivesName = "$mod_id-$minecraft_version"
}
boolean inMultiModWorkspace = rootProject.hasProperty('multiModWorkspace.enabled')
boolean catnipInWorkspace = rootProject.hasProperty('multiModWorkspace.catnip')
boolean ponderInWorkspace = rootProject.hasProperty('multiModWorkspace.ponder')
java.toolchain.languageVersion = JavaLanguageVersion.of(21)
if (catnipInWorkspace) {
evaluationDependsOn(":catnip:Forge")
}
neoForge {
version = project.neo_version
if (ponderInWorkspace) {
evaluationDependsOn(":ponder:Forge")
}
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}"
parchment {
minecraftVersion = project.parchment_minecraft_version
mappingsVersion = project.parchment_version
}
// This property allows configuring Gradle's ProcessResources task(s) to run on IDE output locations before launching the game.
copyIdeResources = true
if (file('src/main/resources/META-INF/accesstransformer.cfg').exists()) {
accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg')
}
accessTransformers = project.files('src/main/resources/META-INF/accesstransformer.cfg')
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 {
workingDirectory project.file('run')
client()
// Comma-separated list of namespaces to load gametests from. Empty = all namespaces.
systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id
}
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 {
workingDirectory project.file('run')
property 'forge.logging.markers', 'REGISTRIES,REGISTRYDUMP'
property 'forge.logging.console.level', 'debug'
args '--mod', 'create', '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources')
data()
// Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources.
programArguments.addAll '--mod', project.mod_id, '--all', '--output', file('src/generated/resources/').getAbsolutePath(), '--existing', file('src/main/resources/').getAbsolutePath()
}
gameTestServer {
workingDirectory project.file('run/gametest')
// setForceExit false <- FIXME 1.20
configureEach {
systemProperty 'forge.logging.markers', 'REGISTRIES'
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 {
maven {
// location of the maven for Registrate and Flywheel
name = 'tterrag maven'
url = 'https://maven.tterrag.com'
}
maven {
// location of the maven that hosts JEI files since January 2023
// location of the maven for Vazkii's mods
name = "Jared's maven"
url = "https://maven.blamejared.com/"
}
/*maven {
// 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/"
maven { url = "https://maven.createmod.net" } // Ponder, Catnip
maven { url = "https://maven.tterrag.com" } // Flywheel
maven { url = "https://maven.ithundxr.dev/snapshots" } // Registrate
maven { url = "https://maven.blamejared.com" } // JEI, Vazkii's Mods
maven { url = "https://harleyoconnor.com/maven" } // Dynamic Trees
maven { url = "https://maven.theillusivec4.top/" } // Curios API
maven { url = "https://maven.squiddev.cc/" } // CC: Tweaked
maven { url = "https://www.cursemaven.com" }
maven { url = "https://api.modrinth.com/maven" }
maven { url = "https://maven.saps.dev/releases" } // FTB Mods
maven { url = "https://maven.architectury.dev/" } // Arch API
maven { url = "https://jm.gserv.me/repository/maven-public/" // JourneyMap
content {
includeGroup "info.journeymap"
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
if (System.getProperty("os.name").contains("Mac") && System.getenv("USER") == "ithundxr") {
maven { url = "https://maven.ithundxr.dev/mirror" }
}
mavenCentral()
mavenLocal()
// todo - temp
maven { url = "https://maven.ithundxr.dev/hidden" } // Flywheel 1.21 PR
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 {
srcDir 'src/generated/resources'
exclude '.cache/'
srcDir "src/generated/resources"
exclude ".cache/"
}
dependencies {
minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}"
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') {
jar {
from('LICENSE') {
rename { "${it}_${project.archivesBaseName}" }
}
}
tasks.jar {
archiveClassifier = 'slim'
finalizedBy('reobfJar')
addLicense it
}
tasks.withType(ProcessResources).configureEach {
var replaceProperties = [
mod_version : mod_version,
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 {
finalizedBy('reobfJarJar')
addLicense it
}
task jarJarRelease {
group = 'jarjar'
doLast {
tasks.jarJar {
archiveClassifier = ''
}
filesMatching(['META-INF/neoforge.mods.toml']) {
expand replaceProperties
}
finalizedBy tasks.jarJar
}
project.publishing {
java {
withSourcesJar()
}
publishing {
publications {
mavenJava(MavenPublication) {
artifactId base.archivesName.get()
register('mavenJava', MavenPublication) {
from components.java
fg.component(it)
jarJar.component(it)
}
}
repositories {
if (project.hasProperty('mavendir')) {
maven { url mavendir }
maven { url = mavendir }
}
}
}
String getChangelogText() {
def changelogFile = file('changelog.txt')
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
tasks.withType(JavaCompile).configureEach {
options.encoding = 'UTF-8'
}
// changelog debugging
// new File("changelog.html").write getChangelogText()
// tasks.curseforge.enabled = !dev && project.hasProperty('simi_curseforge_key')
// curseforge {
// 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'
// }
// }
// }
idea {
module {
downloadSources = true
downloadJavadoc = true
}
}

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.daemon = false
org.gradle.caching = true
# mod version info
# Mod Info
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_name = Create
mod_author = simibubi
mod_description = Technology that empowers the player.
mod_license = MIT
# curseforge information
projectId = 328085
curse_type = beta
# Mod Dependencies
minecraft_version = 1.21.1
minecraft_version_range=[1.21.1]
# github information
github_project = Creators-of-Create/Create
neo_version = 21.1.71
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
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
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

24
gradlew vendored
View file

@ -55,7 +55,7 @@
# Darwin, MinGW, and NonStop.
#
# (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.
#
# You can find Gradle at https://github.com/gradle/gradle/.
@ -83,7 +83,8 @@ done
# This is normally unused
# shellcheck disable=SC2034
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.
MAX_FD=maximum
@ -130,10 +131,13 @@ location of your Java installation."
fi
else
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
location of your Java installation."
fi
fi
# Increase the maximum file descriptors if we can.
@ -141,7 +145,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# 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 ) ||
warn "Could not query maximum file descriptor limit"
esac
@ -149,7 +153,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
'' | soft) :;; #(
*)
# 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" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
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.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \
"-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
if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
@ -57,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail

View file

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

@ -346,7 +346,7 @@ public class AllBlockEntityTypes {
.validBlocks(AllBlocks.HAND_CRANK)
.renderer(() -> HandCrankRenderer::new)
.register();
public static final BlockEntityEntry<ValveHandleBlockEntity> VALVE_HANDLE = REGISTRATE
.blockEntity("valve_handle", ValveHandleBlockEntity::new)
.visual(() -> HandCrankVisual::new)
@ -795,7 +795,7 @@ public class AllBlockEntityTypes {
.validBlocks(AllBlocks.ANALOG_LEVER)
.renderer(() -> AnalogLeverRenderer::new)
.register();
public static final BlockEntityEntry<PlacardBlockEntity> PLACARD = REGISTRATE
.blockEntity("placard", PlacardBlockEntity::new)
.validBlocks(AllBlocks.PLACARD)
@ -941,7 +941,7 @@ public class AllBlockEntityTypes {
.validBlocksDeferred(TrackMaterial::allBlocks)
.renderer(() -> TrackRenderer::new)
.register();
public static final BlockEntityEntry<FakeTrackBlockEntity> FAKE_TRACK = REGISTRATE
.blockEntity("fake_track", FakeTrackBlockEntity::new)
.validBlocks(AllBlocks.FAKE_TRACK)
@ -990,7 +990,7 @@ public class AllBlockEntityTypes {
.renderer(() -> TrackObserverRenderer::new)
.validBlocks(AllBlocks.TRACK_OBSERVER)
.register();
public static final BlockEntityEntry<ClipboardBlockEntity> CLIPBOARD = REGISTRATE
.blockEntity("clipboard", ClipboardBlockEntity::new)
.validBlocks(AllBlocks.CLIPBOARD)

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.item.ItemDescription;
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.DyeHelper;
import com.tterrag.registrate.providers.RegistrateRecipeProvider;
import com.tterrag.registrate.providers.loot.RegistrateBlockLootTables;
import com.tterrag.registrate.util.DataIngredient;
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.core.Direction.Axis;
import net.minecraft.core.Direction.AxisDirection;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.registries.Registries;
import net.minecraft.data.loot.BlockLootSubProvider;
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.Items;
import net.minecraft.world.item.Rarity;
import net.minecraft.world.item.enchantment.Enchantment;
import net.minecraft.world.item.enchantment.Enchantments;
import net.minecraft.world.level.block.Block;
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.entries.LootItem;
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.CopyNbtFunction;
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.providers.nbt.ContextNbtProvider;
import net.minecraft.world.level.storage.loot.providers.number.ConstantValue;
import net.minecraftforge.client.model.generators.ConfiguredModel;
import net.minecraftforge.client.model.generators.ModelFile;
import net.minecraftforge.common.Tags;
import net.minecraftforge.common.util.ForgeSoundType;
import net.neoforged.neoforge.client.model.generators.ConfiguredModel;
import net.neoforged.neoforge.client.model.generators.ModelFile;
import net.neoforged.neoforge.common.Tags;
import net.neoforged.neoforge.common.util.DeferredSoundType;
@SuppressWarnings("removal")
public class AllBlocks {
static {
@ -354,8 +356,9 @@ public class AllBlocks {
.setRolls(ConstantValue.exactly(1))
.add(LootItem.lootTableItem(AllBlocks.SCHEMATICANNON.get()
.asItem())
.apply(CopyNbtFunction.copyData(ContextNbtProvider.BLOCK_ENTITY)
.copy("Options", "BlockEntityTag.Options")))));
// TODO 1.21: Make sure this works
.apply(CopyComponentsFunction.copyComponents(CopyComponentsFunction.Source.BLOCK_ENTITY)
.include(AllDataComponents.SCHEMATICANNON_OPTIONS.value())))));
})
.item()
.transform(customItemModel())
@ -1768,7 +1771,7 @@ public class AllBlocks {
public static final BlockEntry<BeltTunnelBlock> ANDESITE_TUNNEL =
REGISTRATE.block("andesite_tunnel", BeltTunnelBlock::new)
.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 ItemThroughputDisplaySource(), "item_throughput"))
.register();
@ -1996,7 +1999,7 @@ public class AllBlocks {
.transform(BuilderTransformers.tableCloth("brass", SharedProperties::softMetal, false))
.properties(p -> p.mapColor(MapColor.TERRACOTTA_YELLOW)
.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))
.transform(pickaxeOnly())
.register();
@ -2005,7 +2008,7 @@ public class AllBlocks {
REGISTRATE.block("copper_table_cloth", p -> new TableClothBlock(p, "copper"))
.transform(BuilderTransformers.tableCloth("copper", SharedProperties::copperMetal, false))
.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))
.transform(pickaxeOnly())
.register();
@ -2216,17 +2219,17 @@ public class AllBlocks {
.forceSolidOn())
.addLayer(() -> RenderType::cutoutMipped)
.loot((lt, block) -> {
Builder builder = LootTable.lootTable();
LootItemCondition.Builder survivesExplosion = ExplosionCondition.survivesExplosion();
lt.add(block, builder.withPool(LootPool.lootPool()
.when(survivesExplosion)
.setRolls(ConstantValue.exactly(1))
.add(LootItem.lootTableItem(block)
.apply(CopyNameFunction.copyName(CopyNameFunction.NameSource.BLOCK_ENTITY))
.apply(CopyNbtFunction.copyData(ContextNbtProvider.BLOCK_ENTITY)
.copy("UniqueId", "UniqueId"))
.apply(CopyNbtFunction.copyData(ContextNbtProvider.BLOCK_ENTITY)
.copy("Inventory", "Inventory")))));
lt.add(block, LootTable.lootTable().withPool(LootPool.lootPool()
.when(ExplosionCondition.survivesExplosion())
.setRolls(ConstantValue.exactly(1))
.add(LootItem.lootTableItem(block)
.apply(CopyNameFunction.copyName(CopyNameFunction.NameSource.BLOCK_ENTITY))
.apply(CopyComponentsFunction.copyComponents(CopyComponentsFunction.Source.BLOCK_ENTITY)
.include(AllDataComponents.TOOLBOX_UUID.value())
.include(AllDataComponents.TOOLBOX_INVENTORY.value())
)
)
));
})
.blockstate((c, p) -> {
p.horizontalBlock(c.get(), p.models()
@ -2272,21 +2275,21 @@ public class AllBlocks {
public static final BlockEntry<MetalLadderBlock> BRASS_LADDER =
REGISTRATE.block("brass_ladder", MetalLadderBlock::new)
.transform(BuilderTransformers.ladder("brass",
() -> DataIngredient.tag(AllTags.forgeItemTag("ingots/brass")), MapColor.TERRACOTTA_YELLOW))
() -> DataIngredient.tag(AllTags.commonItemTag("ingots/brass")), MapColor.TERRACOTTA_YELLOW))
.register();
public static final BlockEntry<MetalLadderBlock> COPPER_LADDER =
REGISTRATE.block("copper_ladder", MetalLadderBlock::new)
.transform(BuilderTransformers.ladder("copper",
() -> DataIngredient.tag(AllTags.forgeItemTag("ingots/copper")), MapColor.COLOR_ORANGE))
() -> DataIngredient.tag(Tags.Items.INGOTS_COPPER), MapColor.COLOR_ORANGE))
.register();
public static final BlockEntry<IronBarsBlock> ANDESITE_BARS = MetalBarsGen.createBars("andesite", true,
() -> DataIngredient.items(AllItems.ANDESITE_ALLOY.get()), MapColor.STONE);
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,
() -> 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
.block("andesite_scaffolding", MetalScaffoldingBlock::new)
@ -2298,14 +2301,14 @@ public class AllBlocks {
public static final BlockEntry<MetalScaffoldingBlock> BRASS_SCAFFOLD =
REGISTRATE.block("brass_scaffolding", MetalScaffoldingBlock::new)
.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))
.register();
public static final BlockEntry<MetalScaffoldingBlock> COPPER_SCAFFOLD =
REGISTRATE.block("copper_scaffolding", MetalScaffoldingBlock::new)
.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))
.register();
@ -2349,7 +2352,7 @@ public class AllBlocks {
.transform(BuilderTransformers.copycat())
.onRegister(CreateRegistrate.blockModel(() -> CopycatStepModel::new))
.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))
.transform(customItemModel("copycat_base", "step"))
.register();
@ -2359,7 +2362,7 @@ public class AllBlocks {
.transform(BuilderTransformers.copycat())
.onRegister(CreateRegistrate.blockModel(() -> CopycatPanelModel::new))
.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))
.transform(customItemModel("copycat_base", "panel"))
.register();
@ -2472,10 +2475,14 @@ public class AllBlocks {
.requiresCorrectToolForDrops()
.sound(SoundType.STONE))
.transform(pickaxeOnly())
.loot((lt, b) -> lt.add(b,
RegistrateBlockLootTables.createSilkTouchDispatchTable(b,
.loot((lt, 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())
.apply(ApplyBonusCount.addOreBonusCount(Enchantments.BLOCK_FORTUNE))))))
.apply(ApplyBonusCount.addOreBonusCount(enchantmentRegistryLookup.getOrThrow(Enchantments.FORTUNE))))));
})
.tag(BlockTags.NEEDS_IRON_TOOL)
.tag(Tags.Blocks.ORES)
.transform(tagBlockAndItem("ores/zinc", "ores_in_ground/stone"))
@ -2489,10 +2496,15 @@ public class AllBlocks {
.requiresCorrectToolForDrops()
.sound(SoundType.DEEPSLATE))
.transform(pickaxeOnly())
.loot((lt, b) -> lt.add(b,
RegistrateBlockLootTables.createSilkTouchDispatchTable(b,
lt.applyExplosionDecay(b, LootItem.lootTableItem(AllItems.RAW_ZINC.get())
.apply(ApplyBonusCount.addOreBonusCount(Enchantments.BLOCK_FORTUNE))))))
.loot((lt, 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())
.apply(ApplyBonusCount.addOreBonusCount(enchantmentRegistryLookup.getOrThrow(Enchantments.FORTUNE))))));
})
.tag(BlockTags.NEEDS_IRON_TOOL)
.tag(Tags.Blocks.ORES)
.transform(tagBlockAndItem("ores/zinc", "ores_in_ground/deepslate"))
@ -2544,7 +2556,7 @@ public class AllBlocks {
.transform(BuilderTransformers.palettesIronBlock())
.lang("Block of Industrial Iron")
.register();
public static final BlockEntry<Block> WEATHERED_IRON_BLOCK = REGISTRATE.block("weathered_iron_block", Block::new)
.transform(BuilderTransformers.palettesIronBlock())
.lang("Block of Weathered Iron")
@ -2574,9 +2586,9 @@ public class AllBlocks {
.transform(axeOnly())
.blockstate(BlockStateGen.horizontalAxisBlockProvider(false))
.tag(Tags.Blocks.STORAGE_BLOCKS)
.tag(AllTags.forgeBlockTag("storage_blocks/cardboard"))
.tag(AllTags.commonBlockTag("storage_blocks/cardboard"))
.item(CardboardBlockItem::new)
.tag(AllTags.forgeItemTag("storage_blocks/cardboard"))
.tag(AllTags.commonItemTag("storage_blocks/cardboard"))
.tag(Tags.Items.STORAGE_BLOCKS)
.build()
.lang("Block of Cardboard")
@ -2606,7 +2618,7 @@ public class AllBlocks {
REGISTRATE.block("experience_block", ExperienceBlock::new)
.initialProperties(SharedProperties::softMetal)
.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_HIT, () -> SoundEvents.AMETHYST_BLOCK_FALL))
.requiresCorrectToolForDrops()
@ -2662,14 +2674,14 @@ public class AllBlocks {
public static final CopperBlockSet COPPER_SHINGLES = new CopperBlockSet(REGISTRATE, "copper_shingles",
"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);
}, (ws, block) -> connectedTextures(() -> new RoofBlockCTBehaviour(AllSpriteShifts.COPPER_SHINGLES.get(ws)))
.accept(block));
public static final CopperBlockSet COPPER_TILES =
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);
}, (ws, block) -> connectedTextures(() -> new RoofBlockCTBehaviour(AllSpriteShifts.COPPER_TILES.get(ws)))
.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.ReferenceLinkedOpenHashSet;
import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet;
import net.createmod.catnip.platform.CatnipServices;
import net.createmod.catnip.utility.lang.Components;
import net.minecraft.client.Minecraft;
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.Items;
import net.minecraft.world.level.block.Block;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.RegistryObject;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.api.distmarker.OnlyIn;
import net.neoforged.bus.api.IEventBus;
import net.neoforged.neoforge.registries.DeferredHolder;
import net.neoforged.neoforge.registries.DeferredRegister;
@EventBusSubscriber(bus = Bus.MOD)
public class AllCreativeModeTabs {
private static final DeferredRegister<CreativeModeTab> REGISTER =
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()
.title(Components.translatable("itemGroup.create.base"))
.withTabsBefore(CreativeModeTabs.SPAWN_EGGS)
@ -68,7 +65,7 @@ public class AllCreativeModeTabs {
.displayItems(new RegistrateDisplayItemsGenerator(true, AllCreativeModeTabs.BASE_CREATIVE_TAB))
.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()
.title(Components.translatable("itemGroup.create.palettes"))
.withTabsBefore(BASE_CREATIVE_TAB.getKey())
@ -85,14 +82,8 @@ public class AllCreativeModeTabs {
static {
MutableObject<Predicate<Item>> isItem3d = new MutableObject<>(item -> false);
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> {
isItem3d.setValue(item -> {
ItemRenderer itemRenderer = Minecraft.getInstance()
.getItemRenderer();
BakedModel model = itemRenderer.getModel(new ItemStack(item), null, null, 0);
return model.isGui3d();
});
});
if (CatnipServices.PLATFORM.getEnv().isClient())
isItem3d.setValue(makeClient3dItemPredicate());
IS_ITEM_3D_PREDICATE = isItem3d.getValue();
}
@ -107,9 +98,9 @@ public class AllCreativeModeTabs {
}
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.tabFilter = tabFilter;
}
@ -117,7 +108,7 @@ public class AllCreativeModeTabs {
private static Predicate<Item> makeExclusionPredicate() {
Set<Item> exclusions = new ReferenceOpenHashSet<>();
List<ItemProviderEntry<?>> simpleExclusions = List.of(
List<ItemProviderEntry<?, ?>> simpleExclusions = List.of(
AllItems.INCOMPLETE_PRECISION_MECHANISM,
AllItems.INCOMPLETE_REINFORCED_SHEET,
AllItems.INCOMPLETE_TRACK,
@ -154,10 +145,10 @@ public class AllCreativeModeTabs {
AllItems.CRUSHED_URANIUM,
AllItems.CRUSHED_NICKEL
);
exclusions.addAll(PackageStyles.RARE_BOXES);
for (ItemProviderEntry<?> entry : simpleExclusions) {
for (ItemProviderEntry<?, ?> entry : simpleExclusions) {
exclusions.add(entry.asItem());
}
@ -174,12 +165,12 @@ public class AllCreativeModeTabs {
private static List<ItemOrdering> makeOrderings() {
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.SCHEDULE, AllBlocks.TRACK_STATION
);
Map<ItemProviderEntry<?>, ItemProviderEntry<?>> simpleAfterOrderings = Map.of(
Map<ItemProviderEntry<?, ?>, ItemProviderEntry<?, ?>> simpleAfterOrderings = Map.of(
AllItems.VERTICAL_GEARBOX, AllBlocks.GEARBOX
);
@ -190,7 +181,7 @@ public class AllCreativeModeTabs {
simpleAfterOrderings.forEach((entry, otherEntry) -> {
orderings.add(ItemOrdering.after(entry.asItem(), otherEntry.asItem()));
});
PackageStyles.STANDARD_BOXES.forEach(item -> {
orderings.add(ItemOrdering.after(item, AllBlocks.PACKAGER.asItem()));
});
@ -201,15 +192,15 @@ public class AllCreativeModeTabs {
private static Function<Item, ItemStack> makeStackFunc() {
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 -> {
ItemStack stack = new ItemStack(item);
stack.getOrCreateTag().putInt("Air", BacktankUtil.maxAirWithoutEnchants());
stack.set(AllDataComponents.BACKTANK_AIR, BacktankUtil.maxAirWithoutEnchants());
return stack;
},
AllItems.NETHERITE_BACKTANK, item -> {
ItemStack stack = new ItemStack(item);
stack.getOrCreateTag().putInt("Air", BacktankUtil.maxAirWithoutEnchants());
stack.set(AllDataComponents.BACKTANK_AIR, BacktankUtil.maxAirWithoutEnchants());
return stack;
}
);
@ -230,7 +221,7 @@ public class AllCreativeModeTabs {
private static Function<Item, TabVisibility> makeVisibilityFunc() {
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
);
@ -248,14 +239,14 @@ public class AllCreativeModeTabs {
visibilities.put(entry.asItem(), TabVisibility.SEARCH_TAB_ONLY);
}
}
for (BlockEntry<TableClothBlock> entry : AllBlocks.TABLE_CLOTHS) {
TableClothBlock block = entry.get();
if (block.getColor() != DyeColor.RED) {
visibilities.put(entry.asItem(), TabVisibility.SEARCH_TAB_ONLY);
}
}
for (BlockEntry<PostboxBlock> entry : AllBlocks.PACKAGE_POSTBOXES) {
PostboxBlock block = entry.get();
if (block.getColor() != DyeColor.WHITE) {
@ -301,7 +292,7 @@ public class AllCreativeModeTabs {
private List<Item> collectBlocks(Predicate<Item> exclusionPredicate) {
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))
continue;
Item item = entry.get()
@ -317,7 +308,7 @@ public class AllCreativeModeTabs {
private List<Item> collectItems(Predicate<Item> exclusionPredicate) {
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))
continue;
Item item = entry.get();

View file

@ -3,7 +3,7 @@ package com.simibubi.create;
import com.simibubi.create.foundation.damageTypes.DamageTypeBuilder;
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.world.damagesource.DamageEffects;
import net.minecraft.world.damagesource.DamageScaling;
@ -25,7 +25,7 @@ public class AllDamageTypes {
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(CUCKOO_SURPRISE).scaling(DamageScaling.ALWAYS).exhaustion(0.1f).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;
import static com.simibubi.create.Create.REGISTRATE;
import com.simibubi.create.content.equipment.potatoCannon.PotatoProjectileTypeManager;
import com.simibubi.create.content.equipment.armor.CapacityEnchantment;
import com.simibubi.create.content.equipment.potatoCannon.PotatoRecoveryEnchantment;
import com.tterrag.registrate.util.entry.RegistryEntry;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.item.enchantment.Enchantment.Rarity;
import net.minecraft.world.item.enchantment.EnchantmentCategory;
import net.minecraft.advancements.critereon.ItemPredicate;
import net.minecraft.core.HolderGetter;
import net.minecraft.core.HolderSet;
import net.minecraft.core.registries.Registries;
import net.minecraft.data.worldgen.BootstrapContext;
import net.minecraft.resources.ResourceKey;
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 static final ResourceKey<Enchantment>
POTATO_RECOVERY = key("potato_recovery"),
CAPACITY = key("capacity");
public static final RegistryEntry<PotatoRecoveryEnchantment> POTATO_RECOVERY = REGISTRATE.object("potato_recovery")
.enchantment(EnchantmentCategory.BOW, PotatoRecoveryEnchantment::new)
.addSlots(EquipmentSlot.MAINHAND, EquipmentSlot.OFFHAND)
.lang("Potato Recovery")
.rarity(Rarity.UNCOMMON)
.register();
public static final RegistryEntry<CapacityEnchantment> CAPACITY = REGISTRATE.object("capacity")
.enchantment(EnchantmentCategory.ARMOR_CHEST, CapacityEnchantment::new)
.addSlots(EquipmentSlot.CHEST)
.lang("Capacity")
.rarity(Rarity.COMMON)
.register();
private static ResourceKey<Enchantment> key(String name) {
return ResourceKey.create(Registries.ENCHANTMENT, Create.asResource(name));
}
public static void register() {}
public static void bootstrap(BootstrapContext<Enchantment> context) {
HolderGetter<Item> itemHolderGetter = context.lookup(Registries.ITEM);
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 net.minecraft.network.syncher.EntityDataSerializer;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.RegistryObject;
import net.neoforged.bus.api.IEventBus;
import net.neoforged.neoforge.registries.DeferredHolder;
import net.neoforged.neoforge.registries.DeferredRegister;
import net.neoforged.neoforge.registries.NeoForgeRegistries;
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 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) {
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.EntityFactory;
import net.minecraft.world.entity.MobCategory;
import net.minecraftforge.event.entity.EntityAttributeCreationEvent;
import net.neoforged.neoforge.event.entity.EntityAttributeCreationEvent;
public class AllEntityTypes {
@ -69,7 +69,7 @@ public class AllEntityTypes {
public static final EntityEntry<SeatEntity> SEAT = register("seat", SeatEntity::new, () -> SeatEntity.Render::new,
MobCategory.MISC, 5, Integer.MAX_VALUE, false, true, SeatEntity::build).register();
public static final EntityEntry<PackageEntity> PACKAGE = register("package", PackageEntity::new, () -> PackageRenderer::new,
MobCategory.MISC, 10, 3, true, false, PackageEntity::build).register();
@ -99,7 +99,7 @@ public class AllEntityTypes {
})
.renderer(renderer);
}
public static void registerEntityAttributes(EntityAttributeCreationEvent event) {
event.put(PACKAGE.get(), PackageEntity.createPackageAttributes()
.build());

View file

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

View file

@ -1,9 +1,9 @@
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.CRUSHED_RAW_MATERIALS;
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.foundation.data.recipe.CompatMetals.ALUMINUM;
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.BaseArmorItem;
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.DivingHelmetItem;
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.sandPaper.SandPaperItem;
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.wrench.WrenchItem;
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.Item;
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 {
@ -86,18 +88,18 @@ public class AllItems {
REGISTRATE.setCreativeTab(AllCreativeModeTabs.BASE_CREATIVE_TAB);
}
public static final ItemEntry<Item> WHEAT_FLOUR =
taggedIngredient("wheat_flour", forgeItemTag("flour/wheat"), forgeItemTag("flour")),
DOUGH = taggedIngredient("dough", forgeItemTag("dough"), forgeItemTag("dough/wheat")),
public static final ItemEntry<Item>
WHEAT_FLOUR = taggedIngredient("wheat_flour", commonItemTag("flours/wheat"), commonItemTag("flours")),
DOUGH = taggedIngredient("dough", commonItemTag("doughs"), commonItemTag("doughs/wheat")),
CINDER_FLOUR = ingredient("cinder_flour"), ROSE_QUARTZ = ingredient("rose_quartz"),
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"),
CRAFTER_SLOT_COVER = ingredient("crafter_slot_cover"), ELECTRON_TUBE = ingredient("electron_tube"),
TRANSMITTER = ingredient("transmitter"), PULP = ingredient("pulp");
public static final ItemEntry<CombustibleItem> CARDBOARD = REGISTRATE.item("cardboard", CombustibleItem::new)
.tag(forgeItemTag("plates/cardboard"))
.tag(commonItemTag("plates/cardboard"))
.onRegister(i -> i.setBurnTime(1000))
.register();
@ -127,26 +129,26 @@ public class AllItems {
public static final ItemEntry<Item> BAR_OF_CHOCOLATE = REGISTRATE.item("bar_of_chocolate", Item::new)
.properties(p -> p.food(new FoodProperties.Builder().nutrition(6)
.saturationMod(0.3F)
.saturationModifier(0.3F)
.build()))
.lang("Bar of Chocolate")
.register();
public static final ItemEntry<Item> SWEET_ROLL = REGISTRATE.item("sweet_roll", Item::new)
.properties(p -> p.food(new FoodProperties.Builder().nutrition(6)
.saturationMod(0.8F)
.saturationModifier(0.8F)
.build()))
.register();
public static final ItemEntry<Item> CHOCOLATE_BERRIES = REGISTRATE.item("chocolate_glazed_berries", Item::new)
.properties(p -> p.food(new FoodProperties.Builder().nutrition(7)
.saturationMod(0.8F)
.saturationModifier(0.8F)
.build()))
.register();
public static final ItemEntry<Item> HONEYED_APPLE = REGISTRATE.item("honeyed_apple", Item::new)
.properties(p -> p.food(new FoodProperties.Builder().nutrition(8)
.saturationMod(0.8F)
.saturationModifier(0.8F)
.build()))
.register();
@ -159,15 +161,16 @@ public class AllItems {
public static final ItemEntry<CardboardSwordItem> CARDBOARD_SWORD =
REGISTRATE.item("cardboard_sword", CardboardSwordItem::new)
.properties(p -> p.stacksTo(1))
.properties(p -> p.attributes(SwordItem.createAttributes(AllToolMaterials.CARDBOARD, 3, 1)))
.model(AssetLookup.itemModelWithPartials())
.register();
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),
ZINC_INGOT = taggedIngredient("zinc_ingot", forgeItemTag("ingots/zinc"), CREATE_INGOTS.tag),
BRASS_INGOT = taggedIngredient("brass_ingot", forgeItemTag("ingots/brass"), CREATE_INGOTS.tag);
ZINC_INGOT = taggedIngredient("zinc_ingot", commonItemTag("ingots/zinc"), CREATE_INGOTS.tag),
BRASS_INGOT = taggedIngredient("brass_ingot", commonItemTag("ingots/brass"), CREATE_INGOTS.tag);
public static final ItemEntry<ChromaticCompoundItem> CHROMATIC_COMPOUND =
REGISTRATE.item("chromatic_compound", ChromaticCompoundItem::new)
@ -185,10 +188,10 @@ public class AllItems {
.properties(p -> p.rarity(Rarity.UNCOMMON))
.register();
public static final ItemEntry<Item> COPPER_NUGGET =
taggedIngredient("copper_nugget", forgeItemTag("nuggets/copper"), Tags.Items.NUGGETS),
ZINC_NUGGET = taggedIngredient("zinc_nugget", forgeItemTag("nuggets/zinc"), Tags.Items.NUGGETS),
BRASS_NUGGET = taggedIngredient("brass_nugget", forgeItemTag("nuggets/brass"), Tags.Items.NUGGETS);
public static final ItemEntry<Item>
COPPER_NUGGET = taggedIngredient("copper_nugget", commonItemTag("nuggets/copper"), Tags.Items.NUGGETS),
ZINC_NUGGET = taggedIngredient("zinc_nugget", commonItemTag("nuggets/zinc"), Tags.Items.NUGGETS),
BRASS_NUGGET = taggedIngredient("brass_nugget", commonItemTag("nuggets/brass"), Tags.Items.NUGGETS);
public static final ItemEntry<ExperienceNuggetItem> EXP_NUGGET =
REGISTRATE.item("experience_nugget", ExperienceNuggetItem::new)
@ -197,11 +200,11 @@ public class AllItems {
.lang("Nugget of Experience")
.register();
public static final ItemEntry<Item> COPPER_SHEET =
taggedIngredient("copper_sheet", forgeItemTag("plates/copper"), PLATES.tag),
BRASS_SHEET = taggedIngredient("brass_sheet", forgeItemTag("plates/brass"), PLATES.tag),
IRON_SHEET = taggedIngredient("iron_sheet", forgeItemTag("plates/iron"), PLATES.tag),
GOLDEN_SHEET = taggedIngredient("golden_sheet", forgeItemTag("plates/gold"), PLATES.tag, ItemTags.PIGLIN_LOVED),
public static final ItemEntry<Item>
COPPER_SHEET = taggedIngredient("copper_sheet", commonItemTag("plates/copper"), PLATES.tag),
BRASS_SHEET = taggedIngredient("brass_sheet", commonItemTag("plates/brass"), PLATES.tag),
IRON_SHEET = taggedIngredient("iron_sheet", commonItemTag("plates/iron"), PLATES.tag),
GOLDEN_SHEET = taggedIngredient("golden_sheet", commonItemTag("plates/gold"), PLATES.tag, ItemTags.PIGLIN_LOVED),
CRUSHED_IRON = taggedIngredient("crushed_raw_iron", CRUSHED_RAW_MATERIALS.tag),
CRUSHED_GOLD = taggedIngredient("crushed_raw_gold", CRUSHED_RAW_MATERIALS.tag, ItemTags.PIGLIN_LOVED),
@ -275,7 +278,7 @@ public class AllItems {
COPPER_BACKTANK_PLACEABLE))
.model(AssetLookup.customGenericItemModel("_", "item"))
.tag(AllItemTags.PRESSURIZED_AIR_SOURCES.tag)
.tag(forgeItemTag("armors/chestplates"))
.tag(ItemTags.CHEST_ARMOR)
.register(),
NETHERITE_BACKTANK = REGISTRATE
@ -285,7 +288,7 @@ public class AllItems {
.model(AssetLookup.customGenericItemModel("_", "item"))
.properties(p -> p.fireResistant())
.tag(AllItemTags.PRESSURIZED_AIR_SOURCES.tag)
.tag(forgeItemTag("armors/chestplates"))
.tag(ItemTags.CHEST_ARMOR)
.register();
public static final ItemEntry<? extends DivingHelmetItem>
@ -294,14 +297,14 @@ public class AllItems {
REGISTRATE
.item("copper_diving_helmet",
p -> new DivingHelmetItem(AllArmorMaterials.COPPER, p, Create.asResource("copper_diving")))
.tag(forgeItemTag("armors/helmets"))
.tag(ItemTags.HEAD_ARMOR)
.register(),
NETHERITE_DIVING_HELMET = REGISTRATE
.item("netherite_diving_helmet",
p -> new DivingHelmetItem(ArmorMaterials.NETHERITE, p, Create.asResource("netherite_diving")))
.properties(p -> p.fireResistant())
.tag(forgeItemTag("armors/helmets"))
.tag(ItemTags.HEAD_ARMOR)
.register();
public static final ItemEntry<? extends DivingBootsItem>
@ -310,40 +313,41 @@ public class AllItems {
REGISTRATE
.item("copper_diving_boots",
p -> new DivingBootsItem(AllArmorMaterials.COPPER, p, Create.asResource("copper_diving")))
.tag(forgeItemTag("armors/boots"))
.tag(ItemTags.FOOT_ARMOR)
.register(),
NETHERITE_DIVING_BOOTS = REGISTRATE
.item("netherite_diving_boots",
p -> new DivingBootsItem(ArmorMaterials.NETHERITE, p, Create.asResource("netherite_diving")))
.properties(p -> p.fireResistant())
.tag(forgeItemTag("armors/boots"))
.tag(ItemTags.FOOT_ARMOR)
.register();
public static final ItemEntry<? extends BaseArmorItem>
CARDBOARD_HELMET = REGISTRATE.item("cardboard_helmet", p -> new CardboardHelmetItem(ArmorItem.Type.HELMET, p))
.tag(forgeItemTag("armors/helmet"), ItemTags.TRIMMABLE_ARMOR)
CARDBOARD_HELMET = REGISTRATE.item("cardboard_helmet", p -> new CardboardArmorItem(ArmorItem.Type.HELMET, p))
.tag(ItemTags.HEAD_ARMOR, ItemTags.TRIMMABLE_ARMOR)
.onRegisterAfter(Registries.ITEM, v -> ItemDescription.useKey(v, "item.create.cardboard_armor"))
.model(TrimmableArmorModelGenerator::generate)
.clientExtension(() -> () -> new CardboardArmorStealthOverlay())
.register(),
CARDBOARD_CHESTPLATE =
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"))
.model(TrimmableArmorModelGenerator::generate)
.register(),
CARDBOARD_LEGGINGS =
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"))
.model(TrimmableArmorModelGenerator::generate)
.register(),
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"))
.model(TrimmableArmorModelGenerator::generate)
.register();
@ -386,6 +390,7 @@ public class AllItems {
public static final ItemEntry<PotatoCannonItem> POTATO_CANNON =
REGISTRATE.item("potato_cannon", PotatoCannonItem::new)
.model(AssetLookup.itemModelWithPartials())
.tag(Tags.Items.ENCHANTABLES)
.register();
public static final ItemEntry<ExtendoGripItem> EXTENDO_GRIP = REGISTRATE.item("extendo_grip", ExtendoGripItem::new)
@ -490,7 +495,7 @@ public class AllItems {
String metalName = metal.getName();
return REGISTRATE
.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)
.register();
}

View file

@ -1,5 +1,7 @@
package com.simibubi.create;
import net.neoforged.fml.common.EventBusSubscriber;
import org.lwjgl.glfw.GLFW;
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.Minecraft;
import net.minecraft.client.gui.screens.Screen;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.RegisterKeyMappingsEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.neoforge.client.event.RegisterKeyMappingsEvent;
@EventBusSubscriber(value = Dist.CLIENT, bus = EventBusSubscriber.Bus.MOD)
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.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.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.registries.ForgeRegistries;
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<>();
public static void registerBehaviour(ResourceLocation block, MovementBehaviour behaviour) {

View file

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

View file

@ -15,16 +15,15 @@ import com.simibubi.create.foundation.particle.ICustomParticleData;
import net.createmod.catnip.utility.lang.Lang;
import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.core.particles.ParticleType;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.client.event.RegisterParticleProvidersEvent;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.RegistryObject;
import net.minecraft.core.registries.Registries;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.api.distmarker.OnlyIn;
import net.neoforged.bus.api.IEventBus;
import net.neoforged.neoforge.client.event.RegisterParticleProvidersEvent;
import net.neoforged.neoforge.registries.DeferredHolder;
import net.neoforged.neoforge.registries.DeferredRegister;
public enum AllParticleTypes {
ROTATION_INDICATOR(RotationIndicatorParticleData::new),
AIR_FLOW(AirFlowParticleData::new),
AIR(AirParticleData::new),
@ -64,11 +63,11 @@ public enum AllParticleTypes {
}
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 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) {
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.Supplier;
import org.jetbrains.annotations.NotNull;
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.content.equipment.sandPaper.SandPaperPolishingRecipe;
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.crusher.CrushingRecipe;
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.fan.processing.HauntingRecipe;
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.saw.CuttingRecipe;
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.ProcessingRecipeSerializer;
import com.simibubi.create.content.processing.sequenced.SequencedAssemblyRecipeSerializer;
import com.simibubi.create.foundation.recipe.IRecipeTypeInfo;
import net.createmod.catnip.utility.lang.Lang;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries;
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.RecipeHolder;
import net.minecraft.world.item.crafting.RecipeInput;
import net.minecraft.world.item.crafting.RecipeSerializer;
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.level.Level;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.RegistryObject;
import net.neoforged.bus.api.IEventBus;
import net.neoforged.neoforge.registries.DeferredHolder;
import net.neoforged.neoforge.registries.DeferredRegister;
public enum AllRecipeTypes implements IRecipeTypeInfo {
public enum AllRecipeTypes implements IRecipeTypeInfo, StringRepresentable {
CONVERSION(ConversionRecipe::new),
CRUSHING(CrushingRecipe::new),
@ -66,19 +73,25 @@ public enum AllRecipeTypes implements IRecipeTypeInfo {
TOOLBOX_DYEING(() -> new SimpleCraftingRecipeSerializer<>(ToolboxDyeingRecipe::new), () -> RecipeType.CRAFTING, false);
public static final Predicate<? super Recipe<?>> CAN_BE_AUTOMATED = r -> !r.getId()
.getPath()
.endsWith("_manual_only");
public static final Predicate<RecipeHolder<?>> CAN_BE_AUTOMATED = r -> !r.id()
.getPath()
.endsWith("_manual_only");
private final ResourceLocation id;
private final RegistryObject<RecipeSerializer<?>> serializerObject;
public final ResourceLocation id;
public final Supplier<RecipeSerializer<?>> serializerSupplier;
private final DeferredHolder<RecipeSerializer<?>, RecipeSerializer<?>> serializerObject;
@Nullable
private final RegistryObject<RecipeType<?>> typeObject;
private final DeferredHolder<RecipeType<?>, RecipeType<?>> typeObject;
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) {
String name = Lang.asId(name());
id = Create.asResource(name);
this.serializerSupplier = serializerSupplier;
serializerObject = Registers.SERIALIZER_REGISTER.register(name, serializerSupplier);
if (registerType) {
typeObject = Registers.TYPE_REGISTER.register(name, typeSupplier);
@ -87,22 +100,26 @@ public enum AllRecipeTypes implements IRecipeTypeInfo {
typeObject = null;
type = typeSupplier;
}
isProcessingRecipe = false;
}
AllRecipeTypes(Supplier<RecipeSerializer<?>> serializerSupplier) {
String name = Lang.asId(name());
id = Create.asResource(name);
this.serializerSupplier = serializerSupplier;
serializerObject = Registers.SERIALIZER_REGISTER.register(name, serializerSupplier);
typeObject = Registers.TYPE_REGISTER.register(name, () -> RecipeType.simple(id));
type = typeObject;
isProcessingRecipe = false;
}
AllRecipeTypes(ProcessingRecipeFactory<?> processingFactory) {
this(() -> new ProcessingRecipeSerializer<>(processingFactory));
isProcessingRecipe = true;
}
public static void register(IEventBus modEventBus) {
ShapedRecipe.setCraftingSize(9, 9);
ShapedRecipePattern.setCraftingSize(9, 9);
Registers.SERIALIZER_REGISTER.register(modEventBus);
Registers.TYPE_REGISTER.register(modEventBus);
}
@ -120,24 +137,37 @@ public enum AllRecipeTypes implements IRecipeTypeInfo {
@SuppressWarnings("unchecked")
@Override
public <T extends RecipeType<?>> T getType() {
return (T) type.get();
public <I extends RecipeInput, R extends Recipe<I>> RecipeType<R> getType() {
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()
.getRecipeFor(getType(), inv, world);
}
public static boolean shouldIgnoreInAutomation(Recipe<?> recipe) {
RecipeSerializer<?> serializer = recipe.getSerializer();
public static boolean shouldIgnoreInAutomation(RecipeHolder<?> recipe) {
RecipeSerializer<?> serializer = recipe.value().getSerializer();
if (serializer != null && AllTags.AllRecipeSerializerTags.AUTOMATION_IGNORE.matches(serializer))
return true;
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 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);
}

View file

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

View file

@ -27,24 +27,21 @@ import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.RegisterEvent;
import net.minecraftforge.registries.RegistryObject;
import net.neoforged.neoforge.registries.DeferredHolder;
import net.neoforged.neoforge.registries.RegisterEvent;
//@EventBusSubscriber(bus = Bus.FORGE)
public class AllSoundEvents {
public static final Map<ResourceLocation, SoundEntry> ALL = new HashMap<>();
public static final SoundEntry
SCHEMATICANNON_LAUNCH_BLOCK = create("schematicannon_launch_block").subtitle("Schematicannon fires")
.playExisting(SoundEvents.GENERIC_EXPLODE, .1f, 1.1f)
.category(SoundSource.BLOCKS)
.build(),
SCHEMATICANNON_LAUNCH_BLOCK = create("schematicannon_launch_block").subtitle("Schematicannon fires")
.playExisting(SoundEvents.GENERIC_EXPLODE.value(), .1f, 1.1f)
.category(SoundSource.BLOCKS)
.build(),
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)
.build(),
@ -112,12 +109,12 @@ public class AllSoundEvents {
.build(),
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)
.build(),
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)
.build(),
@ -126,7 +123,7 @@ public class AllSoundEvents {
.build(),
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)
.build(),
@ -222,7 +219,7 @@ public class AllSoundEvents {
.build(),
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)
.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 {
@ -527,7 +523,7 @@ public class AllSoundEvents {
}
public SoundEntryBuilder playExisting(Holder<SoundEvent> event) {
return playExisting(event::get, 1, 1);
return playExisting(event::value, 1, 1);
}
public SoundEntry build() {
@ -560,6 +556,8 @@ public class AllSoundEvents {
public abstract void write(JsonObject json);
public abstract Holder<SoundEvent> getMainEventHolder();
public abstract SoundEvent getMainEvent();
public String getSubtitleKey() {
@ -638,7 +636,7 @@ public class AllSoundEvents {
for (int i = 0; i < wrappedEvents.size(); i++) {
ConfiguredSoundEvent wrapped = wrappedEvents.get(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()));
}
}
@ -651,14 +649,18 @@ public class AllSoundEvents {
}
}
@Override
public Holder<SoundEvent> getMainEventHolder() {
return compiledEvents.getFirst().event();
}
@Override
public SoundEvent getMainEvent() {
return compiledEvents.get(0)
.event().get();
return compiledEvents.getFirst().event().get();
}
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
@ -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 {
protected List<ResourceLocation> variants;
protected RegistryObject<SoundEvent> event;
protected DeferredHolder<SoundEvent, SoundEvent> event;
public CustomSoundEntry(ResourceLocation id, List<ResourceLocation> variants, String subtitle,
SoundSource category, int attenuationDistance) {
@ -717,7 +719,7 @@ public class AllSoundEvents {
@Override
public void prepare() {
event = RegistryObject.create(id, ForgeRegistries.SOUND_EVENTS);
event = DeferredHolder.create(Registries.SOUND_EVENT, id);
}
@Override
@ -726,6 +728,11 @@ public class AllSoundEvents {
helper.register(location, SoundEvent.createVariableRangeEvent(location));
}
@Override
public Holder<SoundEvent> getMainEventHolder() {
return event;
}
@Override
public SoundEvent getMainEvent() {
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.world.level.levelgen.structure.templatesystem.StructureProcessorType;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.RegistryObject;
import net.neoforged.bus.api.IEventBus;
import net.neoforged.neoforge.registries.DeferredHolder;
import net.neoforged.neoforge.registries.DeferredRegister;
public class AllStructureProcessorTypes {
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) {
REGISTER.register(modEventBus);

View file

@ -1,15 +1,17 @@
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.FORGE;
import static com.simibubi.create.AllTags.NameSpace.MOD;
import static com.simibubi.create.AllTags.NameSpace.QUARK;
import static com.simibubi.create.AllTags.NameSpace.TIC;
import java.util.Collections;
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.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.BlockTags;
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.material.Fluid;
import net.minecraft.world.level.material.FluidState;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.IForgeRegistry;
public class AllTags {
public static <T> TagKey<T> optionalTag(IForgeRegistry<T> registry,
ResourceLocation id) {
return registry.tags()
.createOptionalTagKey(id, Collections.emptySet());
public static <T> TagKey<T> optionalTag(Registry<T> registry, ResourceLocation id) {
return TagKey.create(registry.key(), id);
}
public static <T> TagKey<T> forgeTag(IForgeRegistry<T> registry, String path) {
return optionalTag(registry, new ResourceLocation("forge", path));
public static <T> TagKey<T> commonTag(Registry<T> registry, String path) {
return optionalTag(registry, ResourceLocation.fromNamespaceAndPath("c", path));
}
public static TagKey<Block> forgeBlockTag(String path) {
return forgeTag(ForgeRegistries.BLOCKS, path);
public static TagKey<Block> commonBlockTag(String path) {
return commonTag(BuiltInRegistries.BLOCK, path);
}
public static TagKey<Item> forgeItemTag(String path) {
return forgeTag(ForgeRegistries.ITEMS, path);
public static TagKey<Item> commonItemTag(String path) {
return commonTag(BuiltInRegistries.ITEM, path);
}
public static TagKey<Fluid> forgeFluidTag(String path) {
return forgeTag(ForgeRegistries.FLUIDS, path);
public static TagKey<Fluid> commonFluidTag(String path) {
return commonTag(BuiltInRegistries.FLUID, path);
}
public enum NameSpace {
MOD(Create.ID, false, true),
FORGE("forge"),
COMMON("c"),
TIC("tconstruct"),
QUARK("quark"),
GS("galosphere"),
@ -108,8 +106,7 @@ public class AllTags {
CORALS,
RELOCATION_NOT_SUPPORTED(FORGE),
WG_STONE(FORGE),
RELOCATION_NOT_SUPPORTED(COMMON),
SLIMY_LOGS(TIC),
NON_DOUBLE_DOOR(QUARK),
@ -136,9 +133,9 @@ public class AllTags {
}
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) {
tag = optionalTag(ForgeRegistries.BLOCKS, id);
tag = optionalTag(BuiltInRegistries.BLOCK, id);
} else {
tag = BlockTags.create(id);
}
@ -172,8 +169,6 @@ public class AllTags {
CREATE_INGOTS,
CRUSHED_RAW_MATERIALS,
DEPLOYABLE_DRINK,
MODDED_STRIPPED_LOGS,
MODDED_STRIPPED_WOOD,
PRESSURIZED_AIR_SOURCES,
SANDPAPER,
SEATS,
@ -187,14 +182,10 @@ public class AllTags {
TRACKS,
UPRIGHT_ON_BELT,
VALVE_HANDLES,
VANILLA_STRIPPED_LOGS,
VANILLA_STRIPPED_WOOD,
STRIPPED_LOGS(FORGE),
STRIPPED_WOOD(FORGE),
PLATES(FORGE),
OBSIDIAN_DUST(FORGE,"dusts/obsidian"),
WRENCH(FORGE, "tools/wrench"),
PLATES(COMMON),
OBSIDIAN_DUST(COMMON,"dusts/obsidian"),
WRENCH(COMMON, "tools/wrench"),
ALLURITE(MOD,"stone_types/galosphere/allurite"),
AMETHYST(MOD,"stone_types/galosphere/amethyst"),
@ -225,9 +216,9 @@ public class AllTags {
}
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) {
tag = optionalTag(ForgeRegistries.ITEMS, id);
tag = optionalTag(BuiltInRegistries.ITEM, id);
} else {
tag = ItemTags.create(id);
}
@ -257,8 +248,6 @@ public class AllTags {
FAN_PROCESSING_CATALYSTS_SMOKING(MOD, "fan_processing_catalysts/smoking"),
FAN_PROCESSING_CATALYSTS_SPLASHING(MOD, "fan_processing_catalysts/splashing"),
HONEY(FORGE)
;
public final TagKey<Fluid> tag;
@ -281,9 +270,9 @@ public class AllTags {
}
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) {
tag = optionalTag(ForgeRegistries.FLUIDS, id);
tag = optionalTag(BuiltInRegistries.FLUID, id);
} else {
tag = FluidTags.create(id);
}
@ -330,9 +319,9 @@ public class AllTags {
}
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) {
tag = optionalTag(ForgeRegistries.ENTITY_TYPES, id);
tag = optionalTag(BuiltInRegistries.ENTITY_TYPE, id);
} else {
tag = TagKey.create(Registries.ENTITY_TYPE, id);
}
@ -377,9 +366,9 @@ public class AllTags {
}
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) {
tag = optionalTag(ForgeRegistries.RECIPE_SERIALIZERS, id);
tag = optionalTag(BuiltInRegistries.RECIPE_SERIALIZER, id);
} else {
tag = TagKey.create(Registries.RECIPE_SERIALIZER, id);
}
@ -387,7 +376,8 @@ public class AllTags {
}
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() {}

View file

@ -4,8 +4,6 @@ import java.util.Random;
import org.slf4j.Logger;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.mojang.logging.LogUtils;
import com.simibubi.create.api.behaviour.BlockSpoutingBehaviour;
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.content.contraptions.ContraptionMovementSetting;
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.fluids.tank.BoilerHeaters;
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.foundation.advancement.AllAdvancements;
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.item.ItemDescription;
import com.simibubi.create.foundation.item.KineticStats;
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.CreateNBTProcessors;
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.lang.LangBuilder;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.item.CreativeModeTab;
import net.minecraft.world.level.Level;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.common.ForgeMod;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.eventbus.api.EventPriority;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fml.ModLoadingContext;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.neoforged.bus.api.EventPriority;
import net.neoforged.bus.api.IEventBus;
import net.neoforged.fml.ModContainer;
import net.neoforged.fml.ModLoadingContext;
import net.neoforged.fml.common.Mod;
import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent;
import net.neoforged.neoforge.common.NeoForgeMod;
import net.neoforged.neoforge.registries.RegisterEvent;
@Mod(Create.ID)
public class Create {
@ -68,10 +66,6 @@ public class Create {
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 */
@Deprecated
public static final Random RANDOM = new Random();
@ -97,22 +91,19 @@ public class Create {
public static final GlobalLogisticsManager LOGISTICS = new GlobalLogisticsManager();
public static final ServerLagger LAGGER = new ServerLagger();
public Create() {
onCtor();
public Create(IEventBus eventBus, ModContainer modContainer) {
onCtor(eventBus, modContainer);
}
public static void onCtor() {
public static void onCtor(IEventBus modEventBus, ModContainer modContainer) {
ModLoadingContext modLoadingContext = ModLoadingContext.get();
IEventBus modEventBus = FMLJavaModLoadingContext.get()
.getModEventBus();
IEventBus forgeEventBus = MinecraftForge.EVENT_BUS;
REGISTRATE.registerEventListeners(modEventBus);
AllSoundEvents.prepare();
AllTags.init();
AllCreativeModeTabs.register(modEventBus);
AllArmorMaterials.register(modEventBus);
AllBlocks.register();
AllItems.register();
AllFluids.register();
@ -120,16 +111,20 @@ public class Create {
AllMenuTypes.register();
AllEntityTypes.register();
AllBlockEntityTypes.register();
AllEnchantments.register();
AllRecipeTypes.register(modEventBus);
AllParticleTypes.register(modEventBus);
AllStructureProcessorTypes.register(modEventBus);
AllEntityDataSerializers.register(modEventBus);
AllPackets.registerPackets();
AllFeatures.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);
AllFanProcessingTypes.register(modEventBus);
@ -148,18 +143,16 @@ public class Create {
ComputerCraftProxy.register();
ForgeMod.enableMilkFluid();
CopperRegistries.inject();
NeoForgeMod.enableMilkFluid();
modEventBus.addListener(Create::init);
modEventBus.addListener(Create::registerAdvancements);
modEventBus.addListener(AllEntityTypes::registerEntityAttributes);
modEventBus.addListener(EventPriority.LOWEST, CreateDatagen::gatherData);
modEventBus.addListener(AllSoundEvents::register);
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> CreateClient.onCtorClient(modEventBus, forgeEventBus));
// 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) {
@ -175,9 +168,14 @@ public class Create {
// --
AttachedRegistry.unwrapAll();
});
}
public static void registerAdvancements(final RegisterEvent event) {
if (event.getRegistry() == BuiltInRegistries.TRIGGER_TYPES) {
AllAdvancements.register();
AllTriggers.register();
});
}
}
public static LangBuilder lang() {
@ -185,7 +183,7 @@ public class Create {
}
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.HoverEvent;
import net.minecraft.network.chat.MutableComponent;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.neoforged.api.distmarker.Dist;
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 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 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(AllParticleTypes::registerFactories);
@ -69,10 +79,10 @@ public class CreateClient {
MODEL_SWAPPER.registerListeners(modEventBus);
ZAPPER_RENDER_HANDLER.registerListeners(forgeEventBus);
POTATO_CANNON_RENDER_HANDLER.registerListeners(forgeEventBus);
Mods.FTBLIBRARY.executeIfInstalled(() -> () -> FTBIntegration.init(modEventBus, forgeEventBus));
ZAPPER_RENDER_HANDLER.registerListeners(neoEventBus);
POTATO_CANNON_RENDER_HANDLER.registerListeners(neoEventBus);
Mods.FTBLIBRARY.executeIfInstalled(() -> () -> FTBIntegration.init(modEventBus, neoEventBus));
}
public static void clientInit(final FMLClientSetupEvent event) {
@ -102,7 +112,7 @@ public class CreateClient {
private static void setupConfigUIBackground() {
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.enableBlend();

View file

@ -8,7 +8,7 @@ import com.simibubi.create.impl.behaviour.BlockSpoutingBehaviourImpl;
import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.Level;
import net.minecraftforge.fluids.FluidStack;
import net.neoforged.neoforge.fluids.FluidStack;
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.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraftforge.common.capabilities.ForgeCapabilities;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.IFluidTank;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.neoforged.neoforge.fluids.FluidStack;
import net.neoforged.neoforge.fluids.IFluidTank;
import net.neoforged.neoforge.fluids.capability.IFluidHandler;
public class ConnectivityHandler {
@ -215,7 +214,7 @@ public class ConnectivityHandler {
}
if (controller instanceof IMultiBlockEntityContainer.Fluid ifluidCon && ifluidCon.hasTank()) {
FluidStack otherFluid = ifluidCon.getFluid(0);
if (!fluid.isEmpty() && !otherFluid.isEmpty() && !fluid.isFluidEqual(otherFluid))
if (!fluid.isEmpty() && !otherFluid.isEmpty() && !FluidStack.isSameFluidSameComponents(fluid, otherFluid))
break Search;
}
}
@ -361,11 +360,9 @@ public class ConnectivityHandler {
}
if (be instanceof IMultiBlockEntityContainer.Inventory inv && inv.hasInventory())
be.getCapability(ForgeCapabilities.ITEM_HANDLER)
.invalidate();
be.getLevel().invalidateCapabilities(be.getBlockPos());
if (be instanceof IMultiBlockEntityContainer.Fluid fluid && fluid.hasTank())
be.getCapability(ForgeCapabilities.FLUID_HANDLER)
.invalidate();
be.getLevel().invalidateCapabilities(be.getBlockPos());
if (tryReconnect)
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.TrainHatInfoReloadListener;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.data.CachedOutput;
import net.minecraft.data.DataProvider;
import net.minecraft.data.PackOutput;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.registries.ForgeRegistries;
public abstract class TrainHatInfoProvider implements DataProvider {
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) {
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

View file

@ -1,14 +1,14 @@
package com.simibubi.create.api.event;
import java.lang.reflect.Type;
import java.util.Map;
import java.util.function.Consumer;
import com.simibubi.create.foundation.blockEntity.SmartBlockEntity;
import com.simibubi.create.foundation.blockEntity.behaviour.BehaviourType;
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.eventbus.api.GenericEvent;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.neoforged.bus.api.Event;
/**
* Event that is fired just before a SmartBlockEntity is being deserialized<br>
@ -22,21 +22,29 @@ import net.minecraftforge.eventbus.api.GenericEvent;
* <br>
* 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
* 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> {
private final T smartBlockEntity;
public class BlockEntityBehaviourEvent extends Event {
private final SmartBlockEntity smartBlockEntity;
private final Map<BehaviourType<?>, BlockEntityBehaviour> behaviours;
public BlockEntityBehaviourEvent(T blockEntity, Map<BehaviourType<?>, BlockEntityBehaviour> behaviours) {
public BlockEntityBehaviourEvent(SmartBlockEntity blockEntity, Map<BehaviourType<?>, BlockEntityBehaviour> behaviours) {
smartBlockEntity = blockEntity;
this.behaviours = behaviours;
}
@Override
public Type getGenericType() {
return smartBlockEntity.getClass();
public <T extends SmartBlockEntity> void forType(BlockEntityType<T> type, Consumer<T> action) {
if (smartBlockEntity.getType() == type) {
action.accept((T) smartBlockEntity);
}
}
public void attach(BlockEntityBehaviour behaviour) {
@ -47,12 +55,4 @@ public class BlockEntityBehaviourEvent<T extends SmartBlockEntity> extends Gener
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.block.state.BlockState;
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>

View file

@ -2,12 +2,11 @@ package com.simibubi.create.api.event;
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 {
private final TrackGraph mergedInto;
private final TrackGraph mergedFrom;
public TrackGraphMergeEvent(TrackGraph from, TrackGraph into) {
mergedInto = into;
mergedFrom = from;

View file

@ -1,10 +1,11 @@
package com.simibubi.create.api.schematic.nbt;
import net.minecraft.core.HolderLookup;
import net.minecraft.nbt.CompoundTag;
public interface IPartialSafeNBT {
/**
* 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 net.minecraft.core.HolderLookup;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.block.entity.BlockEntity;
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 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}
* 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
*/
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.function.Supplier;
import net.createmod.catnip.platform.CatnipServices;
import net.createmod.catnip.utility.RegisteredObjectsHelper;
import net.createmod.catnip.utility.lang.Lang;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.ItemLike;
import net.minecraft.world.level.block.Block;
import net.minecraftforge.fml.ModList;
import net.minecraftforge.registries.ForgeRegistries;
import net.neoforged.fml.ModList;
/**
* For compatibility with and without another mod present, we have to define load conditions of the specific code
*/
public enum Mods {
AETHER,
AETHER_II,
COMPUTERCRAFT,
CONNECTIVITY,
CURIOS,
@ -49,22 +50,22 @@ public enum Mods {
}
public ResourceLocation rl(String path) {
return new ResourceLocation(id, path);
return ResourceLocation.fromNamespaceAndPath(id, path);
}
public Block getBlock(String id) {
return ForgeRegistries.BLOCKS.getValue(rl(id));
return BuiltInRegistries.BLOCK.get(rl(id));
}
public Item getItem(String id) {
return ForgeRegistries.ITEMS.getValue(rl(id));
return BuiltInRegistries.ITEM.get(rl(id));
}
public boolean contains(ItemLike entry) {
if (!isLoaded())
return false;
Item asItem = entry.asItem();
return asItem != null && CatnipServices.REGISTRIES.getKeyOrThrow(asItem)
return asItem != null && RegisteredObjectsHelper.getKeyOrThrow(asItem)
.getNamespace()
.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.BlockEntityBehaviour;
import dan200.computercraft.api.peripheral.IPeripheral;
import net.minecraft.core.HolderLookup;
import net.minecraft.nbt.CompoundTag;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.LazyOptional;
public class AbstractComputerBehaviour extends BlockEntityBehaviour {
@ -20,23 +20,19 @@ public class AbstractComputerBehaviour extends BlockEntityBehaviour {
}
@Override
public void read(CompoundTag nbt, boolean clientPacket) {
public void read(CompoundTag nbt, HolderLookup.Provider registries, boolean clientPacket) {
hasAttachedComputer = nbt.getBoolean("HasAttachedComputer");
super.read(nbt, clientPacket);
super.read(nbt, registries, clientPacket);
}
@Override
public void write(CompoundTag nbt, boolean clientPacket) {
public void write(CompoundTag nbt, HolderLookup.Provider registries, boolean clientPacket) {
nbt.putBoolean("HasAttachedComputer", hasAttachedComputer);
super.write(nbt, clientPacket);
super.write(nbt, registries, clientPacket);
}
public <T> boolean isPeripheralCap(Capability<T> cap) {
return false;
}
public <T> LazyOptional<T> getPeripheralCapability() {
return LazyOptional.empty();
public IPeripheral getPeripheralCapability() {
return null;
}
public void removePeripheral() {}

View file

@ -1,13 +1,22 @@
package com.simibubi.create.compat.computercraft;
import com.simibubi.create.AllPackets;
import com.simibubi.create.foundation.blockEntity.SmartBlockEntity;
import com.simibubi.create.foundation.blockEntity.SyncedBlockEntity;
import com.simibubi.create.foundation.networking.BlockEntityDataPacket;
import io.netty.buffer.ByteBuf;
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 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;
@ -16,16 +25,6 @@ public class AttachedComputerPacket extends BlockEntityDataPacket<SyncedBlockEnt
this.hasAttachedComputer = hasAttachedComputer;
}
public AttachedComputerPacket(FriendlyByteBuf buffer) {
super(buffer);
this.hasAttachedComputer = buffer.readBoolean();
}
@Override
protected void writeData(FriendlyByteBuf buffer) {
buffer.writeBoolean(hasAttachedComputer);
}
@Override
protected void handlePacket(SyncedBlockEntity blockEntity) {
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;
import java.util.function.Supplier;
import com.simibubi.create.compat.computercraft.AbstractComputerBehaviour;
import com.simibubi.create.compat.computercraft.implementation.peripherals.DisplayLinkPeripheral;
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 dan200.computercraft.api.peripheral.IPeripheral;
import net.minecraftforge.common.capabilities.Capability;
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;
import net.minecraft.core.registries.BuiltInRegistries;
public class ComputerBehaviour extends AbstractComputerBehaviour {
protected static final Capability<IPeripheral> PERIPHERAL_CAPABILITY =
CapabilityManager.get(new CapabilityToken<>() {
});
LazyOptional<IPeripheral> peripheral;
NonNullSupplier<IPeripheral> peripheralSupplier;
IPeripheral peripheral;
Supplier<IPeripheral> peripheralSupplier;
SmartBlockEntity be;
public ComputerBehaviour(SmartBlockEntity te) {
super(te);
this.peripheralSupplier = getPeripheralFor(te);
public ComputerBehaviour(SmartBlockEntity be) {
super(be);
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)
return () -> new SpeedControllerPeripheral(scbe, scbe.targetSpeed);
if (be instanceof DisplayLinkBlockEntity dlbe)
@ -51,25 +47,20 @@ public class ComputerBehaviour extends AbstractComputerBehaviour {
return () -> new StationPeripheral(sbe);
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
public <T> boolean isPeripheralCap(Capability<T> cap) {
return cap == PERIPHERAL_CAPABILITY;
}
@Override
public <T> LazyOptional<T> getPeripheralCapability() {
if (peripheral == null || !peripheral.isPresent())
peripheral = LazyOptional.of(peripheralSupplier);
return peripheral.cast();
public IPeripheral getPeripheralCapability() {
if (peripheral == null)
peripheral = peripheralSupplier.get();
return peripheral;
}
@Override
public void removePeripheral() {
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 com.simibubi.create.AllPackets;
import com.simibubi.create.compat.computercraft.implementation.CreateLuaTable;
import com.simibubi.create.content.trains.entity.Train;
import com.simibubi.create.content.trains.schedule.Schedule;
import com.simibubi.create.content.trains.station.GlobalStation;
import com.simibubi.create.content.trains.station.StationBlockEntity;
import com.simibubi.create.content.trains.station.TrainEditPacket;
import net.createmod.catnip.platform.CatnipServices;
import com.simibubi.create.foundation.utility.StringHelper;
import dan200.computercraft.api.lua.IArguments;
@ -28,7 +28,6 @@ import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.NumericTag;
import net.minecraft.nbt.StringTag;
import net.minecraft.nbt.Tag;
import net.minecraftforge.network.PacketDistributor;
public class StationPeripheral extends SyncedPeripheral<StationBlockEntity> {
@ -129,7 +128,7 @@ public class StationPeripheral extends SyncedPeripheral<StationBlockEntity> {
public final void setTrainName(String name) throws LuaException {
Train train = getTrainOrThrow();
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
@ -146,7 +145,7 @@ public class StationPeripheral extends SyncedPeripheral<StationBlockEntity> {
if (schedule == null)
throw new LuaException("train doesn't have a schedule");
return fromCompoundTag(schedule.write());
return fromCompoundTag(schedule.write(blockEntity.getLevel().registryAccess()));
}
@LuaFunction(mainThread = true)
@ -159,7 +158,7 @@ public class StationPeripheral extends SyncedPeripheral<StationBlockEntity> {
throw new LuaException("Schedule must have at least one entry");
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;
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.Nullable;
import com.simibubi.create.AllPackets;
import com.simibubi.create.compat.computercraft.AttachedComputerPacket;
import com.simibubi.create.compat.computercraft.implementation.ComputerBehaviour;
import com.simibubi.create.foundation.blockEntity.SmartBlockEntity;
import net.createmod.catnip.platform.CatnipServices;
import dan200.computercraft.api.peripheral.IComputerAccess;
import dan200.computercraft.api.peripheral.IPeripheral;
import net.minecraftforge.network.PacketDistributor;
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;
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

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.goggles.GogglesItem;
import net.createmod.catnip.platform.CatnipServices;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fml.InterModComms;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.fml.event.lifecycle.InterModEnqueueEvent;
import net.neoforged.bus.api.IEventBus;
import net.neoforged.fml.InterModComms;
import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent;
import net.neoforged.fml.event.lifecycle.InterModEnqueueEvent;
import top.theillusivec4.curios.api.CuriosCapability;
import top.theillusivec4.curios.api.SlotTypeMessage;
import top.theillusivec4.curios.api.SlotTypePreset;
@ -35,10 +34,10 @@ public class Curios {
* @return An optional of the Stacks Handler Map
*/
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::onClientSetup);
@ -74,8 +73,7 @@ public class Curios {
return stacks;
}).orElse(new ArrayList<>()));
DistExecutor.unsafeRunWhenOn(Dist.CLIENT,
() -> () -> modEventBus.addListener(CuriosRenderers::onLayerRegister));
CatnipServices.PLATFORM.executeOnClientOnly(() -> () -> modEventBus.addListener(CuriosRenderers::onLayerRegister));
}
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.model.geom.builders.LayerDefinition;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.client.event.EntityRenderersEvent;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.api.distmarker.OnlyIn;
import net.neoforged.neoforge.client.event.EntityRenderersEvent;
import top.theillusivec4.curios.api.client.CuriosRendererRegistry;
@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.item.ItemDisplayContext;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.api.distmarker.OnlyIn;
import top.theillusivec4.curios.api.SlotContext;
import top.theillusivec4.curios.api.client.ICurioRenderer;
@OnlyIn(Dist.CLIENT)
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;

View file

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

View file

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

View file

@ -2,17 +2,17 @@ package com.simibubi.create.compat.ftb;
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.minecraft.client.gui.screens.Screen;
import net.minecraftforge.client.event.ScreenEvent;
import net.minecraftforge.eventbus.api.EventPriority;
import net.minecraftforge.eventbus.api.IEventBus;
import net.neoforged.bus.api.EventPriority;
import net.neoforged.bus.api.IEventBus;
import net.neoforged.neoforge.client.event.ScreenEvent;
public class FTBIntegration {
private static int buttonStatePreviously = 0;
private static boolean buttonStatePreviously;
public static void init(IEventBus modEventBus, IEventBus forgeEventBus) {
forgeEventBus.addListener(EventPriority.HIGH, FTBIntegration::removeGUIClutterOpen);
forgeEventBus.addListener(EventPriority.LOW, FTBIntegration::removeGUIClutterClose);
@ -23,14 +23,14 @@ public class FTBIntegration {
return;
if (!isCreate(event.getNewScreen()))
return;
buttonStatePreviously = FTBLibraryClient.showButtons;
FTBLibraryClient.showButtons = 0;
buttonStatePreviously = FTBLibraryClientConfig.SIDEBAR_ENABLED.get();
FTBLibraryClientConfig.SIDEBAR_ENABLED.set(false);
}
private static void removeGUIClutterClose(ScreenEvent.Closing event) {
if (!isCreate(event.getScreen()))
return;
FTBLibraryClient.showButtons = buttonStatePreviously;
FTBLibraryClientConfig.SIDEBAR_ENABLED.set(buttonStatePreviously);
}
private static boolean isCreate(Screen screen) {

View file

@ -6,9 +6,9 @@ import javax.annotation.ParametersAreNonnullByDefault;
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.BlueprintMenu;
import net.createmod.catnip.platform.CatnipServices;
import mezz.jei.api.constants.RecipeTypes;
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.inventory.MenuType;
import net.minecraft.world.item.crafting.CraftingRecipe;
import net.minecraft.world.item.crafting.RecipeHolder;
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
public class BlueprintTransferHandler implements IRecipeTransferHandler<BlueprintMenu, CraftingRecipe> {
public class BlueprintTransferHandler implements IRecipeTransferHandler<BlueprintMenu, RecipeHolder<CraftingRecipe>> {
@Override
public Class<BlueprintMenu> getContainerClass() {
public Class<? extends BlueprintMenu> getContainerClass() {
return BlueprintMenu.class;
}
@ -35,16 +36,16 @@ public class BlueprintTransferHandler implements IRecipeTransferHandler<Blueprin
}
@Override
public RecipeType<CraftingRecipe> getRecipeType() {
public RecipeType<RecipeHolder<CraftingRecipe>> getRecipeType() {
return RecipeTypes.CRAFTING;
}
@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)
return null;
AllPackets.getChannel().sendToServer(new BlueprintAssignCompleteRecipePacket(craftingRecipe.getId()));
CatnipServices.NETWORK.sendToServer(new BlueprintAssignCompleteRecipePacket(craftingRecipe.id()));
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.world.item.ItemStack;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.item.crafting.RecipeHolder;
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
@ -22,12 +23,13 @@ public class ConversionRecipe extends ProcessingRecipe<RecipeWrapper> {
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++);
return new ProcessingRecipeBuilder<>(ConversionRecipe::new, recipeId)
ConversionRecipe recipe = new ProcessingRecipeBuilder<>(ConversionRecipe::new, recipeId)
.withItemIngredients(Ingredient.of(from))
.withSingleItemOutput(to)
.build();
return new RecipeHolder<>(recipeId, recipe);
}
public ConversionRecipe(ProcessingRecipeParams params) {

View file

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

View file

@ -1,22 +1,24 @@
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.foundation.gui.menu.AbstractSimiContainerScreen;
import com.simibubi.create.foundation.gui.menu.GhostItemMenu;
import com.simibubi.create.foundation.gui.menu.GhostItemSubmitPacket;
import mezz.jei.api.constants.VanillaTypes;
import mezz.jei.api.gui.handlers.IGhostIngredientHandler;
import mezz.jei.api.ingredients.ITypedIngredient;
import net.createmod.catnip.platform.CatnipServices;
import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.client.renderer.Rect2i;
import net.minecraft.world.inventory.Slot;
import net.minecraft.world.item.ItemStack;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.LinkedList;
import java.util.List;
@MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault
public class GhostIngredientHandler<T extends GhostItemMenu<?>>
@ -83,7 +85,7 @@ public class GhostIngredientHandler<T extends GhostItemMenu<?>>
return;
// 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 com.simibubi.create.AllDataComponents;
import com.simibubi.create.content.fluids.potion.PotionFluid.BottleType;
import mezz.jei.api.ingredients.subtypes.IIngredientSubtypeInterpreter;
import mezz.jei.api.ingredients.subtypes.UidContext;
import net.createmod.catnip.utility.NBTHelper;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.core.component.DataComponents;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.item.alchemy.Potion;
import net.minecraft.world.item.alchemy.PotionUtils;
import net.minecraftforge.fluids.FluidStack;
import net.minecraft.world.item.alchemy.PotionContents;
import net.neoforged.neoforge.fluids.FluidStack;
/* From JEI's Potion item subtype interpreter */
public class PotionFluidSubtypeInterpreter implements IIngredientSubtypeInterpreter<FluidStack> {
@Override
public String apply(FluidStack ingredient, UidContext context) {
if (!ingredient.hasTag())
if (ingredient.getComponentsPatch().isEmpty())
return IIngredientSubtypeInterpreter.NONE;
CompoundTag tag = ingredient.getOrCreateTag();
Potion potionType = PotionUtils.getPotion(tag);
String potionTypeString = potionType.getName("");
String bottleType = NBTHelper.readEnum(tag, "Bottle", BottleType.class)
.toString();
PotionContents contents = ingredient.getOrDefault(DataComponents.POTION_CONTENTS, PotionContents.EMPTY);
String potionTypeString = ingredient.getDescriptionId();
String bottleType = ingredient.getOrDefault(AllDataComponents.POTION_FLUID_BOTTLE_TYPE, BottleType.REGULAR).name();
StringBuilder stringBuilder = new StringBuilder(potionTypeString);
List<MobEffectInstance> effects = PotionUtils.getCustomEffects(tag);
List<MobEffectInstance> effects = contents.customEffects();
stringBuilder.append(";")
.append(bottleType);
for (MobEffectInstance effect : potionType.getEffects())
stringBuilder.append(";")
.append(effect);
contents.potion().ifPresent(p -> {
for (MobEffectInstance effect : p.value().getEffects())
stringBuilder.append(";")
.append(effect);
});
for (MobEffectInstance effect : effects)
stringBuilder.append(";")
.append(effect);
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.StockKeeperRequestMenu;
import com.simibubi.create.content.logistics.stockTicker.StockKeeperRequestScreen;
import com.simibubi.create.foundation.blockEntity.LegacyRecipeWrapper;
import com.simibubi.create.foundation.utility.CreateLang;
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.library.transfer.RecipeTransferErrorMissingSlots;
import mezz.jei.library.transfer.RecipeTransferErrorTooltip;
import net.createmod.catnip.platform.CatnipServices;
import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.world.Container;
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.crafting.Recipe;
import net.minecraft.world.level.Level;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.items.ItemStackHandler;
import net.minecraftforge.items.wrapper.RecipeWrapper;
import net.neoforged.neoforge.items.ItemStackHandler;
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
@ -75,7 +74,7 @@ public class StockKeeperTransferHandler implements IRecipeTransferHandler<StockK
return null;
MutableObject<IRecipeTransferError> result = new MutableObject<>();
if (level.isClientSide())
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> result
CatnipServices.PLATFORM.executeOnClientOnly(() -> () -> result
.setValue(transferRecipeOnClient(container, recipe, recipeSlots, player, maxTransfer, doTransfer)));
return result.getValue();
}
@ -98,13 +97,13 @@ public class StockKeeperTransferHandler implements IRecipeTransferHandler<StockK
if (summary == null)
return null;
Container outputDummy = new RecipeWrapper(new ItemStackHandler(9));
Container outputDummy = new LegacyRecipeWrapper(new ItemStackHandler(9));
List<Slot> craftingSlots = new ArrayList<>();
for (int i = 0; i < outputDummy.getContainerSize(); i++)
craftingSlots.add(new Slot(outputDummy, i, 0, 0));
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<>();
for (int j = 0; j < stacksByCount.size(); 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.Create;
import net.minecraft.core.NonNullList;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.TagKey;
import net.minecraft.world.item.DyeColor;
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.CraftingRecipe;
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.level.block.Block;
@ -21,7 +21,7 @@ import java.util.stream.Stream;
public final class ToolboxColoringRecipeMaker {
// From JEI's ShulkerBoxColoringRecipeMaker
public static Stream<CraftingRecipe> createRecipes() {
public static Stream<RecipeHolder<CraftingRecipe>> createRecipes() {
String group = "create.toolbox.color";
ItemStack baseShulkerStack = AllBlocks.TOOLBOXES.get(DyeColor.BROWN)
.asStack();
@ -42,8 +42,8 @@ public final class ToolboxColoringRecipeMaker {
Block coloredShulkerBox = AllBlocks.TOOLBOXES.get(color)
.get();
ItemStack output = new ItemStack(coloredShulkerBox);
ResourceLocation id = Create.asResource(group + "." + output.getDescriptionId());
return new ShapelessRecipe(id, group, CraftingBookCategory.MISC, output, inputs);
ShapelessRecipe recipe = new ShapelessRecipe(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.item.ItemHelper;
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.ingredient.IRecipeSlotsView;
import mezz.jei.api.neoforge.NeoForgeTypes;
import mezz.jei.api.recipe.IFocusGroup;
import mezz.jei.api.recipe.RecipeIngredientRole;
import net.createmod.catnip.utility.Pair;
@ -20,7 +21,7 @@ import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.world.item.ItemStack;
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 javax.annotation.ParametersAreNonnullByDefault;
@ -63,7 +64,7 @@ public class BasinCategory extends CreateRecipeCategory<BasinRecipe> {
builder
.addSlot(RecipeIngredientRole.INPUT, 17 + xOffset + (i % 3) * 19, 51 - (i / 3) * 19)
.setBackground(getRenderedSlot(), -1, -1)
.addIngredients(ForgeTypes.FLUID_STACK, withImprovedVisibility(fluidIngredient.getMatchingFluidStacks()))
.addIngredients(NeoForgeTypes.FLUID_STACK, withImprovedVisibility(fluidIngredient.getMatchingFluidStacks()))
.addTooltipCallback(addFluidTooltip(fluidIngredient.getRequiredAmount()));
i++;
}
@ -90,7 +91,7 @@ public class BasinCategory extends CreateRecipeCategory<BasinRecipe> {
builder
.addSlot(RecipeIngredientRole.OUTPUT, xPosition, yPosition)
.setBackground(getRenderedSlot(), -1, -1)
.addIngredient(ForgeTypes.FLUID_STACK, withImprovedVisibility(fluidResult))
.addIngredient(NeoForgeTypes.FLUID_STACK, withImprovedVisibility(fluidResult))
.addTooltipCallback(addFluidTooltip(fluidResult.getAmount()));
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.RecipeIngredientRole;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemStack;
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 javax.annotation.ParametersAreNonnullByDefault;
@ -63,7 +62,7 @@ public class BlockCuttingCategory extends CreateRecipeCategory<CondensedBlockCut
List<ItemStack> outputs = new ArrayList<>();
public CondensedBlockCuttingRecipe(Ingredient ingredient) {
super(new ResourceLocation(""), "", ingredient, ItemStack.EMPTY);
super("", ingredient, ItemStack.EMPTY);
}
public void addOutput(ItemStack stack) {
@ -98,19 +97,19 @@ public class BlockCuttingCategory extends CreateRecipeCategory<CondensedBlockCut
}
public static List<CondensedBlockCuttingRecipe> condenseRecipes(List<Recipe<?>> stoneCuttingRecipes) {
List<CondensedBlockCuttingRecipe> condensed = new ArrayList<>();
Recipes: for (Recipe<?> recipe : stoneCuttingRecipes) {
Ingredient i1 = recipe.getIngredients().get(0);
for (CondensedBlockCuttingRecipe condensedRecipe : condensed) {
if (ItemHelper.matchIngredients(i1, condensedRecipe.getIngredients().get(0))) {
condensedRecipe.addOutput(getResultItem(recipe));
public static List<RecipeHolder<CondensedBlockCuttingRecipe>> condenseRecipes(List<RecipeHolder<?>> stoneCuttingRecipes) {
List<RecipeHolder<CondensedBlockCuttingRecipe>> condensed = new ArrayList<>();
Recipes: for (RecipeHolder<?> recipe : stoneCuttingRecipes) {
Ingredient i1 = recipe.value().getIngredients().get(0);
for (RecipeHolder<CondensedBlockCuttingRecipe> condensedRecipe : condensed) {
if (ItemHelper.matchIngredients(i1, condensedRecipe.value().getIngredients().get(0))) {
condensedRecipe.value().addOutput(getResultItem(recipe.value()));
continue Recipes;
}
}
CondensedBlockCuttingRecipe cr = new CondensedBlockCuttingRecipe(i1);
cr.addOutput(getResultItem(recipe));
condensed.add(cr);
cr.addOutput(getResultItem(recipe.value()));
condensed.add(new RecipeHolder<>(recipe.id(), cr));
}
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.foundation.gui.AllGuiTextures;
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.ingredient.IRecipeSlotTooltipCallback;
import mezz.jei.api.neoforge.NeoForgeTypes;
import mezz.jei.api.recipe.RecipeType;
import mezz.jei.api.recipe.category.IRecipeCategory;
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.world.item.ItemStack;
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 javax.annotation.ParametersAreNonnullByDefault;
@ -42,7 +44,7 @@ public abstract class CreateRecipeCategory<T extends Recipe<?>> implements IReci
protected final IDrawable background;
protected final IDrawable icon;
private final Supplier<List<T>> recipes;
private final Supplier<List<RecipeHolder<T>>> recipes;
private final List<Supplier<? extends ItemStack>> catalysts;
public CreateRecipeCategory(Info<T> info) {
@ -76,7 +78,7 @@ public abstract class CreateRecipeCategory<T extends Recipe<?>> implements IReci
}
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) {
@ -133,14 +135,14 @@ public abstract class CreateRecipeCategory<T extends Recipe<?>> implements IReci
public static IRecipeSlotTooltipCallback addFluidTooltip(int mbAmount) {
return (view, tooltip) -> {
Optional<FluidStack> displayed = view.getDisplayedIngredient(ForgeTypes.FLUID_STACK);
Optional<FluidStack> displayed = view.getDisplayedIngredient(NeoForgeTypes.FLUID_STACK);
if (displayed.isEmpty())
return;
FluidStack fluidStack = displayed.get();
if (fluidStack.getFluid().isSame(AllFluids.POTION.get())) {
Component name = fluidStack.getDisplayName();
Component name = fluidStack.getHoverName();
if (tooltip.isEmpty())
tooltip.add(0, name);
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<?>> {

View file

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

View file

@ -5,6 +5,10 @@ import java.util.List;
import javax.annotation.ParametersAreNonnullByDefault;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.crafting.ShapedRecipe;
import org.jetbrains.annotations.NotNull;
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.crafting.CraftingRecipe;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraftforge.common.crafting.IShapedRecipe;
import org.joml.Matrix4fStack;
@ParametersAreNonnullByDefault
public class MechanicalCraftingCategory extends CreateRecipeCategory<CraftingRecipe> {
@ -84,11 +89,11 @@ public class MechanicalCraftingCategory extends CreateRecipeCategory<CraftingRec
}
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) {
return recipe instanceof IShapedRecipe<?> ? ((IShapedRecipe<?>) recipe).getRecipeHeight() : 1;
return recipe instanceof ShapedRecipe ? ((ShapedRecipe) recipe).getHeight() : 1;
}
@Override
@ -154,8 +159,8 @@ public class MechanicalCraftingCategory extends CreateRecipeCategory<CraftingRec
matrixStack.scale(scale, scale, scale);
if (ingredient != null) {
PoseStack modelViewStack = RenderSystem.getModelViewStack();
modelViewStack.pushPose();
Matrix4fStack modelViewStack = RenderSystem.getModelViewStack();
modelViewStack.pushMatrix();
RenderSystem.applyModelViewMatrix();
RenderSystem.enableDepthTest();
Minecraft minecraft = Minecraft.getInstance();
@ -163,7 +168,7 @@ public class MechanicalCraftingCategory extends CreateRecipeCategory<CraftingRec
graphics.renderItem(ingredient, 0, 0);
graphics.renderItemDecorations(font, ingredient, 0, 0, null);
RenderSystem.disableBlend();
modelViewStack.popPose();
modelViewStack.popMatrix();
RenderSystem.applyModelViewMatrix();
}
@ -185,7 +190,7 @@ public class MechanicalCraftingCategory extends CreateRecipeCategory<CraftingRec
Minecraft minecraft = Minecraft.getInstance();
Player player = minecraft.player;
try {
return ingredient.getTooltipLines(player, tooltipFlag);
return ingredient.getTooltipLines(Item.TooltipContext.of(minecraft.level), player, tooltipFlag);
} catch (RuntimeException | LinkageError e) {
List<Component> list = new ArrayList<>();
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.RecipeIngredientRole;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.world.item.crafting.RecipeHolder;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.ArrayList;
@ -17,7 +18,7 @@ import java.util.List;
@ParametersAreNonnullByDefault
public class MysteriousItemConversionCategory extends CreateRecipeCategory<ConversionRecipe> {
public static final List<ConversionRecipe> RECIPES = new ArrayList<>();
public static final List<RecipeHolder<ConversionRecipe>> RECIPES = new ArrayList<>();
static {
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;
import com.simibubi.create.AllDataComponents;
import com.simibubi.create.AllItems;
import com.simibubi.create.content.equipment.sandPaper.SandPaperPolishingRecipe;
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.minecraft.client.gui.GuiGraphics;
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.crafting.Ingredient;
@ -53,10 +54,8 @@ public class PolishingCategory extends CreateRecipeCategory<SandPaperPolishingRe
if (matchingStacks.length == 0)
return;
CompoundTag tag = renderedSandpaper.getOrCreateTag();
tag.put("Polishing", matchingStacks[0].serializeNBT());
tag.putBoolean("JEI", true);
renderedSandpaper.set(AllDataComponents.SAND_PAPER_POLISHING, matchingStacks[0]);
renderedSandpaper.set(AllDataComponents.SAND_PAPER_JEI, Unit.INSTANCE);
GuiGameElement.of(renderedSandpaper)
.<GuiGameElement.GuiRenderBuilder>at(getBackground().getWidth() / 2 - 16, 0, 0)
.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.RecipeIngredientRole;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.core.component.DataComponents;
import net.minecraft.world.item.ItemStack;
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) {
return () -> AllBlocks.ENCASED_FAN.asStack()
.setHoverName(CreateLang.translateDirect("recipe." + name + ".fan").withStyle(style -> style.withItalic(false)));
ItemStack stack = AllBlocks.ENCASED_FAN.asStack();
stack.set(DataComponents.CUSTOM_NAME, CreateLang.translateDirect("recipe." + name + ".fan").withStyle(style -> style.withItalic(false)));
return () -> stack;
}
@Override

View file

@ -1,5 +1,14 @@
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.simibubi.create.compat.jei.category.sequencedAssembly.SequencedAssemblySubCategory;
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.AllIcons;
import com.simibubi.create.foundation.utility.CreateLang;
import mezz.jei.api.gui.builder.IRecipeLayoutBuilder;
import mezz.jei.api.gui.ingredient.IRecipeSlotsView;
import mezz.jei.api.recipe.IFocusGroup;
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.minecraft.ChatFormatting;
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.MutableComponent;
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
public class SequencedAssemblyCategory extends CreateRecipeCategory<SequencedAssemblyRecipe> {
@ -73,7 +76,7 @@ public class SequencedAssemblyCategory extends CreateRecipeCategory<SequencedAss
}
private SequencedAssemblySubCategory getSubCategory(SequencedRecipe<?> sequencedRecipe) {
return subCategories.computeIfAbsent(CatnipServices.REGISTRIES.getKeyOrThrow(sequencedRecipe.getRecipe()
return subCategories.computeIfAbsent(RegisteredObjectsHelper.getKeyOrThrow(sequencedRecipe.getRecipe()
.getSerializer()),
rl -> sequencedRecipe.getAsAssemblyRecipe()
.getJEISubCategory()

View file

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

View file

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

View file

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

View file

@ -1,22 +1,21 @@
package com.simibubi.create.compat.jei.category.animations;
import java.util.List;
import com.mojang.blaze3d.platform.Lighting;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.Tesselator;
import com.mojang.math.Axis;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllPartialModels;
import com.simibubi.create.foundation.fluid.FluidRenderer;
import net.createmod.catnip.gui.UIRenderHelper;
import net.createmod.catnip.utility.AnimationTickHolder;
import net.minecraft.client.gui.GuiGraphics;
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.minecraftforge.fluids.FluidStack;
import java.util.List;
import net.neoforged.neoforge.fluids.FluidStack;
public class AnimatedSpout extends AnimatedKinetics {
@ -67,15 +66,13 @@ public class AnimatedSpout extends AnimatedKinetics {
.render(graphics);
AnimatedKinetics.DEFAULT_LIGHTING.applyLighting();
BufferSource buffer = MultiBufferSource.immediate(Tesselator.getInstance()
.getBuilder());
matrixStack.pushPose();
UIRenderHelper.flipForGuiRender(matrixStack);
matrixStack.scale(16, 16, 16);
float from = 3f / 16f;
float to = 17f / 16f;
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();
float width = 1 / 128f * squeeze;
@ -85,8 +82,8 @@ public class AnimatedSpout extends AnimatedKinetics {
matrixStack.translate(-0.5f, 0, -0.5f);
from = -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());
buffer.endBatch();
FluidRenderer.renderFluidBox(fluidStack.getFluid(), fluidStack.getAmount(), from, 0, from, to, 2, to, graphics.bufferSource(), matrixStack, LightTexture.FULL_BRIGHT, false, true, fluidStack.getComponents());
graphics.flush();
Lighting.setupFor3DItems();
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.foundation.fluid.FluidIngredient;
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.IRecipeSlotBuilder;
import mezz.jei.api.neoforge.NeoForgeTypes;
import mezz.jei.api.recipe.IFocusGroup;
import mezz.jei.api.recipe.RecipeIngredientRole;
import net.minecraft.ChatFormatting;
@ -74,7 +75,7 @@ public abstract class SequencedAssemblySubCategory {
builder
.addSlot(RecipeIngredientRole.INPUT, x + 4, 15)
.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()));
}

View file

@ -5,23 +5,24 @@ import com.simibubi.create.compat.Mods;
import com.simibubi.create.content.fluids.spout.SpoutBlockEntity;
import com.simibubi.create.foundation.fluid.FluidHelper;
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.Direction;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraftforge.common.capabilities.ForgeCapabilities;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler.FluidAction;
import net.neoforged.neoforge.capabilities.Capabilities;
import net.neoforged.neoforge.fluids.FluidStack;
import net.neoforged.neoforge.fluids.capability.IFluidHandler;
import net.neoforged.neoforge.fluids.capability.IFluidHandler.FluidAction;
public class SpoutCasting extends BlockSpoutingBehaviour {
private static final boolean TICON_PRESENT = Mods.TCONSTRUCT.isLoaded();
ResourceLocation TABLE = new ResourceLocation("tconstruct", "table");
ResourceLocation BASIN = new ResourceLocation("tconstruct", "basin");
ResourceLocation TABLE = ResourceLocation.fromNamespaceAndPath("tconstruct", "table");
ResourceLocation BASIN = ResourceLocation.fromNamespaceAndPath("tconstruct", "basin");
@Override
public int fillBlock(Level level, BlockPos pos, SpoutBlockEntity spout, FluidStack availableFluid,
@ -33,21 +34,20 @@ public class SpoutCasting extends BlockSpoutingBehaviour {
if (blockEntity == null)
return 0;
IFluidHandler handler = blockEntity.getCapability(ForgeCapabilities.FLUID_HANDLER, Direction.UP)
.orElse(null);
IFluidHandler handler = level.getCapability(Capabilities.FluidHandler.BLOCK, blockEntity.getBlockPos(), Direction.UP);
if (handler == null)
return 0;
if (handler.getTanks() != 1)
return 0;
ResourceLocation registryName = CatnipServices.REGISTRIES.getKeyOrThrow(blockEntity.getType());
ResourceLocation registryName = RegisteredObjectsHelper.getKeyOrThrow(blockEntity.getType());
if (!registryName.equals(TABLE) && !registryName.equals(BASIN))
return 0;
if (!handler.isFluidValid(0, availableFluid))
return 0;
FluidStack containedFluid = handler.getFluidInTank(0);
if (!(containedFluid.isEmpty() || containedFluid.isFluidEqual(availableFluid)))
if (!(containedFluid.isEmpty() || FluidStack.isSameFluidSameComponents(containedFluid, availableFluid)))
return 0;
// 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 net.createmod.catnip.platform.CatnipServices;
import net.createmod.catnip.utility.RegisteredObjectsHelper;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraftforge.items.IItemHandler;
import net.neoforged.neoforge.items.IItemHandler;
public class FunctionalStorage implements ThresholdSwitchCompat {
@Override
public boolean isFromThisMod(BlockEntity blockEntity) {
return blockEntity != null && Mods.FUNCTIONALSTORAGE.id()
.equals(CatnipServices.REGISTRIES.getKeyOrThrow(blockEntity.getType())
.equals(RegisteredObjectsHelper.getKeyOrThrow(blockEntity.getType())
.getNamespace());
}

View file

@ -2,9 +2,10 @@ package com.simibubi.create.compat.thresholdSwitch;
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.minecraftforge.items.IItemHandler;
import net.neoforged.neoforge.items.IItemHandler;
public class SophisticatedStorage implements ThresholdSwitchCompat {
@ -13,7 +14,7 @@ public class SophisticatedStorage implements ThresholdSwitchCompat {
if (be == null)
return false;
String namespace = CatnipServices.REGISTRIES.getKeyOrThrow(be.getType())
String namespace = RegisteredObjectsHelper.getKeyOrThrow(be.getType())
.getNamespace();
return
@ -23,7 +24,7 @@ public class SophisticatedStorage implements ThresholdSwitchCompat {
@Override
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 net.createmod.catnip.platform.CatnipServices;
import net.createmod.catnip.utility.RegisteredObjectsHelper;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraftforge.items.IItemHandler;
import net.neoforged.neoforge.items.IItemHandler;
public class StorageDrawers implements ThresholdSwitchCompat {
@Override
public boolean isFromThisMod(BlockEntity blockEntity) {
return blockEntity != null && Mods.STORAGEDRAWERS.id()
.equals(CatnipServices.REGISTRIES.getKeyOrThrow(blockEntity.getType())
.equals(RegisteredObjectsHelper.getKeyOrThrow(blockEntity.getType())
.getNamespace());
}

View file

@ -1,7 +1,7 @@
package com.simibubi.create.compat.thresholdSwitch;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraftforge.items.IItemHandler;
import net.neoforged.neoforge.items.IItemHandler;
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.network.chat.FormattedText;
import net.minecraft.util.Mth;
import net.minecraftforge.client.event.InputEvent;
import net.minecraftforge.client.event.RenderTooltipEvent;
import net.minecraftforge.client.event.ScreenEvent;
import net.minecraftforge.fml.util.ObfuscationReflectionHelper;
import net.neoforged.fml.util.ObfuscationReflectionHelper;
import net.neoforged.neoforge.client.event.InputEvent;
import net.neoforged.neoforge.client.event.RenderTooltipEvent;
import net.neoforged.neoforge.client.event.ScreenEvent;
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.infrastructure.config.AllConfigs;
import journeymap.client.api.display.Context.UI;
import journeymap.client.api.util.UIState;
import journeymap.api.v2.client.display.Context;
import journeymap.api.v2.client.util.UIState;
import journeymap.client.ui.fullscreen.Fullscreen;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.renderer.Rect2i;
import net.minecraft.network.chat.FormattedText;
import net.minecraft.util.Mth;
import net.minecraftforge.client.event.InputEvent;
import net.neoforged.neoforge.client.event.InputEvent;
public class JourneyTrainMap {
@ -52,7 +52,7 @@ public class JourneyTrainMap {
UIState state = screen.getUiState();
if (state == null)
return;
if (state.ui != UI.Fullscreen)
if (state.ui != Context.UI.Fullscreen)
return;
if (!state.active)
return;

View file

@ -4,53 +4,50 @@ import com.mojang.blaze3d.platform.InputConstants;
import com.simibubi.create.compat.Mods;
import net.minecraft.client.Minecraft;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.InputEvent;
import net.minecraftforge.client.event.RenderTooltipEvent;
import net.minecraftforge.client.event.ScreenEvent;
import net.minecraftforge.event.TickEvent.ClientTickEvent;
import net.minecraftforge.event.TickEvent.Phase;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.neoforge.client.event.ClientTickEvent;
import net.neoforged.neoforge.client.event.InputEvent;
import net.neoforged.neoforge.client.event.RenderTooltipEvent;
import net.neoforged.neoforge.client.event.ScreenEvent;
@EventBusSubscriber(value = Dist.CLIENT)
public class TrainMapEvents {
@SubscribeEvent
public static void tick(ClientTickEvent event) {
if (event.phase == Phase.START)
return;
public static void tick(ClientTickEvent.Post event) {
Minecraft mc = Minecraft.getInstance();
if (mc.level == null)
return;
if (Mods.FTBCHUNKS.isLoaded())
FTBChunksTrainMap.tick();
if (Mods.JOURNEYMAP.isLoaded())
JourneyTrainMap.tick();
}
@SubscribeEvent
public static void mouseClick(InputEvent.MouseButton.Pre event) {
if (event.getAction() != InputConstants.PRESS)
return;
if (Mods.FTBCHUNKS.isLoaded())
FTBChunksTrainMap.mouseClick(event);
if (Mods.JOURNEYMAP.isLoaded())
JourneyTrainMap.mouseClick(event);
}
@SubscribeEvent
public static void cancelTooltips(RenderTooltipEvent.Pre event) {
if (Mods.FTBCHUNKS.isLoaded())
FTBChunksTrainMap.cancelTooltips(event);
}
@SubscribeEvent
public static void renderGui(ScreenEvent.Render.Post event) {
if (Mods.FTBCHUNKS.isLoaded())
FTBChunksTrainMap.renderGui(event);
}
}

View file

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

View file

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

View file

@ -6,13 +6,12 @@ import java.util.List;
import java.util.UUID;
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.content.trains.entity.Carriage;
import com.simibubi.create.content.trains.entity.Carriage.DimensionalCarriageEntity;
import com.simibubi.create.content.trains.entity.Train;
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.schedule.ScheduleRuntime;
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.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.minecraft.core.UUIDUtil;
import net.minecraft.core.registries.Registries;
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.server.MinecraftServer;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.util.Mth;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.event.TickEvent.ServerTickEvent;
import net.minecraftforge.network.PacketDistributor;
import net.neoforged.neoforge.event.tick.ServerTickEvent;
public class TrainMapSync {
@ -40,21 +46,38 @@ public class TrainMapSync {
public static int ticks;
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 {
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 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
public float[] prevPositions;
public Float[] prevPositions;
public List<ResourceKey<Level>> prevDims;
// Updated every 5 ticks
public float[] positions;
public Float[] positions;
public List<ResourceKey<Level>> dimensions;
public TrainState state = TrainState.RUNNING;
public SignalState signalState = SignalState.NOT_WAITING;
@ -67,65 +90,22 @@ public class TrainMapSync {
public String targetStationName = "";
public UUID waitingForTrain = null;
public void gatherDimensions(DimensionPalette dimensionPalette) {
for (ResourceKey<Level> resourceKey : dimensions)
if (resourceKey != null)
dimensionPalette.encode(resourceKey);
}
public TrainMapSyncEntry() {}
public void send(FriendlyByteBuf buffer, DimensionPalette dimensionPalette, boolean light) {
buffer.writeVarInt(positions.length);
for (float f : positions)
buffer.writeFloat(f);
buffer.writeVarInt(dimensions.size());
for (ResourceKey<Level> resourceKey : dimensions)
buffer.writeVarInt(resourceKey == null ? -1 : dimensionPalette.encode(resourceKey));
buffer.writeVarInt(state.ordinal());
buffer.writeVarInt(signalState.ordinal());
buffer.writeBoolean(fueled);
buffer.writeBoolean(backwards);
buffer.writeVarInt(targetStationDistance);
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 TrainMapSyncEntry(Float[] positions, List<ResourceKey<Level>> dimensions, TrainState state,
SignalState signalState, boolean fueled, boolean backwards, int targetStationDistance,
String ownerName, String targetStationName,
UUID waitingForTrain) {
this.positions = positions;
this.dimensions = dimensions;
this.state = state;
this.signalState = signalState;
this.fueled = fueled;
this.backwards = backwards;
this.targetStationDistance = targetStationDistance;
this.ownerName = ownerName;
this.targetStationName = targetStationName;
this.waitingForTrain = waitingForTrain;
}
public void updateFrom(TrainMapSyncEntry other, boolean light) {
@ -143,8 +123,7 @@ public class TrainMapSync {
if (prevDims != null)
for (int i = 0; i < Math.min(prevDims.size(), dimensions.size()); i++)
if (prevDims.get(i) != dimensions.get(i))
for (int j = 0; j < 6; j++)
prevPositions[i * 6 + j] = positions[i * 6 + j];
System.arraycopy(positions, i * 6, prevPositions, i * 6, 6);
if (light)
return;
@ -198,8 +177,7 @@ public class TrainMapSync {
ServerPlayer player = weakReference.get();
if (player == null)
continue;
AllPackets.getChannel()
.send(PacketDistributor.PLAYER.with(() -> player), packet);
CatnipServices.NETWORK.sendToClient(player, packet);
}
}
@ -207,7 +185,7 @@ public class TrainMapSync {
TrainMapSyncEntry entry = new TrainMapSyncEntry();
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<>();
List<Carriage> carriages = train.carriages;
@ -279,7 +257,7 @@ public class TrainMapSync {
.getPlayer(train.owner);
if (owner != null)
entry.ownerName = owner.getName()
.getString();
.getString();
}
if (train.derailed) {

View file

@ -6,9 +6,9 @@ import java.util.Map;
import java.util.Set;
import java.util.UUID;
import com.simibubi.create.AllPackets;
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.Pair;
@ -23,8 +23,7 @@ public class TrainMapSyncClient {
public static void requestData() {
ticks++;
if (ticks % 5 == 0)
AllPackets.getChannel()
.sendToServer(new TrainMapSyncRequestPacket());
CatnipServices.NETWORK.sendToServer(TrainMapSyncRequestPacket.INSTANCE);
}
public static void stopRequesting() {
@ -35,12 +34,11 @@ public class TrainMapSyncClient {
public static void receive(TrainMapSyncPacket packet) {
if (ticks == 0)
return;
lastPacket = AnimationTickHolder.getTicks();
lastPacket += AnimationTickHolder.getPartialTicks();
Set<UUID> staleEntries = new HashSet<>();
staleEntries.addAll(currentData.keySet());
Set<UUID> staleEntries = new HashSet<>(currentData.keySet());
for (Pair<UUID, TrainMapSyncEntry> pair : packet.entries) {
UUID id = pair.getFirst();

View file

@ -4,62 +4,49 @@ import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import com.simibubi.create.AllPackets;
import com.simibubi.create.compat.trainmap.TrainMapSync.TrainMapSyncEntry;
import com.simibubi.create.content.trains.graph.DimensionPalette;
import com.simibubi.create.foundation.networking.SimplePacketBase;
import net.createmod.catnip.net.base.ClientboundPacketPayload;
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.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 List<Pair<UUID, TrainMapSyncEntry>> entries = new ArrayList<>();
public TrainMapSyncPacket(boolean 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) {
entries.add(Pair.of(trainId, data));
}
public TrainMapSyncPacket(FriendlyByteBuf buffer) {
DimensionPalette dimensionPalette = DimensionPalette.receive(buffer);
light = buffer.readBoolean();
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
public void handle(LocalPlayer player) {
TrainMapSyncClient.receive(this);
}
@Override
public void write(FriendlyByteBuf buffer) {
DimensionPalette dimensionPalette = new DimensionPalette();
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);
}
public PacketTypeProvider getTypeProvider() {
return AllPackets.TRAIN_MAP_SYNC;
}
@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;
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 net.minecraftforge.network.NetworkEvent.Context;
import io.netty.buffer.ByteBuf;
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 TrainMapSyncRequestPacket() {}
public TrainMapSyncRequestPacket(FriendlyByteBuf buffer) {}
public class TrainMapSyncRequestPacket implements ServerboundPacketPayload {
public static final TrainMapSyncRequestPacket INSTANCE = new TrainMapSyncRequestPacket();
public static final StreamCodec<ByteBuf, TrainMapSyncRequestPacket> STREAM_CODEC = StreamCodec.unit(INSTANCE);
@Override
public void write(FriendlyByteBuf buffer) {}
@Override
public boolean handle(Context context) {
context.enqueueWork(() -> TrainMapSync.requestReceived(context.getSender()));
return true;
public void handle(ServerPlayer player) {
TrainMapSync.requestReceived(player);
}
@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.tuple.MutablePair;
import org.jetbrains.annotations.NotNull;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllItems;
import com.simibubi.create.AllMovementBehaviours;
import com.simibubi.create.AllPackets;
import com.simibubi.create.AllSoundEvents;
import com.simibubi.create.Create;
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.collision.Matrix3d;
import com.simibubi.create.foundation.mixin.accessor.ServerLevelAccessor;
import net.createmod.catnip.platform.CatnipServices;
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.math.AngleHelper;
import net.minecraft.client.Minecraft;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.HolderLookup;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtAccounter;
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.protocol.Packet;
import net.minecraft.network.protocol.game.ClientGamePacketListener;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
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.phys.AABB;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.entity.IEntityAdditionalSpawnData;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.network.NetworkHooks;
import net.minecraftforge.network.PacketDistributor;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.api.distmarker.OnlyIn;
import net.neoforged.neoforge.entity.IEntityWithComplexSpawn;
public abstract class AbstractContraptionEntity extends Entity implements IEntityAdditionalSpawnData {
public abstract class AbstractContraptionEntity extends Entity implements IEntityWithComplexSpawn {
private static final EntityDataAccessor<Boolean> STALLED =
SynchedEntityData.defineId(AbstractContraptionEntity.class, EntityDataSerializers.BOOLEAN);
@ -93,6 +92,8 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
protected boolean initialized;
protected boolean prevPosInvalid;
private boolean skipActorStop;
// temporary debug thing
private boolean receivedSpawnData;
/*
* 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<>();
}
public boolean hasReceivedSpawnData() {
return receivedSpawnData;
}
protected void setContraption(Contraption contraption) {
this.contraption = contraption;
if (contraption == null)
@ -165,8 +170,8 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
return;
contraption.getSeatMapping()
.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
@ -182,8 +187,9 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
.put("ContraptionDismountLocation", VecHelper.writeNBT(transformedVector));
contraption.getSeatMapping()
.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
@ -242,15 +248,15 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
return null;
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))
.subtract(0.5, ySize, 0.5);
return transformedVector;
}
@Override
protected boolean canAddPassenger(Entity p_184219_1_) {
if (p_184219_1_ instanceof OrientedContraptionEntity)
protected boolean canAddPassenger(@NotNull Entity pPassenger) {
if (pPassenger instanceof OrientedContraptionEntity)
return true;
return contraption.getSeatMapping()
.size() < contraption.getSeats()
@ -280,8 +286,7 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
public void stopControlling(BlockPos controlsLocalPos) {
getControllingPlayer().map(level()::getPlayerByUUID)
.map(p -> (p instanceof ServerPlayer) ? ((ServerPlayer) p) : null)
.ifPresent(p -> AllPackets.getChannel().send(PacketDistributor.PLAYER.with(() -> p),
new ControlsStopControllingPacket()));
.ifPresent(p -> CatnipServices.NETWORK.sendToClient(p, ControlsStopControllingPacket.INSTANCE));
setControllingPlayer(null);
}
@ -379,14 +384,9 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
tickContraption();
super.tick();
if (level().isClientSide())
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> {
// The visual will handle this with flywheel on.
if (!contraption.deferInvalidate || BackendManager.isBackendOn())
return;
contraption.deferInvalidate = false;
ContraptionRenderInfo.invalidate(contraption);
});
if (level().isClientSide()) {
AbstractContraptionEntityClient.invalidate(contraption);
}
if (!(level() instanceof ServerLevelAccessor sl))
return;
@ -415,7 +415,7 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
float angle = AngleHelper.deg(-Mth.atan2(motion.x, motion.z));
angle = AngleHelper.angleLerp(0.4f, prevAngle, angle);
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.setYRot(angle);
living.setXRot(0);
@ -427,8 +427,7 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
public void setBlock(BlockPos localPos, StructureBlockInfo newInfo) {
contraption.blocks.put(localPos, newInfo);
AllPackets.getChannel().send(PacketDistributor.TRACKING_ENTITY.with(() -> this),
new ContraptionBlockChangedPacket(getId(), localPos, newInfo.state()));
CatnipServices.NETWORK.sendToClientsTrackingEntity(this, new ContraptionBlockChangedPacket(getId(), localPos, newInfo.state()));
}
protected abstract void tickContraption();
@ -523,8 +522,7 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
}
protected void onContraptionStalled() {
AllPackets.getChannel().send(PacketDistributor.TRACKING_ENTITY.with(() -> this),
new ContraptionStallPacket(getId(), getX(), getY(), getZ(), getStalledAngle()));
CatnipServices.NETWORK.sendToClientsTrackingEntity(this, new ContraptionStallPacket(getId(), getX(), getY(), getZ(), getStalledAngle()));
}
protected boolean shouldActorTrigger(MovementContext context, StructureBlockInfo blockInfo, MovementBehaviour actor,
@ -599,20 +597,15 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
}
@Override
protected void defineSynchedData() {
this.entityData.define(STALLED, false);
this.entityData.define(CONTROLLED_BY, Optional.empty());
protected void defineSynchedData(SynchedEntityData.Builder builder) {
builder.define(STALLED, false);
builder.define(CONTROLLED_BY, Optional.empty());
}
@Override
public Packet<ClientGamePacketListener> getAddEntityPacket() {
return NetworkHooks.getEntitySpawningPacket(this);
}
@Override
public void writeSpawnData(FriendlyByteBuf buffer) {
public void writeSpawnData(RegistryFriendlyByteBuf registryFriendlyByteBuf) {
CompoundTag compound = new CompoundTag();
writeAdditional(compound, true);
writeAdditional(compound, registryFriendlyByteBuf.registryAccess(), true);
if (ContraptionData.isTooLargeForSync(compound)) {
String info = getContraption().getType().id + " @" + position() + " (" + getStringUUID() + ")";
@ -620,27 +613,30 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
compound = null;
}
buffer.writeNbt(compound);
registryFriendlyByteBuf.writeNbt(compound);
}
@Override
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)
compound.put("Contraption", contraption.writeNBT(spawnPacket));
compound.put("Contraption", contraption.writeNBT(registries, spawnPacket));
compound.putBoolean("Stalled", isStalled());
compound.putBoolean("Initialized", initialized);
}
@Override
public void readSpawnData(FriendlyByteBuf additionalData) {
CompoundTag nbt = additionalData.readAnySizeNbt();
public void readSpawnData(RegistryFriendlyByteBuf registryFriendlyByteBuf) {
CompoundTag nbt = readAnySizeNbt(registryFriendlyByteBuf);
if (nbt != null) {
readAdditional(nbt, true);
} else {
Create.LOGGER.warn("Null spawn data for AbstractContraptionEntity");
}
receivedSpawnData = true;
}
@Override
@ -648,6 +644,16 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
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) {
if (compound.isEmpty())
return;
@ -667,8 +673,7 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
StructureTransform transform = makeStructureTransform();
contraption.stop(level());
AllPackets.getChannel().send(PacketDistributor.TRACKING_ENTITY.with(() -> this),
new ContraptionDisassemblyPacket(this.getId(), transform));
CatnipServices.NETWORK.sendToClientsTrackingEntity(this, new ContraptionDisassemblyPacket(this.getId(), transform));
contraption.addBlocksToWorld(level(), transform);
contraption.addPassengersToWorld(level(), transform, getPassengers());
@ -728,8 +733,8 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
}
@Override
public void onRemovedFromWorld() {
super.onRemovedFromWorld();
public void onRemovedFromLevel() {
super.onRemovedFromLevel();
}
@Override
@ -745,20 +750,20 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
@OnlyIn(Dist.CLIENT)
static void handleStallPacket(ContraptionStallPacket packet) {
if (Minecraft.getInstance().level.getEntity(packet.entityID) instanceof AbstractContraptionEntity ce)
ce.handleStallInformation(packet.x, packet.y, packet.z, packet.angle);
if (Minecraft.getInstance().level.getEntity(packet.entityId()) instanceof AbstractContraptionEntity ce)
ce.handleStallInformation(packet.x(), packet.y(), packet.z(), packet.angle());
}
@OnlyIn(Dist.CLIENT)
static void handleBlockChangedPacket(ContraptionBlockChangedPacket packet) {
if (Minecraft.getInstance().level.getEntity(packet.entityID) instanceof AbstractContraptionEntity ce)
ce.handleBlockChange(packet.localPos, packet.newState);
if (Minecraft.getInstance().level.getEntity(packet.entityId()) instanceof AbstractContraptionEntity ce)
ce.handleBlockChange(packet.localPos(), packet.newState());
}
@OnlyIn(Dist.CLIENT)
static void handleDisassemblyPacket(ContraptionDisassemblyPacket packet) {
if (Minecraft.getInstance().level.getEntity(packet.entityID) instanceof AbstractContraptionEntity ce)
ce.moveCollidedEntitiesOnDisassembly(packet.transform);
if (Minecraft.getInstance().level.getEntity(packet.entityId()) instanceof AbstractContraptionEntity ce)
ce.moveCollidedEntitiesOnDisassembly(packet.transform());
}
protected abstract float getStalledAngle();
@ -923,10 +928,15 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
}
@Override
public void setSecondsOnFire(int p_70015_1_) {
public void igniteForTicks(int ticks) {
// Contraptions no longer catch fire
}
@Override
public boolean fireImmune() {
return true;
}
// Contraptions shouldn't activate pressure plates and tripwires
@Override
public boolean isIgnoringBlockTriggers() {
@ -944,4 +954,14 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
public boolean isPrevPosInvalid() {
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 net.minecraft.core.BlockPos;
import net.minecraft.core.HolderLookup;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.world.level.block.state.BlockState;
@ -14,12 +15,12 @@ public class AssemblyException extends Exception {
public final Component component;
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)
return;
CompoundTag nbt = new CompoundTag();
nbt.putString("Component", Component.Serializer.toJson(exception.component));
nbt.putString("Component", Component.Serializer.toJson(exception.component, registries));
if (exception.hasPosition())
nbt.putLong("Position", exception.getPosition()
.asLong());
@ -27,13 +28,13 @@ public class AssemblyException extends Exception {
compound.put("LastException", nbt);
}
public static AssemblyException read(CompoundTag compound) {
public static AssemblyException read(CompoundTag compound, HolderLookup.Provider registries) {
if (!compound.contains("LastException"))
return null;
CompoundTag nbt = compound.getCompound("LastException");
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"))
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.Axis;
import net.minecraft.core.HolderGetter;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.registries.Registries;
import net.minecraft.nbt.CompoundTag;
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.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraftforge.client.model.data.ModelData;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.items.IItemHandlerModifiable;
import net.minecraftforge.items.wrapper.CombinedInvWrapper;
import net.minecraftforge.registries.GameData;
import net.neoforged.neoforge.client.model.data.ModelData;
import net.neoforged.neoforge.fluids.FluidStack;
import net.neoforged.neoforge.fluids.capability.IFluidHandler;
import net.neoforged.neoforge.items.IItemHandlerModifiable;
import net.neoforged.neoforge.items.wrapper.CombinedInvWrapper;
import net.neoforged.neoforge.registries.GameData;
public abstract class Contraption {
@ -340,7 +341,7 @@ public abstract class Contraption {
&& !BlockMovementChecks.isNotSupportive(world.getBlockState(attached), offset.getOpposite()))
frontier.add(attached);
}
if (world.getBlockEntity(pos) instanceof ChainConveyorBlockEntity ccbe)
ccbe.notifyConnectedToValidate();
@ -632,7 +633,7 @@ public abstract class Contraption {
if (blockEntity instanceof PoweredShaftBlockEntity)
blockEntity = AllBlockEntityTypes.BRACKETED_KINETIC.create(pos, blockstate);
if (blockEntity instanceof FactoryPanelBlockEntity fpbe)
fpbe.writeSafe(compoundnbt);
fpbe.writeSafe(compoundnbt, world.registryAccess());
return Pair.of(new StructureBlockInfo(pos, blockstate, compoundnbt), blockEntity);
}
@ -670,9 +671,9 @@ public abstract class Contraption {
return;
CompoundTag nbt = structureBlockInfo.nbt();
BlockPos controllerPos = nbt.contains("Controller") ?
toLocalPos(NbtUtils.readBlockPos(nbt.getCompound("Controller"))) :
localPos;
BlockPos controllerPos = NbtUtils.readBlockPos(nbt,"Controller")
.map(this::toLocalPos)
.orElse(localPos);
nbt.put("Controller", NbtUtils.writeBlockPos(controllerPos));
if (multiBlockBE.isController() && multiBlockBE.getHeight() <= 1 && multiBlockBE.getWidth() <= 1) {
@ -689,7 +690,7 @@ public abstract class Contraption {
BlockEntity blockEntity = world.getBlockEntity(pos);
if (blockEntity == null)
return null;
CompoundTag nbt = blockEntity.saveWithFullMetadata();
CompoundTag nbt = blockEntity.saveWithFullMetadata(world.registryAccess());
nbt.remove("x");
nbt.remove("y");
nbt.remove("z");
@ -726,9 +727,9 @@ public abstract class Contraption {
if (!tag.contains("Controller", Tag.TAG_COMPOUND) && !tag.contains("Parts", Tag.TAG_LIST))
return;
BlockPos controllerPos = NbtUtils.readBlockPos(tag.getCompound("Controller"));
BlockPos controllerPos = NbtUtils.readBlockPos(tag, "Controller").orElseThrow();
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);
capturedMultiblocks.put(controllerPos, partInfo);
});
@ -738,14 +739,14 @@ public abstract class Contraption {
nbt.getList("Actors", Tag.TAG_COMPOUND)
.forEach(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)
return;
MovementContext context = MovementContext.readNBT(world, info, comp, this);
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)
setActorsActive(stack, false);
@ -754,7 +755,7 @@ public abstract class Contraption {
c -> superglue.add(SuperGlueEntity.readBoundingBox(c)));
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();
NBTHelper.iterateCompoundList(nbt.getList("Passengers", Tag.TAG_COMPOUND),
@ -766,7 +767,7 @@ public abstract class Contraption {
interactors.clear();
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);
if (structureBlockInfo == null)
return;
@ -775,17 +776,17 @@ public abstract class Contraption {
interactors.put(pos, behaviour);
});
storage.read(nbt, presentBlockEntities, spawnData);
storage.read(nbt, world.registryAccess(), presentBlockEntities, spawnData);
if (nbt.contains("BoundsFront"))
bounds = NBTHelper.readAABB(nbt.getList("BoundsFront", Tag.TAG_FLOAT));
stalled = nbt.getBoolean("Stalled");
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();
nbt.putString("Type", getType().id);
@ -798,7 +799,10 @@ public abstract class Contraption {
Collection<StructureBlockInfo> multiblockParts = capturedMultiblocks.get(controllerPos);
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);
multiblocksNBT.add(tag);
@ -816,7 +820,7 @@ public abstract class Contraption {
actorsNBT.add(compound);
}
ListTag disabledActorsNBT = NBTHelper.writeItemList(disabledActors);
ListTag disabledActorsNBT = NBTHelper.writeItemList(disabledActors, registries);
ListTag superglueNBT = new ListTag();
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();
for (BlockPos pos : interactors.keySet()) {
@ -836,7 +840,11 @@ public abstract class Contraption {
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 -> {
CompoundTag tag = new CompoundTag();
tag.put("Id", NbtUtils.createUUID(e.getKey()));
@ -941,7 +949,7 @@ public abstract class Contraption {
tag.putInt("y", info.pos().getY());
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)
return;
be.setLevel(world);
@ -967,7 +975,7 @@ public abstract class Contraption {
}
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")),
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);
}

View file

@ -1,46 +1,35 @@
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.registries.BuiltInRegistries;
import net.minecraft.nbt.NbtUtils;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.fml.DistExecutor;
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 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;
BlockPos localPos;
BlockState newState;
public ContraptionBlockChangedPacket(int id, BlockPos pos, BlockState state) {
entityID = id;
localPos = pos;
newState = state;
@Override
@OnlyIn(Dist.CLIENT)
public void handle(LocalPlayer player) {
AbstractContraptionEntity.handleBlockChangedPacket(this);
}
@Override
public void write(FriendlyByteBuf buffer) {
buffer.writeInt(entityID);
buffer.writeBlockPos(localPos);
buffer.writeNbt(NbtUtils.writeBlockState(newState));
public PacketTypeProvider getTypeProvider() {
return AllPackets.CONTRAPTION_BLOCK_CHANGED;
}
@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;
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.simibubi.create.AllBlocks;
import com.simibubi.create.AllMovementBehaviours;
import com.simibubi.create.AllPackets;
import com.simibubi.create.content.contraptions.AbstractContraptionEntity.ContraptionRotationState;
import com.simibubi.create.content.contraptions.ContraptionColliderLockPacket.ContraptionColliderLockPacketRequest;
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.utility.BlockHelper;
import com.simibubi.create.infrastructure.config.AllConfigs;
import net.createmod.catnip.platform.CatnipServices;
import net.createmod.catnip.utility.Iterate;
import net.createmod.catnip.utility.VecHelper;
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.Vec3;
import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.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;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.api.distmarker.OnlyIn;
public class ContraptionCollider {
@ -91,8 +92,7 @@ public class ContraptionCollider {
ContraptionRotationState rotation = null;
if (world.isClientSide() && safetyLock.left != null && safetyLock.left.get() == contraptionEntity)
DistExecutor.unsafeRunWhenOn(Dist.CLIENT,
() -> () -> saveClientPlayerFromClipping(contraptionEntity, contraptionMotion));
CatnipServices.PLATFORM.executeOnClientOnly(() -> () -> saveClientPlayerFromClipping(contraptionEntity, contraptionMotion));
// After death, multiple refs to the client player may show up in the area
boolean skipClientPlayer = false;
@ -107,8 +107,7 @@ public class ContraptionCollider {
if (playerType == PlayerType.REMOTE) {
if (!(contraption instanceof TranslatingContraption))
continue;
DistExecutor.unsafeRunWhenOn(Dist.CLIENT,
() -> () -> saveRemotePlayerFromClipping((Player) entity, contraptionEntity, contraptionMotion));
CatnipServices.PLATFORM.executeOnClientOnly(() -> () -> saveRemotePlayerFromClipping((Player) entity, contraptionEntity, contraptionMotion));
continue;
}
@ -203,7 +202,7 @@ public class ContraptionCollider {
Vec3 collisionPosition = intersect.getCollisionPosition();
if (!isTemporal) {
Vec3 separation = intersect.asSeparationVec(entity.getStepHeight());
Vec3 separation = intersect.asSeparationVec(entity.maxUpStep());
if (separation != null && !separation.equals(Vec3.ZERO)) {
collisionResponse.setValue(currentResponse.add(separation));
timeOfImpact = 0;
@ -368,8 +367,7 @@ public class ContraptionCollider {
entity.fallDistance = 0;
for (Entity rider : entity.getIndirectPassengers())
if (getPlayerType(rider) == PlayerType.CLIENT)
AllPackets.getChannel()
.sendToServer(new ClientMotionPacket(rider.getDeltaMovement(), true, 0));
CatnipServices.NETWORK.sendToServer(new ClientMotionPacket(rider.getDeltaMovement(), true, 0));
boolean canWalk = bounce != 0 || slide == 0;
if (canWalk || !rotation.hasVerticalRotation()) {
if (canWalk)
@ -393,8 +391,7 @@ public class ContraptionCollider {
float limbSwing = Mth.sqrt((float) (d0 * d0 + d1 * d1)) * 4.0F;
if (limbSwing > 1.0F)
limbSwing = 1.0F;
AllPackets.getChannel()
.sendToServer(new ClientMotionPacket(entityMotion, true, limbSwing));
CatnipServices.NETWORK.sendToServer(new ClientMotionPacket(entityMotion, true, limbSwing));
if (entity.onGround() && contraption instanceof TranslatingContraption) {
safetyLock.setLeft(new WeakReference<>(contraptionEntity));
@ -424,8 +421,7 @@ public class ContraptionCollider {
if (packetCooldown > 0)
packetCooldown--;
if (packetCooldown == 0) {
AllPackets.getChannel()
.sendToServer(new ContraptionColliderLockPacketRequest(contraptionEntity.getId(), currentDiff));
CatnipServices.NETWORK.sendToServer(new ContraptionColliderLockPacketRequest(contraptionEntity.getId(), currentDiff));
packetCooldown = 3;
}
}
@ -477,7 +473,7 @@ public class ContraptionCollider {
AABB bb = entity.getBoundingBox()
.deflate(1 / 4f, 0, 1 / 4f);
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));
for (int rayIndex = 0; rayIndex < 4; rayIndex++) {
@ -537,8 +533,7 @@ public class ContraptionCollider {
return entityMotion;
if (playerType == PlayerType.CLIENT) {
AllPackets.getChannel()
.sendToServer(new TrainCollisionPacket((int) (damage * 16), contraptionEntity.getId()));
CatnipServices.NETWORK.sendToServer(new TrainCollisionPacket((int) (damage * 16), contraptionEntity.getId()));
world.playSound((Player) entity, entity.blockPosition(), SoundEvents.PLAYER_ATTACK_CRIT,
SoundSource.NEUTRAL, 1, .75f);
} else {
@ -617,12 +612,12 @@ public class ContraptionCollider {
boolean flag1 = p_20273_.y != vec3.y;
boolean flag2 = p_20273_.z != vec3.z;
boolean flag3 = flag1 && p_20273_.y < 0.0D;
if (e.getStepHeight() > 0.0F && flag3 && (flag || flag2)) {
Vec3 vec31 = collideBoundingBox(e, new Vec3(p_20273_.x, (double) e.getStepHeight(), p_20273_.z), aabb,
if (e.maxUpStep() > 0.0F && flag3 && (flag || flag2)) {
Vec3 vec31 = collideBoundingBox(e, new Vec3(p_20273_.x, (double) e.maxUpStep(), p_20273_.z), aabb,
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);
if (vec32.y < (double) e.getStepHeight()) {
if (vec32.y < (double) e.maxUpStep()) {
Vec3 vec33 =
collideBoundingBox(e, new Vec3(p_20273_.x, 0.0D, p_20273_.z), aabb.move(vec32), e.level(), list)
.add(vec32);
@ -646,7 +641,7 @@ public class ContraptionCollider {
if (!entity.level().isClientSide)
return PlayerType.SERVER;
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;
}

View file

@ -1,78 +1,54 @@
package com.simibubi.create.content.contraptions;
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 net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.network.NetworkEvent.Context;
import net.minecraftforge.network.PacketDistributor;
import io.netty.buffer.ByteBuf;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
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;
protected double offset;
private int sender;
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
@OnlyIn(Dist.CLIENT)
public void handle(LocalPlayer player) {
ContraptionCollider.lockPacketReceived(contraption, sender, offset);
}
@Override
public void write(FriendlyByteBuf buffer) {
buffer.writeVarInt(contraption);
buffer.writeDouble(offset);
buffer.writeVarInt(sender);
public PacketTypeProvider getTypeProvider() {
return AllPackets.CONTRAPTION_COLLIDER_LOCK;
}
@Override
public boolean handle(Context context) {
DistExecutor.unsafeRunWhenOn(Dist.CLIENT,
() -> () -> ContraptionCollider.lockPacketReceived(contraption, sender, offset));
return true;
}
public record ContraptionColliderLockPacketRequest(int contraption, double offset) implements ServerboundPacketPayload {
public static final StreamCodec<ByteBuf, ContraptionColliderLockPacketRequest> STREAM_CODEC = StreamCodec.composite(
ByteBufCodecs.VAR_INT, ContraptionColliderLockPacketRequest::contraption,
ByteBufCodecs.DOUBLE, ContraptionColliderLockPacketRequest::offset,
ContraptionColliderLockPacketRequest::new
);
public static class ContraptionColliderLockPacketRequest extends SimplePacketBase {
protected int contraption;
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
public void handle(ServerPlayer player) {
CatnipServices.NETWORK.sendToClientsTrackingEntity(player, new ContraptionColliderLockPacket(contraption, offset, player.getId()));
}
@Override
public void write(FriendlyByteBuf buffer) {
buffer.writeVarInt(contraption);
buffer.writeDouble(offset);
public PacketTypeProvider getTypeProvider() {
return AllPackets.CONTRAPTION_COLLIDER_LOCK_REQUEST;
}
@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 net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtAccounter;
import net.minecraft.nbt.Tag;
import net.minecraft.network.FriendlyByteBuf;
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.
*/
public static boolean isTooLargeForPickup(CompoundTag data) {
public static boolean isTooLargeForPickup(Tag data) {
return packetSize(data) > PICKUP_LIMIT;
}
/**
* @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());
test.writeNbt(data);
NbtAccounter sizeTracker = new NbtAccounter(Long.MAX_VALUE);
NbtAccounter sizeTracker = NbtAccounter.unlimitedHeap();
test.readNbt(sizeTracker);
long size = ((NbtAccounterAccessor) sizeTracker).create$getUsage();
test.release();

View file

@ -1,38 +1,31 @@
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.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.network.NetworkEvent.Context;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
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;
StructureTransform transform;
public ContraptionDisassemblyPacket(int entityID, StructureTransform transform) {
this.entityID = entityID;
this.transform = transform;
}
public ContraptionDisassemblyPacket(FriendlyByteBuf buffer) {
entityID = buffer.readInt();
transform = StructureTransform.fromBuffer(buffer);
@Override
@OnlyIn(Dist.CLIENT)
public void handle(LocalPlayer player) {
AbstractContraptionEntity.handleDisassemblyPacket(this);
}
@Override
public void write(FriendlyByteBuf buffer) {
buffer.writeInt(entityID);
transform.writeToBuffer(buffer);
public PacketTypeProvider getTypeProvider() {
return AllPackets.CONTRAPTION_DISASSEMBLE;
}
@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;
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.AllPackets;
import com.simibubi.create.content.contraptions.sync.ContraptionInteractionPacket;
import com.simibubi.create.content.trains.entity.CarriageContraptionEntity;
import com.simibubi.create.content.trains.entity.TrainRelocator;
import com.simibubi.create.foundation.utility.RaycastHelper;
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.Iterate;
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.Vec3;
import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.client.event.InputEvent;
import net.minecraftforge.event.TickEvent.Phase;
import net.minecraftforge.event.TickEvent.PlayerTickEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
import org.apache.commons.lang3.mutable.MutableObject;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.api.distmarker.OnlyIn;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.neoforge.client.event.InputEvent;
import net.neoforged.neoforge.event.tick.PlayerTickEvent;
import javax.annotation.Nullable;
import java.lang.ref.WeakReference;
import java.util.Collection;
@EventBusSubscriber
@EventBusSubscriber(Dist.CLIENT)
public class ContraptionHandlerClient {
@SubscribeEvent
@OnlyIn(Dist.CLIENT)
public static void preventRemotePlayersWalkingAnimations(PlayerTickEvent event) {
if (event.phase == Phase.START)
public static void preventRemotePlayersWalkingAnimations(PlayerTickEvent.Post event) {
if (!(event.getEntity() instanceof RemotePlayer remotePlayer))
return;
if (!(event.player instanceof RemotePlayer))
return;
RemotePlayer remotePlayer = (RemotePlayer) event.player;
CompoundTag data = remotePlayer.getPersistentData();
if (!data.contains("LastOverrideLimbSwingUpdate"))
return;
@ -106,7 +106,7 @@ public class ContraptionHandlerClient {
BlockPos pos = rayTraceResult.getBlockPos();
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
continue;
@ -128,7 +128,7 @@ public class ContraptionHandlerClient {
public static Couple<Vec3> getRayInputs(LocalPlayer player) {
Minecraft mc = Minecraft.getInstance();
Vec3 origin = RaycastHelper.getTraceOrigin(player);
double reach = mc.gameMode.getPickRange();
double reach = player.blockInteractionRange();
if (mc.hitResult != null && mc.hitResult.getLocation() != null)
reach = Math.min(mc.hitResult.getLocation()
.distanceTo(origin), reach);

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