Crystal chests will now render the items inside again, and the broken upgrade recipes have been fixed. Closes #249, Closes #245

This commit is contained in:
Alexander Behrhof 2021-07-26 20:46:24 -04:00
parent d3605166b0
commit 6206a33628
27 changed files with 895 additions and 120 deletions

253
.editorconfig Normal file
View File

@ -0,0 +1,253 @@
root = true
[*]
charset = utf-8
indent_size = 4
indent_style = space
insert_final_newline = true
max_line_length = 500
# tab_width = 4
# ij_continuation_indent_size = 4
[*.java]
indent_size = 2
# tab_width = 8
# ij_continuation_indent_size = 4
# ij_java_align_consecutive_assignments = false
# ij_java_align_consecutive_variable_declarations = false
# ij_java_align_group_field_declarations = false
# ij_java_align_multiline_annotation_parameters = false
# ij_java_align_multiline_array_initializer_expression = true
# ij_java_align_multiline_assignment = true
# ij_java_align_multiline_binary_operation = true
# ij_java_align_multiline_chained_methods = true
# ij_java_align_multiline_extends_list = true
# ij_java_align_multiline_for = true
# ij_java_align_multiline_method_parentheses = false
# ij_java_align_multiline_parameters = true
# ij_java_align_multiline_parameters_in_calls = true
# ij_java_align_multiline_parenthesized_expression = true
# ij_java_align_multiline_resources = true
# ij_java_align_multiline_ternary_operation = true
# ij_java_align_multiline_throws_list = true
# ij_java_align_subsequent_simple_methods = false
# ij_java_align_throws_keyword = false
# ij_java_annotation_parameter_wrap = off
# ij_java_array_initializer_new_line_after_left_brace = false
# ij_java_array_initializer_right_brace_on_new_line = false
# ij_java_array_initializer_wrap = off
# ij_java_assert_statement_colon_on_next_line = false
# ij_java_assert_statement_wrap = off
# ij_java_assignment_wrap = off
# ij_java_binary_operation_sign_on_next_line = true
# ij_java_binary_operation_wrap = off
# ij_java_blank_lines_after_anonymous_class_header = 0
ij_java_blank_lines_after_class_header = 1
ij_java_blank_lines_after_imports = 1
# ij_java_blank_lines_after_package = 1
# ij_java_blank_lines_around_class = 1
# ij_java_blank_lines_around_field = 0
# ij_java_blank_lines_around_field_in_interface = 0
# ij_java_blank_lines_around_initializer = 1
# ij_java_blank_lines_around_method = 1
# ij_java_blank_lines_around_method_in_interface = 1
# ij_java_blank_lines_before_class_end = 0
# ij_java_blank_lines_before_imports = 1
# ij_java_blank_lines_before_method_body = 0
# ij_java_blank_lines_before_package = 0
# ij_java_block_brace_style = end_of_line
# ij_java_block_comment_at_first_column = true
# ij_java_call_parameters_new_line_after_left_paren = false
# ij_java_call_parameters_right_paren_on_new_line = false
# ij_java_call_parameters_wrap = off
# ij_java_case_statement_on_separate_line = true
# ij_java_catch_on_new_line = false
# ij_java_class_annotation_wrap = split_into_lines
# ij_java_class_brace_style = end_of_line
ij_java_class_count_to_use_import_on_demand = 99
# ij_java_class_names_in_javadoc = 1
# ij_java_do_not_indent_top_level_class_members = false
# ij_java_do_not_wrap_after_single_annotation = false
# ij_java_do_while_brace_force = always
# ij_java_doc_add_blank_line_after_description = true
# ij_java_doc_add_blank_line_after_param_comments = false
# ij_java_doc_add_blank_line_after_return = false
# ij_java_doc_add_p_tag_on_empty_lines = true
# ij_java_doc_align_exception_comments = true
# ij_java_doc_align_param_comments = true
# ij_java_doc_do_not_wrap_if_one_line = false
# ij_java_doc_enable_formatting = true
# ij_java_doc_enable_leading_asterisks = true
# ij_java_doc_indent_on_continuation = false
# ij_java_doc_keep_empty_lines = true
# ij_java_doc_keep_empty_parameter_tag = true
# ij_java_doc_keep_empty_return_tag = true
# ij_java_doc_keep_empty_throws_tag = true
# ij_java_doc_keep_invalid_tags = true
# ij_java_doc_param_description_on_new_line = false
# ij_java_doc_preserve_line_breaks = false
# ij_java_doc_use_throws_not_exception_tag = true
# ij_java_else_on_new_line = true
# ij_java_entity_dd_suffix = EJB
# ij_java_entity_eb_suffix = Bean
# ij_java_entity_hi_suffix = Home
# ij_java_entity_lhi_prefix = Local
# ij_java_entity_lhi_suffix = Home
# ij_java_entity_li_prefix = Local
# ij_java_entity_pk_class = java.lang.String
# ij_java_entity_vo_suffix = VO
# ij_java_enum_constants_wrap = off
# ij_java_extends_keyword_wrap = normal
# ij_java_extends_list_wrap = normal
# ij_java_field_annotation_wrap = split_into_lines
# ij_java_finally_on_new_line = false
# ij_java_for_brace_force = always
# ij_java_for_statement_new_line_after_left_paren = false
# ij_java_for_statement_right_paren_on_new_line = false
# ij_java_for_statement_wrap = normal
# ij_java_generate_final_locals = false
# ij_java_generate_final_parameters = false
# ij_java_if_brace_force = always
# ij_java_imports_layout = com.google.**,|,android.**,|,antenna.**,|,antlr.**,|,ar.**,|,asposewobfuscated.**,|,asquare.**,|,atg.**,|,au.**,|,beaver.**,|,bibtex.**,|,bmsi.**,|,bsh.**,|,ccl.**,|,cern.**,|,ChartDirector.**,|,checkers.**,|,com.**,|,COM.**,|,common.**,|,contribs.**,|,corejava.**,|,cryptix.**,|,cybervillains.**,|,dalvik.**,|,danbikel.**,|,de.**,|,EDU.**,|,eg.**,|,eu.**,|,examples.**,|,fat.**,|,fit.**,|,fitlibrary.**,|,fmpp.**,|,freemarker.**,|,gnu.**,|,groovy.**,|,groovyjarjarantlr.**,|,groovyjarjarasm.**,|,hak.**,|,hep.**,|,ie.**,|,imageinfo.**,|,info.**,|,it.**,|,jal.**,|,Jama.**,|,japa.**,|,japacheckers.**,|,jas.**,|,jasmin.**,|,javancss.**,|,javanet.**,|,javassist.**,|,javazoom.**,|,java_cup.**,|,jcifs.**,|,jetty.**,|,JFlex.**,|,jj2000.**,|,jline.**,|,jp.**,|,JSci.**,|,jsr166y.**,|,junit.**,|,jxl.**,|,jxxload_help.**,|,kawa.**,|,kea.**,|,libcore.**,|,libsvm.**,|,lti.**,|,memetic.**,|,mt.**,|,mx4j.**,|,net.**,|,netscape.**,|,nl.**,|,nu.**,|,oauth.**,|,ognl.**,|,opennlp.**,|,oracle.**,|,org.**,|,penn2dg.**,|,pennconverter.**,|,pl.**,|,prefuse.**,|,proguard.**,|,repackage.**,|,scm.**,|,se.**,|,serp.**,|,simple.**,|,soot.**,|,sqlj.**,|,src.**,|,ssa.**,|,sun.**,|,sunlabs.**,|,tcl.**,|,testdata.**,|,testshell.**,|,testsuite.**,|,twitter4j.**,|,uk.**,|,ViolinStrings.**,|,weka.**,|,wet.**,|,winstone.**,|,woolfel.**,|,wowza.**,|,java.**,|,javax.**,|,*,|,$*
# ij_java_indent_case_from_switch = true
# ij_java_insert_inner_class_imports = false
ij_java_insert_override_annotation = true
ij_java_keep_blank_lines_before_right_brace = 2
ij_java_keep_blank_lines_between_package_declaration_and_header = 2
ij_java_keep_blank_lines_in_code = 2
ij_java_keep_blank_lines_in_declarations = 2
# ij_java_keep_control_statement_in_one_line = false
# ij_java_keep_first_column_comment = true
# ij_java_keep_indents_on_empty_lines = false
# ij_java_keep_line_breaks = true
# ij_java_keep_multiple_expressions_in_one_line = false
ij_java_keep_simple_blocks_in_one_line = true
ij_java_keep_simple_classes_in_one_line = true
ij_java_keep_simple_lambdas_in_one_line = true
ij_java_keep_simple_methods_in_one_line = true
# ij_java_lambda_brace_style = end_of_line
# ij_java_layout_static_imports_separately = true
# ij_java_line_comment_add_space = false
# ij_java_line_comment_at_first_column = true
# ij_java_message_dd_suffix = EJB
# ij_java_message_eb_suffix = Bean
# ij_java_method_annotation_wrap = split_into_lines
# ij_java_method_brace_style = end_of_line
# ij_java_method_call_chain_wrap = off
# ij_java_method_parameters_new_line_after_left_paren = false
# ij_java_method_parameters_right_paren_on_new_line = false
# ij_java_method_parameters_wrap = off
# ij_java_modifier_list_wrap = false
ij_java_names_count_to_use_import_on_demand = 99
# ij_java_packages_to_use_import_on_demand = java.awt.*,javax.swing.*
# ij_java_parameter_annotation_wrap = off
# ij_java_parentheses_expression_new_line_after_left_paren = false
# ij_java_parentheses_expression_right_paren_on_new_line = false
# ij_java_place_assignment_sign_on_next_line = false
# ij_java_prefer_longer_names = true
# ij_java_prefer_parameters_wrap = false
# ij_java_repeat_synchronized = true
# ij_java_replace_instanceof_and_cast = false
# ij_java_replace_null_check = true
# ij_java_replace_sum_lambda_with_method_ref = true
# ij_java_resource_list_new_line_after_left_paren = false
# ij_java_resource_list_right_paren_on_new_line = false
# ij_java_resource_list_wrap = off
# ij_java_session_dd_suffix = EJB
# ij_java_session_eb_suffix = Bean
# ij_java_session_hi_suffix = Home
# ij_java_session_lhi_prefix = Local
# ij_java_session_lhi_suffix = Home
# ij_java_session_li_prefix = Local
# ij_java_session_si_suffix = Service
# ij_java_space_after_closing_angle_bracket_in_type_argument = false
# ij_java_space_after_colon = true
# ij_java_space_after_comma = true
# ij_java_space_after_comma_in_type_arguments = true
# ij_java_space_after_for_semicolon = true
# ij_java_space_after_quest = true
# ij_java_space_after_type_cast = true
# ij_java_space_before_annotation_array_initializer_left_brace = false
# ij_java_space_before_annotation_parameter_list = false
# ij_java_space_before_array_initializer_left_brace = false
# ij_java_space_before_catch_keyword = true
# ij_java_space_before_catch_left_brace = true
# ij_java_space_before_catch_parentheses = false
# ij_java_space_before_class_left_brace = true
# ij_java_space_before_colon = true
# ij_java_space_before_colon_in_foreach = true
# ij_java_space_before_comma = false
# ij_java_space_before_do_left_brace = true
# ij_java_space_before_else_keyword = true
# ij_java_space_before_else_left_brace = true
# ij_java_space_before_finally_keyword = true
# ij_java_space_before_finally_left_brace = true
# ij_java_space_before_for_left_brace = true
# ij_java_space_before_for_parentheses = false
# ij_java_space_before_for_semicolon = false
# ij_java_space_before_if_left_brace = true
# ij_java_space_before_if_parentheses = false
# ij_java_space_before_method_call_parentheses = false
# ij_java_space_before_method_left_brace = true
# ij_java_space_before_method_parentheses = false
# ij_java_space_before_opening_angle_bracket_in_type_parameter = false
# ij_java_space_before_quest = true
# ij_java_space_before_switch_left_brace = true
# ij_java_space_before_switch_parentheses = false
# ij_java_space_before_synchronized_left_brace = true
# ij_java_space_before_synchronized_parentheses = false
# ij_java_space_before_try_left_brace = true
# ij_java_space_before_try_parentheses = false
# ij_java_space_before_type_parameter_list = false
# ij_java_space_before_while_keyword = true
# ij_java_space_before_while_left_brace = true
# ij_java_space_before_while_parentheses = false
# ij_java_space_inside_one_line_enum_braces = false
# ij_java_space_within_empty_array_initializer_braces = false
# ij_java_space_within_empty_method_call_parentheses = false
# ij_java_space_within_empty_method_parentheses = false
# ij_java_spaces_around_additive_operators = true
# ij_java_spaces_around_assignment_operators = true
# ij_java_spaces_around_bitwise_operators = true
# ij_java_spaces_around_equality_operators = true
# ij_java_spaces_around_lambda_arrow = true
# ij_java_spaces_around_logical_operators = true
# ij_java_spaces_around_method_ref_dbl_colon = false
# ij_java_spaces_around_multiplicative_operators = true
# ij_java_spaces_around_relational_operators = true
# ij_java_spaces_around_shift_operators = true
# ij_java_spaces_around_type_bounds_in_type_parameters = true
# ij_java_spaces_around_unary_operator = false
# ij_java_spaces_within_angle_brackets = false
# ij_java_spaces_within_annotation_parentheses = false
# ij_java_spaces_within_array_initializer_braces = false
# ij_java_spaces_within_braces = false
# ij_java_spaces_within_brackets = false
# ij_java_spaces_within_cast_parentheses = false
# ij_java_spaces_within_catch_parentheses = false
# ij_java_spaces_within_for_parentheses = false
# ij_java_spaces_within_if_parentheses = false
# ij_java_spaces_within_method_call_parentheses = false
# ij_java_spaces_within_method_parentheses = false
# ij_java_spaces_within_parentheses = false
# ij_java_spaces_within_switch_parentheses = false
# ij_java_spaces_within_synchronized_parentheses = false
# ij_java_spaces_within_try_parentheses = false
# ij_java_spaces_within_while_parentheses = false
# ij_java_special_else_if_treatment = true
# ij_java_subclass_name_suffix = Impl
# ij_java_ternary_operation_signs_on_next_line = true
# ij_java_ternary_operation_wrap = off
# ij_java_test_name_suffix = Test
# ij_java_throws_keyword_wrap = normal
# ij_java_throws_list_wrap = normal
# ij_java_use_external_annotations = false
# ij_java_use_fq_class_names = false
# ij_java_use_single_class_imports = true
# ij_java_variable_annotation_wrap = off
# ij_java_visibility = public
# ij_java_while_brace_force = always
# ij_java_while_on_new_line = false
# ij_java_wrap_comments = false
# ij_java_wrap_first_method_in_call_chain = false
# ij_java_wrap_long_lines = false

View File

@ -1,24 +1,23 @@
buildscript {
repositories {
mavenLocal()
maven { url = 'https://files.minecraftforge.net/maven' }
jcenter()
maven { url = 'https://maven.minecraftforge.net' }
mavenCentral()
jcenter()
}
dependencies {
classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '3.+', changing: true
classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '5.1.+', changing: true
}
}
apply plugin: 'net.minecraftforge.gradle'
apply plugin: 'maven'
apply plugin: 'eclipse'
apply plugin: 'maven-publish'
repositories {
maven {
name 'DVS1 Maven FS'
url 'http://dvs1.progwml6.com/files/maven'
url 'https://dvs1.progwml6.com/files/maven'
}
}
@ -108,15 +107,6 @@ minecraft {
}
}
dependencies {
minecraft 'net.minecraftforge:forge:' + minecraft_version + '-' + forge_version
// compile against the JEI API but do not include it at runtime
compileOnly fg.deobf("mezz.jei:jei-1.16.2:${jei_version}:api")
// at runtime, use the full JEI jar
runtimeOnly fg.deobf("mezz.jei:jei-1.16.2:${jei_version}")
}
task buildInfo {
def cmd = "git rev-parse --short HEAD"
def proc = cmd.execute()
@ -146,20 +136,25 @@ sourceSets {
}
}
dependencies {
minecraft 'net.minecraftforge:forge:' + minecraft_version + '-' + forge_version
// compile against the JEI API but do not include it at runtime
compileOnly fg.deobf("mezz.jei:jei-${jei_version}:api")
// at runtime, use the full JEI jar
runtimeOnly fg.deobf("mezz.jei:jei-${jei_version}")
}
def modsTomlSpec = copySpec{
from(sourceSets.main.resources) {
include 'META-INF/mods.toml'
expand 'version': project.version,
'minecraft_version_min': minecraft_version_min,
'minecraft_version_max': minecraft_version_max,
'forge_version_min': forge_version_min,
'forge_version_max': forge_version_max,
'javafml_min': javafml_min,
'javafml_max': javafml_max
'loader_range': loader_range,
'minecraft_range': minecraft_range,
'forge_range': forge_range
}
}
// need to copy into each build directory, unfortunately does not seem easy to do this automatically
def buildPaths = [
"$rootDir/out/production/resources", // IDEA
@ -191,15 +186,6 @@ processResources {
finalizedBy replaceResources
}
task sourcesJar(type: Jar) {
from sourceSets.main.allJava
classifier = 'sources'
}
artifacts {
archives sourcesJar
}
jar {
manifest {
attributes([
@ -216,6 +202,15 @@ jar {
jar.finalizedBy('reobfJar')
task sourcesJar(type: Jar) {
from sourceSets.main.allJava
classifier = 'sources'
}
artifacts {
archives sourcesJar
}
publishing {
publications {
mavenJava(MavenPublication) {

View File

@ -7,19 +7,16 @@ org.gradle.daemon=false
mod_version=11.2
# Minecraft Version Information
minecraft_base_version=1.16
minecraft_version_min=1.16.2
minecraft_version=1.16.4
minecraft_version_max=1.17
minecraft_version=1.16.5
minecraft_range=[1.16.5,1.17)
# Forge Version Information
javafml_min=33.0
javafml_max=36.0
forge_version_min=33.0.0
forge_version=35.0.1
forge_version_max=36.0.0
jei_version=7.1.+
loader_range=[33.0,)
forge_version=36.1.1
forge_range=[36.1.1,)
# Mappings Information
mappings_version=20200916-1.16.2
# Build dependencies
jei_version=1.16.4:7.6.1.65

Binary file not shown.

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions-snapshots/gradle-7.2-20210702220150+0000-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-bin.zip

55
gradlew vendored
View File

@ -1,5 +1,21 @@
#!/usr/bin/env sh
#
# Copyright 2015 the original author or 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 UN*X
@ -28,7 +44,7 @@ APP_NAME="Gradle"
APP_BASE_NAME=`basename "$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=""
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
@ -56,7 +72,7 @@ case "`uname`" in
Darwin* )
darwin=true
;;
MINGW* )
MSYS* | MINGW* )
msys=true
;;
NONSTOP* )
@ -66,6 +82,7 @@ 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
@ -109,10 +126,11 @@ if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
@ -138,19 +156,19 @@ if $cygwin ; then
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
i=`expr $i + 1`
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
@ -159,14 +177,9 @@ save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
APP_ARGS=`save "$@"`
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"

43
gradlew.bat vendored
View File

@ -1,3 +1,19 @@
@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
@ -13,15 +29,18 @@ 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=
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 init
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@ -35,7 +54,7 @@ goto fail
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
@ -45,28 +64,14 @@ echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
: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 %CMD_LINE_ARGS%
"%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

View File

@ -25,7 +25,7 @@ db1c86a602b40793abc52cebf70fad24cf6409d9 data/ironchest/recipes/chests/copper_ir
9f141ad7e75e7ac70b175129c058180da5e04ab7 data/ironchest/recipes/chests/diamond_obsidian_chest.json
00cad996bebebe268e2e0a4c59c024127c6f4a06 data/ironchest/recipes/chests/gold_diamond_chest.json
401d6ab7ffb4e815dc1a6562dd70bc7bd1f6d524 data/ironchest/recipes/chests/iron_gold_chest.json
65b0fd37de2ebcfcf88488d3db138e5446ba7d21 data/ironchest/recipes/chests/iron_silver_chest.json
27a78a2d11f8a8cd82ee7560eb64bae5ed61cdaf data/ironchest/recipes/chests/iron_silver_chest.json
f9187402fa4f5768064b0f5071709048c1bf0d24 data/ironchest/recipes/chests/silver_diamond_chest.json
e3d600f97882251c94f14c0bffa63f0b5ff81350 data/ironchest/recipes/chests/silver_gold_chest.json
c4ce3a2d83ee91bc30b7f88fef054b6331f71d8d data/ironchest/recipes/chests/vanilla_copper_chest.json
@ -37,6 +37,6 @@ e25f174a4a36d367d96d2e61561d526e83a5e155 data/ironchest/recipes/upgrades/diamond
9f0931b4d648fcea11dd2a7953d8e09df623d539 data/ironchest/recipes/upgrades/diamond_to_obsidian_chest_upgrade.json
793e25f4ae9a93636292036ceb9b0aaa821d299b data/ironchest/recipes/upgrades/gold_to_diamond_chest_upgrade.json
1b70eef2a303cf31300a5a5bc20780f9cea7e444 data/ironchest/recipes/upgrades/iron_to_gold_chest_upgrade.json
a529978a8ac60c95c4e27f714ee69c1c15b0af9f data/ironchest/recipes/upgrades/silver_to_gold_chest_upgrade.json
aaa8c0135a8ca7c2146337d0a42e7fb84015e4c4 data/ironchest/recipes/upgrades/silver_to_gold_chest_upgrade.json
058c4081d18ddcff952f218a1e1e31ea1c26fa04 data/ironchest/recipes/upgrades/wood_to_copper_chest_upgrade.json
1098d6ebd2e6e1065324fd6314481fe40df132e7 data/ironchest/recipes/upgrades/wood_to_iron_chest_upgrade.json

View File

@ -14,9 +14,9 @@
"recipe": {
"type": "minecraft:crafting_shaped",
"pattern": [
"GGG",
"MGM",
"MSM",
"GGG"
"MGM"
],
"key": {
"M": {

View File

@ -23,7 +23,7 @@
"tag": "forge:ingots/gold"
},
"S": {
"tag": "forge:ingots/copper"
"tag": "forge:ingots/silver"
},
"G": {
"tag": "forge:glass"

View File

@ -1,12 +1,13 @@
package com.progwml6.ironchest;
import com.progwml6.ironchest.client.screen.IronChestScreen;
import com.progwml6.ironchest.client.tileentity.IronChestTileEntityRenderer;
import com.progwml6.ironchest.client.render.IronChestTileEntityRenderer;
import com.progwml6.ironchest.common.block.IronChestsBlocks;
import com.progwml6.ironchest.common.block.tileentity.IronChestsTileEntityTypes;
import com.progwml6.ironchest.common.data.IronChestsRecipeProvider;
import com.progwml6.ironchest.common.inventory.IronChestsContainerTypes;
import com.progwml6.ironchest.common.item.IronChestsItems;
import com.progwml6.ironchest.common.network.IronChestNetwork;
import net.minecraft.client.gui.ScreenManager;
import net.minecraft.data.DataGenerator;
import net.minecraft.item.ItemGroup;
@ -47,6 +48,8 @@ public class IronChests {
modBus.addListener(this::setupClient);
});
IronChestNetwork.setup();
// Registry objects
IronChestsBlocks.BLOCKS.register(modBus);
IronChestsItems.ITEMS.register(modBus);

View File

@ -1,4 +1,4 @@
package com.progwml6.ironchest.client.tileentity;
package com.progwml6.ironchest.client.model;
import com.progwml6.ironchest.IronChests;
import com.progwml6.ironchest.common.block.IronChestsTypes;

View File

@ -1,4 +1,4 @@
package com.progwml6.ironchest.client.tileentity;
package com.progwml6.ironchest.client.model.inventory;
import com.mojang.blaze3d.matrix.MatrixStack;
import net.minecraft.client.renderer.IRenderTypeBuffer;

View File

@ -0,0 +1,59 @@
package com.progwml6.ironchest.client.model.inventory;
import net.minecraft.util.math.vector.Vector3f;
public class ModelItem {
private final Vector3f center;
private final float size;
/** Item center location in percentages, lazy loaded */
private Vector3f centerScaled;
/** Item size in percentages, lazy loaded */
private Float sizeScaled;
public ModelItem(Vector3f center, float size) {
this.center = center;
this.size = size;
}
/**
* Gets the center for rendering this item, scaled for renderer
* @return Scaled center
*/
public Vector3f getCenterScaled() {
if (centerScaled == null) {
centerScaled = center.copy();
centerScaled.mul(1f / 16f);
}
return centerScaled;
}
/**
* Gets the size to render this item, scaled for the renderer
* @return Size scaled
*/
public float getSizeScaled() {
if (sizeScaled == null) {
sizeScaled = size / 16f;
}
return sizeScaled;
}
/**
* Gets the center for rendering this item
* @return Center
*/
public Vector3f getCenter() {
return center;
}
/**
* Gets the size to render this item
* @return Size
*/
public float getSize() {
return size;
}
}

View File

@ -0,0 +1,7 @@
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
package com.progwml6.ironchest.client.model.inventory;
import mcp.MethodsReturnNonnullByDefault;
import javax.annotation.ParametersAreNonnullByDefault;

View File

@ -1,6 +1,6 @@
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
package com.progwml6.ironchest.client.tileentity;
package com.progwml6.ironchest.client.model;
import mcp.MethodsReturnNonnullByDefault;

View File

@ -1,33 +1,63 @@
package com.progwml6.ironchest.client.tileentity;
package com.progwml6.ironchest.client.render;
import com.google.common.primitives.SignedBytes;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.vertex.IVertexBuilder;
import com.progwml6.ironchest.client.model.IronChestsModels;
import com.progwml6.ironchest.client.model.inventory.ModelItem;
import com.progwml6.ironchest.common.block.GenericIronChestBlock;
import com.progwml6.ironchest.common.block.IronChestsTypes;
import com.progwml6.ironchest.common.block.tileentity.CrystalChestTileEntity;
import com.progwml6.ironchest.common.block.tileentity.GenericIronChestTileEntity;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.Atlases;
import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.entity.ItemRenderer;
import net.minecraft.client.renderer.model.ItemCameraTransforms;
import net.minecraft.client.renderer.model.ModelRenderer;
import net.minecraft.client.renderer.model.RenderMaterial;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.client.renderer.tileentity.DualBrightnessCallback;
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.item.ItemEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.IChestLid;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityMerger;
import net.minecraft.util.Direction;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.util.math.vector.Vector3f;
import net.minecraft.world.World;
import java.util.Arrays;
import java.util.List;
public class IronChestTileEntityRenderer<T extends TileEntity & IChestLid> extends TileEntityRenderer<T> {
private final ModelRenderer chestLid;
private final ModelRenderer chestBottom;
private final ModelRenderer chestLock;
private static ItemEntity customItem;
private static ItemRenderer itemRenderer;
private static final List<ModelItem> MODEL_ITEMS = Arrays.asList(
new ModelItem(new Vector3f(0.3F, 0.45F, 0.3F), 3.0F),
new ModelItem(new Vector3f(0.7F, 0.45F, 0.3F), 3.0F),
new ModelItem(new Vector3f(0.3F, 0.45F, 0.7F), 3.0F),
new ModelItem(new Vector3f(0.7F, 0.45F, 0.7F), 3.0F),
new ModelItem(new Vector3f(0.3F, 0.1F, 0.3F), 3.0F),
new ModelItem(new Vector3f(0.7F, 0.1F, 0.3F), 3.0F),
new ModelItem(new Vector3f(0.3F, 0.1F, 0.7F), 3.0F),
new ModelItem(new Vector3f(0.7F, 0.1F, 0.7F), 3.0F),
new ModelItem(new Vector3f(0.5F, 0.32F, 0.5F), 3.0F)
);
public IronChestTileEntityRenderer(TileEntityRendererDispatcher tileEntityRendererDispatcher) {
super(tileEntityRendererDispatcher);
@ -70,8 +100,7 @@ public class IronChestTileEntityRenderer<T extends TileEntity & IChestLid> exten
TileEntityMerger.ICallbackWrapper<? extends GenericIronChestTileEntity> iCallbackWrapper;
if (flag) {
iCallbackWrapper = ironChestBlock.getWrapper(blockstate, world, tileEntity.getPos(), true);
}
else {
} else {
iCallbackWrapper = TileEntityMerger.ICallback::func_225537_b_;
}
@ -86,6 +115,20 @@ public class IronChestTileEntityRenderer<T extends TileEntity & IChestLid> exten
this.handleModelRender(matrixStackIn, ivertexbuilder, this.chestLid, this.chestLock, this.chestBottom, f1, i, combinedOverlayIn);
matrixStackIn.pop();
if (chestType.isTransparent() && tileEntity instanceof CrystalChestTileEntity && Vector3d.copyCentered(tileEntityIn.getPos()).isWithinDistanceOf(this.renderDispatcher.renderInfo.getProjectedView(), 128d)) {
float rotation = (float) (360D * (System.currentTimeMillis() & 0x3FFFL) / 0x3FFFL) - partialTicks;
CrystalChestTileEntity crystalChestTileEntity = (CrystalChestTileEntity) tileEntity;
if (customItem == null) {
assert world != null;
customItem = new ItemEntity(EntityType.ITEM, world);
}
for (int j = 0; j < MODEL_ITEMS.size() - 1; j++) {
renderItem(matrixStackIn, bufferIn, crystalChestTileEntity.getTopItems().get(j), MODEL_ITEMS.get(j), rotation, combinedLightIn, partialTicks);
}
}
}
}
@ -96,4 +139,54 @@ public class IronChestTileEntityRenderer<T extends TileEntity & IChestLid> exten
secondModel.render(matrixStackIn, iVertexBuilder, p_228871_7_, p_228871_8_);
thirdModel.render(matrixStackIn, iVertexBuilder, p_228871_7_, p_228871_8_);
}
/**
* Renders a single item in a TESR
*
* @param matrices Matrix stack instance
* @param buffer Buffer instance
* @param item Item to render
* @param modelItem Model items for render information
* @param light Model light
*/
public static void renderItem(MatrixStack matrices, IRenderTypeBuffer buffer, ItemStack item, ModelItem modelItem, float rotation, int light, float partialTicks) {
// if no stack, skip
if (item.isEmpty()) return;
customItem.setItem(item);
// start rendering
matrices.push();
Vector3f center = modelItem.getCenter();
matrices.translate(center.getX(), center.getY(), center.getZ());
matrices.rotate(Vector3f.YP.rotation(rotation));
// scale
float scale = modelItem.getSizeScaled();
matrices.scale(scale, scale, scale);
// render the actual item
if (itemRenderer == null) {
itemRenderer = new ItemRenderer(Minecraft.getInstance().getRenderManager(), Minecraft.getInstance().getItemRenderer()) {
@Override
public int getModelCount(ItemStack stack) {
return SignedBytes.saturatedCast(Math.min(stack.getCount() / 32, 15) + 1);
}
@Override
public boolean shouldBob() {
return false;
}
@Override
public boolean shouldSpreadItems() {
return true;
}
};
}
itemRenderer.render(customItem, 0F, partialTicks, matrices, buffer, light);
matrices.pop();
}
}

View File

@ -0,0 +1,7 @@
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
package com.progwml6.ironchest.client.render;
import mcp.MethodsReturnNonnullByDefault;
import javax.annotation.ParametersAreNonnullByDefault;

View File

@ -1,13 +1,12 @@
package com.progwml6.ironchest.common.block;
import com.progwml6.ironchest.IronChests;
import com.progwml6.ironchest.client.tileentity.IronChestItemStackRenderer;
import com.progwml6.ironchest.client.model.inventory.IronChestItemStackRenderer;
import com.progwml6.ironchest.common.block.tileentity.CopperChestTileEntity;
import com.progwml6.ironchest.common.block.tileentity.CrystalChestTileEntity;
import com.progwml6.ironchest.common.block.tileentity.DiamondChestTileEntity;
import com.progwml6.ironchest.common.block.tileentity.DirtChestTileEntity;
import com.progwml6.ironchest.common.block.tileentity.GoldChestTileEntity;
import com.progwml6.ironchest.common.block.tileentity.GenericIronChestTileEntity;
import com.progwml6.ironchest.common.block.tileentity.IronChestTileEntity;
import com.progwml6.ironchest.common.block.tileentity.ObsidianChestTileEntity;
import com.progwml6.ironchest.common.block.tileentity.SilverChestTileEntity;

View File

@ -3,11 +3,15 @@ package com.progwml6.ironchest.common.block.tileentity;
import com.progwml6.ironchest.common.block.IronChestsBlocks;
import com.progwml6.ironchest.common.block.IronChestsTypes;
import com.progwml6.ironchest.common.inventory.IronChestContainer;
import com.progwml6.ironchest.common.network.InventoryTopStacksSyncPacket;
import com.progwml6.ironchest.common.network.IronChestNetwork;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.container.Container;
import net.minecraft.item.ItemStack;
import net.minecraft.util.NonNullList;
import net.minecraft.world.server.ServerWorld;
import net.minecraftforge.fml.network.PacketDistributor;
import java.util.Collections;
@ -177,10 +181,12 @@ public class CrystalChestTileEntity extends GenericIronChestTileEntity {
protected void sendTopStacksPacket() {
NonNullList<ItemStack> stacks = this.buildItemStackDataList();
//PacketHandler.send(PacketDistributor.TRACKING_CHUNK.with(() -> (Chunk) this.getWorld().getChunk(this.getPos())), new PacketTopStackSyncChest(this.getWorld().getDimension().getType().getId(), this.getPos(), stacks));
if (this.world != null && this.world instanceof ServerWorld && !this.world.isRemote) {
IronChestNetwork.getInstance().sendToClientsAround(new InventoryTopStacksSyncPacket(stacks, this.pos), (ServerWorld) this.world, this.pos);
}
}
public void receiveMessageFromServer(NonNullList<ItemStack> topStacks) {
this.topStacks = topStacks;
}
}
}

View File

@ -13,6 +13,7 @@ import net.minecraft.data.DataGenerator;
import net.minecraft.data.IFinishedRecipe;
import net.minecraft.data.RecipeProvider;
import net.minecraft.data.ShapedRecipeBuilder;
import net.minecraft.item.Item;
import net.minecraft.item.crafting.Ingredient;
import net.minecraft.tags.ItemTags;
import net.minecraft.util.IItemProvider;
@ -28,6 +29,9 @@ import java.util.function.Consumer;
public class IronChestsRecipeProvider extends RecipeProvider implements IConditionBuilder {
public static final Tags.IOptionalNamedTag<Item> INGOTS_COPPER = tag("ingots/copper");
public static final Tags.IOptionalNamedTag<Item> INGOTS_SILVER = tag("ingots/silver");
public IronChestsRecipeProvider(DataGenerator generatorIn) {
super(generatorIn);
}
@ -121,18 +125,18 @@ public class IronChestsRecipeProvider extends RecipeProvider implements IConditi
ConditionalRecipe.builder()
.addCondition(not(new TagEmptyCondition("forge:ingots/silver")))
.addRecipe(ShapedRecipeBuilder.shapedRecipe(IronChestsBlocks.SILVER_CHEST.get())
.key('M', ItemTags.makeWrapperTag("forge:ingots/silver"))
.key('M', INGOTS_SILVER)
.key('S', IronChestsBlocks.COPPER_CHEST.get())
.patternLine("MMM")
.patternLine("MSM")
.patternLine("MMM")
.addCriterion("has_item", hasItem(ItemTags.makeWrapperTag("forge:ingots/silver")))::build)
.addCriterion("has_item", hasItem(INGOTS_SILVER))::build)
.setAdvancement(location("recipes/ironchest/chests/copper_silver_chest"), ConditionalAdvancement.builder()
.addCondition(not(new TagEmptyCondition("forge:ingots/silver")))
.addAdvancement(Advancement.Builder.builder()
.withParentId(new ResourceLocation("recipes/root"))
.withRewards(AdvancementRewards.Builder.recipe(copperToSilverChest))
.withCriterion("has_item", hasItem(ItemTags.makeWrapperTag("forge:ingots/silver")))
.withCriterion("has_item", hasItem(INGOTS_SILVER))
.withCriterion("has_the_recipe", RecipeUnlockedTrigger.create(copperToSilverChest))
.withRequirementsStrategy(IRequirementsStrategy.OR))
).build(consumer, copperToSilverChest);
@ -141,19 +145,19 @@ public class IronChestsRecipeProvider extends RecipeProvider implements IConditi
ConditionalRecipe.builder()
.addCondition(not(new TagEmptyCondition("forge:ingots/silver")))
.addRecipe(ShapedRecipeBuilder.shapedRecipe(IronChestsBlocks.SILVER_CHEST.get())
.key('M', ItemTags.makeWrapperTag("forge:ingots/silver"))
.key('M', INGOTS_SILVER)
.key('S', IronChestsBlocks.IRON_CHEST.get())
.key('G', Tags.Items.GLASS)
.patternLine("GGG")
.patternLine("MGM")
.patternLine("MSM")
.patternLine("GGG")
.addCriterion("has_item", hasItem(ItemTags.makeWrapperTag("forge:ingots/silver")))::build)
.patternLine("MGM")
.addCriterion("has_item", hasItem(INGOTS_SILVER))::build)
.setAdvancement(location("recipes/ironchest/chests/iron_silver_chest"), ConditionalAdvancement.builder()
.addCondition(not(new TagEmptyCondition("forge:ingots/silver")))
.addAdvancement(Advancement.Builder.builder()
.withParentId(new ResourceLocation("recipes/root"))
.withRewards(AdvancementRewards.Builder.recipe(ironToSilverChest))
.withCriterion("has_item", hasItem(ItemTags.makeWrapperTag("forge:ingots/silver")))
.withCriterion("has_item", hasItem(INGOTS_SILVER))
.withCriterion("has_the_recipe", RecipeUnlockedTrigger.create(ironToSilverChest))
.withRequirementsStrategy(IRequirementsStrategy.OR))
).build(consumer, ironToSilverChest);
@ -162,18 +166,18 @@ public class IronChestsRecipeProvider extends RecipeProvider implements IConditi
ConditionalRecipe.builder()
.addCondition(not(new TagEmptyCondition("forge:ingots/copper")))
.addRecipe(ShapedRecipeBuilder.shapedRecipe(IronChestsBlocks.COPPER_CHEST.get())
.key('M', ItemTags.makeWrapperTag("forge:ingots/copper"))
.key('M', INGOTS_COPPER)
.key('S', Tags.Items.CHESTS_WOODEN)
.patternLine("MMM")
.patternLine("MSM")
.patternLine("MMM")
.addCriterion("has_item", hasItem(ItemTags.makeWrapperTag("forge:ingots/copper")))::build)
.addCriterion("has_item", hasItem(INGOTS_COPPER))::build)
.setAdvancement(location("recipes/ironchest/chests/vanilla_copper_chest"), ConditionalAdvancement.builder()
.addCondition(not(new TagEmptyCondition("forge:ingots/silver")))
.addAdvancement(Advancement.Builder.builder()
.withParentId(new ResourceLocation("recipes/root"))
.withRewards(AdvancementRewards.Builder.recipe(vanillaToCopperChest))
.withCriterion("has_item", hasItem(ItemTags.makeWrapperTag("forge:ingots/copper")))
.withCriterion("has_item", hasItem(INGOTS_COPPER))
.withCriterion("has_the_recipe", RecipeUnlockedTrigger.create(vanillaToCopperChest))
.withRequirementsStrategy(IRequirementsStrategy.OR))
).build(consumer, vanillaToCopperChest);
@ -188,13 +192,13 @@ public class IronChestsRecipeProvider extends RecipeProvider implements IConditi
.patternLine("MGM")
.patternLine("GSG")
.patternLine("MGM")
.addCriterion("has_item", hasItem(ItemTags.makeWrapperTag("forge:ingots/silver")))::build)
.addCriterion("has_item", hasItem(INGOTS_SILVER))::build)
.setAdvancement(location("recipes/ironchest/chests/silver_gold_chest"), ConditionalAdvancement.builder()
.addCondition(not(new TagEmptyCondition("forge:ingots/silver")))
.addAdvancement(Advancement.Builder.builder()
.withParentId(new ResourceLocation("recipes/root"))
.withRewards(AdvancementRewards.Builder.recipe(silverToGoldChest))
.withCriterion("has_item", hasItem(ItemTags.makeWrapperTag("forge:ingots/silver")))
.withCriterion("has_item", hasItem(INGOTS_SILVER))
.withCriterion("has_the_recipe", RecipeUnlockedTrigger.create(silverToGoldChest))
.withRequirementsStrategy(IRequirementsStrategy.OR))
).build(consumer, silverToGoldChest);
@ -274,7 +278,7 @@ public class IronChestsRecipeProvider extends RecipeProvider implements IConditi
ConditionalRecipe.builder()
.addCondition(not(new TagEmptyCondition("forge:ingots/copper")))
.addRecipe(ShapedRecipeBuilder.shapedRecipe(IronChestsItems.UPGRADES.get(IronChestsUpgradeType.WOOD_TO_COPPER).get())
.key('M', ItemTags.makeWrapperTag("forge:ingots/copper"))
.key('M', INGOTS_COPPER)
.key('S', ItemTags.PLANKS)
.patternLine("MMM")
.patternLine("MSM")
@ -295,7 +299,7 @@ public class IronChestsRecipeProvider extends RecipeProvider implements IConditi
.addCondition(not(new TagEmptyCondition("forge:ingots/copper")))
.addRecipe(ShapedRecipeBuilder.shapedRecipe(IronChestsItems.UPGRADES.get(IronChestsUpgradeType.COPPER_TO_IRON).get())
.key('M', Tags.Items.INGOTS_IRON)
.key('S', ItemTags.makeWrapperTag("forge:ingots/copper"))
.key('S', INGOTS_COPPER)
.key('G', Tags.Items.GLASS)
.patternLine("MGM")
.patternLine("GSG")
@ -315,18 +319,18 @@ public class IronChestsRecipeProvider extends RecipeProvider implements IConditi
ConditionalRecipe.builder()
.addCondition(and(not(new TagEmptyCondition("forge:ingots/copper")), not(new TagEmptyCondition("forge:ingots/silver"))))
.addRecipe(ShapedRecipeBuilder.shapedRecipe(IronChestsItems.UPGRADES.get(IronChestsUpgradeType.COPPER_TO_SILVER).get())
.key('M', ItemTags.makeWrapperTag("forge:ingots/silver"))
.key('S', ItemTags.makeWrapperTag("forge:ingots/copper"))
.key('M', INGOTS_SILVER)
.key('S', INGOTS_COPPER)
.patternLine("MMM")
.patternLine("MSM")
.patternLine("MMM")
.addCriterion("has_item", hasItem(ItemTags.makeWrapperTag("forge:ingots/copper")))::build)
.addCriterion("has_item", hasItem(INGOTS_COPPER))::build)
.setAdvancement(location("recipes/ironchest/upgrades/copper_to_silver_chest_upgrade"), ConditionalAdvancement.builder()
.addCondition(and(not(new TagEmptyCondition("forge:ingots/copper")), not(new TagEmptyCondition("forge:ingots/silver"))))
.addAdvancement(Advancement.Builder.builder()
.withParentId(new ResourceLocation("recipes/root"))
.withRewards(AdvancementRewards.Builder.recipe(copperToSilverChestUpgrade))
.withCriterion("has_item", hasItem(ItemTags.makeWrapperTag("forge:ingots/copper")))
.withCriterion("has_item", hasItem(INGOTS_COPPER))
.withCriterion("has_the_recipe", RecipeUnlockedTrigger.create(copperToSilverChestUpgrade))
.withRequirementsStrategy(IRequirementsStrategy.OR))
).build(consumer, copperToSilverChestUpgrade);
@ -336,7 +340,7 @@ public class IronChestsRecipeProvider extends RecipeProvider implements IConditi
.addCondition(not(new TagEmptyCondition("forge:ingots/silver")))
.addRecipe(ShapedRecipeBuilder.shapedRecipe(IronChestsItems.UPGRADES.get(IronChestsUpgradeType.SILVER_TO_GOLD).get())
.key('M', Tags.Items.INGOTS_GOLD)
.key('S', ItemTags.makeWrapperTag("forge:ingots/copper"))
.key('S', INGOTS_SILVER)
.key('G', Tags.Items.GLASS)
.patternLine("MGM")
.patternLine("GSG")
@ -361,4 +365,8 @@ public class IronChestsRecipeProvider extends RecipeProvider implements IConditi
private static ResourceLocation location(String id) {
return new ResourceLocation(IronChests.MODID, id);
}
private static Tags.IOptionalNamedTag<Item> tag(String name) {
return ItemTags.createOptional(new ResourceLocation("forge", name));
}
}

View File

@ -0,0 +1,75 @@
package com.progwml6.ironchest.common.network;
import com.progwml6.ironchest.common.block.tileentity.CrystalChestTileEntity;
import com.progwml6.ironchest.common.network.helper.IThreadsafePacket;
import net.minecraft.client.Minecraft;
import net.minecraft.item.ItemStack;
import net.minecraft.network.PacketBuffer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.NonNullList;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.fml.network.NetworkEvent.Context;
public class InventoryTopStacksSyncPacket implements IThreadsafePacket {
private final BlockPos pos;
private final NonNullList<ItemStack> topStacks;
public InventoryTopStacksSyncPacket(NonNullList<ItemStack> topStacks, BlockPos pos) {
this.topStacks = topStacks;
this.pos = pos;
}
public InventoryTopStacksSyncPacket(PacketBuffer buffer) {
int size = buffer.readInt();
NonNullList<ItemStack> topStacks = NonNullList.<ItemStack>withSize(size, ItemStack.EMPTY);
for (int item = 0; item < size; item++) {
ItemStack itemStack = buffer.readItemStack();
topStacks.set(item, itemStack);
}
this.topStacks = topStacks;
this.pos = buffer.readBlockPos();
}
@Override
public void encode(PacketBuffer packetBuffer) {
packetBuffer.writeInt(this.topStacks.size());
for (ItemStack stack : this.topStacks) {
packetBuffer.writeItemStack(stack);
}
packetBuffer.writeBlockPos(this.pos);
}
@Override
public void handleThreadsafe(Context context) {
HandleClient.handle(this);
}
/**
* Safely runs client side only code in a method only called on client
*/
private static class HandleClient {
private static void handle(InventoryTopStacksSyncPacket packet) {
World world = Minecraft.getInstance().world;
if (world != null) {
TileEntity te = world.getTileEntity(packet.pos);
if (te != null) {
if (te instanceof CrystalChestTileEntity) {
((CrystalChestTileEntity) te).receiveMessageFromServer(packet.topStacks);
Minecraft.getInstance().worldRenderer.notifyBlockUpdate(null, packet.pos, null, null, 0);
}
}
}
}
}
}

View File

@ -0,0 +1,193 @@
package com.progwml6.ironchest.common.network;
import com.progwml6.ironchest.IronChests;
import com.progwml6.ironchest.common.network.helper.ISimplePacket;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.network.IPacket;
import net.minecraft.network.PacketBuffer;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IWorld;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.server.ServerWorld;
import net.minecraftforge.common.util.FakePlayer;
import net.minecraftforge.fml.network.NetworkDirection;
import net.minecraftforge.fml.network.NetworkEvent;
import net.minecraftforge.fml.network.NetworkRegistry;
import net.minecraftforge.fml.network.PacketDistributor;
import net.minecraftforge.fml.network.simple.SimpleChannel;
import javax.annotation.Nullable;
import java.util.Optional;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.Supplier;
public class IronChestNetwork {
private static IronChestNetwork instance = null;
public final SimpleChannel network;
private int id = 0;
private static final String PROTOCOL_VERSION = Integer.toString(1);
public IronChestNetwork() {
this.network = NetworkRegistry.ChannelBuilder.named(new ResourceLocation(IronChests.MODID, "network"))
.clientAcceptedVersions(PROTOCOL_VERSION::equals)
.serverAcceptedVersions(PROTOCOL_VERSION::equals)
.networkProtocolVersion(() -> PROTOCOL_VERSION)
.simpleChannel();
}
/**
* Gets the instance of the network
*/
public static IronChestNetwork getInstance() {
if (instance == null) {
throw new IllegalStateException("Attempt to call network getInstance before network is setup");
}
return instance;
}
/**
* Called during mod construction to setup the network
*/
public static void setup() {
if (instance != null) {
return;
}
instance = new IronChestNetwork();
instance.registerPacket(InventoryTopStacksSyncPacket.class, InventoryTopStacksSyncPacket::new, NetworkDirection.PLAY_TO_CLIENT);
}
/**
* Registers a new {@link ISimplePacket}
*
* @param clazz Packet class
* @param decoder Packet decoder, typically the constructor
* @param <MSG> Packet class type
*/
public <MSG extends ISimplePacket> void registerPacket(Class<MSG> clazz, Function<PacketBuffer, MSG> decoder, @Nullable NetworkDirection direction) {
registerPacket(clazz, ISimplePacket::encode, decoder, ISimplePacket::handle, direction);
}
/**
* Registers a new generic packet
*
* @param clazz Packet class
* @param encoder Encodes a packet to the buffer
* @param decoder Packet decoder, typically the constructor
* @param consumer Logic to handle a packet
* @param direction Network direction for validation. Pass null for no direction
* @param <MSG> Packet class type
*/
public <MSG> void registerPacket(Class<MSG> clazz, BiConsumer<MSG, PacketBuffer> encoder, Function<PacketBuffer, MSG> decoder, BiConsumer<MSG, Supplier<NetworkEvent.Context>> consumer, @Nullable NetworkDirection direction) {
this.network.registerMessage(this.id++, clazz, encoder, decoder, consumer, Optional.ofNullable(direction));
}
/* Sending packets */
/**
* Sends a packet to the server
*
* @param msg Packet to send
*/
public void sendToServer(Object msg) {
this.network.sendToServer(msg);
}
/**
* Sends a packet to the given packet distributor
*
* @param target Packet target
* @param message Packet to send
*/
public void send(PacketDistributor.PacketTarget target, Object message) {
network.send(target, message);
}
/**
* Sends a vanilla packet to the given entity
*
* @param player Player receiving the packet
* @param packet Packet
*/
public void sendVanillaPacket(IPacket<?> packet, Entity player) {
if (player instanceof ServerPlayerEntity && ((ServerPlayerEntity) player).connection != null) {
((ServerPlayerEntity) player).connection.sendPacket(packet);
}
}
/**
* Sends a packet to a player
*
* @param msg Packet
* @param player Player to send
*/
public void sendTo(Object msg, PlayerEntity player) {
if (player instanceof ServerPlayerEntity) {
sendTo(msg, (ServerPlayerEntity) player);
}
}
/**
* Sends a packet to a player
*
* @param msg Packet
* @param player Player to send
*/
public void sendTo(Object msg, ServerPlayerEntity player) {
if (!(player instanceof FakePlayer)) {
network.sendTo(msg, player.connection.netManager, NetworkDirection.PLAY_TO_CLIENT);
}
}
/**
* Sends a packet to players near a location
*
* @param msg Packet to send
* @param serverWorld World instance
* @param position Position within range
*/
public void sendToClientsAround(Object msg, ServerWorld serverWorld, BlockPos position) {
Chunk chunk = serverWorld.getChunkAt(position);
network.send(PacketDistributor.TRACKING_CHUNK.with(() -> chunk), msg);
}
/**
* Sends a packet to all entities tracking the given entity
*
* @param msg Packet
* @param entity Entity to check
*/
public void sendToTrackingAndSelf(Object msg, Entity entity) {
this.network.send(PacketDistributor.TRACKING_ENTITY_AND_SELF.with(() -> entity), msg);
}
/**
* Sends a packet to all entities tracking the given entity
*
* @param msg Packet
* @param entity Entity to check
*/
public void sendToTracking(Object msg, Entity entity) {
this.network.send(PacketDistributor.TRACKING_ENTITY.with(() -> entity), msg);
}
/**
* Same as {@link #sendToClientsAround(Object, ServerWorld, BlockPos)}, but checks that the world is a serverworld
*
* @param msg Packet to send
* @param world World instance
* @param position Target position
*/
public void sendToClientsAround(Object msg, @Nullable IWorld world, BlockPos position) {
if (world instanceof ServerWorld) {
sendToClientsAround(msg, (ServerWorld) world, position);
}
}
}

View File

@ -0,0 +1,23 @@
package com.progwml6.ironchest.common.network.helper;
import net.minecraft.network.PacketBuffer;
import net.minecraftforge.fml.network.NetworkEvent;
import java.util.function.Supplier;
/**
* Packet interface to add common methods for registration
*/
public interface ISimplePacket {
/**
* Encodes a packet for the buffer
* @param buf Buffer instance
*/
void encode(PacketBuffer buf);
/**
* Handles receiving the packet
* @param context Packet context
*/
void handle(Supplier<NetworkEvent.Context> context);
}

View File

@ -0,0 +1,25 @@
package com.progwml6.ironchest.common.network.helper;
import net.minecraftforge.fml.network.NetworkEvent;
import java.util.function.Supplier;
/**
* Packet instance that automatically wraps the logic in {@link NetworkEvent.Context#enqueueWork(Runnable)} for thread safety
*/
public interface IThreadsafePacket extends ISimplePacket {
@Override
default void handle(Supplier<NetworkEvent.Context> supplier) {
NetworkEvent.Context context = supplier.get();
context.enqueueWork(() -> handleThreadsafe(context));
context.setPacketHandled(true);
}
/**
* Handles receiving the packet on the correct thread
* Packet is automatically set to handled as well by the base logic
* @param context Packet context
*/
void handleThreadsafe(NetworkEvent.Context context);
}

View File

@ -0,0 +1,7 @@
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
package com.progwml6.ironchest.common.network;
import mcp.MethodsReturnNonnullByDefault;
import javax.annotation.ParametersAreNonnullByDefault;

View File

@ -1,5 +1,5 @@
modLoader="javafml"
loaderVersion="[${javafml_min},${javafml_max})"
loaderVersion="${loader_range}"
issueTrackerURL="https://github.com/progwml6/ironchest/issues"
license="GNU General Public License v3.0"
@ -18,6 +18,13 @@ The feature chest is the crystal chest, which is transparent - some inventory co
[[dependencies.ironchest]]
modId="forge"
mandatory=true
versionRange="[${forge_version_min},${forge_version_max})"
versionRange="${forge_range}"
ordering="NONE"
side="BOTH"
[[dependencies.ironchest]]
modId="minecraft"
mandatory=true
versionRange="${minecraft_range}"
ordering="NONE"
side="BOTH"