🎉 Trading starts!
26
.gitignore
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
# eclipse
|
||||
bin
|
||||
*.launch
|
||||
.settings
|
||||
.metadata
|
||||
.classpath
|
||||
.project
|
||||
|
||||
# idea
|
||||
out
|
||||
*.ipr
|
||||
*.iws
|
||||
*.iml
|
||||
.idea
|
||||
|
||||
# gradle
|
||||
build
|
||||
.gradle
|
||||
|
||||
# other
|
||||
eclipse
|
||||
run
|
||||
|
||||
# Files from Forge MDK
|
||||
forge*changelog.txt
|
||||
scripts/output
|
||||
65
CREDITS.txt
Normal file
@@ -0,0 +1,65 @@
|
||||
Minecraft Forge: Credits/Thank You
|
||||
|
||||
Forge is a set of tools and modifications to the Minecraft base game code to assist
|
||||
mod developers in creating new and exciting content. It has been in development for
|
||||
several years now, but I would like to take this time thank a few people who have
|
||||
helped it along it's way.
|
||||
|
||||
First, the people who originally created the Forge projects way back in Minecraft
|
||||
alpha. Eloraam of RedPower, and SpaceToad of Buildcraft, without their acceptiance
|
||||
of me taking over the project, who knows what Minecraft modding would be today.
|
||||
|
||||
Secondly, someone who has worked with me, and developed some of the core features
|
||||
that allow modding to be as functional, and as simple as it is, cpw. For developing
|
||||
FML, which stabelized the client and server modding ecosystem. As well as the base
|
||||
loading system that allows us to modify Minecraft's code as elegently as possible.
|
||||
|
||||
Mezz, who has stepped up as the issue and pull request manager. Helping to keep me
|
||||
sane as well as guiding the community into creating better additions to Forge.
|
||||
|
||||
Searge, Bspks, Fesh0r, ProfMobious, and all the rest over on the MCP team {of which
|
||||
I am a part}. For creating some of the core tools needed to make Minecraft modding
|
||||
both possible, and as stable as can be.
|
||||
On that note, here is some specific information of the MCP data we use:
|
||||
* Minecraft Coder Pack (MCP) *
|
||||
Forge Mod Loader and Minecraft Forge have permission to distribute and automatically
|
||||
download components of MCP and distribute MCP data files. This permission is not
|
||||
transitive and others wishing to redistribute the Minecraft Forge source independently
|
||||
should seek permission of MCP or remove the MCP data files and request their users
|
||||
to download MCP separately.
|
||||
|
||||
And lastly, the countless community members who have spent time submitting bug reports,
|
||||
pull requests, and just helping out the community in general. Thank you.
|
||||
|
||||
--LexManos
|
||||
|
||||
=========================================================================
|
||||
|
||||
This is Forge Mod Loader.
|
||||
|
||||
You can find the source code at all times at https://github.com/MinecraftForge/MinecraftForge/tree/1.12.x/src/main/java/net/minecraftforge/fml
|
||||
|
||||
This minecraft mod is a clean open source implementation of a mod loader for minecraft servers
|
||||
and minecraft clients.
|
||||
|
||||
The code is authored by cpw.
|
||||
|
||||
It began by partially implementing an API defined by the client side ModLoader, authored by Risugami.
|
||||
http://www.minecraftforum.net/topic/75440-
|
||||
This support has been dropped as of Minecraft release 1.7, as Risugami no longer maintains ModLoader.
|
||||
|
||||
It also contains suggestions and hints and generous helpings of code from LexManos, author of MinecraftForge.
|
||||
http://www.minecraftforge.net/
|
||||
|
||||
Additionally, it contains an implementation of topological sort based on that
|
||||
published at http://keithschwarz.com/interesting/code/?dir=topological-sort
|
||||
|
||||
It also contains code from the Maven project for performing versioned dependency
|
||||
resolution. http://maven.apache.org/
|
||||
|
||||
It also contains a partial repackaging of the javaxdelta library from http://sourceforge.net/projects/javaxdelta/
|
||||
with credit to it's authors.
|
||||
|
||||
Forge Mod Loader downloads components from the Minecraft Coder Pack
|
||||
(http://mcp.ocean-labs.de/index.php/Main_Page) with kind permission from the MCP team.
|
||||
|
||||
7
LICENSE.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
Copyright 2022 oierbravo
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
321
build.gradle
Normal file
@@ -0,0 +1,321 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
gradlePluginPortal()
|
||||
maven { url = 'https://maven.minecraftforge.net' }
|
||||
mavenCentral()
|
||||
maven { url = 'https://repo.spongepowered.org/repository/maven-public' }
|
||||
maven { url = 'https://maven.parchmentmc.org' }
|
||||
|
||||
}
|
||||
dependencies {
|
||||
classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: "${forgegradle_version}", changing: false
|
||||
classpath 'gradle.plugin.com.matthewprenger:CurseGradle:1.1.0'
|
||||
classpath group: 'org.spongepowered', name: 'mixingradle', version: '0.7-SNAPSHOT'
|
||||
classpath "org.parchmentmc:librarian:1.+"
|
||||
}
|
||||
}
|
||||
|
||||
plugins {
|
||||
id 'maven-publish'
|
||||
id 'com.matthewprenger.cursegradle' version "${cursegradle_version}"
|
||||
id "com.modrinth.minotaur" version "2.+"
|
||||
}
|
||||
|
||||
apply plugin: 'net.minecraftforge.gradle'
|
||||
apply plugin: 'org.parchmentmc.librarian.forgegradle'
|
||||
apply plugin: 'com.matthewprenger.cursegradle'
|
||||
apply plugin: 'org.spongepowered.mixin'
|
||||
apply plugin: 'idea'
|
||||
apply plugin: 'maven-publish'
|
||||
|
||||
jarJar.enable()
|
||||
|
||||
group = "com.${author}.${modid}"
|
||||
version = "${mod_version}"
|
||||
archivesBaseName = "${modid}-${minecraft_version}"
|
||||
|
||||
java.toolchain.languageVersion = JavaLanguageVersion.of(17)
|
||||
|
||||
println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getProperty('java.vm.version') + '(' + System.getProperty('java.vendor') + ') Arch: ' + System.getProperty('os.arch'))
|
||||
minecraft {
|
||||
if (Boolean.parseBoolean(project.use_parchment)) {
|
||||
mappings channel: 'parchment', version: "${parchment_version}-${minecraft_version}"
|
||||
} else {
|
||||
mappings channel: 'official', version: "${minecraft_version}"
|
||||
}
|
||||
|
||||
// accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg') // Currently, this location cannot be changed from the default.
|
||||
|
||||
runs {
|
||||
client {
|
||||
workingDirectory project.file('run')
|
||||
|
||||
// Recommended logging data for a userdev environment
|
||||
// The markers can be added/remove as needed separated by commas.
|
||||
// "SCAN": For mods scan.
|
||||
// "REGISTRIES": For firing of registry events.
|
||||
// "REGISTRYDUMP": For getting the contents of all registries.
|
||||
property 'forge.logging.markers', 'REGISTRIES'
|
||||
|
||||
// Recommended logging level for the console
|
||||
// You can set various levels here.
|
||||
// Please read: https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels
|
||||
property 'forge.logging.console.level', 'debug'
|
||||
|
||||
// Comma-separated list of namespaces to load gametests from. Empty = all namespaces.
|
||||
property 'forge.enabledGameTestNamespaces', 'trading_station'
|
||||
|
||||
mods {
|
||||
trading_station {
|
||||
source sourceSets.main
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
workingDirectory project.file('run')
|
||||
|
||||
property 'forge.logging.markers', 'REGISTRIES'
|
||||
|
||||
property 'forge.logging.console.level', 'debug'
|
||||
|
||||
// Comma-separated list of namespaces to load gametests from. Empty = all namespaces.
|
||||
property 'forge.enabledGameTestNamespaces', 'trading_station'
|
||||
|
||||
mods {
|
||||
trading_station {
|
||||
source sourceSets.main
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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 {
|
||||
workingDirectory project.file('run')
|
||||
|
||||
// Recommended logging data for a userdev environment
|
||||
// The markers can be added/remove as needed separated by commas.
|
||||
// "SCAN": For mods scan.
|
||||
// "REGISTRIES": For firing of registry events.
|
||||
// "REGISTRYDUMP": For getting the contents of all registries.
|
||||
property 'forge.logging.markers', 'REGISTRIES'
|
||||
|
||||
// Recommended logging level for the console
|
||||
// You can set various levels here.
|
||||
// Please read: https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels
|
||||
property 'forge.logging.console.level', 'debug'
|
||||
|
||||
// Comma-separated list of namespaces to load gametests from. Empty = all namespaces.
|
||||
property 'forge.enabledGameTestNamespaces', 'trading_station'
|
||||
|
||||
mods {
|
||||
trading_station {
|
||||
source sourceSets.main
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data {
|
||||
workingDirectory project.file('run')
|
||||
|
||||
property 'forge.logging.markers', 'REGISTRIES'
|
||||
|
||||
property 'forge.logging.console.level', 'debug'
|
||||
|
||||
// Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources.
|
||||
args '--mod', 'trading_station', '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/')
|
||||
|
||||
mods {
|
||||
trading_station {
|
||||
source sourceSets.main
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Include resources generated by data generators.
|
||||
sourceSets.main.resources { srcDir 'src/generated/resources' }
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
// Location of the maven that hosts JEI files (and TiC)
|
||||
name 'Progwml6 maven'
|
||||
url 'https://dvs1.progwml6.com/files/maven'
|
||||
}
|
||||
maven {
|
||||
name = 'tterrag maven'
|
||||
url = 'https://maven.tterrag.com/'
|
||||
}
|
||||
maven {
|
||||
url "https://www.cursemaven.com"
|
||||
content {
|
||||
includeGroup "curse.maven"
|
||||
}
|
||||
}
|
||||
maven {
|
||||
url "https://maven.saps.dev/minecraft"
|
||||
content {
|
||||
includeGroup "dev.latvian.mods"
|
||||
includeGroup "dev.ftb.mods"
|
||||
}
|
||||
}
|
||||
maven {
|
||||
url "https://maven.architectury.dev/"
|
||||
content {
|
||||
includeGroup "dev.architectury"
|
||||
}
|
||||
}
|
||||
maven {
|
||||
url "https://maven.blamejared.com"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
dependencies {
|
||||
implementation 'org.jetbrains:annotations:22.0.0'
|
||||
minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}"
|
||||
|
||||
jarJar(group: 'com.tterrag.registrate', name: 'Registrate', version: "[MC1.19,MC1.20)")
|
||||
|
||||
jarJar(group: 'com.tterrag.registrate', name: 'Registrate', version: '[MC1.19-1.1.5,)') {
|
||||
jarJar.pin(it, project.registrate_version)
|
||||
}
|
||||
implementation fg.deobf("com.tterrag.registrate:Registrate:${registrate_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}")
|
||||
|
||||
if (kubejs_enabled.toBoolean()) {
|
||||
implementation fg.deobf("dev.latvian.mods:rhino-forge:${rhino_version}")
|
||||
implementation fg.deobf("dev.architectury:architectury-forge:${architectury_version}")
|
||||
implementation fg.deobf("dev.latvian.mods:kubejs-forge:${kubejs_version}")
|
||||
}
|
||||
implementation fg.deobf("curse.maven:jade-324717:${jade_id}")
|
||||
|
||||
if (create_enabled.toBoolean()) {
|
||||
implementation fg.deobf("com.simibubi.create:create-${create_minecraft_version}:${create_version}:slim") { transitive = false }
|
||||
implementation fg.deobf("com.jozufozu.flywheel:flywheel-forge-${flywheel_minecraft_version}:${flywheel_version}")
|
||||
}
|
||||
|
||||
if (ct_enabled.toBoolean()) {
|
||||
def minecraftVersion= "net.minecraftforge:forge:${minecraft_version}-${forge_version}"
|
||||
def ctDep = "com.blamejared.crafttweaker:CraftTweaker-forge-${ct_minecraft_version}:${ct_version}"
|
||||
compileOnly(ctDep)
|
||||
runtimeOnly(fg.deobf(ctDep))
|
||||
|
||||
annotationProcessor "com.blamejared.crafttweaker:Crafttweaker_Annotation_Processors:${ct_annotation_processor_version}"
|
||||
annotationProcessor minecraftVersion
|
||||
annotationProcessor ctDep
|
||||
}
|
||||
|
||||
//annotationProcessor 'org.spongepowered:mixin:0.8.5:processor'
|
||||
|
||||
}
|
||||
|
||||
compileJava.options.encoding = 'UTF-8'
|
||||
compileJava {
|
||||
options.compilerArgs = ['-Xdiags:verbose']
|
||||
}
|
||||
tasks.withType(Jar) {
|
||||
//from tasks.createChangelog.outputFile
|
||||
archiveClassifier = 'slim'
|
||||
manifest {
|
||||
attributes([
|
||||
"Specification-Title" : modid,
|
||||
"Specification-Vendor" : author,
|
||||
"Specification-Version" : "1", // We are version 1 of ourselves
|
||||
"Implementation-Title" : project.name,
|
||||
"Implementation-Version" : project.version,
|
||||
"Implementation-Vendor" : author,
|
||||
"Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"),
|
||||
"MixinConfigs" : "${modid}.mixins.json"
|
||||
])
|
||||
}
|
||||
|
||||
if(file("./src/main/resources/${modid}.mixins.json").exists()) {
|
||||
manifest {
|
||||
attributes 'MixinConfigs': "${modid}.mixins.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
task jarJarRelease {
|
||||
group = 'jarjar'
|
||||
doLast {
|
||||
tasks.jarJar {
|
||||
archiveClassifier = ''
|
||||
}
|
||||
}
|
||||
finalizedBy tasks.jarJar
|
||||
}
|
||||
tasks.jarJar {
|
||||
archiveClassifier = ''
|
||||
}
|
||||
void addLicense(jarTask) {
|
||||
jarTask.from('LICENSE.txt') {
|
||||
rename { "${it}_${project.archivesBaseName}" }
|
||||
}
|
||||
}
|
||||
addLicense(jar)
|
||||
addLicense(tasks.jarJar)
|
||||
|
||||
mixin {
|
||||
add sourceSets.main, "${modid}.refmap.json"
|
||||
}
|
||||
afterEvaluate {
|
||||
tasks.configureReobfTaskForReobfJar.mustRunAfter(tasks.compileJava)
|
||||
tasks.configureReobfTaskForReobfJarJar.mustRunAfter(tasks.compileJava)
|
||||
}
|
||||
|
||||
tasks.withType(JavaCompile).configureEach {
|
||||
options.encoding = 'UTF-8' // Use the UTF-8 charset for Java compilation
|
||||
}
|
||||
compileJava {
|
||||
options.compilerArgs = ['-Xdiags:verbose']
|
||||
}
|
||||
reobf {
|
||||
jarJar { }
|
||||
}
|
||||
|
||||
|
||||
jar.finalizedBy('reobfJar')
|
||||
tasks.jarJar.finalizedBy('reobfJarJar')
|
||||
|
||||
//from components.java
|
||||
//def getArtifact = { ->
|
||||
// from components.java
|
||||
// return jarJar.component(it)
|
||||
// Method body here
|
||||
//}
|
||||
if(System.getenv('MODRINTH_TOKEN') != null) {
|
||||
|
||||
modrinth {
|
||||
token = System.getenv("MODRINTH_TOKEN")
|
||||
projectId = "trading_station"
|
||||
versionNumber = "${mod_version}"
|
||||
versionName = "${display_name} - v${mod_version} for Minecraft ${minecraft_version}"
|
||||
versionType = "release" // This is the default -- can also be `beta` or `alpha`
|
||||
uploadFile = tasks.jarJar // With Loom, this MUST be set to `remapJar` instead of `jar`!
|
||||
gameVersions = ["${minecraft_version}"] // Must be an array, even with only one version
|
||||
loaders = ["forge"] // Must also be an array - no need to specify this if you're using Loom or ForgeGradle
|
||||
dependencies { // A special DSL for creating dependencies
|
||||
optional.project "create"
|
||||
optional.project "jei"
|
||||
optional.project "crafttweaker"
|
||||
}
|
||||
syncBodyFrom = rootProject.file("README.md").text
|
||||
}
|
||||
tasks.modrinth.dependsOn(tasks.modrinthSyncBody)
|
||||
|
||||
}
|
||||
|
||||
// However if you are in a multi-project build, dev time needs unobfed jar files, so you can delay the obfuscation until publishing by doing
|
||||
// publish.dependsOn('reobfJar')
|
||||
|
||||
|
||||
tasks.withType(JavaCompile).configureEach {
|
||||
options.encoding = 'UTF-8' // Use the UTF-8 charset for Java compilation
|
||||
}
|
||||
383
changelog.txt
Normal file
@@ -0,0 +1,383 @@
|
||||
1.18.x Changelog
|
||||
40.1
|
||||
====
|
||||
- 40.1.80 Revert "[1.18.x] Backport: Cache resource listing calls in resource packs (#8868)" (#9026)
|
||||
This reverts commit 4df024ef43524d8ec48928c70f561903f7a8e184.
|
||||
- 40.1.79 [1.18.x] Backport #8981 ("Add event to growing fungus") to 1.18 (#8998)
|
||||
- 40.1.78 LTS Backport of ModMismachEvent (#8989) (#9010)
|
||||
- 40.1.77 LTS Backport of #8927 (#9012)
|
||||
- 40.1.76 Backport Reach Distance fix (#9008)
|
||||
- 40.1.75 Backport version-checker user-agent changes to 1.18 (#8975)
|
||||
- 40.1.74 Fix circular dependency in static init of RecipeBookRegistry (#8996)
|
||||
- 40.1.73 Backport: Load custom ITransformationServices from the classpath in dev (#8350)
|
||||
- 40.1.72 [1.18.x] Backport: Cache resource listing calls in resource packs (#8868)
|
||||
- 40.1.71 Backport: Re-add PotentialSpawns event (#8944)
|
||||
- 40.1.70 [1.18.2][Backport] Let isRemotePresent check minecraft:register for packet ids from other mod loaders (#8943)
|
||||
- 40.1.69 Fix crossbows not firing ArrowLooseEvent (#8888)
|
||||
- 40.1.68 [1.18] Allow blocks to provide a dynamic MaterialColor for display on maps (#8855)
|
||||
- 40.1.67 [1.18.x] Add RenderLevelStageEvent to expand on and replace RenderLevelLastEvent (#8603)
|
||||
- 40.1.66 [1.18] Fix EnumArgument to use enum names for suggestions (#8746)
|
||||
Previously, the suggestions used the string representation of the enum
|
||||
through Enum#toString, which can differ from the name of the enum as
|
||||
required by Enum#valueOf, causing invalid suggestions (both in gui and
|
||||
through the error message).
|
||||
Using Enum#name fixes this discrepancy, so now the suggestions are
|
||||
always valid inputs regardless of the return of Enum#toString.
|
||||
Fixes #8618
|
||||
- 40.1.65 [1.18] Add MC-105317 fix into patch to rotate entities in structures properly (#8793)
|
||||
- 40.1.64 [1.18] Update to the latest JarJar (#8848)
|
||||
- 40.1.63 [1.18.x] Fix a weird interaction between shulker boxes and hoppers. (#8824)
|
||||
- 40.1.62 [1.18.x] Implement full support for IPv6 (#8376)
|
||||
- 40.1.61 [1.16] Make tryEmptyContainer respect doDrain (#8318)
|
||||
- 40.1.60 Jar-In-Jar (#8657)
|
||||
* Jar-In-Jar
|
||||
* Change to use the custom 4.x SPI.
|
||||
* Bump JarJar to fix some version range selectors.
|
||||
* Address requested changes.
|
||||
* Mark the JiJ locator as a locator.
|
||||
* Remove the unused imports.
|
||||
- 40.1.59 Fix static member ordering crash in UnitSprite (#8839)
|
||||
The previous ordering caused LOCATION to be null during the construction
|
||||
of the UnitSprite INSTANCE, leading to errors as the atlas location for
|
||||
the sprite would be null.
|
||||
Fixes #8795
|
||||
- 40.1.58 Backport: ForgeChunkManager ticking ticket fixes. (#8784)
|
||||
- 40.1.57 Delete LootItemRandomChanceCondition.java.patch (#8734)
|
||||
- 40.1.56 Use stack sensitive translation key by default (#8674)
|
||||
- 40.1.55 Add callback after a BlockState was changed and the neighbors were updated (#8617)
|
||||
- 40.1.54 [1.18.x] Allow safely registering RenderType predicates at any time (#8671)
|
||||
* Allow safely registering RenderType predicates at any time
|
||||
* Requested changes
|
||||
- 40.1.53 Add Filtered Message to ServerChatEvent
|
||||
- 40.1.52 [1.18] Make ConfigValue implement Supplier. (#8777)
|
||||
- 40.1.51 Make IVertexConsumers such as the lighting pipeline, be aware of which format they are dealing with (#8665)
|
||||
Also fix Lighting pipeline ignoring the overlay coords from the block renderer.
|
||||
- 40.1.50 Revert "TeamCity change in 'MinecraftForge / MinecraftForge' project: build features of 'Build' build configuration were updated"
|
||||
This reverts commit 0cc85bc314c8c90f1bdb24d77c7035bb09150489.
|
||||
- 40.1.49 TeamCity change in 'MinecraftForge / MinecraftForge' project: build features of 'Build' build configuration were updated
|
||||
- 40.1.48 [1.18.x] Fix #8530 (Banner Pattern) NPE (#8666)
|
||||
- 40.1.47 Revert "[1.18.x] Enable the Forge light pipeline by default (#8629)" (#8663)
|
||||
- 40.1.46 Fix eager loading of model loaders during datagen causing NPE (#8659)
|
||||
- 40.1.45 [1.18.x] Fix 2 crossbow animations not applying to custom variants (#8625)
|
||||
- 40.1.44 [1.18.x] Added new Disconnection screen to display better channel/registry mismatch information (#8402)
|
||||
Co-authored-by: Curle <42079760+TheCurle@users.noreply.github.com>
|
||||
- 40.1.43 [1.18] Avoid exclusive synchronisation in block render type lookups (#8476)
|
||||
- 40.1.42 [1.18] Fix command redirects by replacing Commands#fillUsableCommands (#8616)
|
||||
Commands#fillUsableCommands does not handle redirect nodes properly. It
|
||||
blindly pulls from the cached node map for a redirect node, which may
|
||||
have no result because the target node of the redirect has not been
|
||||
visited yet.
|
||||
CommandHelper#mergeCommandNode is better in this regard, because it
|
||||
visits the target node of the redirect instead of blindly pulling from
|
||||
the node map.
|
||||
Fixes #7551
|
||||
- 40.1.41 [1.18] Fix tags command suggestion to include dynamic registries (#8638)
|
||||
Manually entering the names of dynamic registries work as expected. The
|
||||
suggestions for registries didn't include dynamic registries because
|
||||
they queried the static registries rather than querying all registries
|
||||
from the server's `RegistryAccess` (which includes both static
|
||||
registries and dynamic registries).
|
||||
- 40.1.40 Low code language provider (#8633)
|
||||
Co-authored-by: Curle <42079760+TheCurle@users.noreply.github.com>
|
||||
- 40.1.39 [1.18.x] Add checkJarCompatibility task (#8644)
|
||||
- 40.1.38 [1.18.x] Fix Banner Patterns not being extensible (#8530)
|
||||
Co-authored-by: Curle <42079760+TheCurle@users.noreply.github.com>
|
||||
- 40.1.37 1.18.x Port BiomeDictionary over to biome tags (#8564)
|
||||
- 40.1.36 [1.18.x] Enable the Forge light pipeline by default (#8629)
|
||||
- 40.1.35 [1.18.x] Allow Modders to add custom data-pack registries through RegistryBuilder (#8630)
|
||||
Co-authored-by: Silverminer007 <66484505+Silverminer007@users.noreply.github.com>
|
||||
Co-authored-by: Curle <42079760+TheCurle@users.noreply.github.com>
|
||||
- 40.1.34 [1.18] Allow custom rarities to directly modify the style (#8648)
|
||||
- 40.1.33 [1.18] Fix reload listener registration in ModelLoaderRegistry (#8650)
|
||||
- 40.1.32 Fix wrong position in Level#hasChunk() call in IForgeBlockGetter (#8654)
|
||||
- 40.1.31 Add ItemStack context to Enchantment#getDamageBonus (#8635)
|
||||
- 40.1.30 Fix attack cooldown bar showing when out of reach of target. Closes #8639 (#8640)
|
||||
- 40.1.29 Improve TagsUpdatedEvent by adding update case information. (#8636)
|
||||
- 40.1.28 Deprecate patched-in Style methods for removal, vanilla variants exist. (#8615)
|
||||
- 40.1.27 Add pack-type-specific format versions in pack metadata. Fixes #8563 (#8612)
|
||||
- 40.1.26 Catch and aggregate exceptions during NewRegistryEvent (#8601)
|
||||
- 40.1.25 Added removeErroringEntities config option (#8627)
|
||||
Counterpart to removeErroringBlockEntities
|
||||
- 40.1.24 Add missing patches for not lowering mipmap level for small textures (#8622)
|
||||
- 40.1.23 Make TransformType enum extensible, includes the possibility to specify a fallback type for cases where models don't specify the transform explicitly. (#8566)
|
||||
Makes it possible to add new perspectives.
|
||||
- 40.1.22 Fix CheckSAS to actually validate that the SAS line will do something.
|
||||
This removes all method level lines as they are not necessary now.
|
||||
- 40.1.21 Add Attack Range attribute and Update Reach Distance (#8478)
|
||||
- 40.1.20 Implement PlayerNegotiationEvent (#8599)
|
||||
- 40.1.19 Fire EntityTravelToDimensionEvent in all expected cases (#8614)
|
||||
Fixes #8520
|
||||
- 40.1.18 Fix isEdible crash (#8613)
|
||||
Fixes #8602
|
||||
- 40.1.17 Fix typo in Snow Golem patch causing them to destroy blocks they shouldn't. Closes #8611
|
||||
- 40.1.16 Re-introduce an attribute for entity step height in a non-breaking way (#8607)
|
||||
- 40.1.15 Revert step height attribute (#8604)
|
||||
- 40.1.14 [1.18.x] Fix ContextNbtProvider serializing the wrong name (#8575)
|
||||
- 40.1.13 Let BaseRailBlock decide if the calculated RailShape for placement or connection to neighbors is valid (#8562)
|
||||
- 40.1.12 Fix shears not playing a breakage sound (#8600)
|
||||
- 40.1.11 Update IExtensionPoint javadoc to be correct (#8568)
|
||||
- 40.1.10 Fix IDs of Multi-part entities being desynced across client and server. (#8576)
|
||||
- 40.1.9 Expose ICondition$IContext to modded reload listeners. (#8596)
|
||||
- 40.1.8 Fix undead causing chunkloading leading to extensive lag (#8583)
|
||||
- 40.1.7 Accomodate Bukkit-like Servers not sending Command Args (#8582)
|
||||
Note to modded server devs:
|
||||
Please, please, please implement full compatibility with [Brigadier](https://github.com/Mojang/Brigadier) instead of hacking around it.
|
||||
- 40.1.6 Restore translation key comments to ForgeConfigSpec (#8584)
|
||||
- 40.1.5 Fix entity parts being ignored when collecting entities in an AABB (#8588)
|
||||
Previously entity parts are only taken into consideration when the parent entity is in a chunk that intersects with the AABB
|
||||
- 40.1.4 Fix EntityInteraction event running twice on client side (#8598)
|
||||
- 40.1.3 Introduce an attribute for step height additions (#8389)
|
||||
- 40.1.2 Fix shears passing on a client when interacting with a shearable entity (#8597)
|
||||
Caused the offhand item to also interact with the entity, possibly sending a packet to the server causing both hands to interact
|
||||
- 40.1.1 Allow Exception passed through CommandEvent to propagate (#8590)
|
||||
- 40.1.0 Mark 1.18.2 Recommended Build.
|
||||
Co-authored-by: sciwhiz12 <arnoldnunag12@gmail.com>
|
||||
Co-authored-by: Marc Hermans <marc.hermans@ldtteam.com>
|
||||
Co-authored-by: Curle <curle@gemwire.uk>
|
||||
Co-authored-by: SizableShrimp <sizableshrimp@sizableshrimp.me>
|
||||
Co-authored-by: David Quintana <gigaherz@gmail.com>
|
||||
|
||||
40.0
|
||||
====
|
||||
- 40.0.54 Add event for hooking into StructuresBecomeConfiguredFix Fixes #8505
|
||||
Pass-through unknown structure IDs with "unknown." prefix
|
||||
This avoids the fixer throwing an exception due to the unknown
|
||||
structure, which causes the chunk data to be dropped (and freshly
|
||||
regenerated later). The deserializer logs and ignores the unknown
|
||||
structure ID, avoiding full chunk data loss.
|
||||
- 40.0.53 Fix missed patch for loading modded dimensions on Dedicated Server start (#8555)
|
||||
- 40.0.52 Fix potential concurrency issues with BiomeDictionary. Closes #8266
|
||||
- 40.0.51 Fix debug text being rendered slightly wrong.
|
||||
- 40.0.50 Fix intrusive handlers on dummy objects.
|
||||
- 40.0.49 Amend license header to include contributors and apply to FML subprojects (#8525)
|
||||
After internal discussion, it was decided that we need to include
|
||||
"contributors" to the license header. This avoids claiming that the
|
||||
Java source files are under the exclusive copyright ownership of Forge
|
||||
LLC, which excludes contributors that still hold copyright ownership
|
||||
over their contributions (but is licensed under the LGPLv2.1 as stated
|
||||
in the Forge CLA).
|
||||
- 40.0.48 Add modern implementation of the Slider widget and deprecate the old one (#8496)
|
||||
- 40.0.47 Implement ItemStack and LivingEntity sensitive method to get the FoodProperties for an Item (#8477)
|
||||
- 40.0.46 Add use context and simulate flag to getToolModifiedState, enabled HOE_TILL action. (#8557)
|
||||
- 40.0.45 Remove bad patch for AbstractFurnaceBlockEntity (#8561)
|
||||
The patch prevented the entity from being marked as changed when an
|
||||
item finished smelting.
|
||||
- 40.0.44 Fix issues with custom forge ingredients causing sub ingredients to be prematurely and invalidly cached (#8550)
|
||||
Add config option and skip checking for empty ingredients in shapeless recipe deserialization
|
||||
- 40.0.43 Add EnderManAngerEvent to make it possible to prevent endermen getting angry at a player based on more then their helmet. (#8406)
|
||||
- 40.0.42 Fix misaligned patch in BlockEntity.save.
|
||||
- 40.0.41 Expose `getHolder()` method on RegistryObject, as helper for when absolutely necessary to pass into Vanilla code. (#8548)
|
||||
It is recommended you avoid if you can.
|
||||
- 40.0.40 Fix return value of Recipe#isIncomplete being inaccurate for empty tags (#8549)
|
||||
- 40.0.39 Simplfy default behavior of isSimple (#8543)
|
||||
isSimple should only return true if the ingredient is any more sensitive then JUST itemA == itemB
|
||||
It used to take metadata and damage into account, but that was removed in the flattening.
|
||||
Also prevents fetching tag values too early, as tags are not ready during the ingredient constructor
|
||||
- 40.0.38 Implement IPlantable in BambooBlock (#8508)
|
||||
- 40.0.37 Fix compiler error in eclipse, bump MCPConfig for FF/Record fix.
|
||||
- 40.0.36 Fix TagEmptyCondition by passing tag context into conditional and recipe deserializers. (#8546)
|
||||
- 40.0.35 Allow using DeferredRegisters for vanilla registries (#8527)
|
||||
Catch and aggregate exceptions when applying object holders
|
||||
- 40.0.34 Remove cut copper from copper storage blocks tag. Closes #8403 (#8539)
|
||||
- 40.0.33 Fix brewing stand input placement not auto-splitting stackable potions. (#8534)
|
||||
- 40.0.32 Fix lost validation of registry data on singleplayer world load (#8533)
|
||||
Fix some leftover 1.18.2 TODOs
|
||||
- 40.0.31 1.18 Allow mod menus to have their own recipebook (#8028)
|
||||
- 40.0.30 [1.18.x] Add 3 new ingredient types, and make existing ingredients compatible with datagen (#8517)
|
||||
- 40.0.29 [1.18.x] Add the projectile search event. (#8322)
|
||||
Co-authored-by: noeppi_noeppi <noeppinoeppi@gmail.com>
|
||||
- 40.0.28 Allow confirm-and-save of the Experimental Settings warning. (#7275)
|
||||
- 40.0.27 Add hook for powdered-snow shoes (#8514)
|
||||
- 40.0.26 Add some helper Access Transformers (#8490)
|
||||
- 40.0.25 Fix incorrect method used in getStream (#8532)
|
||||
The original correct method is getPath, but the patch uses getLocation.
|
||||
The former is the actual resource path to the sound OGG file, while the
|
||||
latter is the sound's location.
|
||||
Fixes #8531
|
||||
- 40.0.24 [1.18] Make it easier to register custom skull blocks models (#8351)
|
||||
- 40.0.23 Rework fog events (#8492)
|
||||
- 40.0.22 Update Forge Auto Renaming Tool to the latest version (#8515)
|
||||
- 40.0.21 Add patches to enable MobEffects with IDs > 255 (#8380)
|
||||
- 40.0.20 Allow sound instances to play custom audio streams (#8295)
|
||||
- 40.0.19 Fix NPE caused by canceling onServerChatEvent (#8516)
|
||||
- 40.0.18 [1.18.2] Fix tags for custom forge registries. (#8495)
|
||||
Tag-enabled registries must now be registered to vanilla's root registry. See RegistryBuilder#hasTags.
|
||||
Modded tag-enabled registries have to use the format `data/<namespace>/tags/<registrynamespace>/<registryname>/<tag>.json`
|
||||
This format is to prevent conflicts for registries with the same path but different namespaces
|
||||
EX: Registry name `examplemod:shoe`, tag name `blue_shoes` would be `data/<namespace>/tags/examplemod/shoe/blue_shoes.json`
|
||||
RegistryEvent.NewRegistry has been moved and renamed to NewRegistryEvent.
|
||||
RegistryBuilder#create has been made private. See NewRegistryEvent#create
|
||||
Created new ITagManager system for looking up Forge tags. See IForgeRegistry#tags.
|
||||
Add lookup methods for Holders from forge registries. See IForgeRegistry#getHolder.
|
||||
- 40.0.17 Lower custom item entity replacement from highest to high so mods can cancel it during a specific tick (#8417)
|
||||
- 40.0.16 Fix MC-176559 related to the Mending enchantment (#7606)
|
||||
- 40.0.15 [1.18.x] Allow blocks to hide faces on a neighboring block (#8300)
|
||||
* Allow blocks to hide faces on a neighboring block
|
||||
* Allow blocks to opt-out of external face hiding
|
||||
- 40.0.14 [1.18.x] Fix FMLOnly in forgedev and userdev (#8512)
|
||||
- 40.0.13 Clear local variable table on RuntimeEnumExtender transformation (#8502)
|
||||
- 40.0.12 Pass server resources to reload listener event (#8493)
|
||||
- 40.0.11 Use UTF-8 charset for Java compilation (#8486)
|
||||
- 40.0.10 Use wither as griefing entity when it indirectly hurts an entity (#8431)
|
||||
- 40.0.9 Provide access to the haveTime supplier in WorldTickEvent and ServerTickEvent (#8470)
|
||||
- 40.0.8 Fix durability bar not respecting an item's custom max damage (#8482)
|
||||
- 40.0.7 Add event for controlling potion indicators size (#8483)
|
||||
This event allows forcing the rendering of the potion indicators in the
|
||||
inventory screen to either compact mode (icons only) or classic mode
|
||||
(full width with potion effect name).
|
||||
- 40.0.6 Introduce system mods to mod loading (#8238)
|
||||
Core game mods are mods which are required to exist in the environment
|
||||
during mod loading. These may be specially provided mods (for example,
|
||||
the `minecraft` mod), or mods which are vital to the framework which
|
||||
FML is connected to (for example, Forge and the `forge` mod).
|
||||
These core game mods are used as the only existing mods in the mod list
|
||||
if mod sorting or dependency verification fails. This allows later
|
||||
steps in the which use resources from these mod files to work correctly
|
||||
(up to when the error screen is shown and the game exits).
|
||||
- 40.0.5 Add missing module exports arg to server arguments list (#8500)
|
||||
- 40.0.4 Fixed swim speed attribute (#8499)
|
||||
- 40.0.3 Fix incorrect movement distance calculation (#8497)
|
||||
- 40.0.2 Add support to Forge registry wrappers for new Holder system. Closes #8491
|
||||
Fix TagBasedToolTypesTest not generating needed data correctly.
|
||||
- 40.0.1 Fix JNA not working at runtime and causing issues with natives.
|
||||
- 40.0.0 Update to 1.18.2
|
||||
Co-authored-by: sciwhiz12 <arnoldnunag12@gmail.com>
|
||||
Co-authored-by: Marc Hermans <marc.hermans@ldtteam.com>
|
||||
Co-authored-by: LexManos <LexManos@gmail.com>
|
||||
Co-authored-by: Curle <curle@gemwire.uk>
|
||||
|
||||
39.1
|
||||
====
|
||||
- 39.1.2 1.18.x Omnibus (#8239)
|
||||
- 39.1.1 Bump modlauncher and securejarhandler version (#8489)
|
||||
- 39.1.0 Update license headers to compact SPDX format.
|
||||
License has not changed, this is just more compact and doesn't include years.
|
||||
Bump version for RB.
|
||||
|
||||
39.0
|
||||
====
|
||||
- 39.0.91 Remove - from allowed characters in mod ids.
|
||||
The Java Module System does not allow them in module ids.
|
||||
Closes #8488
|
||||
- 39.0.90 Fix static initializer crash when loading BakedRenderable.
|
||||
- 39.0.89 Fix regressions for onAddedTo/RemovedFromWorld and related events (#8434)
|
||||
- 39.0.88 [1.18] Integrate the gametest framework with Forge (#8225)
|
||||
- 39.0.87 Re-add missing Shulker patch for EntityTeleportEvent (#8481)
|
||||
- 39.0.86 Fix entity type in conversion event to Drowned (#8479)
|
||||
- 39.0.85 Add VanillaGameEvent to allow for globally listening to vanilla's GameEvents (#8472)
|
||||
- 39.0.84 Provide damage source context to Item#onDestroyed(ItemEntity) (#8473)
|
||||
- 39.0.83 Add missing shear and elytra game events (#8471)
|
||||
- 39.0.82 Fix comment for permission handler config setting (#8466)
|
||||
- 39.0.81 Apply nullable annotations to LootingLevelEvent (#8422)
|
||||
- 39.0.80 Fix Mob Spawner logic with CustomSpawnRules. Closes #8398
|
||||
- 39.0.79 Fix LivingDropsEvent not having all drops for foxes (#8387)
|
||||
- 39.0.78 Add missing Locale parameter to String.format calls, Fixes getArmorResource functionality on some locaales. (#8463)
|
||||
- 39.0.77 Allow items to hide parts of their tooltips by default (#8358)
|
||||
- 39.0.76 Prevent 1.x Branches being treated as Pull Requests. (#8443)
|
||||
- 39.0.75 Fix RegistryObject not working if created after registry events (#8383)
|
||||
- 39.0.74 Add support for tagging StructureFeatures (#8408)
|
||||
- 39.0.73 Re-added the patch for LivingExperienceDropEvent and enable it for dragons (#8388)
|
||||
- 39.0.72 Implement getPickupSound on ForgeFlowingFluid (#8374)
|
||||
- 39.0.71 Add getCodec method in ForgeRegistry (#8333)
|
||||
- 39.0.70 Fix #8298 (MobBucketItem) and add test mod (#8313)
|
||||
- 39.0.69 Deprecate IForgeAbstractMinecart::getCartItem (#8283)
|
||||
- 39.0.68 Fix HoeItem patch incorrectly applied during migration. (#8384)
|
||||
- 39.0.67 Fix issues with client only commands in combination with server only commands not using MC's command system. (#8452)
|
||||
- 39.0.66 Fix FoliagePlacerType and TreeDecoratorType registry (#8394)
|
||||
- 39.0.65 Fix PlayerChangeGameModeEvent (#8441)
|
||||
- 39.0.64 Fix comparison of custom ParticleRenderTypes leading to broken particle effects. (#8385)
|
||||
- 39.0.63 Fix cases where null is potentially sent to Screen events. Closes #8432
|
||||
- 39.0.62 Ensure ScreenEvent doesn't accept null screens (#8296)
|
||||
- 39.0.61 Update cobblestone tags (#8292)
|
||||
- 39.0.60 Prevent release of custom payload packet buffer on the server side. (#8181)
|
||||
- 39.0.59 Make `MinecraftLocator` respect non-`MOD` FML Mod Types Fixes #8344 (#8346)
|
||||
- 39.0.58 Fix vanilla worlds being marked experimental (#8415)
|
||||
- 39.0.57 Simplify usage of IItemRenderProperties::getArmorModel (#8349)
|
||||
- 39.0.56 Hide mod update notification while screen is still fading in (#8386)
|
||||
- 39.0.55 Revert "Hooks to allow registering and managing custom DFU schemes and types. (#8242)"
|
||||
- 39.0.54 Provide NPE protection against out of order init of the TYPES and REF (#8410)
|
||||
- 39.0.53 Add ShieldBlockEvent (#8261)
|
||||
- 39.0.52 Add renderable API to allow easier rendering of OBJ and other custom models, from Entity and BlockEntity renderers. (#8259)
|
||||
This is a redesign of a discarded section of my initial model system rewrite, back in 1.14.
|
||||
In order to use it with the OBJ loader, you can use OBJLoader.INSTANCE.loadModel to get the OBJModel, and then call OBJModel#bakeRenderable() to get a SimpleRenderable object to render with.
|
||||
The SimpleRenderable support animation, by providing different transformation matrices for each part in the MultipartTransforms.
|
||||
Additionally, a BakedRenderable helper exists to turn an arbitrary BakedModel into a renderable.
|
||||
After trying to get the B3D loader to work, I decided it wasn't worth the trouble and marked it for removal instead.
|
||||
- 39.0.51 Merge values of defaulted optional tags, Fixes issue where multiple mods declare the same optional tag. (#8250)
|
||||
- 39.0.50 Added new 1.18 biomes to the BiomeDictionary (#8246)
|
||||
- 39.0.49 Hooks to allow registering and managing custom DFU schemes and types. (#8242)
|
||||
- 39.0.48 Ping data compression (#8169)
|
||||
- 39.0.47 Expand the LevelStem codec to allow dimension jsons to specify that the dimension's chunk generator should use the overworld/server's seed (#7955)
|
||||
- 39.0.46 Add Client Commands (#7754)
|
||||
- 39.0.45 Remove references to the now-broken `BlockEntity#save(CompoundTag)` method (#8235)
|
||||
- 39.0.44 update McModLauncher libraries to newer versions...
|
||||
- 39.0.43 add extra keystore properties
|
||||
- 39.0.42 TeamCity change in 'MinecraftForge / MinecraftForge' project: project parameters were changed
|
||||
- 39.0.41 TeamCity change in 'MinecraftForge / MinecraftForge' project: project parameters were changed
|
||||
- 39.0.40 TeamCity change in 'MinecraftForge / MinecraftForge' project: project parameters were changed
|
||||
- 39.0.39 TeamCity change in 'MinecraftForge / MinecraftForge' project: project parameters were changed
|
||||
- 39.0.38 TeamCity change in 'MinecraftForge / MinecraftForge' project: project parameters were changed
|
||||
- 39.0.37 TeamCity change in 'MinecraftForge / MinecraftForge' project: project parameters were changed
|
||||
- 39.0.36 fix crowdin key
|
||||
- 39.0.35 TeamCity change in 'MinecraftForge / MinecraftForge' project: project parameters were changed
|
||||
- 39.0.34 TeamCity change in 'MinecraftForge / MinecraftForge' project: project parameters were changed
|
||||
- 39.0.33 TeamCity change in 'MinecraftForge / MinecraftForge' project: project parameters were changed
|
||||
- 39.0.32 fix secondary branches builds
|
||||
- 39.0.31 TeamCity change in 'MinecraftForge / MinecraftForge' project: parameters of 'Build - Secondary Branches' build configuration were updated
|
||||
- 39.0.30 TeamCity change in 'MinecraftForge / MinecraftForge' project: VCS roots of 'Build - Secondary Branches' build configuration were updated
|
||||
- 39.0.29 TeamCity change in 'MinecraftForge / MinecraftForge' project: VCS roots of 'Build - Secondary Branches' build configuration were updated
|
||||
- 39.0.28 TeamCity change in 'MinecraftForge / MinecraftForge' project: VCS roots of 'Build - Secondary Branches' build configuration were updated
|
||||
- 39.0.27 TeamCity change in 'MinecraftForge / MinecraftForge' project: parameters of 'Build - Secondary Branches' build configuration were updated
|
||||
- 39.0.26 TeamCity change in 'MinecraftForge / MinecraftForge' project: parameters of 'Build - Secondary Branches' build configuration were updated
|
||||
- 39.0.25 TeamCity change in 'MinecraftForge / MinecraftForge' project: VCS roots of 'Build - Secondary Branches' build configuration were updated
|
||||
- 39.0.24 Remove primary branches from building on secondary branch configuration and publish crowdin data. (#8397)
|
||||
* Remove the normalized branch names also from the filter.
|
||||
* Add the additional publishing arguments to get the crowdin information.
|
||||
* TeamCity change in 'MinecraftForge / MinecraftForge' project: project parameters were changed
|
||||
* Fix the configuration.
|
||||
* Remove the required patch and use the base script.
|
||||
* Make a note about the reference.
|
||||
Co-authored-by: cpw <cpw@weeksfamily.ca>
|
||||
- 39.0.23 TeamCity change in 'MinecraftForge / MinecraftForge' project: project parameters were changed
|
||||
- 39.0.22 Correct the build configuration to support a setup. (#8395)
|
||||
* Add a setup task and publish the correct versions.
|
||||
* Reconfigure build task and disable the normal build and test cycle on everything but pull requests, run an assemble there.
|
||||
* Fix the derp in the build configuration.
|
||||
- 39.0.21 Enable the TeamCity CI pipeline (#8368)
|
||||
* Setup the build.gradle
|
||||
* Setup the teamcity toolchain.
|
||||
* Revert the usage of the local build of GU.
|
||||
* Automatically add it now, it will always exist and is added to maven automatically by GU.
|
||||
* Implement the branch filter and move the constant for the minimal changelog tag to a constant in the extension.
|
||||
* Adding the JDK and Gradle version to the build script.
|
||||
- 39.0.20 Fix and improve Ingredient invalidation (#8361)
|
||||
- 39.0.19 Rework world persistence hooks to fix the double registry injection when loading single player worlds. (#8234)
|
||||
- 39.0.18 Update tags for new 1.17 and 1.18 content (#7891)
|
||||
- 39.0.17 Fix TerrainParticle rendering black under certain conditions (#8378)
|
||||
- 39.0.16 Allow modded tools to work on glow lichen (#8371)
|
||||
- 39.0.15 Fix custom climbable blocks not sending a death message (#8372)
|
||||
Fixes #8370
|
||||
- 39.0.14 Provide access to the blockstate in BucketPickup#getPickupSound for multiply-logged blocks (#8357)
|
||||
- 39.0.13 Fix clients being unable to deserialize tags for custom registries (#8352)
|
||||
- 39.0.12 Fix particles going fullbright for a few frames when first spawning (#8291)
|
||||
- 39.0.11 Also create parent directories when creating config files (#8364)
|
||||
- 39.0.10 Fix crash with PermissionsAPI (#8330)
|
||||
Fixes a crash in singleplayer, when the internal server didn't shut down correctly between world loads.
|
||||
- 39.0.9 Re-add missing default spawn lists in features (#8285)
|
||||
Fixes #8265
|
||||
Fixes #8301
|
||||
- 39.0.8 Fixed incorrect generic in PermissionAPI (#8317)
|
||||
- 39.0.7 Redo of the whole PermissionAPI (#7780)
|
||||
Co-authored-by: LexManos <LexManos@gmail.com>
|
||||
- 39.0.6 Fix misplaced patch in SpreadingSnowyDirtBlock.
|
||||
Fixes #8308.
|
||||
- 39.0.5 Add RenderArmEvent to make overriding just the arm rendering not require copying nearly as much vanilla code (#8254)
|
||||
- 39.0.4 Add MobEffect tags (#8231)
|
||||
- 39.0.3 Log missing or unsupported dependencies (#8218)
|
||||
- 39.0.2 Fix datagen test for sounds definitions provider (#8249)
|
||||
- 39.0.1 Fix wrong stage being declared in transition to common (#8267)
|
||||
- 39.0.0 Update to 1.18.1
|
||||
Co-Authored by:
|
||||
- Curle
|
||||
_ Orion
|
||||
|
||||
48
gradle.properties
Normal file
@@ -0,0 +1,48 @@
|
||||
# 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
|
||||
|
||||
mod_version=0.0.1
|
||||
modid=trading_station
|
||||
author=oierbravo
|
||||
display_name=Trading Station
|
||||
|
||||
forgegradle_version = 5.1.74
|
||||
mixingradle_version = 0.7-SNAPSHOT
|
||||
|
||||
librarian_version = 1.+
|
||||
cursegradle_version = 1.4.0
|
||||
|
||||
# Versions
|
||||
minecraft_version = 1.19.2
|
||||
forge_version = 43.2.4
|
||||
|
||||
use_parchment=true
|
||||
mappings_channel=parchment
|
||||
parchment_version = 2022.11.27
|
||||
|
||||
|
||||
registrate_version = MC1.19-1.1.5
|
||||
|
||||
jei_minecraft_version = 1.19.2
|
||||
jei_version = 11.4.0.290
|
||||
|
||||
create_enabled = false;
|
||||
create_minecraft_version = 1.19.2
|
||||
flywheel_minecraft_version = 1.19.2
|
||||
create_version = 0.5.1.c-36
|
||||
flywheel_version = 0.6.9-18
|
||||
|
||||
kubejs_enabled = true
|
||||
architectury_version=6.5.85
|
||||
rhino_version=1902.2.2-build.269
|
||||
kubejs_version=1902.6.1-build.348
|
||||
|
||||
|
||||
jade_id = 3960379
|
||||
|
||||
ct_enabled = false
|
||||
ct_minecraft_version = 1.19.2
|
||||
ct_version = 10.1.40
|
||||
ct_annotation_processor_version = 3.0.0.10
|
||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
5
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
234
gradlew
vendored
Executable file
@@ -0,0 +1,234 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Gradle start up script for POSIX generated by Gradle.
|
||||
#
|
||||
# Important for running:
|
||||
#
|
||||
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||
# noncompliant, but you have some other compliant shell such as ksh or
|
||||
# bash, then to run this script, type that shell name before the whole
|
||||
# command line, like:
|
||||
#
|
||||
# ksh Gradle
|
||||
#
|
||||
# Busybox and similar reduced shells will NOT work, because this script
|
||||
# requires all of these POSIX shell features:
|
||||
# * functions;
|
||||
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||
# * compound commands having a testable exit status, especially «case»;
|
||||
# * various built-in commands including «command», «set», and «ulimit».
|
||||
#
|
||||
# Important for patching:
|
||||
#
|
||||
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||
#
|
||||
# The "traditional" practice of packing multiple parameters into a
|
||||
# space-separated string is a well documented source of bugs and security
|
||||
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||
# options in "$@", and eventually passing that to Java.
|
||||
#
|
||||
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||
# see the in-line comments for details.
|
||||
#
|
||||
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
|
||||
# Resolve links: $0 may be a link
|
||||
app_path=$0
|
||||
|
||||
# Need this for daisy-chained symlinks.
|
||||
while
|
||||
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||
[ -h "$app_path" ]
|
||||
do
|
||||
ls=$( ls -ld "$app_path" )
|
||||
link=${ls#*' -> '}
|
||||
case $link in #(
|
||||
/*) app_path=$link ;; #(
|
||||
*) app_path=$APP_HOME$link ;;
|
||||
esac
|
||||
done
|
||||
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=${0##*/}
|
||||
|
||||
# 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"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD=maximum
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
} >&2
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
} >&2
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "$( uname )" in #(
|
||||
CYGWIN* ) cygwin=true ;; #(
|
||||
Darwin* ) darwin=true ;; #(
|
||||
MSYS* | MINGW* ) msys=true ;; #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||
else
|
||||
JAVACMD=$JAVA_HOME/bin/java
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
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.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
case $MAX_FD in #(
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command, stacking in reverse order:
|
||||
# * args from the command line
|
||||
# * the main class name
|
||||
# * -classpath
|
||||
# * -D...appname settings
|
||||
# * --module-path (only if needed)
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if "$cygwin" || "$msys" ; then
|
||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||
|
||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
for arg do
|
||||
if
|
||||
case $arg in #(
|
||||
-*) false ;; # don't mess with options #(
|
||||
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||
[ -e "$t" ] ;; #(
|
||||
*) false ;;
|
||||
esac
|
||||
then
|
||||
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||
fi
|
||||
# Roll the args list around exactly as many times as the number of
|
||||
# args, so each arg winds up back in the position where it started, but
|
||||
# possibly modified.
|
||||
#
|
||||
# NB: a `for` loop captures its iteration list before it begins, so
|
||||
# changing the positional parameters here affects neither the number of
|
||||
# iterations, nor the values presented in `arg`.
|
||||
shift # remove old arg
|
||||
set -- "$@" "$arg" # push replacement arg
|
||||
done
|
||||
fi
|
||||
|
||||
# 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.
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
"$@"
|
||||
|
||||
# Use "xargs" to parse quoted args.
|
||||
#
|
||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||
#
|
||||
# In Bash we could simply go:
|
||||
#
|
||||
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||
# set -- "${ARGS[@]}" "$@"
|
||||
#
|
||||
# but POSIX shell has neither arrays nor command substitution, so instead we
|
||||
# post-process each arg (as a line of input to sed) to backslash-escape any
|
||||
# character that might be a shell metacharacter, then use eval to reverse
|
||||
# that process (while maintaining the separation between arguments), and wrap
|
||||
# the whole thing up as a single "set" statement.
|
||||
#
|
||||
# This will of course break if any of these variables contains a newline or
|
||||
# an unmatched quote.
|
||||
#
|
||||
|
||||
eval "set -- $(
|
||||
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||
xargs -n1 |
|
||||
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
||||
tr '\n' ' '
|
||||
)" '"$@"'
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
89
gradlew.bat
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "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.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
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.
|
||||
|
||||
goto fail
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
@@ -0,0 +1,9 @@
|
||||
// 1.19.2 2023-08-15T19:12:23.552338231 Registrate Provider for trading_station [Recipes, Advancements, Loot tables, Tags (blocks), Tags (items), Tags (fluids), Tags (entity_types), Blockstates, Item models, Lang (en_us/en_ud)]
|
||||
ac427e21e7a0915809800ce83800780c045678c6 assets/trading_station/blockstates/powered_trading_station.json
|
||||
391b0f87f6c9bd80e20dfc8b949e7dd99cd16fe9 assets/trading_station/blockstates/trading_station.json
|
||||
59d487ef1d18c0234dbb7c4b7a99eb0a8bf30520 assets/trading_station/lang/en_ud.json
|
||||
fcd793fe1e0ddcc1d5cc535bda29fe37fee4c1a2 assets/trading_station/lang/en_us.json
|
||||
373be6ce42eee460888161c967f098e5943e3778 assets/trading_station/models/item/powered_trading_station.json
|
||||
7ddda578b6d6072db924599a9959579470354897 assets/trading_station/models/item/trading_station.json
|
||||
c3b4c04c1cecdc5001fcddda7b30b11b15f0b2b2 data/trading_station/loot_tables/blocks/powered_trading_station.json
|
||||
4c82f05fb35c8b26972d5fd3abf4bb5da6cba466 data/trading_station/loot_tables/blocks/trading_station.json
|
||||
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"variants": {
|
||||
"facing=east,powered=false": {
|
||||
"model": "trading_station:block/powered_trading_station",
|
||||
"y": 90
|
||||
},
|
||||
"facing=east,powered=true": {
|
||||
"model": "trading_station:block/powered_trading_station_powered",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,powered=false": {
|
||||
"model": "trading_station:block/powered_trading_station"
|
||||
},
|
||||
"facing=north,powered=true": {
|
||||
"model": "trading_station:block/powered_trading_station_powered"
|
||||
},
|
||||
"facing=south,powered=false": {
|
||||
"model": "trading_station:block/powered_trading_station",
|
||||
"y": 180
|
||||
},
|
||||
"facing=south,powered=true": {
|
||||
"model": "trading_station:block/powered_trading_station_powered",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,powered=false": {
|
||||
"model": "trading_station:block/powered_trading_station",
|
||||
"y": 270
|
||||
},
|
||||
"facing=west,powered=true": {
|
||||
"model": "trading_station:block/powered_trading_station_powered",
|
||||
"y": 270
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"variants": {
|
||||
"facing=east,powered=false": {
|
||||
"model": "trading_station:block/trading_station",
|
||||
"y": 90
|
||||
},
|
||||
"facing=east,powered=true": {
|
||||
"model": "trading_station:block/trading_station_powered",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,powered=false": {
|
||||
"model": "trading_station:block/trading_station"
|
||||
},
|
||||
"facing=north,powered=true": {
|
||||
"model": "trading_station:block/trading_station_powered"
|
||||
},
|
||||
"facing=south,powered=false": {
|
||||
"model": "trading_station:block/trading_station",
|
||||
"y": 180
|
||||
},
|
||||
"facing=south,powered=true": {
|
||||
"model": "trading_station:block/trading_station_powered",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,powered=false": {
|
||||
"model": "trading_station:block/trading_station",
|
||||
"y": 270
|
||||
},
|
||||
"facing=west,powered=true": {
|
||||
"model": "trading_station:block/trading_station_powered",
|
||||
"y": 270
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"block.trading_station.powered_trading_station": "uoıʇɐʇS buıpɐɹ⟘ pǝɹǝʍoԀ",
|
||||
"block.trading_station.trading_station": "uoıʇɐʇS buıpɐɹ⟘",
|
||||
"config.jade.plugin_trading_station.trading_station_data": "ɐʇɐp uoıʇɐʇS buıpɐɹ⟘",
|
||||
"itemGroup.trading_station:main": "uoıʇɐʇS buıpɐɹ⟘",
|
||||
"trading_station.block.display": "uoıʇɐʇS buıpɐɹ⟘",
|
||||
"trading_station.recipe": "ǝdıɔǝɹ buıpɐɹ⟘",
|
||||
"trading_station.select_target.button": "ʇǝbɹɐʇ ʇɔǝןǝS",
|
||||
"trading_station.select_target.clear": "ɹɐǝןƆ",
|
||||
"trading_station.select_target.title": "ʇǝbɹɐʇ ʇndʇno uɐ ʇɔǝןǝS",
|
||||
"trading_station.tooltip.progress": "%d%% :ssǝɹboɹԀ"
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"block.trading_station.powered_trading_station": "Powered Trading Station",
|
||||
"block.trading_station.trading_station": "Trading Station",
|
||||
"config.jade.plugin_trading_station.trading_station_data": "Trading Station data",
|
||||
"itemGroup.trading_station:main": "Trading Station",
|
||||
"trading_station.block.display": "Trading Station",
|
||||
"trading_station.recipe": "Trading recipe",
|
||||
"trading_station.select_target.button": "Select target",
|
||||
"trading_station.select_target.clear": "Clear",
|
||||
"trading_station.select_target.title": "Select an output target",
|
||||
"trading_station.tooltip.progress": "Progress: %d%%"
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"parent": "trading_station:block/powered_trading_station"
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"parent": "trading_station:block/trading_station"
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"type": "minecraft:block",
|
||||
"pools": [
|
||||
{
|
||||
"bonus_rolls": 0.0,
|
||||
"conditions": [
|
||||
{
|
||||
"condition": "minecraft:survives_explosion"
|
||||
}
|
||||
],
|
||||
"entries": [
|
||||
{
|
||||
"type": "minecraft:item",
|
||||
"name": "trading_station:powered_trading_station"
|
||||
}
|
||||
],
|
||||
"rolls": 1.0
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"type": "minecraft:block",
|
||||
"pools": [
|
||||
{
|
||||
"bonus_rolls": 0.0,
|
||||
"conditions": [
|
||||
{
|
||||
"condition": "minecraft:survives_explosion"
|
||||
}
|
||||
],
|
||||
"entries": [
|
||||
{
|
||||
"type": "minecraft:item",
|
||||
"name": "trading_station:trading_station"
|
||||
}
|
||||
],
|
||||
"rolls": 1.0
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package com.oierbravo.trading_station;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.oierbravo.trading_station.foundation.util.ModLang;
|
||||
import com.oierbravo.trading_station.registrate.*;
|
||||
import com.tterrag.registrate.Registrate;
|
||||
import net.minecraftforge.common.util.Lazy;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.CreativeModeTab;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.eventbus.api.IEventBus;
|
||||
import net.minecraftforge.fml.ModList;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
// The value here should match an entry in the META-INF/mods.toml file
|
||||
@Mod("trading_station")
|
||||
public class TradingStation
|
||||
{
|
||||
// Directly reference a slf4j logger
|
||||
public static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
public static final String MODID = "trading_station";
|
||||
public static final String DISPLAY_NAME = "Trading Station";
|
||||
|
||||
public static IEventBus modEventBus;
|
||||
|
||||
private static final Lazy<Registrate> REGISTRATE = Lazy.of(() -> Registrate.create(MODID));
|
||||
|
||||
public static final boolean withCreate = ModList.get().isLoaded("create");
|
||||
|
||||
|
||||
public static final Gson GSON = new GsonBuilder().setPrettyPrinting()
|
||||
.disableHtmlEscaping()
|
||||
.create();
|
||||
public TradingStation()
|
||||
{
|
||||
modEventBus = FMLJavaModLoadingContext.get().getModEventBus();
|
||||
// Register ourselves for server and other game events we are interested in
|
||||
MinecraftForge.EVENT_BUS.register(this);
|
||||
|
||||
ModCreativeTab modTab = new ModCreativeTab();
|
||||
|
||||
ModBlocks.register();
|
||||
ModBlockEntities.register();
|
||||
ModRecipes.register(modEventBus);
|
||||
ModMessages.register();
|
||||
ModMenus.register();
|
||||
Config.register();
|
||||
|
||||
registrate().addRawLang("itemGroup.trading_station:main", "Trading Station");
|
||||
registrate().addRawLang(ModLang.key("block.display"), "Trading Station");
|
||||
registrate().addRawLang(ModLang.key("recipe"), "Trading recipe");
|
||||
registrate().addRawLang(ModLang.key("tooltip.progress"), "Progress: %d%%");
|
||||
registrate().addRawLang(ModLang.key("select_target.title"), "Select an output target");
|
||||
registrate().addRawLang(ModLang.key("select_target.button"), "Select target");
|
||||
registrate().addRawLang(ModLang.key("select_target.clear"), "Clear");
|
||||
registrate().addRawLang("config.jade.plugin_trading_station.trading_station_data", "Trading Station data");
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static Registrate registrate() {
|
||||
return REGISTRATE.get();
|
||||
}
|
||||
|
||||
|
||||
public static ResourceLocation asResource(String path) {
|
||||
return new ResourceLocation(MODID, path);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.oierbravo.trading_station.compat.crafttweaker;
|
||||
|
||||
import com.blamejared.crafttweaker.api.recipe.component.IDecomposedRecipe;
|
||||
import com.blamejared.crafttweaker.api.recipe.handler.IRecipeHandler;
|
||||
import com.blamejared.crafttweaker.api.recipe.manager.base.IRecipeManager;
|
||||
import com.oierbravo.trading_station.content.trading_station.TradingRecipe;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.crafting.Recipe;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@IRecipeHandler.For(TradingRecipe.class)
|
||||
public class TradingRecipeHandler implements IRecipeHandler<TradingRecipe>{
|
||||
|
||||
@Override
|
||||
public String dumpToCommandString(IRecipeManager<? super TradingRecipe> manager, TradingRecipe recipe) {
|
||||
return manager.getCommandString() + recipe.toString() + recipe.getOutput() + "[" + recipe.getIngredient() + "]";
|
||||
}
|
||||
@Override
|
||||
public <U extends Recipe<?>> boolean doesConflict(IRecipeManager<? super TradingRecipe> manager, TradingRecipe firstRecipe, U secondRecipe) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<IDecomposedRecipe> decompose(IRecipeManager<? super TradingRecipe> manager, TradingRecipe recipe) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<TradingRecipe> recompose(IRecipeManager<? super TradingRecipe> manager, ResourceLocation name, IDecomposedRecipe recipe) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.oierbravo.trading_station.compat.crafttweaker;
|
||||
|
||||
|
||||
import com.blamejared.crafttweaker.api.CraftTweakerAPI;
|
||||
import com.blamejared.crafttweaker.api.action.recipe.ActionAddRecipe;
|
||||
import com.blamejared.crafttweaker.api.annotation.ZenRegister;
|
||||
import com.blamejared.crafttweaker.api.fluid.IFluidStack;
|
||||
import com.blamejared.crafttweaker.api.ingredient.IIngredient;
|
||||
import com.blamejared.crafttweaker.api.recipe.manager.base.IRecipeManager;
|
||||
import com.oierbravo.trading_station.TradingStation;
|
||||
import com.oierbravo.trading_station.content.trading_station.TradingRecipe;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.crafting.RecipeType;
|
||||
import org.openzen.zencode.java.ZenCodeType;
|
||||
|
||||
@ZenRegister
|
||||
@ZenCodeType.Name("mods.trading_station.TradingManager")
|
||||
//@Document("mods/trading_station/melting")
|
||||
public class TradingRecipeManager implements IRecipeManager<TradingRecipe> {
|
||||
/**
|
||||
* Adds a Trading recipe.
|
||||
*
|
||||
* @param name The name of the recipe
|
||||
* @param output The output fluidStack of the recipe.
|
||||
* @param input The input of the recipe.
|
||||
* @param processingTime The duration of the recipe (default 100 ticks)
|
||||
* @param heatLevel Minimum heat level
|
||||
*
|
||||
* @docParam name "meltDown"
|
||||
* @docParam output <fluid:minecraft:lava> * 100
|
||||
* @docParam input <item:minecraft:dirt>
|
||||
* @docParam duration 200
|
||||
* @docParam heatLevel 2
|
||||
*/
|
||||
@ZenCodeType.Method
|
||||
public void addRecipe(String name, IFluidStack output, IIngredient input, int processingTime, int heatLevel ){
|
||||
name = fixRecipeName(name);
|
||||
ResourceLocation resourceLocation = new ResourceLocation(TradingStation.MODID, name);
|
||||
CraftTweakerAPI.apply(new ActionAddRecipe<>( this, new TradingRecipe(resourceLocation, output.getInternal(), input.asVanillaIngredient(), processingTime, heatLevel)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecipeType<TradingRecipe> getRecipeType() {
|
||||
return TradingRecipe.Type.INSTANCE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.oierbravo.trading_station.compat.jade;
|
||||
|
||||
import com.oierbravo.trading_station.content.trading_station.TradingStationBlockEntity;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import snownee.jade.api.BlockAccessor;
|
||||
import snownee.jade.api.IBlockComponentProvider;
|
||||
import snownee.jade.api.IServerDataProvider;
|
||||
import snownee.jade.api.ITooltip;
|
||||
import snownee.jade.api.config.IPluginConfig;
|
||||
import snownee.jade.api.ui.IElementHelper;
|
||||
import snownee.jade.api.ui.IProgressStyle;
|
||||
|
||||
public class ProgressComponentProvider implements IBlockComponentProvider, IServerDataProvider<BlockEntity> {
|
||||
|
||||
@Override
|
||||
public void appendTooltip(ITooltip tooltip, BlockAccessor accessor, IPluginConfig config) {
|
||||
//CompoundTag serverData = accessor.getServerData();
|
||||
if (accessor.getServerData().contains("trading_station.progress")) {
|
||||
int progress = accessor.getServerData().getInt("trading_station.progress");
|
||||
IElementHelper elementHelper = tooltip.getElementHelper();
|
||||
IProgressStyle progressStyle = elementHelper.progressStyle();
|
||||
if(progress > 0)
|
||||
tooltip.add(elementHelper.progress((float)progress / 100, Component.translatable("trading_station.tooltip.progress", progress), progressStyle,elementHelper.borderStyle()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendServerData(CompoundTag compoundTag, ServerPlayer serverPlayer, Level level, BlockEntity blockEntity, boolean b) {
|
||||
if(blockEntity instanceof TradingStationBlockEntity){
|
||||
TradingStationBlockEntity trading_station = (TradingStationBlockEntity) blockEntity;
|
||||
compoundTag.putInt("trading_station.progress",trading_station.getProgressPercent());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getUid() {
|
||||
return TradingStationPlugin.TRADING_STATION_DATA;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.oierbravo.trading_station.compat.jade;
|
||||
|
||||
import com.oierbravo.trading_station.TradingStation;
|
||||
import com.oierbravo.trading_station.content.trading_station.TradingStationBlock;
|
||||
import com.oierbravo.trading_station.content.trading_station.TradingStationBlockEntity;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import snownee.jade.api.*;
|
||||
|
||||
@WailaPlugin
|
||||
public class TradingStationPlugin implements IWailaPlugin {
|
||||
public static final ResourceLocation TRADING_STATION_DATA = TradingStation.asResource("trading_station_data");
|
||||
|
||||
@Override
|
||||
public void register(IWailaCommonRegistration registration) {
|
||||
registration.registerBlockDataProvider(new ProgressComponentProvider(), TradingStationBlockEntity.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerClient(IWailaClientRegistration registration) {
|
||||
registration.registerBlockComponent(new ProgressComponentProvider(), TradingStationBlock.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.oierbravo.trading_station.compat.jei;
|
||||
|
||||
import com.oierbravo.trading_station.TradingStation;
|
||||
import com.oierbravo.trading_station.content.trading_station.TradingRecipe;
|
||||
import com.oierbravo.trading_station.content.trading_station.TradingStationScreen;
|
||||
import com.oierbravo.trading_station.registrate.ModBlocks;
|
||||
import mezz.jei.api.IModPlugin;
|
||||
import mezz.jei.api.JeiPlugin;
|
||||
import mezz.jei.api.recipe.RecipeType;
|
||||
import mezz.jei.api.registration.IGuiHandlerRegistration;
|
||||
import mezz.jei.api.registration.IRecipeCatalystRegistration;
|
||||
import mezz.jei.api.registration.IRecipeCategoryRegistration;
|
||||
import mezz.jei.api.registration.IRecipeRegistration;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.crafting.RecipeManager;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@JeiPlugin
|
||||
public class JEIPlugin implements IModPlugin {
|
||||
|
||||
@Override
|
||||
public ResourceLocation getPluginUid() {
|
||||
return new ResourceLocation(TradingStation.MODID, "jei_plugin");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerCategories(IRecipeCategoryRegistration registration) {
|
||||
registration.addRecipeCategories(new
|
||||
TradingRecipeCategory(registration.getJeiHelpers().getGuiHelper()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerRecipeCatalysts(IRecipeCatalystRegistration registration) {
|
||||
registration.addRecipeCatalyst(new ItemStack(ModBlocks.TRADING_STATION.get()),new RecipeType<>(TradingRecipeCategory.UID, TradingRecipe.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerRecipes(IRecipeRegistration registration) {
|
||||
RecipeManager rm = Objects.requireNonNull(Minecraft.getInstance().level).getRecipeManager();
|
||||
|
||||
List<TradingRecipe> tradingRecipes = rm.getAllRecipesFor(TradingRecipe.Type.INSTANCE);
|
||||
registration.addRecipes(new RecipeType<>(TradingRecipeCategory.UID, TradingRecipe.class), tradingRecipes);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
package com.oierbravo.trading_station.compat.jei;
|
||||
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.oierbravo.trading_station.TradingStation;
|
||||
import com.oierbravo.trading_station.content.trading_station.TradingRecipe;
|
||||
import com.oierbravo.trading_station.foundation.util.ModLang;
|
||||
import com.oierbravo.trading_station.registrate.ModBlocks;
|
||||
import mezz.jei.api.constants.VanillaTypes;
|
||||
import mezz.jei.api.gui.builder.IRecipeLayoutBuilder;
|
||||
import mezz.jei.api.gui.drawable.IDrawable;
|
||||
import mezz.jei.api.gui.drawable.IDrawableAnimated;
|
||||
import mezz.jei.api.gui.ingredient.IRecipeSlotsView;
|
||||
import mezz.jei.api.helpers.IGuiHelper;
|
||||
import mezz.jei.api.recipe.IFocusGroup;
|
||||
import mezz.jei.api.recipe.RecipeIngredientRole;
|
||||
import mezz.jei.api.recipe.RecipeType;
|
||||
import mezz.jei.api.recipe.category.IRecipeCategory;
|
||||
import mezz.jei.common.Constants;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.core.NonNullList;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.crafting.Ingredient;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class TradingRecipeCategory implements IRecipeCategory<TradingRecipe> {
|
||||
public final static ResourceLocation UID = new ResourceLocation(TradingStation.MODID, "trading");
|
||||
private final LoadingCache<Integer, IDrawableAnimated> cachedArrows;
|
||||
|
||||
private final IDrawable background;
|
||||
private final IDrawable icon;
|
||||
|
||||
public TradingRecipeCategory(IGuiHelper helper) {
|
||||
this.cachedArrows = CacheBuilder.newBuilder()
|
||||
.maximumSize(25)
|
||||
.build(new CacheLoader<>() {
|
||||
@Override
|
||||
public IDrawableAnimated load(Integer cookTime) {
|
||||
return helper.drawableBuilder(Constants.RECIPE_GUI_VANILLA, 82, 128, 24, 17)
|
||||
.buildAnimated(cookTime, IDrawableAnimated.StartDirection.LEFT, false);
|
||||
}
|
||||
});
|
||||
this.background = new IDrawable() {
|
||||
@Override
|
||||
public int getWidth() {
|
||||
return 176;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
return 45;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(PoseStack poseStack, int xOffset, int yOffset) {
|
||||
|
||||
}
|
||||
};
|
||||
this.icon = helper.createDrawableIngredient(VanillaTypes.ITEM_STACK, new ItemStack(ModBlocks.TRADING_STATION.get()));
|
||||
|
||||
}
|
||||
|
||||
protected IDrawableAnimated getArrow() {
|
||||
return this.cachedArrows.getUnchecked(50);
|
||||
}
|
||||
@Override
|
||||
public RecipeType<TradingRecipe> getRecipeType() {
|
||||
return RecipeType.create("trading_station","trading", TradingRecipe.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getTitle() {
|
||||
return ModLang.translate("trading.recipe");
|
||||
}
|
||||
|
||||
@Override
|
||||
public IDrawable getBackground() {
|
||||
return this.background;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IDrawable getIcon() {
|
||||
return this.icon;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRecipe(@Nonnull IRecipeLayoutBuilder builder, @Nonnull TradingRecipe recipe, @Nonnull IFocusGroup focusGroup) {
|
||||
NonNullList<Ingredient> ingredients = recipe.getIngredients();
|
||||
for(int index = 0; index < ingredients.size(); index++) {
|
||||
Ingredient ing = ingredients.get(index);
|
||||
builder.addSlot(RecipeIngredientRole.INPUT, 41 + index * 18, 11)
|
||||
.addIngredients(ingredients.get(index));
|
||||
//.addItemStacks(Arrays.asList(ingredients.get(0).getItems()));
|
||||
|
||||
}
|
||||
|
||||
builder.addSlot(RecipeIngredientRole.OUTPUT, 113, 11)
|
||||
.addItemStack(recipe.getResultItem());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(TradingRecipe recipe, IRecipeSlotsView recipeSlotsView, PoseStack stack, double mouseX, double mouseY) {
|
||||
IRecipeCategory.super.draw(recipe, recipeSlotsView, stack, mouseX, mouseY);
|
||||
IDrawableAnimated arrow = getArrow();
|
||||
arrow.draw(stack, 75, 14);
|
||||
drawProcessingTime(recipe, stack, 81,4);
|
||||
|
||||
|
||||
}
|
||||
protected void drawProcessingTime(TradingRecipe recipe, PoseStack poseStack, int x, int y) {
|
||||
int processingTime = recipe.getProcessingTime();
|
||||
if (processingTime > 0) {
|
||||
int cookTimeSeconds = processingTime / 20;
|
||||
MutableComponent timeString = Component.translatable("gui.jei.category.smelting.time.seconds", cookTimeSeconds);
|
||||
Minecraft minecraft = Minecraft.getInstance();
|
||||
Font fontRenderer = minecraft.font;
|
||||
fontRenderer.draw(poseStack, timeString, x, y, 0xFF808080);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.oierbravo.trading_station.compat.kubejs;
|
||||
|
||||
import com.oierbravo.trading_station.content.trading_station.TradingRecipe;
|
||||
import dev.latvian.mods.kubejs.recipe.schema.RegisterRecipeSchemasEvent;
|
||||
|
||||
public class KubeJSPlugin extends dev.latvian.mods.kubejs.KubeJSPlugin {
|
||||
@Override
|
||||
public void registerRecipeSchemas(RegisterRecipeSchemasEvent event) {
|
||||
event.register(TradingRecipe.Serializer.ID, TradingRecipeSchema.SCHEMA);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.oierbravo.trading_station.compat.kubejs;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import dev.latvian.mods.kubejs.item.InputItem;
|
||||
import dev.latvian.mods.kubejs.item.OutputItem;
|
||||
import dev.latvian.mods.kubejs.recipe.RecipeJS;
|
||||
import dev.latvian.mods.kubejs.recipe.RecipeKey;
|
||||
import dev.latvian.mods.kubejs.recipe.component.ItemComponents;
|
||||
import dev.latvian.mods.kubejs.recipe.component.NumberComponent;
|
||||
import dev.latvian.mods.kubejs.recipe.schema.RecipeSchema;
|
||||
|
||||
public interface TradingRecipeSchema {
|
||||
RecipeKey<InputItem[]> INGREDIENTS = ItemComponents.INPUT_ARRAY.key("ingredients");
|
||||
RecipeKey<OutputItem> RESULT = ItemComponents.OUTPUT.key("result");
|
||||
RecipeKey<Integer> PROCESSING_TIME = NumberComponent.INT.key("processingTime").optional(1);
|
||||
public class TradingRecipeJS extends RecipeJS{
|
||||
@Override
|
||||
public JsonElement writeInputItem(InputItem value) {
|
||||
JsonObject json = super.writeInputItem(value).getAsJsonObject();
|
||||
if(value.count > 1){
|
||||
json.addProperty("count", value.count);
|
||||
}
|
||||
return (JsonElement) json;
|
||||
}
|
||||
}
|
||||
RecipeSchema SCHEMA = new RecipeSchema(TradingRecipeJS.class, TradingRecipeJS::new, RESULT, INGREDIENTS, PROCESSING_TIME);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,416 @@
|
||||
package com.oierbravo.trading_station.content.trading_station;
|
||||
|
||||
import com.oierbravo.trading_station.foundation.util.ModLang;
|
||||
import com.oierbravo.trading_station.network.packets.ItemStackSyncS2CPacket;
|
||||
import com.oierbravo.trading_station.registrate.ModMessages;
|
||||
import com.oierbravo.trading_station.registrate.ModRecipes;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.NonNullList;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.Connection;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.Containers;
|
||||
import net.minecraft.world.MenuProvider;
|
||||
import net.minecraft.world.SimpleContainer;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.inventory.ContainerData;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.crafting.Ingredient;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.common.capabilities.ForgeCapabilities;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.ItemStackHandler;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Optional;
|
||||
|
||||
public abstract class AbstractTradingStationBlockEntity extends BlockEntity {
|
||||
private CompoundTag updateTag;
|
||||
public final ItemStackHandler inputItems = createInputItemHandler();
|
||||
public final ItemStackHandler outputItems = createOutputItemHandler();
|
||||
|
||||
public final ItemStackHandler targetItemHandler = createTargetItemHandler();
|
||||
private final LazyOptional<IItemHandler> inputItemHandler = LazyOptional.of(() -> inputItems);
|
||||
private final LazyOptional<IItemHandler> outputItemHandler = LazyOptional.of(() -> outputItems);
|
||||
|
||||
public int progress = 0;
|
||||
public int maxProgress = 1;
|
||||
private BlockState lastBlockState;
|
||||
|
||||
protected final ContainerData containerData;
|
||||
private Item preferedItem;
|
||||
|
||||
public AbstractTradingStationBlockEntity(BlockEntityType<?> pType, BlockPos pWorldPosition, BlockState pBlockState) {
|
||||
super(pType, pWorldPosition, pBlockState);
|
||||
updateTag = getPersistentData();
|
||||
lastBlockState = this.getBlockState();
|
||||
preferedItem = ItemStack.EMPTY.getItem();
|
||||
containerData = AbstractTradingStationBlockEntity.createContainerData(this);
|
||||
}
|
||||
public static ContainerData createContainerData(AbstractTradingStationBlockEntity pBlockEntity){
|
||||
return new ContainerData(){
|
||||
@Override
|
||||
public int get(int pIndex){
|
||||
return switch (pIndex) {
|
||||
case 0 -> pBlockEntity.progress;
|
||||
case 1 -> pBlockEntity.maxProgress;
|
||||
default -> 0;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void set(int pIndex, int pValue) {
|
||||
switch (pIndex) {
|
||||
case 0 -> pBlockEntity.progress = pValue;
|
||||
case 1 -> pBlockEntity.maxProgress = pValue;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return 2;
|
||||
}
|
||||
};
|
||||
}
|
||||
@NotNull
|
||||
@Nonnull
|
||||
private ItemStackHandler createTargetItemHandler() {
|
||||
return new ItemStackHandler(1) {
|
||||
@Override
|
||||
protected void onContentsChanged(int slot) {
|
||||
setChanged();
|
||||
if(!level.isClientSide()) {
|
||||
ModMessages.sendToClients(new ItemStackSyncS2CPacket(slot,this.getStackInSlot(0), worldPosition, ItemStackSyncS2CPacket.SlotType.TARGET));
|
||||
}
|
||||
if(!level.isClientSide()) {
|
||||
level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3);
|
||||
}
|
||||
// clientSync();
|
||||
}
|
||||
@Override
|
||||
public boolean isItemValid(int slot, ItemStack stack) {
|
||||
return true;
|
||||
//return canProcess(stack) && super.isItemValid(slot, stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ItemStack extractItem(int slot, int amount, boolean simulate) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private ItemStackHandler createInputItemHandler() {
|
||||
return new ItemStackHandler(2) {
|
||||
@Override
|
||||
protected void onContentsChanged(int slot) {
|
||||
setChanged();
|
||||
if(!level.isClientSide()) {
|
||||
ModMessages.sendToClients(new ItemStackSyncS2CPacket(slot,this.getStackInSlot(0), worldPosition, ItemStackSyncS2CPacket.SlotType.INPUT));
|
||||
}
|
||||
if(!level.isClientSide()) {
|
||||
level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3);
|
||||
}
|
||||
// clientSync();
|
||||
}
|
||||
@Override
|
||||
public boolean isItemValid(int slot, ItemStack stack) {
|
||||
return true;
|
||||
//return canProcess(stack) && super.isItemValid(slot, stack);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Nonnull
|
||||
private ItemStackHandler createOutputItemHandler() {
|
||||
return new ItemStackHandler(1) {
|
||||
@Override
|
||||
protected void onContentsChanged(int slot) {
|
||||
setChanged();
|
||||
if(!level.isClientSide()) {
|
||||
ModMessages.sendToClients(new ItemStackSyncS2CPacket(slot, this.getStackInSlot(slot), worldPosition, ItemStackSyncS2CPacket.SlotType.OUTPUT));
|
||||
}
|
||||
if(!level.isClientSide()) {
|
||||
level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3);
|
||||
}
|
||||
// clientSync();
|
||||
}
|
||||
@Override
|
||||
public boolean isItemValid(int slot, ItemStack stack) {
|
||||
return canProcess(stack) && super.isItemValid(slot, stack);
|
||||
//return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
@Override
|
||||
public <T> LazyOptional<T> getCapability(@NotNull Capability<T> cap, @Nullable Direction side) {
|
||||
if (cap == ForgeCapabilities.ITEM_HANDLER) {
|
||||
return inputItemHandler.cast();
|
||||
}
|
||||
return super.getCapability(cap, side);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRemoved() {
|
||||
super.setRemoved();
|
||||
inputItemHandler.invalidate();
|
||||
outputItemHandler.invalidate();
|
||||
}
|
||||
public LazyOptional<IItemHandler> getInputItemHandler(){
|
||||
return inputItemHandler;
|
||||
}
|
||||
public LazyOptional<IItemHandler> getOutputItemHandler(){
|
||||
return outputItemHandler;
|
||||
}
|
||||
@Override
|
||||
public void onLoad() {
|
||||
super.onLoad();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidateCaps() {
|
||||
super.invalidateCaps();
|
||||
inputItemHandler.invalidate();
|
||||
outputItemHandler.invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveAdditional(@NotNull CompoundTag tag) {
|
||||
super.saveAdditional(tag);
|
||||
tag.put("input", inputItems.serializeNBT());
|
||||
tag.put("output", outputItems.serializeNBT());
|
||||
tag.put("target", targetItemHandler.serializeNBT());
|
||||
tag.putInt("trading_station.progress", progress);
|
||||
tag.putInt("trading_station.maxProgress", maxProgress);
|
||||
String preferedItemString = ForgeRegistries.ITEMS.getKey(preferedItem).toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(CompoundTag tag) {
|
||||
super.load(tag);
|
||||
inputItems.deserializeNBT(tag.getCompound("input"));
|
||||
outputItems.deserializeNBT(tag.getCompound("output"));
|
||||
targetItemHandler.deserializeNBT(tag.getCompound("target"));
|
||||
progress = tag.getInt("trading_station.progress");
|
||||
maxProgress = tag.getInt("trading_station.maxProgress");
|
||||
String preferedItemString = tag.getString("trading_station.preferedItem");
|
||||
preferedItem = ForgeRegistries.ITEMS.getValue( ResourceLocation.tryParse(preferedItemString));
|
||||
}
|
||||
|
||||
public void drops() {
|
||||
SimpleContainer inventory = new SimpleContainer(inputItems.getSlots() + 1);
|
||||
for (int i = 0; i < inputItems.getSlots(); i++) {
|
||||
inventory.setItem(i, inputItems.getStackInSlot(i));
|
||||
}
|
||||
inventory.setItem(inputItems.getSlots(), inputItems.getStackInSlot(0));
|
||||
|
||||
Containers.dropContents(this.level, this.worldPosition, inventory);
|
||||
}
|
||||
|
||||
|
||||
public void resetProgress() {
|
||||
this.progress = 0;
|
||||
this.maxProgress = 1;
|
||||
}
|
||||
|
||||
protected static Optional<TradingRecipe> getRecipe(AbstractTradingStationBlockEntity pBlockEntity){
|
||||
Level level = pBlockEntity.getLevel();
|
||||
SimpleContainer inputInventory = getInputInventory(pBlockEntity);
|
||||
if(!pBlockEntity.targetItemHandler.getStackInSlot(0).isEmpty())
|
||||
return ModRecipes.findByOutput(level,pBlockEntity.targetItemHandler.getStackInSlot(0));
|
||||
return ModRecipes.find(inputInventory,level);
|
||||
// return level.getRecipeManager().getRecipeFor(TradingRecipe.Type.INSTANCE, inputInventory, level);
|
||||
}
|
||||
protected int getProcessingTime(AbstractTradingStationBlockEntity pBlockEntity) {
|
||||
return getRecipe(pBlockEntity).map(TradingRecipe::getProcessingTime).orElse(1);
|
||||
}
|
||||
|
||||
public static void tick(Level pLevel, BlockPos pPos, BlockState pState, AbstractTradingStationBlockEntity pBlockEntity) {
|
||||
|
||||
if(pLevel.isClientSide()) {
|
||||
return;
|
||||
}
|
||||
if(!isPowered(pBlockEntity))
|
||||
return;
|
||||
|
||||
if (canCraftItem(pBlockEntity)) {
|
||||
pBlockEntity.progress += 1;
|
||||
BlockEntity.setChanged(pLevel, pPos, pState);
|
||||
pBlockEntity.maxProgress = pBlockEntity.getProcessingTime(pBlockEntity);
|
||||
if (pBlockEntity.progress > pBlockEntity.maxProgress) {
|
||||
AbstractTradingStationBlockEntity.craftItem(pBlockEntity);
|
||||
}
|
||||
BlockEntity.setChanged(pLevel, pPos, pState);
|
||||
|
||||
} else {
|
||||
pBlockEntity.resetProgress();
|
||||
BlockEntity.setChanged(pLevel, pPos, pState);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
protected static void updateProgress(AbstractTradingStationBlockEntity pBlockEntity){
|
||||
pBlockEntity.progress += 1;
|
||||
|
||||
}
|
||||
private static boolean isPowered(AbstractTradingStationBlockEntity pBlockEntity){
|
||||
return pBlockEntity.getLevel().getBlockState(pBlockEntity.getBlockPos())
|
||||
.getValue(BlockStateProperties.POWERED);
|
||||
}
|
||||
private static SimpleContainer getInputInventory(AbstractTradingStationBlockEntity pBlockEntity){
|
||||
int containerSize = 0;
|
||||
for(int index = 0; index < pBlockEntity.inputItems.getSlots(); index++) {
|
||||
if (!pBlockEntity.inputItems.getStackInSlot(index).isEmpty())
|
||||
containerSize++;
|
||||
}
|
||||
|
||||
SimpleContainer inputInventory = new SimpleContainer(containerSize);
|
||||
pBlockEntity.inputItemHandler.ifPresent(iItemHandler -> {
|
||||
for(int slot = 0; slot < iItemHandler.getSlots(); slot++) {
|
||||
if(!iItemHandler.getStackInSlot(slot).isEmpty()){
|
||||
inputInventory.addItem(iItemHandler.getStackInSlot(slot));
|
||||
}
|
||||
}
|
||||
});
|
||||
return inputInventory;
|
||||
}
|
||||
private static void craftItem(AbstractTradingStationBlockEntity pBlockEntity) {
|
||||
Level level = pBlockEntity.getLevel();
|
||||
SimpleContainer inputInventory = getInputInventory(pBlockEntity);
|
||||
|
||||
Optional<TradingRecipe> recipe = getRecipe(pBlockEntity);
|
||||
|
||||
if(recipe.isPresent()){
|
||||
for (int i = 0; i < recipe.get().getIngredients().size(); i++) {
|
||||
Ingredient ingredient = recipe.get().getIngredients().get(i);
|
||||
|
||||
for (int slot = 0; slot < pBlockEntity.inputItems.getSlots(); slot++) {
|
||||
ItemStack itemStack = pBlockEntity.inputItems.getStackInSlot(slot);
|
||||
if(ingredient.test(itemStack)){
|
||||
pBlockEntity.inputItems.extractItem(slot,ingredient.getItems()[0].getCount(),false);
|
||||
inputInventory.setChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
pBlockEntity.outputItems.insertItem(0, recipe.get().getResultItem(), false);
|
||||
}
|
||||
|
||||
pBlockEntity.resetProgress();
|
||||
pBlockEntity.setChanged();
|
||||
}
|
||||
|
||||
|
||||
static boolean canCraftItem(AbstractTradingStationBlockEntity pBlockEntity) {
|
||||
Level level = pBlockEntity.getLevel();
|
||||
if(level == null)
|
||||
return false;
|
||||
|
||||
SimpleContainer inputInventory = getInputInventory(pBlockEntity);
|
||||
|
||||
Optional<TradingRecipe> match = getRecipe(pBlockEntity);
|
||||
|
||||
if(match.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
//return false;
|
||||
return match.isPresent()
|
||||
&& AbstractTradingStationBlockEntity.hasEnoughInputItems(inputInventory,match.get().getIngredients())
|
||||
&& AbstractTradingStationBlockEntity.hasEnoughOutputSpace(pBlockEntity.outputItems,match.get().getResultItem());
|
||||
}
|
||||
|
||||
private boolean canProcess(ItemStack stack) {
|
||||
|
||||
return getRecipe(this).isPresent();
|
||||
}
|
||||
protected static boolean hasEnoughInputItems(SimpleContainer inventory, NonNullList<Ingredient> ingredients){
|
||||
int enough = 0;
|
||||
for(int ingredientIndex = 0; ingredientIndex < ingredients.size();ingredientIndex ++){
|
||||
Ingredient ingredient = ingredients.get(ingredientIndex);
|
||||
for(int slot = 0; slot < inventory.getContainerSize(); slot++){
|
||||
if(ingredient.test(inventory.getItem(slot))){
|
||||
if(inventory.getItem(slot).getCount() >= ingredient.getItems()[0].getCount() )
|
||||
enough++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ingredients.size() == enough;
|
||||
}
|
||||
|
||||
protected static boolean hasEnoughOutputSpace(ItemStackHandler stackHandler,ItemStack resultItemStack){
|
||||
return stackHandler.getStackInSlot(0).isEmpty() || stackHandler.getStackInSlot(0).is(resultItemStack.getItem()) && stackHandler.getStackInSlot(0).getMaxStackSize() - stackHandler.getStackInSlot(0).getCount() >= resultItemStack.getCount() ;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag getUpdateTag() {
|
||||
this.saveAdditional(updateTag);
|
||||
return updateTag;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public ClientboundBlockEntityDataPacket getUpdatePacket() {
|
||||
return ClientboundBlockEntityDataPacket.create(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleUpdateTag(CompoundTag tag) {
|
||||
this.load(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDataPacket(Connection net, ClientboundBlockEntityDataPacket pkt) {
|
||||
this.load(pkt.getTag());
|
||||
}
|
||||
|
||||
|
||||
|
||||
public int getProgressPercent() {
|
||||
return this.progress * 100 / this.maxProgress;
|
||||
}
|
||||
|
||||
|
||||
public void setItemStack(int slot, ItemStack itemStack,ItemStackSyncS2CPacket.SlotType slotType) {
|
||||
if(slotType == ItemStackSyncS2CPacket.SlotType.INPUT)
|
||||
inputItems.setStackInSlot(slot,itemStack);
|
||||
else if (slotType == ItemStackSyncS2CPacket.SlotType.OUTPUT)
|
||||
outputItems.setStackInSlot(slot,itemStack);
|
||||
else if (slotType == ItemStackSyncS2CPacket.SlotType.TARGET)
|
||||
targetItemHandler.setStackInSlot(slot,itemStack);
|
||||
|
||||
}
|
||||
|
||||
public void setPreferedItem(ItemStack itemStack) {
|
||||
this.targetItemHandler.setStackInSlot(0,itemStack);
|
||||
}
|
||||
|
||||
|
||||
public ItemStack getPreferedItemStack() {
|
||||
return targetItemHandler.getStackInSlot(0);
|
||||
}
|
||||
public ItemStackHandler getTargetItemHandler(){
|
||||
return targetItemHandler;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
package com.oierbravo.trading_station.content.trading_station;
|
||||
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.mojang.blaze3d.platform.Lighting;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.LightTexture;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.renderer.block.model.ItemTransforms;
|
||||
import net.minecraft.client.renderer.entity.ItemRenderer;
|
||||
import net.minecraft.client.renderer.texture.OverlayTexture;
|
||||
import net.minecraft.client.renderer.texture.TextureManager;
|
||||
import net.minecraft.client.resources.model.BakedModel;
|
||||
import net.minecraft.world.inventory.InventoryMenu;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
/**
|
||||
* This class can be used to render a 2D ItemStack to the screen with optional transparency. The item being rendered
|
||||
* doesn't need to represent a real ItemStack held in an inventory or container.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class FakeItemRenderer {
|
||||
|
||||
private static final Minecraft MINECRAFT = Minecraft.getInstance();
|
||||
private static final ItemRenderer ITEM_RENDERER = MINECRAFT.getItemRenderer();
|
||||
private static final TextureManager TEXTURE_MANAGER = MINECRAFT.getTextureManager();
|
||||
|
||||
|
||||
public static void renderFakeItem(ItemStack pItemStack, int pX, int pY) {
|
||||
renderFakeItem(pItemStack, pX, pY, 1.0F);
|
||||
}
|
||||
|
||||
public static void renderFakeItem(ItemStack pItemStack, int pX, int pY, float pAlpha) {
|
||||
|
||||
if (!pItemStack.isEmpty()) {
|
||||
BakedModel model = getBakedModel(pItemStack);
|
||||
|
||||
TEXTURE_MANAGER.getTexture(InventoryMenu.BLOCK_ATLAS).setFilter(true, false);
|
||||
RenderSystem.setShaderTexture(0, InventoryMenu.BLOCK_ATLAS);
|
||||
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
RenderSystem.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA);
|
||||
RenderSystem.enableBlend();
|
||||
|
||||
PoseStack modelViewStack = RenderSystem.getModelViewStack();
|
||||
modelViewStack.pushPose();
|
||||
modelViewStack.translate(pX + 8.0D, pY + 8.0D, 0F);
|
||||
modelViewStack.scale(16.0F, -16.0F, 16.0F);
|
||||
RenderSystem.applyModelViewMatrix();
|
||||
|
||||
if (!model.usesBlockLight()) {
|
||||
Lighting.setupForFlatItems();
|
||||
}
|
||||
|
||||
MultiBufferSource.BufferSource bufferSource = MINECRAFT.renderBuffers().bufferSource();
|
||||
ITEM_RENDERER.render(pItemStack,
|
||||
ItemTransforms.TransformType.GUI,
|
||||
false,
|
||||
new PoseStack(),
|
||||
getWrappedBuffer(bufferSource, pAlpha),
|
||||
LightTexture.FULL_BRIGHT,
|
||||
OverlayTexture.NO_OVERLAY,
|
||||
model);
|
||||
bufferSource.endBatch();
|
||||
RenderSystem.enableDepthTest();
|
||||
|
||||
if (!model.usesBlockLight()) {
|
||||
Lighting.setupFor3DItems();
|
||||
}
|
||||
|
||||
modelViewStack.popPose();
|
||||
RenderSystem.applyModelViewMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
private static MultiBufferSource getWrappedBuffer(MultiBufferSource pBufferSource, float pAlpha) {
|
||||
return pRenderType -> new WrappedVertexConsumer(pBufferSource.getBuffer(RenderType.entityTranslucent(InventoryMenu.BLOCK_ATLAS)), 1F, 1F, 1F, pAlpha);
|
||||
}
|
||||
|
||||
private static BakedModel getBakedModel(ItemStack pItemStack) {
|
||||
return ITEM_RENDERER.getModel(pItemStack, null, MINECRAFT.player, 0);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
class WrappedVertexConsumer implements VertexConsumer {
|
||||
|
||||
protected final VertexConsumer consumer;
|
||||
protected final float red;
|
||||
protected final float green;
|
||||
protected final float blue;
|
||||
protected final float alpha;
|
||||
|
||||
public WrappedVertexConsumer(VertexConsumer pConsumer, float pRed, float pGreen, float pBlue, float pAlpha) {
|
||||
this.consumer = pConsumer;
|
||||
this.red = pRed;
|
||||
this.green = pGreen;
|
||||
this.blue = pBlue;
|
||||
this.alpha = pAlpha;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VertexConsumer vertex(double pX, double pY, double pZ) {
|
||||
return consumer.vertex(pX, pY, pZ);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VertexConsumer color(int pRed, int pGreen, int pBlue, int pAlpha) {
|
||||
return consumer.color((int)(pRed * red), (int)(pGreen * green), (int)(pBlue * blue), (int)(pAlpha * alpha));
|
||||
}
|
||||
|
||||
@Override
|
||||
public VertexConsumer uv(float pU, float pV) {
|
||||
return consumer.uv(pU, pV);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VertexConsumer overlayCoords(int pU, int pV) {
|
||||
return consumer.overlayCoords(pU, pV);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VertexConsumer uv2(int pU, int pV) {
|
||||
return consumer.uv2(pU, pV);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VertexConsumer normal(float pX, float pY, float pZ) {
|
||||
return consumer.normal(pX, pY, pZ);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVertex() {
|
||||
consumer.endVertex();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void defaultColor(int pDefaultR, int pDefaultG, int pDefaultB, int pDefaultA) {
|
||||
consumer.defaultColor(pDefaultR, pDefaultG, pDefaultB, pDefaultA);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unsetDefaultColor() {
|
||||
consumer.unsetDefaultColor();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
package com.oierbravo.trading_station.content.trading_station;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.oierbravo.trading_station.TradingStation;
|
||||
import com.oierbravo.trading_station.content.trading_station.TradingRecipeBuilder.TradingRecipeParams;
|
||||
import net.minecraft.core.NonNullList;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.SimpleContainer;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.crafting.*;
|
||||
import net.minecraft.world.level.Level;
|
||||
|
||||
public class TradingRecipe implements Recipe<SimpleContainer> {
|
||||
private final ResourceLocation id;
|
||||
private final NonNullList<Ingredient> itemIngredients;
|
||||
private final ItemStack result;
|
||||
|
||||
private final int processingTime;
|
||||
|
||||
public TradingRecipe(TradingRecipeParams params) {
|
||||
this.id = params.id;
|
||||
this.result = params.result;
|
||||
this.itemIngredients = params.itemIngredients;
|
||||
this.processingTime = params.processingTime;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public boolean matches(SimpleContainer pContainer, Level pLevel) {
|
||||
if(pLevel.isClientSide)
|
||||
return false;
|
||||
if(pContainer.getContainerSize() != itemIngredients.size())
|
||||
return false;
|
||||
|
||||
int matchedIngredients = 0;
|
||||
for (int i = 0; i < itemIngredients.size(); i++) {
|
||||
Ingredient ingredient = itemIngredients.get(i);
|
||||
|
||||
for (int slot = 0; slot < pContainer.getContainerSize(); slot++) {
|
||||
ItemStack itemStack = pContainer.getItem(slot);
|
||||
if(ingredient.test(pContainer.getItem(slot))){
|
||||
matchedIngredients++;
|
||||
}
|
||||
}
|
||||
|
||||
return matchedIngredients == itemIngredients.size();
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
public boolean matches(SimpleContainer pContainer, Level pLevel, ItemStack preferedOutput){
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean matchesOutput(ItemStack targetItemStack){
|
||||
return result.sameItem(targetItemStack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NonNullList<Ingredient> getIngredients() {
|
||||
return itemIngredients;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack assemble(SimpleContainer pContainer) {
|
||||
|
||||
return result.copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canCraftInDimensions(int pWidth, int pHeight) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ItemStack getResultItem() {
|
||||
return result.copy();
|
||||
}
|
||||
public ItemStack getResult(){
|
||||
return result.copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecipeSerializer<?> getSerializer() {
|
||||
return Serializer.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecipeType<?> getType() {
|
||||
return Type.INSTANCE;
|
||||
}
|
||||
public static class Type implements RecipeType<TradingRecipe> {
|
||||
private Type() { }
|
||||
public static final Type INSTANCE = new Type();
|
||||
public static final String ID = "trading";
|
||||
}
|
||||
public static class Serializer implements RecipeSerializer<TradingRecipe> {
|
||||
public static final Serializer INSTANCE = new Serializer();
|
||||
public static final ResourceLocation ID =
|
||||
new ResourceLocation(TradingStation.MODID,"trading");
|
||||
|
||||
@Override
|
||||
public TradingRecipe fromJson(ResourceLocation id, JsonObject json) {
|
||||
TradingRecipeBuilder builder = new TradingRecipeBuilder(id);
|
||||
NonNullList<Ingredient> itemIngredients = NonNullList.create();
|
||||
int processingTime = 1;
|
||||
|
||||
for (JsonElement je : GsonHelper.getAsJsonArray(json, "ingredients")) {
|
||||
JsonObject jsonObject = je.getAsJsonObject();
|
||||
Ingredient ingredient = Ingredient.fromJson(jsonObject);
|
||||
if(jsonObject.has("count")){
|
||||
ItemStack itemStack = ingredient.getItems()[0];
|
||||
itemStack.setCount(jsonObject.get("count").getAsInt());
|
||||
}
|
||||
|
||||
itemIngredients.add(ingredient);
|
||||
}
|
||||
|
||||
ItemStack result = ShapedRecipe.itemStackFromJson(GsonHelper.getAsJsonObject(json, "result"));
|
||||
|
||||
if(GsonHelper.isValidNode(json,"processingTime")){
|
||||
processingTime = GsonHelper.getAsInt(json,"processingTime");
|
||||
}
|
||||
|
||||
builder.withItemIngredients(itemIngredients)
|
||||
.withSingleItemOutput(result)
|
||||
.processingTime(processingTime);
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TradingRecipe fromNetwork(ResourceLocation id, FriendlyByteBuf buffer) {
|
||||
TradingRecipeBuilder builder = new TradingRecipeBuilder(id);
|
||||
NonNullList<Ingredient> itemIngredients = NonNullList.create();
|
||||
int processingTime = 1;
|
||||
|
||||
int size = buffer.readVarInt();
|
||||
for (int i = 0; i < size; i++)
|
||||
itemIngredients.add(Ingredient.fromNetwork(buffer));
|
||||
|
||||
ItemStack result = buffer.readItem();
|
||||
processingTime = buffer.readInt();
|
||||
|
||||
|
||||
builder.withItemIngredients(itemIngredients)
|
||||
.withSingleItemOutput(result)
|
||||
.processingTime(processingTime);
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toNetwork(FriendlyByteBuf buffer, TradingRecipe recipe) {
|
||||
NonNullList<Ingredient> itemIngredients = recipe.itemIngredients;
|
||||
int processingTime = recipe.getProcessingTime();
|
||||
|
||||
|
||||
buffer.writeVarInt(itemIngredients.size());
|
||||
itemIngredients.forEach(i -> i.toNetwork(buffer));
|
||||
buffer.writeItem(recipe.getResultItem());
|
||||
buffer.writeInt(processingTime);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public int getProcessingTime() {
|
||||
return processingTime;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package com.oierbravo.trading_station.content.trading_station;
|
||||
|
||||
import net.minecraft.core.NonNullList;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.crafting.Ingredient;
|
||||
import net.minecraftforge.common.crafting.conditions.ICondition;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class TradingRecipeBuilder {
|
||||
protected TradingRecipeParams params;
|
||||
protected List<ICondition> recipeConditions;
|
||||
public TradingRecipeBuilder(ResourceLocation recipeId) {
|
||||
params = new TradingRecipeParams(recipeId);
|
||||
recipeConditions = new ArrayList<>();
|
||||
|
||||
|
||||
}
|
||||
public TradingRecipeBuilder withItemIngredients(Ingredient... itemIngredients) {
|
||||
return withItemIngredients(NonNullList.of(Ingredient.EMPTY, itemIngredients));
|
||||
}
|
||||
|
||||
public TradingRecipeBuilder withItemIngredients(NonNullList<Ingredient> itemIngredients) {
|
||||
params.itemIngredients = itemIngredients;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TradingRecipeBuilder withSingleItemOutput(ItemStack output) {
|
||||
params.result = output;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TradingRecipeBuilder processingTime(int time) {
|
||||
params.processingTime = time;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public TradingRecipe build(){
|
||||
return new TradingRecipe(params);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public static class TradingRecipeParams {
|
||||
|
||||
protected ResourceLocation id;
|
||||
protected NonNullList<Ingredient> itemIngredients;
|
||||
protected ItemStack result;
|
||||
protected int fuelConsumed;
|
||||
protected int processingTime;
|
||||
|
||||
protected TradingRecipeParams(ResourceLocation id) {
|
||||
this.id = id;
|
||||
itemIngredients = NonNullList.create();
|
||||
result = ItemStack.EMPTY;
|
||||
fuelConsumed = 0;
|
||||
processingTime = 1;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
package com.oierbravo.trading_station.content.trading_station;
|
||||
|
||||
import com.oierbravo.trading_station.registrate.ModBlockEntities;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.context.BlockPlaceContext;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.BaseEntityBlock;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.RenderShape;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityTicker;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.StateDefinition;
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||
import net.minecraft.world.level.block.state.properties.BooleanProperty;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.Shapes;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
import net.minecraftforge.network.NetworkHooks;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import static net.minecraft.world.level.block.state.properties.BlockStateProperties.HORIZONTAL_FACING;
|
||||
|
||||
|
||||
public class TradingStationBlock extends BaseEntityBlock {
|
||||
public static final BooleanProperty POWERED = BlockStateProperties.POWERED;
|
||||
|
||||
private static final VoxelShape RENDER_SHAPE = Shapes.box(0, 0, 0, 1, 1, 1);
|
||||
//public static final BooleanProperty BOTTOM = BlockStateProperties.BOTTOM;
|
||||
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState pState, BlockGetter pLevel, BlockPos pPos, CollisionContext pContext) {
|
||||
return RENDER_SHAPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getCollisionShape(BlockState pState, BlockGetter pLevel, BlockPos pPos, CollisionContext pContext) {
|
||||
return RENDER_SHAPE;
|
||||
}
|
||||
|
||||
public TradingStationBlock(Properties pProperties) {
|
||||
super(pProperties);
|
||||
registerDefaultState(getStateDefinition().any().setValue(HORIZONTAL_FACING, Direction.NORTH).setValue(POWERED,false));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public BlockState getStateForPlacement(BlockPlaceContext context)
|
||||
{
|
||||
if (!context.getLevel().getBlockState(context.getClickedPos().above()).canBeReplaced(context))
|
||||
return null;
|
||||
return super.getStateForPlacement(context)
|
||||
.setValue(HORIZONTAL_FACING, context.getHorizontalDirection().getOpposite())
|
||||
.setValue(POWERED, context.getLevel().hasNeighborSignal(context.getClickedPos()));
|
||||
}
|
||||
@Override
|
||||
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
|
||||
builder.add(HORIZONTAL_FACING).add(POWERED);
|
||||
}
|
||||
@Override
|
||||
public RenderShape getRenderShape(BlockState pState) {
|
||||
return RenderShape.MODEL;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public BlockEntity newBlockEntity(BlockPos pPos, BlockState pState) {
|
||||
return ModBlockEntities.TRADING_STATION.create(pPos, pState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick(BlockState state, ServerLevel worldIn, BlockPos pos, RandomSource r) {
|
||||
boolean previouslyPowered = state.getValue(POWERED);
|
||||
if (previouslyPowered != worldIn.hasNeighborSignal(pos))
|
||||
worldIn.setBlock(pos, state.cycle(POWERED), 2);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level pLevel, BlockState pState, BlockEntityType<T> pBlockEntityType) {
|
||||
return createTickerHelper(pBlockEntityType, ModBlockEntities.TRADING_STATION.get(),
|
||||
TradingStationBlockEntity::tick);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void neighborChanged(BlockState state, Level worldIn, BlockPos pos, Block blockIn, BlockPos fromPos,
|
||||
boolean isMoving) {
|
||||
super.neighborChanged(state, worldIn, pos, blockIn, fromPos, isMoving);
|
||||
if (worldIn.isClientSide)
|
||||
return;
|
||||
if (!worldIn.getBlockTicks()
|
||||
.willTickThisTick(pos, this))
|
||||
worldIn.scheduleTick(pos, this, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemove(BlockState pState, Level pLevel, BlockPos pPos, BlockState pNewState, boolean pIsMoving) {
|
||||
if (pState.getBlock() != pNewState.getBlock()) {
|
||||
BlockEntity blockEntity = pLevel.getBlockEntity(pPos);
|
||||
if (blockEntity instanceof TradingStationBlockEntity) {
|
||||
((TradingStationBlockEntity) blockEntity).drops();
|
||||
}
|
||||
}
|
||||
super.onRemove(pState, pLevel, pPos, pNewState, pIsMoving);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InteractionResult use(BlockState state, Level pLevel, BlockPos pPos, Player pPlayer, InteractionHand handIn, BlockHitResult hit) {
|
||||
|
||||
if (!pLevel.isClientSide()) {
|
||||
BlockEntity blockEntity = pLevel.getBlockEntity(pPos);
|
||||
if(blockEntity instanceof TradingStationBlockEntity) {
|
||||
NetworkHooks.openScreen(((ServerPlayer)pPlayer), (TradingStationBlockEntity)blockEntity, pPos);
|
||||
} else {
|
||||
throw new IllegalStateException("Our Container provider is missing!");
|
||||
}
|
||||
}
|
||||
|
||||
return InteractionResult.sidedSuccess(pLevel.isClientSide());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,434 @@
|
||||
package com.oierbravo.trading_station.content.trading_station;
|
||||
|
||||
import com.oierbravo.trading_station.foundation.util.ModLang;
|
||||
import com.oierbravo.trading_station.network.packets.ItemStackSyncS2CPacket;
|
||||
import com.oierbravo.trading_station.registrate.ModMessages;
|
||||
import com.oierbravo.trading_station.registrate.ModRecipes;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.NonNullList;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.Connection;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.Containers;
|
||||
import net.minecraft.world.MenuProvider;
|
||||
import net.minecraft.world.SimpleContainer;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.inventory.ContainerData;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.crafting.Ingredient;
|
||||
import net.minecraft.world.item.crafting.ShapelessRecipe;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.common.capabilities.ForgeCapabilities;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.ItemStackHandler;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public class TradingStationBlockEntity extends BlockEntity implements MenuProvider {
|
||||
|
||||
|
||||
//private final int FLUID_CAPACITY = TradingStationConfig.trading_station_CAPACITY.get();
|
||||
//private static final int FLIUD_PER_TICK = TradingStationConfig.trading_statio_FLUID_PER_TICK.get();
|
||||
private CompoundTag updateTag;
|
||||
public final ItemStackHandler inputItems = createInputItemHandler();
|
||||
public final ItemStackHandler outputItems = createOutputItemHandler();
|
||||
|
||||
public final ItemStackHandler targetItemHandler = createTargetItemHandler();
|
||||
private final LazyOptional<IItemHandler> inputItemHandler = LazyOptional.of(() -> inputItems);
|
||||
private final LazyOptional<IItemHandler> outputItemHandler = LazyOptional.of(() -> outputItems);
|
||||
|
||||
public int progress = 0;
|
||||
public int maxProgress = 1;
|
||||
private BlockState lastBlockState;
|
||||
|
||||
protected final ContainerData containerData;
|
||||
private Item preferedItem;
|
||||
|
||||
public TradingStationBlockEntity(BlockEntityType<?> pType, BlockPos pWorldPosition, BlockState pBlockState) {
|
||||
super(pType, pWorldPosition, pBlockState);
|
||||
updateTag = getPersistentData();
|
||||
lastBlockState = this.getBlockState();
|
||||
preferedItem = ItemStack.EMPTY.getItem();
|
||||
containerData = TradingStationBlockEntity.createContainerData(this);
|
||||
}
|
||||
public static ContainerData createContainerData(TradingStationBlockEntity pBlockEntity){
|
||||
return new ContainerData(){
|
||||
@Override
|
||||
public int get(int pIndex){
|
||||
return switch (pIndex) {
|
||||
case 0 -> pBlockEntity.progress;
|
||||
case 1 -> pBlockEntity.maxProgress;
|
||||
default -> 0;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void set(int pIndex, int pValue) {
|
||||
switch (pIndex) {
|
||||
case 0 -> pBlockEntity.progress = pValue;
|
||||
case 1 -> pBlockEntity.maxProgress = pValue;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return 2;
|
||||
}
|
||||
};
|
||||
}
|
||||
@NotNull
|
||||
@Nonnull
|
||||
private ItemStackHandler createTargetItemHandler() {
|
||||
return new ItemStackHandler(1) {
|
||||
@Override
|
||||
protected void onContentsChanged(int slot) {
|
||||
setChanged();
|
||||
if(!level.isClientSide()) {
|
||||
ModMessages.sendToClients(new ItemStackSyncS2CPacket(slot,this.getStackInSlot(0), worldPosition, ItemStackSyncS2CPacket.SlotType.TARGET));
|
||||
}
|
||||
if(!level.isClientSide()) {
|
||||
level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3);
|
||||
}
|
||||
// clientSync();
|
||||
}
|
||||
@Override
|
||||
public boolean isItemValid(int slot, ItemStack stack) {
|
||||
return true;
|
||||
//return canProcess(stack) && super.isItemValid(slot, stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ItemStack extractItem(int slot, int amount, boolean simulate) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private ItemStackHandler createInputItemHandler() {
|
||||
return new ItemStackHandler(2) {
|
||||
@Override
|
||||
protected void onContentsChanged(int slot) {
|
||||
setChanged();
|
||||
if(!level.isClientSide()) {
|
||||
ModMessages.sendToClients(new ItemStackSyncS2CPacket(slot,this.getStackInSlot(0), worldPosition, ItemStackSyncS2CPacket.SlotType.INPUT));
|
||||
}
|
||||
if(!level.isClientSide()) {
|
||||
level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3);
|
||||
}
|
||||
// clientSync();
|
||||
}
|
||||
@Override
|
||||
public boolean isItemValid(int slot, ItemStack stack) {
|
||||
return true;
|
||||
//return canProcess(stack) && super.isItemValid(slot, stack);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Nonnull
|
||||
private ItemStackHandler createOutputItemHandler() {
|
||||
return new ItemStackHandler(1) {
|
||||
@Override
|
||||
protected void onContentsChanged(int slot) {
|
||||
setChanged();
|
||||
if(!level.isClientSide()) {
|
||||
ModMessages.sendToClients(new ItemStackSyncS2CPacket(slot, this.getStackInSlot(slot), worldPosition, ItemStackSyncS2CPacket.SlotType.OUTPUT));
|
||||
}
|
||||
if(!level.isClientSide()) {
|
||||
level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3);
|
||||
}
|
||||
// clientSync();
|
||||
}
|
||||
@Override
|
||||
public boolean isItemValid(int slot, ItemStack stack) {
|
||||
return canProcess(stack) && super.isItemValid(slot, stack);
|
||||
//return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
@Override
|
||||
public <T> LazyOptional<T> getCapability(@NotNull Capability<T> cap, @Nullable Direction side) {
|
||||
if (cap == ForgeCapabilities.ITEM_HANDLER) {
|
||||
return inputItemHandler.cast();
|
||||
}
|
||||
return super.getCapability(cap, side);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRemoved() {
|
||||
super.setRemoved();
|
||||
inputItemHandler.invalidate();
|
||||
outputItemHandler.invalidate();
|
||||
}
|
||||
public LazyOptional<IItemHandler> getInputItemHandler(){
|
||||
return inputItemHandler;
|
||||
}
|
||||
public LazyOptional<IItemHandler> getOutputItemHandler(){
|
||||
return outputItemHandler;
|
||||
}
|
||||
@Override
|
||||
public void onLoad() {
|
||||
super.onLoad();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidateCaps() {
|
||||
super.invalidateCaps();
|
||||
inputItemHandler.invalidate();
|
||||
outputItemHandler.invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveAdditional(@NotNull CompoundTag tag) {
|
||||
super.saveAdditional(tag);
|
||||
tag.put("input", inputItems.serializeNBT());
|
||||
tag.put("output", outputItems.serializeNBT());
|
||||
tag.put("target", targetItemHandler.serializeNBT());
|
||||
tag.putInt("trading_station.progress", progress);
|
||||
tag.putInt("trading_station.maxProgress", maxProgress);
|
||||
String preferedItemString = ForgeRegistries.ITEMS.getKey(preferedItem).toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(CompoundTag tag) {
|
||||
super.load(tag);
|
||||
inputItems.deserializeNBT(tag.getCompound("input"));
|
||||
outputItems.deserializeNBT(tag.getCompound("output"));
|
||||
targetItemHandler.deserializeNBT(tag.getCompound("target"));
|
||||
progress = tag.getInt("trading_station.progress");
|
||||
maxProgress = tag.getInt("trading_station.maxProgress");
|
||||
String preferedItemString = tag.getString("trading_station.preferedItem");
|
||||
preferedItem = ForgeRegistries.ITEMS.getValue( ResourceLocation.tryParse(preferedItemString));
|
||||
}
|
||||
|
||||
public void drops() {
|
||||
SimpleContainer inventory = new SimpleContainer(inputItems.getSlots() + 1);
|
||||
for (int i = 0; i < inputItems.getSlots(); i++) {
|
||||
inventory.setItem(i, inputItems.getStackInSlot(i));
|
||||
}
|
||||
inventory.setItem(inputItems.getSlots(), inputItems.getStackInSlot(0));
|
||||
|
||||
Containers.dropContents(this.level, this.worldPosition, inventory);
|
||||
}
|
||||
|
||||
|
||||
public void resetProgress() {
|
||||
this.progress = 0;
|
||||
this.maxProgress = 1;
|
||||
}
|
||||
|
||||
protected static Optional<TradingRecipe> getRecipe(TradingStationBlockEntity pBlockEntity){
|
||||
Level level = pBlockEntity.getLevel();
|
||||
SimpleContainer inputInventory = getInputInventory(pBlockEntity);
|
||||
if(!pBlockEntity.targetItemHandler.getStackInSlot(0).isEmpty())
|
||||
return ModRecipes.findByOutput(level,pBlockEntity.targetItemHandler.getStackInSlot(0));
|
||||
return ModRecipes.find(inputInventory,level);
|
||||
// return level.getRecipeManager().getRecipeFor(TradingRecipe.Type.INSTANCE, inputInventory, level);
|
||||
}
|
||||
protected int getProcessingTime(TradingStationBlockEntity pBlockEntity) {
|
||||
return getRecipe(pBlockEntity).map(TradingRecipe::getProcessingTime).orElse(1);
|
||||
}
|
||||
|
||||
public static void tick(Level pLevel, BlockPos pPos, BlockState pState, TradingStationBlockEntity pBlockEntity) {
|
||||
|
||||
if(pLevel.isClientSide()) {
|
||||
return;
|
||||
}
|
||||
if(!isPowered(pBlockEntity))
|
||||
return;
|
||||
|
||||
if (canCraftItem(pBlockEntity)) {
|
||||
pBlockEntity.progress += 1;
|
||||
BlockEntity.setChanged(pLevel, pPos, pState);
|
||||
pBlockEntity.maxProgress = pBlockEntity.getProcessingTime(pBlockEntity);
|
||||
if (pBlockEntity.progress > pBlockEntity.maxProgress) {
|
||||
TradingStationBlockEntity.craftItem(pBlockEntity);
|
||||
}
|
||||
BlockEntity.setChanged(pLevel, pPos, pState);
|
||||
|
||||
} else {
|
||||
pBlockEntity.resetProgress();
|
||||
BlockEntity.setChanged(pLevel, pPos, pState);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
protected static void updateProgress(TradingStationBlockEntity pBlockEntity){
|
||||
pBlockEntity.progress += 1;
|
||||
|
||||
}
|
||||
private static boolean isPowered(TradingStationBlockEntity pBlockEntity){
|
||||
return pBlockEntity.getLevel().getBlockState(pBlockEntity.getBlockPos())
|
||||
.getValue(BlockStateProperties.POWERED);
|
||||
}
|
||||
private static SimpleContainer getInputInventory(TradingStationBlockEntity pBlockEntity){
|
||||
int containerSize = 0;
|
||||
for(int index = 0; index < pBlockEntity.inputItems.getSlots(); index++) {
|
||||
if (!pBlockEntity.inputItems.getStackInSlot(index).isEmpty())
|
||||
containerSize++;
|
||||
}
|
||||
|
||||
SimpleContainer inputInventory = new SimpleContainer(containerSize);
|
||||
pBlockEntity.inputItemHandler.ifPresent(iItemHandler -> {
|
||||
for(int slot = 0; slot < iItemHandler.getSlots(); slot++) {
|
||||
if(!iItemHandler.getStackInSlot(slot).isEmpty()){
|
||||
inputInventory.addItem(iItemHandler.getStackInSlot(slot));
|
||||
}
|
||||
}
|
||||
});
|
||||
return inputInventory;
|
||||
}
|
||||
private static void craftItem(TradingStationBlockEntity pBlockEntity) {
|
||||
Level level = pBlockEntity.getLevel();
|
||||
SimpleContainer inputInventory = getInputInventory(pBlockEntity);
|
||||
|
||||
Optional<TradingRecipe> recipe = getRecipe(pBlockEntity);
|
||||
|
||||
if(recipe.isPresent()){
|
||||
for (int i = 0; i < recipe.get().getIngredients().size(); i++) {
|
||||
Ingredient ingredient = recipe.get().getIngredients().get(i);
|
||||
|
||||
for (int slot = 0; slot < pBlockEntity.inputItems.getSlots(); slot++) {
|
||||
ItemStack itemStack = pBlockEntity.inputItems.getStackInSlot(slot);
|
||||
if(ingredient.test(itemStack)){
|
||||
pBlockEntity.inputItems.extractItem(slot,ingredient.getItems()[0].getCount(),false);
|
||||
inputInventory.setChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
pBlockEntity.outputItems.insertItem(0, recipe.get().getResultItem(), false);
|
||||
}
|
||||
|
||||
pBlockEntity.resetProgress();
|
||||
pBlockEntity.setChanged();
|
||||
}
|
||||
|
||||
|
||||
static boolean canCraftItem(TradingStationBlockEntity pBlockEntity) {
|
||||
Level level = pBlockEntity.getLevel();
|
||||
if(level == null)
|
||||
return false;
|
||||
|
||||
SimpleContainer inputInventory = getInputInventory(pBlockEntity);
|
||||
|
||||
Optional<TradingRecipe> match = getRecipe(pBlockEntity);
|
||||
|
||||
if(match.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
//return false;
|
||||
return match.isPresent()
|
||||
&& TradingStationBlockEntity.hasEnoughInputItems(inputInventory,match.get().getIngredients())
|
||||
&& TradingStationBlockEntity.hasEnoughOutputSpace(pBlockEntity.outputItems,match.get().getResultItem());
|
||||
}
|
||||
|
||||
private boolean canProcess(ItemStack stack) {
|
||||
|
||||
return getRecipe(this).isPresent();
|
||||
}
|
||||
protected static boolean hasEnoughInputItems(SimpleContainer inventory, NonNullList<Ingredient> ingredients){
|
||||
int enough = 0;
|
||||
for(int ingredientIndex = 0; ingredientIndex < ingredients.size();ingredientIndex ++){
|
||||
Ingredient ingredient = ingredients.get(ingredientIndex);
|
||||
for(int slot = 0; slot < inventory.getContainerSize(); slot++){
|
||||
if(ingredient.test(inventory.getItem(slot))){
|
||||
if(inventory.getItem(slot).getCount() >= ingredient.getItems()[0].getCount() )
|
||||
enough++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ingredients.size() == enough;
|
||||
}
|
||||
|
||||
protected static boolean hasEnoughOutputSpace(ItemStackHandler stackHandler,ItemStack resultItemStack){
|
||||
return stackHandler.getStackInSlot(0).isEmpty() || stackHandler.getStackInSlot(0).is(resultItemStack.getItem()) && stackHandler.getStackInSlot(0).getMaxStackSize() - stackHandler.getStackInSlot(0).getCount() >= resultItemStack.getCount() ;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag getUpdateTag() {
|
||||
this.saveAdditional(updateTag);
|
||||
return updateTag;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public ClientboundBlockEntityDataPacket getUpdatePacket() {
|
||||
return ClientboundBlockEntityDataPacket.create(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleUpdateTag(CompoundTag tag) {
|
||||
this.load(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDataPacket(Connection net, ClientboundBlockEntityDataPacket pkt) {
|
||||
this.load(pkt.getTag());
|
||||
}
|
||||
|
||||
|
||||
|
||||
public int getProgressPercent() {
|
||||
return this.progress * 100 / this.maxProgress;
|
||||
}
|
||||
|
||||
|
||||
public void setItemStack(int slot, ItemStack itemStack,ItemStackSyncS2CPacket.SlotType slotType) {
|
||||
if(slotType == ItemStackSyncS2CPacket.SlotType.INPUT)
|
||||
inputItems.setStackInSlot(slot,itemStack);
|
||||
else if (slotType == ItemStackSyncS2CPacket.SlotType.OUTPUT)
|
||||
outputItems.setStackInSlot(slot,itemStack);
|
||||
else if (slotType == ItemStackSyncS2CPacket.SlotType.TARGET)
|
||||
targetItemHandler.setStackInSlot(slot,itemStack);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getDisplayName() {
|
||||
return ModLang.translate("block.display");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public AbstractContainerMenu createMenu(int pContainerId, Inventory pPlayerInventory, Player pPlayer) {
|
||||
return new TradingStationMenu(pContainerId, pPlayerInventory, this, this.containerData);
|
||||
}
|
||||
|
||||
public void setPreferedItem(ItemStack itemStack) {
|
||||
this.targetItemHandler.setStackInSlot(0,itemStack);
|
||||
}
|
||||
|
||||
|
||||
public ItemStack getPreferedItemStack() {
|
||||
return targetItemHandler.getStackInSlot(0);
|
||||
}
|
||||
public ItemStackHandler getTargetItemHandler(){
|
||||
return targetItemHandler;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.oierbravo.trading_station.content.trading_station;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.LightTexture;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.block.model.ItemTransforms;
|
||||
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
|
||||
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class TradingStationBlockRenderer implements BlockEntityRenderer<TradingStationBlockEntity> {
|
||||
public TradingStationBlockRenderer(BlockEntityRendererProvider.Context context) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(TradingStationBlockEntity pBlockEntity, float pPartialTick, @NotNull PoseStack pPoseStack, @NotNull MultiBufferSource pBufferSource, int pPackedLight, int pPackedOverlay) {
|
||||
if(!pBlockEntity.getPreferedItemStack().isEmpty()){
|
||||
pPoseStack.pushPose();
|
||||
pPoseStack.translate(0.5d, 1.1d, 0.5d);
|
||||
renderBlock(pPoseStack,pBufferSource, LightTexture.FULL_BRIGHT,pPackedOverlay,pBlockEntity.getPreferedItemStack());
|
||||
pPoseStack.popPose();
|
||||
}
|
||||
}
|
||||
protected void renderBlock(PoseStack ms, MultiBufferSource buffer, int light, int overlay, ItemStack stack) {
|
||||
Minecraft.getInstance()
|
||||
.getItemRenderer()
|
||||
.renderStatic(stack, ItemTransforms.TransformType.GROUND, light, overlay, ms, buffer, 0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.oierbravo.trading_station.content.trading_station;
|
||||
|
||||
import net.minecraftforge.common.ForgeConfigSpec;
|
||||
|
||||
public class TradingStationConfig {
|
||||
//public static ForgeConfigSpec.IntValue MELTER_CAPACITY;
|
||||
//public static ForgeConfigSpec.IntValue MELTER_FLUID_PER_TICK;
|
||||
|
||||
public static void registerServerConfig(ForgeConfigSpec.Builder COMMON_BUILDER) {
|
||||
/* SERVER_BUILDER.comment("Settings for the trading_station").push("trading_station");
|
||||
MELTER_CAPACITY = SERVER_BUILDER
|
||||
.comment("How much liquid fits into the trading_station, in mB")
|
||||
.defineInRange("capacity", 1000, 1, Integer.MAX_VALUE);
|
||||
MELTER_FLUID_PER_TICK = SERVER_BUILDER
|
||||
.comment("How much liquid generates per tick, in mB")
|
||||
.defineInRange("liquidPerTick", 2, 1, Integer.MAX_VALUE);
|
||||
SERVER_BUILDER.pop();*/
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
package com.oierbravo.trading_station.content.trading_station;
|
||||
|
||||
import com.oierbravo.trading_station.registrate.ModBlocks;
|
||||
import com.oierbravo.trading_station.registrate.ModMenus;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.MenuProvider;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.inventory.*;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraftforge.common.capabilities.ForgeCapabilities;
|
||||
import net.minecraftforge.items.ItemStackHandler;
|
||||
import net.minecraftforge.items.SlotItemHandler;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class TradingStationMenu extends AbstractContainerMenu {
|
||||
public final TradingStationBlockEntity blockEntity;
|
||||
public final Inventory inventory;
|
||||
private final Level level;
|
||||
private final ContainerData containerData;
|
||||
public ItemStackHandler ghostInventory;
|
||||
|
||||
|
||||
public TradingStationMenu(int pContainerId, Inventory inv, FriendlyByteBuf extraData){
|
||||
this(pContainerId, inv, inv.player.level.getBlockEntity(extraData.readBlockPos()), new SimpleContainerData(2));
|
||||
}
|
||||
|
||||
public TradingStationMenu(int pContainerId, Inventory pInv, BlockEntity pBlockEntity, ContainerData pData){
|
||||
super(ModMenus.TRADING_STATION.get(), pContainerId);
|
||||
checkContainerSize(pInv, 3);
|
||||
blockEntity = (TradingStationBlockEntity) pBlockEntity;
|
||||
this.level = pInv.player.getLevel();
|
||||
this.containerData = pData;
|
||||
this.inventory = pInv;
|
||||
addPlayerHotbar(pInv);
|
||||
addPlayerInventory(pInv);
|
||||
this.addDataSlots(pData);
|
||||
//this.blockEntity.inputItems
|
||||
this.blockEntity.getInputItemHandler().ifPresent(itemHandler -> {
|
||||
this.addSlot(new SlotItemHandler(itemHandler,0,TradingStationScreen.inputSlotX[0],TradingStationScreen.inputSlotY));
|
||||
this.addSlot(new SlotItemHandler(itemHandler,1,TradingStationScreen.inputSlotX[1],TradingStationScreen.inputSlotY));
|
||||
});
|
||||
this.blockEntity.getOutputItemHandler().ifPresent(itemHandler -> {
|
||||
this.addSlot(new SlotItemHandler(itemHandler,0,TradingStationScreen.outputSlotX,TradingStationScreen.outputSlotY));
|
||||
});
|
||||
this.addSlot(new SlotItemHandler(this.blockEntity.getTargetItemHandler(),0,87,28));
|
||||
|
||||
|
||||
}
|
||||
|
||||
public TradingStationMenu(int pContainerId, Inventory pInventory, BlockPos sourcePos) {
|
||||
this(pContainerId, pInventory, Minecraft.getInstance().level.getBlockEntity(sourcePos), TradingStationBlockEntity.createContainerData((TradingStationBlockEntity) Minecraft.getInstance().level.getBlockEntity(sourcePos)));
|
||||
}
|
||||
|
||||
public static TradingStationMenu factory(@Nullable MenuType<TradingStationMenu> pMenuType, int pContainerId, Inventory inventory, FriendlyByteBuf buf) {
|
||||
return new TradingStationMenu(pContainerId, inventory, buf);
|
||||
}
|
||||
public int getScaledProgress() {
|
||||
int progress = this.containerData.get(0);
|
||||
int maxProgress = this.containerData.get(1); // Max Progress
|
||||
int progressArrowSize = 34; // This is the height in pixels of your arrow
|
||||
|
||||
return maxProgress != 0 && progress != 0 ? progress * progressArrowSize / maxProgress : 0;
|
||||
}
|
||||
public boolean isCrafting() {
|
||||
return containerData.get(0) > 0;
|
||||
}
|
||||
private static final int HOTBAR_SLOT_COUNT = 9;
|
||||
private static final int PLAYER_INVENTORY_ROW_COUNT = 3;
|
||||
private static final int PLAYER_INVENTORY_COLUMN_COUNT = 9;
|
||||
private static final int PLAYER_INVENTORY_SLOT_COUNT = PLAYER_INVENTORY_COLUMN_COUNT * PLAYER_INVENTORY_ROW_COUNT;
|
||||
private static final int VANILLA_SLOT_COUNT = HOTBAR_SLOT_COUNT + PLAYER_INVENTORY_SLOT_COUNT;
|
||||
private static final int VANILLA_FIRST_SLOT_INDEX = 0;
|
||||
private static final int TE_INVENTORY_FIRST_SLOT_INDEX = VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT;
|
||||
|
||||
// THIS YOU HAVE TO DEFINE!
|
||||
private static final int TE_INVENTORY_SLOT_COUNT = 2; // must be the number of slots you have!
|
||||
@Override
|
||||
public ItemStack quickMoveStack(Player playerIn, int pIndex) {
|
||||
Slot sourceSlot = slots.get(pIndex);
|
||||
if (sourceSlot == null || !sourceSlot.hasItem()) return ItemStack.EMPTY; //EMPTY_ITEM
|
||||
ItemStack sourceStack = sourceSlot.getItem();
|
||||
ItemStack copyOfSourceStack = sourceStack.copy();
|
||||
|
||||
// Check if the slot clicked is one of the vanilla container slots
|
||||
if (pIndex < VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT) {
|
||||
// This is a vanilla container slot so merge the stack into the tile inventory
|
||||
if (!moveItemStackTo(sourceStack, TE_INVENTORY_FIRST_SLOT_INDEX, TE_INVENTORY_FIRST_SLOT_INDEX
|
||||
+ TE_INVENTORY_SLOT_COUNT, false)) {
|
||||
return ItemStack.EMPTY; // EMPTY_ITEM
|
||||
}
|
||||
} else if (pIndex < TE_INVENTORY_FIRST_SLOT_INDEX + TE_INVENTORY_SLOT_COUNT) {
|
||||
// This is a TE slot so merge the stack into the players inventory
|
||||
if (!moveItemStackTo(sourceStack, VANILLA_FIRST_SLOT_INDEX, VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT, false)) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
} else if (pIndex == TE_INVENTORY_FIRST_SLOT_INDEX + TE_INVENTORY_SLOT_COUNT) {
|
||||
// This is a TE Outpu slot so merge the stack into the players inventory
|
||||
if (!moveItemStackTo(sourceStack, VANILLA_FIRST_SLOT_INDEX, VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT, false)) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
} else {
|
||||
System.out.println("Invalid slotIndex:" + pIndex);
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
// If stack size == 0 (the entire stack was moved) set slot contents to null
|
||||
if (sourceStack.getCount() == 0) {
|
||||
sourceSlot.set(ItemStack.EMPTY);
|
||||
} else {
|
||||
sourceSlot.setChanged();
|
||||
}
|
||||
sourceSlot.onTake(playerIn, sourceStack);
|
||||
return copyOfSourceStack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stillValid(Player pPlayer) {
|
||||
return stillValid(ContainerLevelAccess.create(level, blockEntity.getBlockPos()), pPlayer, ModBlocks.TRADING_STATION.get());
|
||||
}
|
||||
private static final int PLAYER_INVENTORY_Y = 64;
|
||||
|
||||
private void addPlayerInventory(Inventory playerInventory) {
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
for (int l = 0; l < 9; ++l) {
|
||||
this.addSlot(new Slot(playerInventory, l + i * 9 + 9, 8 + l * 18, PLAYER_INVENTORY_Y + i * 18));
|
||||
}
|
||||
}
|
||||
}
|
||||
private static final int HOTBAR_Y = 122;
|
||||
|
||||
private void addPlayerHotbar(Inventory playerInventory) {
|
||||
for (int i = 0; i < 9; ++i) {
|
||||
this.addSlot(new Slot(playerInventory, i, 8 + i * 18, HOTBAR_Y));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package com.oierbravo.trading_station.content.trading_station;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.oierbravo.trading_station.TradingStation;
|
||||
import com.oierbravo.trading_station.foundation.util.ModLang;
|
||||
import com.oierbravo.trading_station.registrate.ModRecipes;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.crafting.Ingredient;
|
||||
import net.minecraftforge.client.gui.widget.ExtendedButton;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Optional;
|
||||
|
||||
public class TradingStationScreen extends AbstractContainerScreen<TradingStationMenu> {
|
||||
private static final ResourceLocation TEXTURE = TradingStation.asResource("textures/gui/trading_station.png");
|
||||
|
||||
private int progressArrowX = 79;
|
||||
private int progressArrowY = 47;
|
||||
|
||||
private int targetSelectButtonX = 131;
|
||||
private int targetSelectButtonY = 18;
|
||||
|
||||
public static int inputSlotX[] = {19,42};
|
||||
public static int inputSlotY = 38;
|
||||
public static int outputSlotX = 131;
|
||||
public static int outputSlotY = 38;
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
super.init();
|
||||
this.titleLabelX = 4;
|
||||
this.titleLabelY = 4;
|
||||
this.inventoryLabelY = 100000;
|
||||
this.addRenderableWidget(new ExtendedButton(leftPos + targetSelectButtonX,topPos + targetSelectButtonY,16,16, ModLang.translate("select_target.button"), btn ->{
|
||||
TradingStationTargetSelectScreen screen = new TradingStationTargetSelectScreen( this.menu.blockEntity);
|
||||
Minecraft.getInstance().pushGuiLayer(screen);
|
||||
|
||||
}));
|
||||
}
|
||||
|
||||
public TradingStationScreen(TradingStationMenu pMenu, Inventory pPlayerInventory, Component pTitle) {
|
||||
super(pMenu, pPlayerInventory, pTitle);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderBg(PoseStack pPoseStack, float pPartialTick, int pMouseX, int pMouseY) {
|
||||
RenderSystem.setShader(GameRenderer::getPositionTexShader);
|
||||
RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
RenderSystem.setShaderTexture(0, TEXTURE);
|
||||
this.fillGradient(pPoseStack, 0, 0, this.width, this.height, -1072689136, -804253680);
|
||||
|
||||
int x = (width - imageWidth) / 2;
|
||||
int y = (height - imageHeight) / 2;
|
||||
this.blit(pPoseStack, x, y, 0, 0, imageWidth, imageHeight);
|
||||
|
||||
if (menu.isCrafting()) {
|
||||
this.blit(pPoseStack, x + progressArrowX, y + progressArrowY, 179, 0, menu.getScaledProgress(), 7);
|
||||
}
|
||||
|
||||
if(!menu.blockEntity.getPreferedItemStack().isEmpty()){
|
||||
Optional<TradingRecipe> recipe = ModRecipes.findByOutput(menu.blockEntity.getLevel(),menu.blockEntity.getPreferedItemStack());
|
||||
if(recipe.isPresent()){
|
||||
renderFakeRecipe(recipe.get(), pPoseStack);
|
||||
}
|
||||
}
|
||||
}
|
||||
private void renderFakeRecipe(TradingRecipe recipe, PoseStack pPoseStack){
|
||||
for(int index = 0; index < recipe.getIngredients().size(); index++){
|
||||
Ingredient ingredient = recipe.getIngredients().get(index);
|
||||
if(!ingredient.isEmpty())
|
||||
FakeItemRenderer.renderFakeItem(ingredient.getItems()[0],getGuiLeft() + TradingStationScreen.inputSlotX[index],getGuiTop() + TradingStationScreen.inputSlotY, .5f);
|
||||
}
|
||||
FakeItemRenderer.renderFakeItem(recipe.getResultItem(),getGuiLeft() + TradingStationScreen.outputSlotX,getGuiTop() + TradingStationScreen.outputSlotY, .5f);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void render(PoseStack pPoseStack, int pMouseX, int pMouseY, float pPartialTick) {
|
||||
super.render(pPoseStack, pMouseX, pMouseY, pPartialTick);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,246 @@
|
||||
package com.oierbravo.trading_station.content.trading_station;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.oierbravo.trading_station.TradingStation;
|
||||
import com.oierbravo.trading_station.foundation.util.ModLang;
|
||||
import com.oierbravo.trading_station.network.packets.GhostItemSyncC2SPacket;
|
||||
import com.oierbravo.trading_station.registrate.ModMessages;
|
||||
import com.oierbravo.trading_station.registrate.ModRecipes;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.components.Button;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.client.resources.sounds.SimpleSoundInstance;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Scroll code and loop adapted from Alchemistry/src/main/java/com/smashingmods/alchemistry/client/container/RecipeSelectorScreen.java
|
||||
*/
|
||||
public class TradingStationTargetSelectScreen extends Screen {
|
||||
private static final ResourceLocation TEXTURE = TradingStation.asResource("textures/gui/trade_select.png");
|
||||
private TradingStationBlockEntity blockEntity;
|
||||
private List<ItemStack> allPossibleOutputs;
|
||||
private LinkedList<ItemStack> displayedItemStacks = new LinkedList<>();
|
||||
|
||||
|
||||
private float scrollOffset;
|
||||
private boolean scrolling;
|
||||
private int startIndex;
|
||||
private static int MAX_DISPLAYED_RECIPES = 24;
|
||||
private static final int COLUMNS = 8;
|
||||
private static final int TARGET_BOX_SIZE = 17;
|
||||
|
||||
private int targetBoxLeftPosOffset = 7;
|
||||
private int targetBoxTopPosOffset = 19;
|
||||
|
||||
private int scrollBarXOffset = 148;
|
||||
private int scrollBarYOffset = 22;
|
||||
|
||||
protected int titleLabelX;
|
||||
protected int titleLabelY;
|
||||
protected int imageWidth = 165;
|
||||
protected int imageHeight = 83;
|
||||
protected int leftPos;
|
||||
protected int topPos;
|
||||
|
||||
protected TradingStationTargetSelectScreen(Component pTitle) {
|
||||
super(pTitle);
|
||||
}
|
||||
public TradingStationTargetSelectScreen(TradingStationBlockEntity pBlockEntity) {
|
||||
this(ModLang.translate("select_target.title"));
|
||||
this.blockEntity = pBlockEntity;
|
||||
this.allPossibleOutputs = ModRecipes.getAllOutputs(pBlockEntity.getLevel());
|
||||
resetDisplayedTargets();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
super.init();
|
||||
this.titleLabelX = 4;
|
||||
this.titleLabelY = 4;
|
||||
this.leftPos = (this.width - this.imageWidth) / 2;
|
||||
this.topPos = (this.height - this.imageHeight) / 2;
|
||||
addRenderableWidget(new Button(getGuiLeft() - 25, getGuiTop() + 1, 25, 20, Component.literal("<--"), (button) -> {
|
||||
Minecraft.getInstance().popGuiLayer();
|
||||
}));
|
||||
addRenderableWidget(new Button(getGuiLeft() - 25, getGuiTop() + 30, 25, 20, ModLang.translate("select_target.clear"), (button) -> {
|
||||
ModMessages.sendToServer(new GhostItemSyncC2SPacket(ItemStack.EMPTY,this.blockEntity.getBlockPos()));
|
||||
Minecraft.getInstance().getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_STONECUTTER_SELECT_RECIPE, 1.0f));
|
||||
Minecraft.getInstance().popGuiLayer();
|
||||
}));
|
||||
}
|
||||
|
||||
public int getGuiLeft() { return leftPos; }
|
||||
public int getGuiTop() { return topPos; }
|
||||
@Override
|
||||
public void tick() {
|
||||
if (displayedItemStacks.size() < MAX_DISPLAYED_RECIPES) {
|
||||
mouseScrolled(0, 0, 0);
|
||||
scrollOffset = 0.0f;
|
||||
}
|
||||
if (displayedItemStacks.size() <= MAX_DISPLAYED_RECIPES) {
|
||||
startIndex = 0;
|
||||
scrollOffset = 0;
|
||||
}
|
||||
super.tick();
|
||||
}
|
||||
@Override
|
||||
public void render(PoseStack pPoseStack, int pMouseX, int pMouseY, float pPartialTick) {
|
||||
|
||||
renderBackground(pPoseStack);
|
||||
|
||||
int lastDisplayedIndex = startIndex + MAX_DISPLAYED_RECIPES;
|
||||
|
||||
renderScrollbar(pPoseStack);
|
||||
renderSelectedTarget(pPoseStack, pMouseX, pMouseY, lastDisplayedIndex);
|
||||
renderTargetItems(pPoseStack, pMouseX, pMouseY, lastDisplayedIndex);
|
||||
renderLabels(pPoseStack, pMouseX, pMouseY);
|
||||
|
||||
super.render(pPoseStack, pMouseX, pMouseY, pPartialTick);
|
||||
}
|
||||
protected void renderLabels(PoseStack pPoseStack, int pMouseX, int pMouseY) {
|
||||
this.font.draw(pPoseStack, this.title, (float)this.titleLabelX + getGuiLeft(), (float)this.titleLabelY + getGuiTop(), 4210752);
|
||||
}
|
||||
private void renderSelectedTarget(PoseStack pPoseStack, int pMouseX, int pMouseY, int pLastDisplayedIndex) {
|
||||
LinkedList<ItemStack> displayedRecipes = getDisplayedItemStacks();
|
||||
ItemStack selectedTarget = this.blockEntity.getTargetItemHandler().getStackInSlot(0);
|
||||
for (int index = startIndex; index >= 0 && index < pLastDisplayedIndex && index < displayedRecipes.size(); index++) {
|
||||
|
||||
int firstDisplayedIndex = index - startIndex;
|
||||
ItemStack target = allPossibleOutputs.get(index);
|
||||
int xStart = getGuiLeft() + targetBoxLeftPosOffset + firstDisplayedIndex % COLUMNS * TARGET_BOX_SIZE + 1;
|
||||
int yStart = getGuiTop() + targetBoxTopPosOffset + (firstDisplayedIndex / COLUMNS) * TARGET_BOX_SIZE + 3;
|
||||
if(target.sameItem(selectedTarget))
|
||||
blit(pPoseStack, xStart, yStart, 0, imageHeight + 19, TARGET_BOX_SIZE, TARGET_BOX_SIZE);
|
||||
}
|
||||
}
|
||||
private void renderTargetItems(PoseStack pPoseStack, int pMouseX, int pMouseY, int pLastDisplayedIndex) {
|
||||
LinkedList<ItemStack> displayedRecipes = getDisplayedItemStacks();
|
||||
|
||||
for (int index = startIndex; index >= 0 && index < pLastDisplayedIndex && index < displayedRecipes.size(); index++) {
|
||||
|
||||
int firstDisplayedIndex = index - startIndex;
|
||||
ItemStack target = allPossibleOutputs.get(index);
|
||||
int xStart = getGuiLeft() + targetBoxLeftPosOffset + firstDisplayedIndex % COLUMNS * TARGET_BOX_SIZE + 1;
|
||||
int yStart = getGuiTop() + targetBoxTopPosOffset + (firstDisplayedIndex / COLUMNS) * TARGET_BOX_SIZE + 3;
|
||||
|
||||
renderFloatingItem(target, xStart, yStart);
|
||||
|
||||
if (pMouseX >= xStart - 1 && pMouseX <= xStart + 16 && pMouseY >= yStart - 1 && pMouseY <= yStart + 16) {
|
||||
renderTooltip(pPoseStack, target, pMouseX, pMouseY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private LinkedList<ItemStack> getDisplayedItemStacks() {
|
||||
return displayedItemStacks;
|
||||
}
|
||||
|
||||
private void renderFloatingItem(ItemStack pItemStack, int pX, int pY) {
|
||||
RenderSystem.applyModelViewMatrix();
|
||||
setBlitOffset(2000);
|
||||
itemRenderer.blitOffset = 2000.0f;
|
||||
|
||||
itemRenderer.renderAndDecorateItem(pItemStack, pX, pY);
|
||||
itemRenderer.renderGuiItemDecorations(font, pItemStack, pX, pY, "");
|
||||
|
||||
setBlitOffset(0);
|
||||
itemRenderer.blitOffset = 0.0f;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void renderBackground(PoseStack pPoseStack) {
|
||||
RenderSystem.setShader(GameRenderer::getPositionTexShader);
|
||||
RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
RenderSystem.setShaderTexture(0, TEXTURE);
|
||||
this.fillGradient(pPoseStack, 0, 0, this.width, this.height, -1072689136, -804253680);
|
||||
this.blit(pPoseStack, getGuiLeft(), getGuiTop(), 0, 0, imageWidth, imageHeight);
|
||||
}
|
||||
|
||||
private void renderScrollbar(PoseStack pPoseStack) {
|
||||
int scrollPosition = (int) (43.0f * scrollOffset);
|
||||
blit(pPoseStack, getGuiLeft() + scrollBarXOffset, getGuiTop() + scrollBarYOffset + scrollPosition, 0, imageHeight + 1 + (isScrollBarActive() ? 0 : 9), 7, 9);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseClicked(double pMouseX, double pMouseY, int pButton) {
|
||||
scrolling = false;
|
||||
|
||||
int lastDisplayedIndex = startIndex + MAX_DISPLAYED_RECIPES;
|
||||
|
||||
for (int index = startIndex; index < lastDisplayedIndex; index++) {
|
||||
int currentIndex = index - startIndex;
|
||||
double boxX = pMouseX - (double)(getGuiLeft() + targetBoxLeftPosOffset + currentIndex % COLUMNS * TARGET_BOX_SIZE);
|
||||
double boxY = pMouseY - (double)(getGuiTop() + targetBoxTopPosOffset + currentIndex / COLUMNS * TARGET_BOX_SIZE);
|
||||
|
||||
if (boxX > 0 && boxX <= TARGET_BOX_SIZE + 1 && boxY > 0 && boxY <= TARGET_BOX_SIZE + 1 && isValidRecipeIndex(index)) {
|
||||
ItemStack itemStack = getDisplayedItemStacks().get(index);
|
||||
ModMessages.sendToServer(new GhostItemSyncC2SPacket(itemStack,this.blockEntity.getBlockPos()));
|
||||
Minecraft.getInstance().getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_STONECUTTER_SELECT_RECIPE, 1.0f));
|
||||
Minecraft.getInstance().popGuiLayer();
|
||||
return true;
|
||||
}
|
||||
|
||||
int scrollMinX = leftPos + 148;
|
||||
int scrollMinY = topPos + 9;
|
||||
int scrollMaxX = scrollMinX + 6;
|
||||
int scrollMaxY = scrollMinY + 60;
|
||||
|
||||
if (pMouseX >= scrollMinX && pMouseX < scrollMaxX && pMouseY >= scrollMinY && pMouseY < scrollMaxY) {
|
||||
scrolling = true;
|
||||
}
|
||||
}
|
||||
return super.mouseClicked(pMouseX, pMouseY, pButton);
|
||||
}
|
||||
private boolean isValidRecipeIndex(int pSlot) {
|
||||
return pSlot >= 0 && pSlot < getDisplayedItemStacks().size();
|
||||
}
|
||||
@Override
|
||||
public boolean isPauseScreen() {
|
||||
return false;
|
||||
}
|
||||
public void resetDisplayedTargets() {
|
||||
this.displayedItemStacks.clear();
|
||||
this.displayedItemStacks.addAll(allPossibleOutputs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseDragged(double pMouseX, double pMouseY, int pButton, double pDragX, double pDragY) {
|
||||
if (scrolling && isScrollBarActive()) {
|
||||
int scrollbarTopPos = getGuiTop() + 9;
|
||||
int scrollbarBottomPos = scrollbarTopPos + 51;
|
||||
scrollOffset = ((float) pMouseY - (float) scrollbarTopPos - 7.5f) / ((float) (scrollbarBottomPos - scrollbarTopPos) - 9.0f);
|
||||
scrollOffset = Mth.clamp(scrollOffset, 0.0f, 1.0f);
|
||||
startIndex = (int) ((double) (scrollOffset * (float) getOffscreenRows()) + 0.5d) * COLUMNS;
|
||||
return true;
|
||||
} else {
|
||||
return super.mouseDragged(pMouseX, pMouseY, pButton, pDragX, pDragY);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseScrolled(double pMouseX, double pMouseY, double pDelta) {
|
||||
if (pMouseX >= leftPos && pMouseX < leftPos + imageWidth && pMouseY >= topPos && pMouseY < topPos + imageHeight && isScrollBarActive()) {
|
||||
scrollOffset = Mth.clamp(scrollOffset - (float) pDelta / (float) getOffscreenRows(), 0.0f, 1.0f);
|
||||
startIndex = (int) ((double) (scrollOffset * (float) getOffscreenRows()) + 0.5d) * COLUMNS;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
private int getOffscreenRows() {
|
||||
return (displayedItemStacks.size() + 6 - 1) / 6 - 3;
|
||||
}
|
||||
private boolean isScrollBarActive() {
|
||||
return displayedItemStacks.size() > MAX_DISPLAYED_RECIPES;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.oierbravo.trading_station.content.trading_station.powered;
|
||||
|
||||
import com.oierbravo.trading_station.content.trading_station.TradingStationBlock;
|
||||
import com.oierbravo.trading_station.content.trading_station.TradingStationBlockEntity;
|
||||
import com.oierbravo.trading_station.registrate.ModBlockEntities;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityTicker;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class PoweredTradingStationBlock extends TradingStationBlock {
|
||||
public PoweredTradingStationBlock(Properties pProperties) {
|
||||
super(pProperties);
|
||||
}
|
||||
@Nullable
|
||||
@Override
|
||||
public BlockEntity newBlockEntity(BlockPos pPos, BlockState pState) {
|
||||
return ModBlockEntities.POWERED_TRADING_STATION.create(pPos, pState);
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level pLevel, BlockState pState, BlockEntityType<T> pBlockEntityType) {
|
||||
return createTickerHelper(pBlockEntityType, ModBlockEntities.POWERED_TRADING_STATION.get(),
|
||||
TradingStationBlockEntity::tick);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.oierbravo.trading_station.content.trading_station.powered;
|
||||
|
||||
import com.oierbravo.trading_station.content.trading_station.TradingStationBlockEntity;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public class PoweredTradingStationBlockEntity extends TradingStationBlockEntity {
|
||||
public PoweredTradingStationBlockEntity(BlockEntityType<?> pType, BlockPos pWorldPosition, BlockState pBlockState) {
|
||||
super(pType, pWorldPosition, pBlockState);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.oierbravo.trading_station.foundation.gui;
|
||||
|
||||
import com.oierbravo.trading_station.content.trading_station.TradingStationScreen;
|
||||
import net.minecraft.client.gui.components.Button;
|
||||
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraftforge.client.gui.widget.ExtendedButton;
|
||||
|
||||
public class BackButton extends ExtendedButton {
|
||||
public BackButton(int pX, int pY, int pWidth, int pHeight, Component pMessage, OnPress pOnPress) {
|
||||
super(pX, pY, pWidth, pHeight, pMessage, pOnPress);
|
||||
}
|
||||
/* public BackButton(int pX, int pY, AbstractContainerScreen<TradingStationScreen> parentScreen){
|
||||
this(pX,pY,16,16,Component.literal("Back"), btn->{
|
||||
this.
|
||||
})
|
||||
}*/
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
package com.oierbravo.trading_station.foundation.render;
|
||||
|
||||
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
import com.oierbravo.trading_station.TradingStation;
|
||||
import net.minecraft.client.renderer.RenderStateShard;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.renderer.ShaderInstance;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.packs.resources.ResourceManager;
|
||||
import net.minecraft.world.inventory.InventoryMenu;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.client.event.RegisterShadersEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
// TODO 1.17: use custom shaders instead of vanilla ones
|
||||
public class RenderTypes extends RenderStateShard {
|
||||
|
||||
public static final ShaderStateShard GLOWING_SHADER = new ShaderStateShard(() -> Shaders.glowingShader);
|
||||
|
||||
|
||||
|
||||
|
||||
public static RenderType getOutlineTranslucent(ResourceLocation texture, boolean cull) {
|
||||
return RenderType.create(createLayerName("outline_translucent" + (cull ? "_cull" : "")),
|
||||
DefaultVertexFormat.NEW_ENTITY, VertexFormat.Mode.QUADS, 256, false, true, RenderType.CompositeState.builder()
|
||||
.setShaderState(cull ? RENDERTYPE_ENTITY_TRANSLUCENT_CULL_SHADER : RENDERTYPE_ENTITY_TRANSLUCENT_SHADER)
|
||||
.setTextureState(new TextureStateShard(texture, false, false))
|
||||
.setTransparencyState(TRANSLUCENT_TRANSPARENCY)
|
||||
.setCullState(cull ? CULL : NO_CULL)
|
||||
.setLightmapState(LIGHTMAP)
|
||||
.setOverlayState(OVERLAY)
|
||||
.setWriteMaskState(COLOR_WRITE)
|
||||
.createCompositeState(false));
|
||||
}
|
||||
|
||||
public static RenderType getGlowingSolid(ResourceLocation texture) {
|
||||
return RenderType.create(createLayerName("glowing_solid"), DefaultVertexFormat.NEW_ENTITY, VertexFormat.Mode.QUADS, 256,
|
||||
true, false, RenderType.CompositeState.builder()
|
||||
.setShaderState(GLOWING_SHADER)
|
||||
.setTextureState(new TextureStateShard(texture, false, false))
|
||||
.setCullState(CULL)
|
||||
.setLightmapState(LIGHTMAP)
|
||||
.setOverlayState(OVERLAY)
|
||||
.createCompositeState(true));
|
||||
}
|
||||
|
||||
private static final RenderType GLOWING_SOLID_DEFAULT = getGlowingSolid(InventoryMenu.BLOCK_ATLAS);
|
||||
|
||||
public static RenderType getGlowingSolid() {
|
||||
return GLOWING_SOLID_DEFAULT;
|
||||
}
|
||||
|
||||
public static RenderType getGlowingTranslucent(ResourceLocation texture) {
|
||||
return RenderType.create(createLayerName("glowing_translucent"), DefaultVertexFormat.NEW_ENTITY, VertexFormat.Mode.QUADS,
|
||||
256, true, true, RenderType.CompositeState.builder()
|
||||
.setShaderState(GLOWING_SHADER)
|
||||
.setTextureState(new TextureStateShard(texture, false, false))
|
||||
.setTransparencyState(TRANSLUCENT_TRANSPARENCY)
|
||||
.setLightmapState(LIGHTMAP)
|
||||
.setOverlayState(OVERLAY)
|
||||
.createCompositeState(true));
|
||||
}
|
||||
|
||||
private static final RenderType ADDITIVE = RenderType.create(createLayerName("additive"), DefaultVertexFormat.BLOCK,
|
||||
VertexFormat.Mode.QUADS, 256, true, true, RenderType.CompositeState.builder()
|
||||
.setShaderState(BLOCK_SHADER)
|
||||
.setTextureState(new TextureStateShard(InventoryMenu.BLOCK_ATLAS, false, false))
|
||||
.setTransparencyState(ADDITIVE_TRANSPARENCY)
|
||||
.setCullState(NO_CULL)
|
||||
.setLightmapState(LIGHTMAP)
|
||||
.setOverlayState(OVERLAY)
|
||||
.createCompositeState(true));
|
||||
|
||||
public static RenderType getAdditive() {
|
||||
return ADDITIVE;
|
||||
}
|
||||
|
||||
private static final RenderType GLOWING_TRANSLUCENT_DEFAULT = getGlowingTranslucent(InventoryMenu.BLOCK_ATLAS);
|
||||
|
||||
public static RenderType getGlowingTranslucent() {
|
||||
return GLOWING_TRANSLUCENT_DEFAULT;
|
||||
}
|
||||
|
||||
private static final RenderType ITEM_PARTIAL_SOLID =
|
||||
RenderType.create(createLayerName("item_partial_solid"), DefaultVertexFormat.NEW_ENTITY, VertexFormat.Mode.QUADS, 256, true,
|
||||
false, RenderType.CompositeState.builder()
|
||||
.setShaderState(RENDERTYPE_ENTITY_SOLID_SHADER)
|
||||
.setTextureState(BLOCK_SHEET)
|
||||
.setCullState(CULL)
|
||||
.setLightmapState(LIGHTMAP)
|
||||
.setOverlayState(OVERLAY)
|
||||
.createCompositeState(true));
|
||||
|
||||
public static RenderType getItemPartialSolid() {
|
||||
return ITEM_PARTIAL_SOLID;
|
||||
}
|
||||
|
||||
private static final RenderType ITEM_PARTIAL_TRANSLUCENT = RenderType.create(createLayerName("item_partial_translucent"),
|
||||
DefaultVertexFormat.NEW_ENTITY, VertexFormat.Mode.QUADS, 256, true, true, RenderType.CompositeState.builder()
|
||||
.setShaderState(RENDERTYPE_ENTITY_TRANSLUCENT_CULL_SHADER)
|
||||
.setTextureState(BLOCK_SHEET)
|
||||
.setTransparencyState(TRANSLUCENT_TRANSPARENCY)
|
||||
.setLightmapState(LIGHTMAP)
|
||||
.setOverlayState(OVERLAY)
|
||||
.createCompositeState(true));
|
||||
|
||||
public static RenderType getItemPartialTranslucent() {
|
||||
return ITEM_PARTIAL_TRANSLUCENT;
|
||||
}
|
||||
|
||||
private static final RenderType FLUID = RenderType.create(createLayerName("fluid"),
|
||||
DefaultVertexFormat.NEW_ENTITY, VertexFormat.Mode.QUADS, 256, false, true, RenderType.CompositeState.builder()
|
||||
.setShaderState(RENDERTYPE_ENTITY_TRANSLUCENT_CULL_SHADER)
|
||||
.setTextureState(BLOCK_SHEET_MIPPED)
|
||||
.setTransparencyState(TRANSLUCENT_TRANSPARENCY)
|
||||
.setLightmapState(LIGHTMAP)
|
||||
.setOverlayState(OVERLAY)
|
||||
.createCompositeState(true));
|
||||
|
||||
public static RenderType getFluid() {
|
||||
return FLUID;
|
||||
}
|
||||
|
||||
private static String createLayerName(String name) {
|
||||
return TradingStation.MODID + ":" + name;
|
||||
}
|
||||
|
||||
// Mmm gimme those protected fields
|
||||
private RenderTypes() {
|
||||
super(null, null, null);
|
||||
}
|
||||
|
||||
@EventBusSubscriber(value = Dist.CLIENT, bus = EventBusSubscriber.Bus.MOD)
|
||||
private static class Shaders {
|
||||
private static ShaderInstance glowingShader;
|
||||
|
||||
/*@SubscribeEvent
|
||||
public static void onRegisterShaders(RegisterShadersEvent event) throws IOException {
|
||||
ResourceManager resourceManager = event.getResourceManager();
|
||||
event.registerShader(new ShaderInstance(resourceManager, TradingStation.asResource("glowing_shader"), DefaultVertexFormat.NEW_ENTITY), shader -> glowingShader = shader);
|
||||
}*/
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.oierbravo.trading_station.foundation.util;
|
||||
|
||||
import com.oierbravo.trading_station.TradingStation;
|
||||
import net.minecraft.network.chat.Component;
|
||||
|
||||
public class ModLang {
|
||||
|
||||
public static Component translate(String key){
|
||||
return Component.translatable(TradingStation.MODID + '.' + key);
|
||||
}
|
||||
public static String key(String key){
|
||||
return TradingStation.MODID + '.' + key;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.oierbravo.trading_station.network.packets;
|
||||
|
||||
import com.oierbravo.trading_station.content.trading_station.TradingStationBlockEntity;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraftforge.network.NetworkEvent;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class GhostItemSyncC2SPacket {
|
||||
private final ItemStack itemStack;
|
||||
private final BlockPos pos;
|
||||
|
||||
public GhostItemSyncC2SPacket(ItemStack itemStack, BlockPos pos) {
|
||||
this.itemStack = itemStack;
|
||||
this.pos = pos;
|
||||
|
||||
}
|
||||
|
||||
public GhostItemSyncC2SPacket(FriendlyByteBuf buf) {
|
||||
this.itemStack = buf.readItem();
|
||||
this.pos = buf.readBlockPos();
|
||||
|
||||
}
|
||||
|
||||
public void toBytes(FriendlyByteBuf buf) {
|
||||
buf.writeItem(itemStack);
|
||||
buf.writeBlockPos(pos);
|
||||
|
||||
}
|
||||
|
||||
public static void handle(GhostItemSyncC2SPacket message, Supplier<NetworkEvent.Context> supplier) {
|
||||
NetworkEvent.Context context = supplier.get();
|
||||
|
||||
context.enqueueWork(() -> {
|
||||
ServerPlayer sender = context.getSender();
|
||||
if (sender == null)
|
||||
return;
|
||||
|
||||
AbstractContainerMenu container = sender.containerMenu;
|
||||
if (container == null)
|
||||
return;
|
||||
|
||||
if(sender.getLevel().getBlockEntity(message.pos) instanceof TradingStationBlockEntity blockEntity) {
|
||||
blockEntity.setPreferedItem(message.itemStack);
|
||||
//blockEntity.setChanged();
|
||||
|
||||
}
|
||||
});
|
||||
context.setPacketHandled(true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.oierbravo.trading_station.network.packets;
|
||||
|
||||
import com.oierbravo.trading_station.content.trading_station.TradingStationBlockEntity;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.network.NetworkEvent;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class ItemStackSyncS2CPacket {
|
||||
private final int slot;
|
||||
private final ItemStack itemStack;
|
||||
private final BlockPos pos;
|
||||
public enum SlotType {
|
||||
INPUT, OUTPUT, TARGET;
|
||||
}
|
||||
private final SlotType slotType;
|
||||
|
||||
public ItemStackSyncS2CPacket(int slot, ItemStack itemStack, BlockPos pos,SlotType slotType) {
|
||||
this.slot = slot;
|
||||
this.itemStack = itemStack;
|
||||
this.pos = pos;
|
||||
this.slotType = slotType;
|
||||
}
|
||||
|
||||
public ItemStackSyncS2CPacket(FriendlyByteBuf buf) {
|
||||
this.slot = buf.readInt();
|
||||
this.itemStack = buf.readItem();
|
||||
this.pos = buf.readBlockPos();
|
||||
this.slotType = SlotType.values()[buf.readInt()];
|
||||
}
|
||||
|
||||
public void toBytes(FriendlyByteBuf buf) {
|
||||
buf.writeInt(slot);
|
||||
buf.writeItem(itemStack);
|
||||
buf.writeBlockPos(pos);
|
||||
buf.writeInt(slotType.ordinal());
|
||||
|
||||
}
|
||||
|
||||
public static boolean handle(ItemStackSyncS2CPacket message, Supplier<NetworkEvent.Context> supplier) {
|
||||
NetworkEvent.Context context = supplier.get();
|
||||
context.enqueueWork(() -> {
|
||||
if(Minecraft.getInstance().level.getBlockEntity(message.pos) instanceof TradingStationBlockEntity blockEntity) {
|
||||
blockEntity.setItemStack(message.slot,message.itemStack,message.slotType);
|
||||
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.oierbravo.trading_station.network.packets;
|
||||
|
||||
import com.oierbravo.trading_station.content.trading_station.TradingStationBlockEntity;
|
||||
import com.oierbravo.trading_station.content.trading_station.TradingStationMenu;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.SimpleMenuProvider;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraftforge.network.NetworkEvent;
|
||||
import net.minecraftforge.network.NetworkHooks;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class OpenTargetSelectPacket {
|
||||
private BlockPos sourcePos;
|
||||
|
||||
public OpenTargetSelectPacket(BlockPos pSourcePos){
|
||||
this.sourcePos = pSourcePos;
|
||||
}
|
||||
public OpenTargetSelectPacket(FriendlyByteBuf buf){
|
||||
this(buf.readBlockPos());
|
||||
}
|
||||
|
||||
public void toBytes(FriendlyByteBuf buf) {
|
||||
buf.writeBlockPos(sourcePos);
|
||||
}
|
||||
public static boolean handle(OpenTargetSelectPacket message, Supplier<NetworkEvent.Context> supplier) {
|
||||
NetworkEvent.Context context = supplier.get();
|
||||
context.enqueueWork(() -> {
|
||||
ServerPlayer sender = context.getSender();
|
||||
if (sender == null)
|
||||
return;
|
||||
|
||||
TradingStationMenu container = (TradingStationMenu) sender.containerMenu;
|
||||
if (container == null)
|
||||
return;
|
||||
|
||||
/*NetworkHooks.openScreen(sender, new SimpleMenuProvider(
|
||||
(windowId, playerInventory, playerEntity) -> new TradingTradeSelectMenu(windowId, message.sourcePos), Component.translatable("")), (buf -> {
|
||||
buf.writeBlockPos(message.sourcePos);
|
||||
}));*/
|
||||
NetworkHooks.openScreen(((ServerPlayer)sender), (TradingStationBlockEntity)container.blockEntity, message.sourcePos);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.oierbravo.trading_station.network.packets;
|
||||
|
||||
import com.oierbravo.trading_station.content.trading_station.TradingStationMenu;
|
||||
import dev.latvian.mods.rhino.ast.Block;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.SimpleMenuProvider;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraftforge.network.NetworkEvent;
|
||||
import net.minecraftforge.network.NetworkHooks;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class OpenTradingMenuPacket {
|
||||
protected BlockPos sourcePos;
|
||||
|
||||
public OpenTradingMenuPacket(BlockPos pSourcePos){
|
||||
this.sourcePos = pSourcePos;
|
||||
}
|
||||
public OpenTradingMenuPacket(FriendlyByteBuf buf){
|
||||
this(buf.readBlockPos());
|
||||
}
|
||||
|
||||
public void toBytes(FriendlyByteBuf buf) {
|
||||
buf.writeBlockPos(sourcePos);
|
||||
}
|
||||
|
||||
public BlockPos getSourcePos(){
|
||||
return sourcePos;
|
||||
}
|
||||
public static boolean handle(OpenTradingMenuPacket message, Supplier<NetworkEvent.Context> supplier) {
|
||||
NetworkEvent.Context context = supplier.get();
|
||||
context.enqueueWork(() -> {
|
||||
ServerPlayer sender = context.getSender();
|
||||
if (sender == null)
|
||||
return;
|
||||
|
||||
AbstractContainerMenu container = sender.containerMenu;
|
||||
if (container == null)
|
||||
return;
|
||||
|
||||
NetworkHooks.openScreen(sender, new SimpleMenuProvider(
|
||||
(windowId, playerInventory, playerEntity) -> new TradingStationMenu(windowId,playerInventory,message.sourcePos), Component.translatable("trading_station.block.display")), (buf -> {
|
||||
buf.writeBlockPos(message.sourcePos);
|
||||
}));
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.oierbravo.trading_station.registrate;
|
||||
|
||||
import com.oierbravo.trading_station.content.trading_station.TradingStationConfig;
|
||||
import net.minecraftforge.common.ForgeConfigSpec;
|
||||
import net.minecraftforge.fml.ModLoadingContext;
|
||||
import net.minecraftforge.fml.config.ModConfig;
|
||||
|
||||
//From https://github.com/McJty/TutorialV3/blob/1.19/src/main/java/com/example/tutorialv3/setup/Config.java
|
||||
public class Config {
|
||||
public static void register() {
|
||||
registerServerConfigs();
|
||||
//registerCommonConfigs();
|
||||
//registerClientConfigs();
|
||||
}
|
||||
private static void registerClientConfigs() {
|
||||
ForgeConfigSpec.Builder CLIENT_BUILDER = new ForgeConfigSpec.Builder();
|
||||
ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, CLIENT_BUILDER.build());
|
||||
}
|
||||
|
||||
private static void registerCommonConfigs() {
|
||||
ForgeConfigSpec.Builder COMMON_BUILDER = new ForgeConfigSpec.Builder();
|
||||
ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, COMMON_BUILDER.build());
|
||||
}
|
||||
|
||||
private static void registerServerConfigs() {
|
||||
ForgeConfigSpec.Builder SERVER_BUILDER = new ForgeConfigSpec.Builder();
|
||||
TradingStationConfig.registerServerConfig(SERVER_BUILDER);
|
||||
ModLoadingContext.get().registerConfig(ModConfig.Type.SERVER, SERVER_BUILDER.build());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.oierbravo.trading_station.registrate;
|
||||
|
||||
import com.oierbravo.trading_station.TradingStation;
|
||||
import com.oierbravo.trading_station.content.trading_station.TradingStationBlockEntity;
|
||||
import com.oierbravo.trading_station.content.trading_station.TradingStationBlockRenderer;
|
||||
import com.oierbravo.trading_station.content.trading_station.powered.PoweredTradingStationBlockEntity;
|
||||
import com.tterrag.registrate.util.entry.BlockEntityEntry;
|
||||
|
||||
public class ModBlockEntities {
|
||||
public static final BlockEntityEntry<TradingStationBlockEntity> TRADING_STATION = TradingStation.registrate()
|
||||
.blockEntity("trading_station", TradingStationBlockEntity::new)
|
||||
.validBlocks(ModBlocks.TRADING_STATION)
|
||||
.renderer(() -> TradingStationBlockRenderer::new)
|
||||
.register();
|
||||
|
||||
public static final BlockEntityEntry<PoweredTradingStationBlockEntity> POWERED_TRADING_STATION = TradingStation.registrate()
|
||||
.blockEntity("powered_trading_station", PoweredTradingStationBlockEntity::new)
|
||||
.validBlocks(ModBlocks.POWERED_TRADING_STATION)
|
||||
.renderer(() -> TradingStationBlockRenderer::new)
|
||||
.register();
|
||||
public static void register() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.oierbravo.trading_station.registrate;
|
||||
|
||||
import com.oierbravo.trading_station.TradingStation;
|
||||
import com.oierbravo.trading_station.content.trading_station.TradingStationBlock;
|
||||
import com.oierbravo.trading_station.content.trading_station.powered.PoweredTradingStationBlock;
|
||||
import com.oierbravo.trading_station.content.trading_station.TradingStationBlockEntity;
|
||||
import com.oierbravo.trading_station.content.trading_station.powered.PoweredTradingStationBlockEntity;
|
||||
|
||||
import com.tterrag.registrate.Registrate;
|
||||
import com.tterrag.registrate.util.entry.BlockEntry;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||
import net.minecraftforge.client.model.generators.ConfiguredModel;
|
||||
|
||||
public class ModBlocks {
|
||||
private static final Registrate REGISTRATE = TradingStation.registrate()
|
||||
.creativeModeTab(() -> ModCreativeTab.MAIN);
|
||||
public static final BlockEntry<TradingStationBlock> TRADING_STATION = TradingStation.registrate()
|
||||
.block("trading_station", TradingStationBlock::new)
|
||||
.lang("Trading Station")
|
||||
.blockstate((ctx, prov) ->
|
||||
prov.getVariantBuilder(ctx.getEntry()).forAllStates(state -> {
|
||||
String modelFileName = "trading_station:block/trading_station";
|
||||
if(state.getValue(BlockStateProperties.POWERED))
|
||||
modelFileName += "_powered";
|
||||
return ConfiguredModel.builder().modelFile(prov.models().getExistingFile(ResourceLocation.tryParse(modelFileName)))
|
||||
.rotationY(((int) state.getValue(BlockStateProperties.HORIZONTAL_FACING).toYRot() + 180) % 360).build();
|
||||
|
||||
})
|
||||
)
|
||||
.simpleItem()
|
||||
.blockEntity(TradingStationBlockEntity::new)
|
||||
.build()
|
||||
.register();
|
||||
public static final BlockEntry<PoweredTradingStationBlock> POWERED_TRADING_STATION = TradingStation.registrate()
|
||||
.block("powered_trading_station", PoweredTradingStationBlock::new)
|
||||
.lang("Powered Trading Station")
|
||||
.blockstate((ctx, prov) ->
|
||||
prov.getVariantBuilder(ctx.getEntry()).forAllStates(state -> {
|
||||
String modelFileName = "trading_station:block/powered_trading_station";
|
||||
if(state.getValue(BlockStateProperties.POWERED))
|
||||
modelFileName += "_powered";
|
||||
return ConfiguredModel.builder().modelFile(prov.models().getExistingFile(ResourceLocation.tryParse(modelFileName)))
|
||||
.rotationY(((int) state.getValue(BlockStateProperties.HORIZONTAL_FACING).toYRot() + 180) % 360).build();
|
||||
|
||||
})
|
||||
)
|
||||
.simpleItem()
|
||||
.blockEntity(PoweredTradingStationBlockEntity::new)
|
||||
.build()
|
||||
.register();
|
||||
public static void register() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.oierbravo.trading_station.registrate;
|
||||
|
||||
import com.oierbravo.trading_station.TradingStation;
|
||||
import net.minecraft.world.item.CreativeModeTab;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
public class ModCreativeTab extends CreativeModeTab {
|
||||
public static ModCreativeTab MAIN;
|
||||
|
||||
|
||||
public ModCreativeTab() {
|
||||
super(TradingStation.DISPLAY_NAME);
|
||||
MAIN = this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack makeIcon() {
|
||||
return new ItemStack(ModBlocks.TRADING_STATION.get());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.oierbravo.trading_station.registrate;
|
||||
|
||||
import com.oierbravo.trading_station.TradingStation;
|
||||
import com.oierbravo.trading_station.content.trading_station.TradingStationMenu;
|
||||
import com.oierbravo.trading_station.content.trading_station.TradingStationScreen;
|
||||
import com.tterrag.registrate.util.entry.MenuEntry;
|
||||
import com.tterrag.registrate.util.entry.RegistryEntry;
|
||||
import net.minecraft.client.gui.screens.inventory.ContainerScreen;
|
||||
|
||||
import net.minecraft.world.SimpleContainer;
|
||||
import net.minecraft.world.inventory.ChestMenu;
|
||||
import net.minecraft.world.inventory.MenuType;
|
||||
|
||||
public class ModMenus {
|
||||
public static final MenuEntry<TradingStationMenu> TRADING_STATION = TradingStation.registrate()
|
||||
.menu("trading_station",TradingStationMenu::factory, () -> TradingStationScreen::new)
|
||||
.register();
|
||||
|
||||
public static final MenuEntry<TradingStationMenu> TRADING_STATION_TRADE_SELECT = TradingStation.registrate()
|
||||
.menu("trading_station_trade_select",TradingStationMenu::factory, () -> TradingStationScreen::new)
|
||||
.register();
|
||||
public static void register() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package com.oierbravo.trading_station.registrate;
|
||||
|
||||
import com.oierbravo.trading_station.TradingStation;
|
||||
import com.oierbravo.trading_station.network.packets.GhostItemSyncC2SPacket;
|
||||
import com.oierbravo.trading_station.network.packets.ItemStackSyncS2CPacket;
|
||||
import com.oierbravo.trading_station.network.packets.OpenTargetSelectPacket;
|
||||
import com.oierbravo.trading_station.network.packets.OpenTradingMenuPacket;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraftforge.network.NetworkDirection;
|
||||
import net.minecraftforge.network.NetworkRegistry;
|
||||
import net.minecraftforge.network.PacketDistributor;
|
||||
import net.minecraftforge.network.simple.SimpleChannel;
|
||||
|
||||
public class ModMessages {
|
||||
private static SimpleChannel INSTANCE;
|
||||
|
||||
private static int packetId = 0;
|
||||
private static int id() {
|
||||
return packetId++;
|
||||
}
|
||||
|
||||
public static void register() {
|
||||
SimpleChannel net = NetworkRegistry.ChannelBuilder
|
||||
.named(new ResourceLocation(TradingStation.MODID, "messages"))
|
||||
.networkProtocolVersion(() -> "1.0")
|
||||
.clientAcceptedVersions(s -> true)
|
||||
.serverAcceptedVersions(s -> true)
|
||||
.simpleChannel();
|
||||
|
||||
INSTANCE = net;
|
||||
|
||||
|
||||
net.messageBuilder(ItemStackSyncS2CPacket.class, id(), NetworkDirection.PLAY_TO_CLIENT)
|
||||
.decoder(ItemStackSyncS2CPacket::new)
|
||||
.encoder(ItemStackSyncS2CPacket::toBytes)
|
||||
.consumerMainThread(ItemStackSyncS2CPacket::handle)
|
||||
.add();
|
||||
|
||||
net.messageBuilder(GhostItemSyncC2SPacket.class, id(), NetworkDirection.PLAY_TO_SERVER)
|
||||
.decoder(GhostItemSyncC2SPacket::new)
|
||||
.encoder(GhostItemSyncC2SPacket::toBytes)
|
||||
.consumerMainThread(GhostItemSyncC2SPacket::handle)
|
||||
.add();
|
||||
|
||||
net.messageBuilder(OpenTradingMenuPacket.class, id(), NetworkDirection.PLAY_TO_SERVER)
|
||||
.decoder(OpenTradingMenuPacket::new)
|
||||
.encoder(OpenTradingMenuPacket::toBytes)
|
||||
.consumerMainThread(OpenTradingMenuPacket::handle)
|
||||
.add();
|
||||
|
||||
net.messageBuilder(OpenTargetSelectPacket.class, id(), NetworkDirection.PLAY_TO_SERVER)
|
||||
.decoder(OpenTargetSelectPacket::new)
|
||||
.encoder(OpenTargetSelectPacket::toBytes)
|
||||
.consumerMainThread(OpenTargetSelectPacket::handle)
|
||||
.add();
|
||||
}
|
||||
|
||||
public static <MSG> void sendToServer(MSG message) {
|
||||
INSTANCE.sendToServer(message);
|
||||
}
|
||||
|
||||
public static <MSG> void sendToPlayer(MSG message, ServerPlayer player) {
|
||||
INSTANCE.send(PacketDistributor.PLAYER.with(() -> player), message);
|
||||
}
|
||||
|
||||
public static <MSG> void sendToClients(MSG message) {
|
||||
INSTANCE.send(PacketDistributor.ALL.noArg(), message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package com.oierbravo.trading_station.registrate;
|
||||
|
||||
import com.oierbravo.trading_station.TradingStation;
|
||||
import com.oierbravo.trading_station.content.trading_station.TradingRecipe;
|
||||
import net.minecraft.world.SimpleContainer;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.crafting.RecipeSerializer;
|
||||
import net.minecraft.world.item.crafting.RecipeType;
|
||||
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 java.util.Comparator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class ModRecipes {
|
||||
public static final DeferredRegister<RecipeSerializer<?>> SERIALIZERS =
|
||||
DeferredRegister.create(ForgeRegistries.RECIPE_SERIALIZERS, TradingStation.MODID);
|
||||
public static final DeferredRegister<RecipeType<?>> RECIPE_TYPES = DeferredRegister.create(ForgeRegistries.RECIPE_TYPES, TradingStation.MODID);
|
||||
|
||||
public static final RegistryObject<RecipeType<TradingRecipe>> TRADING_TYPE =
|
||||
RECIPE_TYPES.register("trading",() -> TradingRecipe.Type.INSTANCE);
|
||||
|
||||
public static final RegistryObject<RecipeSerializer<TradingRecipe>> TRADING_SERIALIZER =
|
||||
SERIALIZERS.register("trading", () -> TradingRecipe.Serializer.INSTANCE);
|
||||
|
||||
public static Optional<TradingRecipe> find(SimpleContainer pInv, Level pLevel) {
|
||||
if(pLevel.isClientSide())
|
||||
return Optional.empty();
|
||||
return pLevel.getRecipeManager().getRecipeFor(TradingRecipe.Type.INSTANCE,pInv,pLevel);
|
||||
}
|
||||
/*public static List<ItemStack> getAllOutputs(Level pLevel){
|
||||
List<ItemStack> allOutputs = pLevel.getRecipeManager().getAllRecipesFor(TradingRecipe.Type.INSTANCE).stream()
|
||||
.map(TradingRecipe::getResult).toList();
|
||||
allOutputs.add(ItemStack.EMPTY);
|
||||
return allOutputs;
|
||||
|
||||
}*/
|
||||
public static List<ItemStack> getAllOutputs(Level pLevel){
|
||||
return pLevel.getRecipeManager().getAllRecipesFor(TradingRecipe.Type.INSTANCE).stream()
|
||||
.map(TradingRecipe::getResult).toList();
|
||||
|
||||
}
|
||||
public static Optional<TradingRecipe> findByOutput(Level pLevel,ItemStack targetedOutput){
|
||||
//if(pLevel.isClientSide())
|
||||
// return Optional.empty();
|
||||
return pLevel.getRecipeManager().getAllRecipesFor(TradingRecipe.Type.INSTANCE).stream()
|
||||
.filter(recipe -> recipe.matchesOutput(targetedOutput)).findFirst();
|
||||
|
||||
}
|
||||
/*public static Optional<TradingRecipe> findWithPreferdOutput(SimpleContainer pInv, Level pLevel, ItemStack preferedOutput){
|
||||
if(pLevel.isClientSide())
|
||||
return Optional.empty();
|
||||
List<TradingRecipe> allTradingRecipes = pLevel.getRecipeManager().getAllRecipesFor(TradingRecipe.Type.INSTANCE);
|
||||
|
||||
return allTradingRecipes.stream().filter(extrudingRecipe -> TradingRecipe.matches(tradingStation,tradingRecipe)).findFirst();
|
||||
|
||||
}*/
|
||||
public static void register(IEventBus eventBus) {
|
||||
SERIALIZERS.register(eventBus);
|
||||
|
||||
RECIPE_TYPES.register(eventBus);
|
||||
}
|
||||
}
|
||||
28
src/main/resources/META-INF/mods.toml
Normal file
@@ -0,0 +1,28 @@
|
||||
modLoader="javafml"
|
||||
loaderVersion="[43,)"
|
||||
issueTrackerURL="https://github.com/oierbravo/trading-station-mod/issues"
|
||||
license="MIT"
|
||||
|
||||
[[mods]]
|
||||
modId="trading_station"
|
||||
version="${file.jarVersion}"
|
||||
displayName="Trading Station"
|
||||
logoFile="logo.png"
|
||||
credits="Code inspirtation from the amazing Create mod"
|
||||
authors="oierbravo"
|
||||
description='''
|
||||
Trading made simple
|
||||
'''
|
||||
# A dependency - use the . to indicate dependency for a specific modid. Dependencies are optional.
|
||||
[[dependencies.trading_station]] #optional
|
||||
modId="forge"
|
||||
mandatory=true
|
||||
versionRange="[43.2.3,)"
|
||||
ordering="NONE"
|
||||
side="BOTH"
|
||||
[[dependencies.trading_station]]
|
||||
modId="minecraft"
|
||||
mandatory=true
|
||||
versionRange="[1.19.2,1.20)"
|
||||
ordering="NONE"
|
||||
side="BOTH"
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"credit": "Made with Blockbench",
|
||||
"parent": "trading_station:block/trading_station",
|
||||
"textures": {
|
||||
"3": "trading_station:block/powered_trading_station"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"credit": "Made with Blockbench",
|
||||
"parent": "trading_station:block/powered_trading_station",
|
||||
"textures": {
|
||||
"3": "trading_station:block/powered_trading_station_powered"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{"meta":{"format_version":"4.5","model_format":"java_block","box_uv":false},"name":"trading_station","parent":"minecraft/block","ambientocclusion":true,"front_gui_light":false,"visible_box":[1,1,0],"variable_placeholders":"","variable_placeholder_buttons":[],"unhandled_root_fields":{},"resolution":{"width":16,"height":16},"elements":[{"name":"cube","box_uv":false,"rescale":false,"locked":false,"render_order":"default","allow_mirror_modeling":true,"from":[0,0,0],"to":[16,16,17],"autouv":1,"color":0,"origin":[0,0,0],"faces":{"north":{"uv":[0,0,16,16],"texture":2},"east":{"uv":[0,0,16,16],"texture":1},"south":{"uv":[0,0,16,16],"texture":1},"west":{"uv":[0,0,16,16],"texture":1},"up":{"uv":[0,0,16,16],"texture":0},"down":{"uv":[0,0,16,16],"texture":0}},"type":"cube","uuid":"01e24cac-cecb-3dde-0f23-731a20048b15"}],"outliner":["01e24cac-cecb-3dde-0f23-731a20048b15"],"textures":[{"path":"/home/oier/projects/mc-mods/trading-station/src/main/resources/assets/trading_station/textures/block/trading_station_top.png","name":"trading_station_top.png","folder":"block","namespace":"trading_station","id":"0","particle":true,"render_mode":"default","render_sides":"auto","frame_time":1,"frame_order_type":"loop","frame_order":"","frame_interpolate":false,"visible":true,"mode":"bitmap","saved":true,"uuid":"097851dc-7e0f-9ce3-3e13-13cd0cc603b9","relative_path":"../../../textures/block/trading_station_top.png","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAhJJREFUOE99Uz1vE0EQfZv4Pnznu3C2sUFYCQI3iAIqkFAkFChpkFCgiETNPyDUINHDT0gN/Aj+QJp0lCEQEyfmfF97Z3vR7GWcOwmYZndmn2b2vZkRD2911Kq5CjJLrOiTTaoF5vm8FnMsQ/v05tsmBCWgYNBt6YciKWA4JYh9vlPcshxImWAaZYjTHOLp/YHyWzYyOcNwvYsky2sVq45jm7BMAwfffqDX8TAaTyGeb15X5Dx59Q77n95rfD4TMBtKn2zks9199gafP7xGks0gdraGqhc0oXABJiBVY+Nfccy2TByPp4jiBOLRnZ5ymya6nbbmxhy1qOd86ayJKxNEsURRKIiXj28oz3Xhu2VF370QkOlkMocQAp7TwNlU4jSeo0gTRCTiztZNFfgOLgdlF2Re6JPE4jtRCHwXlCiVBZSCFjuMZCmibTUw6F9adoDAZ2GMfttZCsnJKPliscDRrxBhlJVtXLFsrHcdtNdaSNKZ/oEQc5BYrD51hJJSckp2MokRp0U5SP5aE17LrglVFY7FrQJOxqcIf6dlG92mgUE/WFYjoCKiFeOZYCqHx5OSwvbmhup3fD1IX/feLnX41xyQuPde7OLLx11MwhRi+8GGGlzx8X00xe3h1Xq/zztCweqIH41CXOt5OPwZloNEW0jLxIv0P/6kB+GiROqN1CLSOv9tlakyr3N1jfmbRsPEH0RYCWjadlbnAAAAAElFTkSuQmCC"},{"path":"/home/oier/projects/mc-mods/trading-station/src/main/resources/assets/trading_station/textures/block/trading_station_side.png","name":"trading_station_side.png","folder":"block","namespace":"trading_station","id":"1","particle":false,"render_mode":"default","render_sides":"auto","frame_time":1,"frame_order_type":"loop","frame_order":"","frame_interpolate":false,"visible":true,"mode":"bitmap","saved":true,"uuid":"dd0f02fb-6a8f-e0ba-b5ef-3411622545be","relative_path":"../../../textures/block/trading_station_side.png","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAASJJREFUOE/Fk81LAzEQxV8oLCYpCF1rL61fh6r0sgeptJcV/Af8u6WHXgTxIEp78KsIQpK6WCITGNyKu+nNueb9XuZNJuLqvOvbrSa0TNDabsK6LyyLJepKbSX4MJ+YP71D5KepJ3EjaQQT44pamA5ZtypWEOOLS9/eTXF7cxcFy4KTQR+vLwuIbDjySikoLWGN28iEtdZaiONB5qWWYJMqh9nDHL2Dbjimiwh2xlUbEPC7ZYpJJlEDgvN8tGbw/LZAZyfF/eOs3oBhEpbraL8X4GiEKgMCeQ7RCFqr8Kw8NIYpVjQCi+mdy7vBcDQCCSgvD43nUJ7JWgRapOFZFlqj1rlo4mTyVxljwyXXkynE3mE//AWpfuBN1tFZG2Ti33/jN0IY5K3kdLtoAAAAAElFTkSuQmCC"},{"path":"/home/oier/projects/mc-mods/trading-station/src/main/resources/assets/trading_station/textures/block/trading_station.png","name":"trading_station.png","folder":"block","namespace":"trading_station","id":"2","particle":false,"render_mode":"default","render_sides":"auto","frame_time":1,"frame_order_type":"loop","frame_order":"","frame_interpolate":false,"visible":true,"mode":"bitmap","saved":true,"uuid":"821f2390-40fb-97d8-e5dc-9207618506a7","relative_path":"../../../textures/block/trading_station.png","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAWdJREFUOE/FU1tLAkEYPYO0uTOG5mIQaG7SBQ3KhzDqpaA/0O+OHqoHeyhkRaGLbdplZmxLJmZoxEVdemtezu5855yds9835OygqAr5DJjrIJ/NQMhvDKMhkhZNO3jjn+g+9EGOq57S5JSTMiZcRoliXbS8UTQCOTo5VYUVD8xNI8MYPjgHl8PYu93X+Pgcmprm9J5CkHrjUFFKIYSAxr8sy9VoDBr7dZxfXEJy+Rc9XObCasja+pZyKYUUwogrwS0YgCUAfRAsQ8Xwxt8wPKsZR6DMRSfowm9eG9H7r8kkcgD3tT2U/CIElyY22d6pK30knT/shXAcB2r0NRWFpBbMXhRF8AqeEevIUwa2+NILUSyXDHHyWYvmGnTbnZmiJLPYCbRBNpdLjPA6GIw/MhVBG1SDu8Sf2PI34wZ2DlrtjunCavMKizPaZ9sZ1HZNFyrlkpkdMwe2rxrtPMybKN3/SR7599v4Aw5hBdkgFY5mAAAAAElFTkSuQmCC"}]}
|
||||
@@ -0,0 +1,63 @@
|
||||
{
|
||||
"credit": "Made with Blockbench",
|
||||
"parent": "minecraft/block",
|
||||
"render_type": "minecraft:translucent",
|
||||
"textures": {
|
||||
"3": "trading_station:block/trading_station"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [0, 0, 0],
|
||||
"to": [16, 16, 17],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 0, 8, 8], "texture": "#3"},
|
||||
"east": {"uv": [0, 8, 8, 16], "texture": "#3"},
|
||||
"south": {"uv": [0, 8, 8, 16], "texture": "#3"},
|
||||
"west": {"uv": [0, 8, 8, 16], "texture": "#3"},
|
||||
"up": {"uv": [8, 0, 16, 8], "texture": "#3"},
|
||||
"down": {"uv": [8, 8, 16, 16], "texture": "#3"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [3, 16, 4],
|
||||
"to": [13, 18, 13],
|
||||
"faces": {
|
||||
"north": {"uv": [9.5, 5, 14.5, 6], "texture": "#3"},
|
||||
"east": {"uv": [9.5, 5, 14.5, 6], "texture": "#3"},
|
||||
"south": {"uv": [9.5, 5, 14.5, 6], "texture": "#3"},
|
||||
"west": {"uv": [9.5, 5, 14.5, 6], "texture": "#3"},
|
||||
"up": {"uv": [9.5, 2, 14.5, 6], "texture": "#3"},
|
||||
"down": {"uv": [0, 0, 0, 0], "texture": "#3"}
|
||||
}
|
||||
}
|
||||
],
|
||||
"display": {
|
||||
"thirdperson_righthand": {
|
||||
"scale": [0.3, 0.3, 0.3]
|
||||
},
|
||||
"thirdperson_lefthand": {
|
||||
"scale": [0.3, 0.3, 0.3]
|
||||
},
|
||||
"firstperson_righthand": {
|
||||
"scale": [0.3, 0.3, 0.3]
|
||||
},
|
||||
"firstperson_lefthand": {
|
||||
"scale": [0.3, 0.3, 0.3]
|
||||
},
|
||||
"ground": {
|
||||
"scale": [0.5, 0.5, 0.5]
|
||||
},
|
||||
"gui": {
|
||||
"rotation": [23, 135, 0],
|
||||
"scale": [0.61, 0.61, 0.61]
|
||||
},
|
||||
"head": {
|
||||
"scale": [0.89, 0.89, 0.89]
|
||||
},
|
||||
"fixed": {
|
||||
"rotation": [0, -45, 0],
|
||||
"translation": [0, 0, -2.5],
|
||||
"scale": [0.72, 0.72, 0.72]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"credit": "Made with Blockbench",
|
||||
"parent": "trading_station:block/trading_station",
|
||||
"textures": {
|
||||
"3": "trading_station:block/trading_station_powered"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 857 B |
|
After Width: | Height: | Size: 988 B |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 925 B |
|
After Width: | Height: | Size: 1.3 KiB |
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"type": "trading_station:trading",
|
||||
"ingredients": [
|
||||
{"item": "minecraft:emerald", "count": 5}
|
||||
],
|
||||
"result": {
|
||||
"item": "minecraft:diamond",
|
||||
"count": 5
|
||||
},
|
||||
"processingTime": 500
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"type": "trading_station:trading",
|
||||
"ingredients": [
|
||||
{"item": "minecraft:diamond", "count": 5}
|
||||
],
|
||||
"result": {
|
||||
"item": "minecraft:enchanted_book",
|
||||
"nbt": "{StoredEnchantments: [{id:\"looting\",lvl:3s}]}"
|
||||
},
|
||||
"processingTime": 100
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"pattern": [
|
||||
"S S",
|
||||
"S S",
|
||||
"NSN"
|
||||
],
|
||||
"key": {
|
||||
"N": {
|
||||
"item": "minecraft:iron_nugget"
|
||||
},
|
||||
"S": {
|
||||
"tag": "forge:stone"
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"item": "trading_station:trading_station"
|
||||
}
|
||||
}
|
||||
1
src/main/resources/kubejs.plugins.txt
Normal file
@@ -0,0 +1 @@
|
||||
com.oierbravo.trading_station.compat.kubejs.KubeJSPlugin
|
||||
BIN
src/main/resources/logo.png
Normal file
|
After Width: | Height: | Size: 37 KiB |
8
src/main/resources/pack.mcmeta
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"pack": {
|
||||
"description": "TradingStation resources",
|
||||
"pack_format": 9,
|
||||
"forge:resource_pack_format": 8,
|
||||
"forge:data_pack_format": 9
|
||||
}
|
||||
}
|
||||
12
src/main/resources/trading_station.mixins.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"required": true,
|
||||
"package": "com.oierbravo.trading_station.mixin",
|
||||
"compatibilityLevel": "JAVA_17",
|
||||
"refmap": "trading_station.refmap.json",
|
||||
"mixins": [
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
},
|
||||
"minVersion": "0.8"
|
||||
}
|
||||