diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..e3c79b4 --- /dev/null +++ b/.editorconfig @@ -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 diff --git a/build.gradle b/build.gradle index a98cb88..7e30aa2 100755 --- a/build.gradle +++ b/build.gradle @@ -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) { diff --git a/gradle.properties b/gradle.properties index a2a06ab..db7d3d3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -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 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 7a3265e..7454180 100755 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 949819d..0595cf7 100755 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -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 diff --git a/gradlew b/gradlew index cccdd3d..744e882 100755 --- a/gradlew +++ b/gradlew @@ -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" "$@" diff --git a/gradlew.bat b/gradlew.bat index e95643d..ac1b06f 100755 --- a/gradlew.bat +++ b/gradlew.bat @@ -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 diff --git a/src/generated/resources/.cache/cache b/src/generated/resources/.cache/cache index da72a46..a1f7c53 100644 --- a/src/generated/resources/.cache/cache +++ b/src/generated/resources/.cache/cache @@ -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 diff --git a/src/generated/resources/data/ironchest/recipes/chests/iron_silver_chest.json b/src/generated/resources/data/ironchest/recipes/chests/iron_silver_chest.json index 20c39ed..67d5a5d 100644 --- a/src/generated/resources/data/ironchest/recipes/chests/iron_silver_chest.json +++ b/src/generated/resources/data/ironchest/recipes/chests/iron_silver_chest.json @@ -14,9 +14,9 @@ "recipe": { "type": "minecraft:crafting_shaped", "pattern": [ - "GGG", + "MGM", "MSM", - "GGG" + "MGM" ], "key": { "M": { diff --git a/src/generated/resources/data/ironchest/recipes/upgrades/silver_to_gold_chest_upgrade.json b/src/generated/resources/data/ironchest/recipes/upgrades/silver_to_gold_chest_upgrade.json index 3b10d16..3aaf1dd 100644 --- a/src/generated/resources/data/ironchest/recipes/upgrades/silver_to_gold_chest_upgrade.json +++ b/src/generated/resources/data/ironchest/recipes/upgrades/silver_to_gold_chest_upgrade.json @@ -23,7 +23,7 @@ "tag": "forge:ingots/gold" }, "S": { - "tag": "forge:ingots/copper" + "tag": "forge:ingots/silver" }, "G": { "tag": "forge:glass" diff --git a/src/main/java/com/progwml6/ironchest/IronChests.java b/src/main/java/com/progwml6/ironchest/IronChests.java index add666d..9d4b7aa 100644 --- a/src/main/java/com/progwml6/ironchest/IronChests.java +++ b/src/main/java/com/progwml6/ironchest/IronChests.java @@ -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); diff --git a/src/main/java/com/progwml6/ironchest/client/tileentity/IronChestsModels.java b/src/main/java/com/progwml6/ironchest/client/model/IronChestsModels.java similarity index 98% rename from src/main/java/com/progwml6/ironchest/client/tileentity/IronChestsModels.java rename to src/main/java/com/progwml6/ironchest/client/model/IronChestsModels.java index 8ca6492..1ccaa3f 100644 --- a/src/main/java/com/progwml6/ironchest/client/tileentity/IronChestsModels.java +++ b/src/main/java/com/progwml6/ironchest/client/model/IronChestsModels.java @@ -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; diff --git a/src/main/java/com/progwml6/ironchest/client/tileentity/IronChestItemStackRenderer.java b/src/main/java/com/progwml6/ironchest/client/model/inventory/IronChestItemStackRenderer.java similarity index 95% rename from src/main/java/com/progwml6/ironchest/client/tileentity/IronChestItemStackRenderer.java rename to src/main/java/com/progwml6/ironchest/client/model/inventory/IronChestItemStackRenderer.java index 1ca3b65..34d1f4d 100644 --- a/src/main/java/com/progwml6/ironchest/client/tileentity/IronChestItemStackRenderer.java +++ b/src/main/java/com/progwml6/ironchest/client/model/inventory/IronChestItemStackRenderer.java @@ -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; diff --git a/src/main/java/com/progwml6/ironchest/client/model/inventory/ModelItem.java b/src/main/java/com/progwml6/ironchest/client/model/inventory/ModelItem.java new file mode 100644 index 0000000..5920f12 --- /dev/null +++ b/src/main/java/com/progwml6/ironchest/client/model/inventory/ModelItem.java @@ -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; + } +} diff --git a/src/main/java/com/progwml6/ironchest/client/model/inventory/package-info.java b/src/main/java/com/progwml6/ironchest/client/model/inventory/package-info.java new file mode 100644 index 0000000..91c79f1 --- /dev/null +++ b/src/main/java/com/progwml6/ironchest/client/model/inventory/package-info.java @@ -0,0 +1,7 @@ +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +package com.progwml6.ironchest.client.model.inventory; + +import mcp.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/src/main/java/com/progwml6/ironchest/client/tileentity/package-info.java b/src/main/java/com/progwml6/ironchest/client/model/package-info.java similarity index 76% rename from src/main/java/com/progwml6/ironchest/client/tileentity/package-info.java rename to src/main/java/com/progwml6/ironchest/client/model/package-info.java index 8ca7484..727a282 100644 --- a/src/main/java/com/progwml6/ironchest/client/tileentity/package-info.java +++ b/src/main/java/com/progwml6/ironchest/client/model/package-info.java @@ -1,6 +1,6 @@ @ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault -package com.progwml6.ironchest.client.tileentity; +package com.progwml6.ironchest.client.model; import mcp.MethodsReturnNonnullByDefault; diff --git a/src/main/java/com/progwml6/ironchest/client/tileentity/IronChestTileEntityRenderer.java b/src/main/java/com/progwml6/ironchest/client/render/IronChestTileEntityRenderer.java similarity index 55% rename from src/main/java/com/progwml6/ironchest/client/tileentity/IronChestTileEntityRenderer.java rename to src/main/java/com/progwml6/ironchest/client/render/IronChestTileEntityRenderer.java index 9c55e0b..c262802 100644 --- a/src/main/java/com/progwml6/ironchest/client/tileentity/IronChestTileEntityRenderer.java +++ b/src/main/java/com/progwml6/ironchest/client/render/IronChestTileEntityRenderer.java @@ -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 extends TileEntityRenderer { private final ModelRenderer chestLid; private final ModelRenderer chestBottom; private final ModelRenderer chestLock; + private static ItemEntity customItem; + private static ItemRenderer itemRenderer; + + private static final List 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 exten TileEntityMerger.ICallbackWrapper 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 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 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(); + } } diff --git a/src/main/java/com/progwml6/ironchest/client/render/package-info.java b/src/main/java/com/progwml6/ironchest/client/render/package-info.java new file mode 100644 index 0000000..fbdbd06 --- /dev/null +++ b/src/main/java/com/progwml6/ironchest/client/render/package-info.java @@ -0,0 +1,7 @@ +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +package com.progwml6.ironchest.client.render; + +import mcp.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/src/main/java/com/progwml6/ironchest/common/block/IronChestsBlocks.java b/src/main/java/com/progwml6/ironchest/common/block/IronChestsBlocks.java index 890fe39..2d05738 100644 --- a/src/main/java/com/progwml6/ironchest/common/block/IronChestsBlocks.java +++ b/src/main/java/com/progwml6/ironchest/common/block/IronChestsBlocks.java @@ -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; diff --git a/src/main/java/com/progwml6/ironchest/common/block/tileentity/CrystalChestTileEntity.java b/src/main/java/com/progwml6/ironchest/common/block/tileentity/CrystalChestTileEntity.java index 94632ed..7d2df4a 100644 --- a/src/main/java/com/progwml6/ironchest/common/block/tileentity/CrystalChestTileEntity.java +++ b/src/main/java/com/progwml6/ironchest/common/block/tileentity/CrystalChestTileEntity.java @@ -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 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 topStacks) { this.topStacks = topStacks; } -} \ No newline at end of file +} diff --git a/src/main/java/com/progwml6/ironchest/common/data/IronChestsRecipeProvider.java b/src/main/java/com/progwml6/ironchest/common/data/IronChestsRecipeProvider.java index 4edcc7b..95b6965 100644 --- a/src/main/java/com/progwml6/ironchest/common/data/IronChestsRecipeProvider.java +++ b/src/main/java/com/progwml6/ironchest/common/data/IronChestsRecipeProvider.java @@ -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 INGOTS_COPPER = tag("ingots/copper"); + public static final Tags.IOptionalNamedTag 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 tag(String name) { + return ItemTags.createOptional(new ResourceLocation("forge", name)); + } } diff --git a/src/main/java/com/progwml6/ironchest/common/network/InventoryTopStacksSyncPacket.java b/src/main/java/com/progwml6/ironchest/common/network/InventoryTopStacksSyncPacket.java new file mode 100644 index 0000000..5527634 --- /dev/null +++ b/src/main/java/com/progwml6/ironchest/common/network/InventoryTopStacksSyncPacket.java @@ -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 topStacks; + + public InventoryTopStacksSyncPacket(NonNullList topStacks, BlockPos pos) { + this.topStacks = topStacks; + this.pos = pos; + } + + public InventoryTopStacksSyncPacket(PacketBuffer buffer) { + int size = buffer.readInt(); + NonNullList topStacks = NonNullList.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); + } + } + } + } + } +} diff --git a/src/main/java/com/progwml6/ironchest/common/network/IronChestNetwork.java b/src/main/java/com/progwml6/ironchest/common/network/IronChestNetwork.java new file mode 100644 index 0000000..21fd765 --- /dev/null +++ b/src/main/java/com/progwml6/ironchest/common/network/IronChestNetwork.java @@ -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 Packet class type + */ + public void registerPacket(Class clazz, Function 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 Packet class type + */ + public void registerPacket(Class clazz, BiConsumer encoder, Function decoder, BiConsumer> 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); + } + } +} diff --git a/src/main/java/com/progwml6/ironchest/common/network/helper/ISimplePacket.java b/src/main/java/com/progwml6/ironchest/common/network/helper/ISimplePacket.java new file mode 100644 index 0000000..67bfeda --- /dev/null +++ b/src/main/java/com/progwml6/ironchest/common/network/helper/ISimplePacket.java @@ -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 context); +} diff --git a/src/main/java/com/progwml6/ironchest/common/network/helper/IThreadsafePacket.java b/src/main/java/com/progwml6/ironchest/common/network/helper/IThreadsafePacket.java new file mode 100644 index 0000000..77721ac --- /dev/null +++ b/src/main/java/com/progwml6/ironchest/common/network/helper/IThreadsafePacket.java @@ -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 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); +} diff --git a/src/main/java/com/progwml6/ironchest/common/network/package-info.java b/src/main/java/com/progwml6/ironchest/common/network/package-info.java new file mode 100644 index 0000000..f7b7ef8 --- /dev/null +++ b/src/main/java/com/progwml6/ironchest/common/network/package-info.java @@ -0,0 +1,7 @@ +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +package com.progwml6.ironchest.common.network; + +import mcp.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml index 7c195cb..af1978b 100644 --- a/src/main/resources/META-INF/mods.toml +++ b/src/main/resources/META-INF/mods.toml @@ -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"