From 2f949d234eea158b29de95d23ed4f401516d8ccd Mon Sep 17 00:00:00 2001 From: btwonion Date: Tue, 11 Jun 2024 22:10:45 +0200 Subject: [PATCH] way to much to explain --- .editorconfig | 433 ++++++++++++++++-- .gitignore | 4 +- build.gradle.kts | 4 +- gradle.properties | 3 +- settings.gradle.kts | 13 +- telekinesis-fabric/build.gradle.kts | 96 ++-- .../mixins/AbstractChestedHorseMixin.java | 7 +- .../mixins/AbstractHorseMixin.java | 20 +- .../mixins/AbstractMinecartMixin.java | 8 +- .../nyon/telekinesis/mixins/AllayMixin.java | 39 +- .../nyon/telekinesis/mixins/BlockMixin.java | 131 +++--- .../nyon/telekinesis/mixins/BoatMixin.java | 8 +- .../mixins/CatalystBlockAccessor.java | 13 - .../telekinesis/mixins/ChestBoatMixin.java | 33 +- .../mixins/DropExperienceBlockAccessor.java | 13 - .../telekinesis/mixins/EnchantmentsMixin.java | 8 +- .../telekinesis/mixins/EnderManMixin.java | 11 +- .../telekinesis/mixins/FishingHookMixin.java | 73 ++- .../telekinesis/mixins/InventoryMixin.java | 1 - .../telekinesis/mixins/LivingEntityMixin.java | 2 - .../telekinesis/mixins/MinecartTNTMixin.java | 9 +- .../mixins/MinecraftServerMixin.java | 24 - .../dev/nyon/telekinesis/mixins/MobMixin.java | 27 +- .../dev/nyon/telekinesis/mixins/PigMixin.java | 7 +- .../nyon/telekinesis/mixins/PiglinMixin.java | 29 +- .../nyon/telekinesis/mixins/PlayerMixin.java | 40 ++ .../nyon/telekinesis/mixins/SheepMixin.java | 1 - ...nowgolemMixin.java => SnowGolemMixin.java} | 3 +- .../telekinesis/mixins/SpawnerBlockMixin.java | 49 ++ .../nyon/telekinesis/mixins/StriderMixin.java | 5 +- .../mixins/SweetBerryBushBlockMixin.java | 55 +-- .../mixins/VehicleEntityMixin.java | 44 +- .../telekinesis/mixins/WitherBossMixin.java | 32 +- .../betternether/BetterNetherMixinPlugin.java | 60 --- .../compat/betternether/RubyFireMixin.java | 99 ---- .../mixins/compat/levelz/BlockMixinMixin.java | 88 ---- .../levelz/EnderDragonEntityMixinMixin.java | 55 --- .../levelz/FishingBobberEntityMixinMixin.java | 36 -- .../levelz/LevelExperienceOrbAccessor.java | 9 - .../levelz/LevelExperienceOrbEntityMixin.java | 34 -- .../compat/levelz/LevelZMixinPlugin.java | 61 --- .../compat/levelz/LivingEntityMixinMixin.java | 35 -- .../compat/levelz/PlantBlockMixinMixin.java | 39 -- .../treeharvester/TreeCutEventsMixin.java | 44 -- .../TreeHarvesterMixinPlugin.java | 60 --- .../nyon/telekinesis/utils/EntityUtils.java | 65 --- .../nyon/telekinesis/utils/MixinHelper.java | 114 +++++ .../nyon/telekinesis/utils/PlayerUtils.java | 33 -- .../telekinesis/utils/TelekinesisUtils.java | 94 ---- .../kotlin/dev/nyon/telekinesis/DropEvent.kt | 21 + .../main/kotlin/dev/nyon/telekinesis/Main.kt | 5 +- .../telekinesis/TelekinesisEnchantment.kt | 14 +- .../TelekinesisEnchantmentGenerator.kt | 60 +++ .../resources/compat.betternether.mixins.json | 15 - .../main/resources/compat.levelz.mixins.json | 21 - .../compat.treeharvester.mixins.json | 13 - .../src/main/resources/fabric.mod.json | 101 ++-- .../main/resources/telekinesis.mixins.json | 65 ++- telekinesis-fabric/stonecutter.gradle.kts | 89 +++- .../versions/1.21/gradle.properties | 10 + 60 files changed, 1219 insertions(+), 1366 deletions(-) delete mode 100644 telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/CatalystBlockAccessor.java delete mode 100644 telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/DropExperienceBlockAccessor.java delete mode 100644 telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/MinecraftServerMixin.java create mode 100644 telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/PlayerMixin.java rename telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/{SnowgolemMixin.java => SnowGolemMixin.java} (95%) create mode 100644 telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/SpawnerBlockMixin.java delete mode 100644 telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/compat/betternether/BetterNetherMixinPlugin.java delete mode 100644 telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/compat/betternether/RubyFireMixin.java delete mode 100644 telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/compat/levelz/BlockMixinMixin.java delete mode 100644 telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/compat/levelz/EnderDragonEntityMixinMixin.java delete mode 100644 telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/compat/levelz/FishingBobberEntityMixinMixin.java delete mode 100644 telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/compat/levelz/LevelExperienceOrbAccessor.java delete mode 100644 telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/compat/levelz/LevelExperienceOrbEntityMixin.java delete mode 100644 telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/compat/levelz/LevelZMixinPlugin.java delete mode 100644 telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/compat/levelz/LivingEntityMixinMixin.java delete mode 100644 telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/compat/levelz/PlantBlockMixinMixin.java delete mode 100644 telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/compat/treeharvester/TreeCutEventsMixin.java delete mode 100644 telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/compat/treeharvester/TreeHarvesterMixinPlugin.java delete mode 100644 telekinesis-fabric/src/main/java/dev/nyon/telekinesis/utils/EntityUtils.java create mode 100644 telekinesis-fabric/src/main/java/dev/nyon/telekinesis/utils/MixinHelper.java delete mode 100644 telekinesis-fabric/src/main/java/dev/nyon/telekinesis/utils/PlayerUtils.java delete mode 100644 telekinesis-fabric/src/main/java/dev/nyon/telekinesis/utils/TelekinesisUtils.java create mode 100644 telekinesis-fabric/src/main/kotlin/dev/nyon/telekinesis/DropEvent.kt create mode 100644 telekinesis-fabric/src/main/kotlin/dev/nyon/telekinesis/TelekinesisEnchantmentGenerator.kt delete mode 100644 telekinesis-fabric/src/main/resources/compat.betternether.mixins.json delete mode 100644 telekinesis-fabric/src/main/resources/compat.levelz.mixins.json delete mode 100644 telekinesis-fabric/src/main/resources/compat.treeharvester.mixins.json create mode 100644 telekinesis-fabric/versions/1.21/gradle.properties diff --git a/.editorconfig b/.editorconfig index 4e0d1ae..2f10bbb 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,40 +1,409 @@ -# https://editorconfig.org -root = true - [*] -indent_style = space -indent_size = 2 -max_line_length = 140 - -end_of_line = lf charset = utf-8 -trim_trailing_whitespace = true -insert_final_newline = true - -[*.{java,kt,kts,scala,rs,xml,kt.spec,kts.spec}] +end_of_line = lf indent_size = 4 +indent_style = space +insert_final_newline = false +max_line_length = 120 +tab_width = 4 +ij_continuation_indent_size = 8 +ij_formatter_off_tag = @formatter:off +ij_formatter_on_tag = @formatter:on +ij_formatter_tags_enabled = true +ij_smart_tabs = false +ij_wrap_on_typing = false -[*.{kt,kts}] -ktlint_code_style = ktlint_official -ktlint_ignore_back_ticked_identifier = true -ij_kotlin_allow_trailing_comma_on_call_site = false -ij_kotlin_allow_trailing_comma = false - -ktlint_standard = enabled - -# Don't allow any wildcard imports -ij_kotlin_packages_to_use_import_on_demand = unset +[*.java] +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 = false +ij_java_align_multiline_assignment = false +ij_java_align_multiline_binary_operation = false +ij_java_align_multiline_chained_methods = false +ij_java_align_multiline_deconstruction_list_components = true +ij_java_align_multiline_extends_list = false +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 = false +ij_java_align_multiline_parenthesized_expression = false +ij_java_align_multiline_records = true +ij_java_align_multiline_resources = true +ij_java_align_multiline_ternary_operation = false +ij_java_align_multiline_text_blocks = false +ij_java_align_multiline_throws_list = false +ij_java_align_subsequent_simple_methods = false +ij_java_align_throws_keyword = false +ij_java_align_types_in_multi_catch = true +ij_java_annotation_parameter_wrap = split_into_lines +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 = false +ij_java_binary_operation_wrap = normal +ij_java_blank_lines_after_anonymous_class_header = 0 +ij_java_blank_lines_after_class_header = 0 +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_add_space = false +ij_java_block_comment_at_first_column = true +ij_java_call_parameters_new_line_after_left_paren = true +ij_java_call_parameters_right_paren_on_new_line = true +ij_java_call_parameters_wrap = on_every_item +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 = 5 +ij_java_class_names_in_javadoc = 1 +ij_java_deconstruction_list_wrap = normal +ij_java_do_not_indent_top_level_class_members = false +ij_java_do_not_wrap_after_single_annotation = false +ij_java_do_not_wrap_after_single_annotation_in_parameter = false +ij_java_do_while_brace_force = never +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 = false +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 = split_into_lines +ij_java_enum_field_annotation_wrap = off +ij_java_extends_keyword_wrap = off +ij_java_extends_list_wrap = off +ij_java_field_annotation_wrap = split_into_lines +ij_java_finally_on_new_line = false +ij_java_for_brace_force = never +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 = off +ij_java_generate_final_locals = false +ij_java_generate_final_parameters = false +ij_java_if_brace_force = never +ij_java_imports_layout = *, |, javax.**, java.**, |, $* +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_builder_methods_indents = false +ij_java_keep_control_statement_in_one_line = true +ij_java_keep_first_column_comment = false +ij_java_keep_indents_on_empty_lines = false +ij_java_keep_line_breaks = false +ij_java_keep_multiple_expressions_in_one_line = false +ij_java_keep_simple_blocks_in_one_line = false +ij_java_keep_simple_classes_in_one_line = false +ij_java_keep_simple_lambdas_in_one_line = false +ij_java_keep_simple_methods_in_one_line = false +ij_java_label_indent_absolute = false +ij_java_label_indent_size = 0 +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_add_space_on_reformat = 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 = split_into_lines +ij_java_method_parameters_new_line_after_left_paren = true +ij_java_method_parameters_right_paren_on_new_line = true +ij_java_method_parameters_wrap = split_into_lines +ij_java_modifier_list_wrap = false +ij_java_multi_catch_types_wrap = normal +ij_java_names_count_to_use_import_on_demand = 3 +ij_java_new_line_after_lparen_in_annotation = true +ij_java_new_line_after_lparen_in_deconstruction_pattern = true +ij_java_new_line_after_lparen_in_record_header = false +ij_java_new_line_when_body_is_presented = false +ij_java_packages_to_use_import_on_demand = java.awt.*, javax.swing.* +ij_java_parameter_annotation_wrap = split_into_lines +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_record_components_wrap = normal +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_rparen_on_new_line_in_annotation = true +ij_java_rparen_on_new_line_in_deconstruction_pattern = true +ij_java_rparen_on_new_line_in_record_header = false +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 = true +ij_java_space_before_catch_keyword = true +ij_java_space_before_catch_left_brace = true +ij_java_space_before_catch_parentheses = true +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_deconstruction_list = 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 = true +ij_java_space_before_for_semicolon = false +ij_java_space_before_if_left_brace = true +ij_java_space_before_if_parentheses = true +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 = true +ij_java_space_before_synchronized_left_brace = true +ij_java_space_before_synchronized_parentheses = true +ij_java_space_before_try_left_brace = true +ij_java_space_before_try_parentheses = true +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 = true +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_annotation_eq = 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 = true +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_deconstruction_list = 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_record_header = 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_switch_expressions_wrap = normal +ij_java_ternary_operation_signs_on_next_line = false +ij_java_ternary_operation_wrap = off +ij_java_test_name_suffix = Test +ij_java_throws_keyword_wrap = off +ij_java_throws_list_wrap = off +ij_java_use_external_annotations = false +ij_java_use_fq_class_names = false +ij_java_use_relative_indents = false +ij_java_use_single_class_imports = true +ij_java_variable_annotation_wrap = split_into_lines +ij_java_visibility = public +ij_java_while_brace_force = never +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 +ij_java_wrap_semicolon_after_call_chain = false -# Prevent wildcard imports -ij_kotlin_name_count_to_use_star_import = 99 -ij_kotlin_name_count_to_use_star_import_for_members = 99 +[.editorconfig] +ij_editorconfig_align_group_field_declarations = false +ij_editorconfig_space_after_colon = false +ij_editorconfig_space_after_comma = true +ij_editorconfig_space_before_colon = false +ij_editorconfig_space_before_comma = false +ij_editorconfig_spaces_around_assignment_operators = true -[*.md] -trim_trailing_whitespace = false -max_line_length = unset +[{*.kt,*.kts}] +ij_continuation_indent_size = 4 +ij_kotlin_align_in_columns_case_branch = false +ij_kotlin_align_multiline_binary_operation = false +ij_kotlin_align_multiline_extends_list = false +ij_kotlin_align_multiline_method_parentheses = false +ij_kotlin_align_multiline_parameters = true +ij_kotlin_align_multiline_parameters_in_calls = false +ij_kotlin_allow_trailing_comma = false +ij_kotlin_allow_trailing_comma_on_call_site = false +ij_kotlin_assignment_wrap = normal +ij_kotlin_blank_lines_after_class_header = 0 +ij_kotlin_blank_lines_around_block_when_branches = 0 +ij_kotlin_blank_lines_before_declaration_with_comment_or_annotation_on_separate_line = 1 +ij_kotlin_block_comment_add_space = false +ij_kotlin_block_comment_at_first_column = true +ij_kotlin_call_parameters_new_line_after_left_paren = true +ij_kotlin_call_parameters_right_paren_on_new_line = true +ij_kotlin_call_parameters_wrap = on_every_item +ij_kotlin_catch_on_new_line = false +ij_kotlin_class_annotation_wrap = split_into_lines +ij_kotlin_code_style_defaults = KOTLIN_OFFICIAL +ij_kotlin_continuation_indent_for_chained_calls = false +ij_kotlin_continuation_indent_for_expression_bodies = false +ij_kotlin_continuation_indent_in_argument_lists = false +ij_kotlin_continuation_indent_in_elvis = false +ij_kotlin_continuation_indent_in_if_conditions = false +ij_kotlin_continuation_indent_in_parameter_lists = false +ij_kotlin_continuation_indent_in_supertype_lists = false +ij_kotlin_else_on_new_line = false +ij_kotlin_enum_constants_wrap = split_into_lines +ij_kotlin_extends_list_wrap = normal +ij_kotlin_field_annotation_wrap = split_into_lines +ij_kotlin_finally_on_new_line = false +ij_kotlin_if_rparen_on_new_line = true +ij_kotlin_import_nested_classes = false +ij_kotlin_imports_layout = *, java.**, javax.**, kotlin.**, ^ +ij_kotlin_insert_whitespaces_in_simple_one_line_method = true +ij_kotlin_keep_blank_lines_before_right_brace = 0 +ij_kotlin_keep_blank_lines_in_code = 1 +ij_kotlin_keep_blank_lines_in_declarations = 1 +ij_kotlin_keep_first_column_comment = false +ij_kotlin_keep_indents_on_empty_lines = false +ij_kotlin_keep_line_breaks = false +ij_kotlin_lbrace_on_next_line = false +ij_kotlin_line_break_after_multiline_when_entry = false +ij_kotlin_line_comment_add_space = false +ij_kotlin_line_comment_add_space_on_reformat = false +ij_kotlin_line_comment_at_first_column = true +ij_kotlin_method_annotation_wrap = split_into_lines +ij_kotlin_method_call_chain_wrap = normal +ij_kotlin_method_parameters_new_line_after_left_paren = true +ij_kotlin_method_parameters_right_paren_on_new_line = true +ij_kotlin_method_parameters_wrap = on_every_item +ij_kotlin_name_count_to_use_star_import = 5 +ij_kotlin_name_count_to_use_star_import_for_members = 3 +ij_kotlin_packages_to_use_import_on_demand = java.util.*, kotlinx.android.synthetic.**, io.ktor.** +ij_kotlin_parameter_annotation_wrap = split_into_lines +ij_kotlin_space_after_comma = true +ij_kotlin_space_after_extend_colon = true +ij_kotlin_space_after_type_colon = true +ij_kotlin_space_before_catch_parentheses = true +ij_kotlin_space_before_comma = false +ij_kotlin_space_before_extend_colon = true +ij_kotlin_space_before_for_parentheses = true +ij_kotlin_space_before_if_parentheses = true +ij_kotlin_space_before_lambda_arrow = true +ij_kotlin_space_before_type_colon = false +ij_kotlin_space_before_when_parentheses = true +ij_kotlin_space_before_while_parentheses = true +ij_kotlin_spaces_around_additive_operators = true +ij_kotlin_spaces_around_assignment_operators = true +ij_kotlin_spaces_around_equality_operators = true +ij_kotlin_spaces_around_function_type_arrow = true +ij_kotlin_spaces_around_logical_operators = true +ij_kotlin_spaces_around_multiplicative_operators = true +ij_kotlin_spaces_around_range = true +ij_kotlin_spaces_around_relational_operators = true +ij_kotlin_spaces_around_unary_operator = false +ij_kotlin_spaces_around_when_arrow = true +ij_kotlin_variable_annotation_wrap = split_into_lines +ij_kotlin_while_on_new_line = false +ij_kotlin_wrap_elvis_expressions = 1 +ij_kotlin_wrap_expression_body_functions = 1 +ij_kotlin_wrap_first_method_in_call_chain = false -[gradle/verification-metadata.xml] -indent_size = 3 +[{*.markdown,*.md}] +ij_continuation_indent_size = 4 +ij_markdown_force_one_space_after_blockquote_symbol = true +ij_markdown_force_one_space_after_header_symbol = true +ij_markdown_force_one_space_after_list_bullet = true +ij_markdown_force_one_space_between_words = true +ij_markdown_format_tables = true +ij_markdown_insert_quote_arrows_on_wrap = true +ij_markdown_keep_indents_on_empty_lines = false +ij_markdown_keep_line_breaks_inside_text_blocks = true +ij_markdown_max_lines_around_block_elements = 1 +ij_markdown_max_lines_around_header = 1 +ij_markdown_max_lines_between_paragraphs = 1 +ij_markdown_min_lines_around_block_elements = 1 +ij_markdown_min_lines_around_header = 1 +ij_markdown_min_lines_between_paragraphs = 1 +ij_markdown_wrap_text_if_long = true +ij_markdown_wrap_text_inside_blockquotes = true -[*.yml] -ij_yaml_spaces_within_brackets = false \ No newline at end of file +[{*.yaml,*.yml}] +indent_size = 2 +ij_yaml_align_values_properties = do_not_align +ij_yaml_autoinsert_sequence_marker = true +ij_yaml_block_mapping_on_new_line = false +ij_yaml_indent_sequence_value = true +ij_yaml_keep_indents_on_empty_lines = false +ij_yaml_keep_line_breaks = true +ij_yaml_sequence_on_new_line = false +ij_yaml_space_before_colon = false +ij_yaml_spaces_within_braces = true +ij_yaml_spaces_within_brackets = true \ No newline at end of file diff --git a/.gitignore b/.gitignore index 073af1c..1f93e88 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,6 @@ **/.gradle/ **/run/ !run/mods/ -**/build/ \ No newline at end of file +**/build/ +.kotlin +**/generated \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 4a92d56..afa332b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,6 +1,6 @@ plugins { - kotlin("jvm") version "1.9.24" - kotlin("plugin.serialization") version "1.9.24" + kotlin("jvm") version "2.0.0" + kotlin("plugin.serialization") version "2.0.0" id("me.modmuss50.mod-publish-plugin") version "0.5.+" diff --git a/gradle.properties b/gradle.properties index ee05a44..7d28631 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,2 +1 @@ -kotlin.code.style=official -org.gradle.jvmargs=-Xmx2048m -Xms2048m -XX:ThreadStackSize=4096 -XX:CompilerThreadStackSize=4096 \ No newline at end of file +org.gradle.jvmargs=-Xmx1G \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 640c9fd..f579813 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -7,14 +7,21 @@ pluginManagement { gradlePluginPortal() maven("https://maven.fabricmc.net/") maven("https://server.bbkr.space/artifactory/libs-release/") - maven("https://maven.quiltmc.org/repository/release/") maven("https://repo.papermc.io/repository/maven-public/") maven("https://maven.kikugie.dev/releases") + maven("https://maven.kikugie.dev/snapshots") } } plugins { - id("dev.kikugie.stonecutter") version "0.3.5" + id("dev.kikugie.stonecutter") version "0.3.9" +} + +buildscript { + repositories { mavenCentral() } + dependencies { + classpath("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.0-RC") + } } //include("telekinesis-paper") @@ -24,7 +31,7 @@ extensions.configure { kotlinController = true centralScript = "build.gradle.kts" shared { - versions("1.20.1", "1.20.4", "1.20.6") + versions("1.20.1", "1.20.4", "1.20.6", "1.21") vcsVersion = "1.20.6" } create(project(":telekinesis-fabric")) diff --git a/telekinesis-fabric/build.gradle.kts b/telekinesis-fabric/build.gradle.kts index 4a99bf2..67e1602 100644 --- a/telekinesis-fabric/build.gradle.kts +++ b/telekinesis-fabric/build.gradle.kts @@ -1,11 +1,11 @@ @file:Suppress("SpellCheckingInspection") +import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.tasks.KotlinCompile -import kotlin.io.path.readText plugins { - kotlin("jvm") version "1.9.24" - kotlin("plugin.serialization") version "1.9.24" + kotlin("jvm") version "2.0.0" + kotlin("plugin.serialization") version "2.0.0" id("fabric-loom") version "1.6-SNAPSHOT" id("me.modmuss50.mod-publish-plugin") version "0.5.+" @@ -23,23 +23,28 @@ group = "dev.nyon" val projectAuthors = listOf("btwonion") val githubRepo = "btwonion/telekinesis" +base { + archivesName.set(rootProject.name) +} + loom { if (stonecutter.current.isActive) { runConfigs.all { ideConfigGenerated(true) runDir("../../run") } - - project.tasks.register("runActive") { - group = "mod" - - dependsOn(tasks.named("runClient")) - } } mixin { useLegacyMixinAp = false } - accessWidenerPath = file("../../src/main/resources/telekinesis.accesswidener") + accessWidenerPath = rootProject.file("telekinesis-fabric/src/main/resources/telekinesis.accesswidener") +} + +// Enable data generation for >1.20.6 +if (!listOf("1.20.1", "1.20.4", "1.20.6").contains(stonecutter.current.version)) { + fabricApi { + configureDataGeneration() + } } repositories { @@ -56,35 +61,29 @@ repositories { maven("https://maven.parchmentmc.org") maven("https://repo.nyon.dev/releases") maven("https://maven.isxander.dev/releases") - maven("https://oss.sonatype.org/content/repositories/snapshots/") + maven("https://maven.isxander.dev/snapshots") maven("https://jitpack.io") } dependencies { minecraft("com.mojang:minecraft:$mcVersion") - mappings( - loom.layered { - parchment("org.parchmentmc.data:parchment-${property("deps.parchment")}@zip") - officialMojangMappings() - } - ) + mappings(loom.layered { + val parchment: String = property("deps.parchment").toString() + if (parchment.isNotEmpty()) parchment("org.parchmentmc.data:parchment-$parchment@zip") + officialMojangMappings() + }) implementation("org.vineflower:vineflower:1.10.1") modImplementation("net.fabricmc:fabric-loader:0.15.11") modImplementation("net.fabricmc.fabric-api:fabric-api:${property("deps.fapi")!!}") - modImplementation("net.fabricmc:fabric-language-kotlin:1.10.20+kotlin.1.9.24") + modImplementation("net.fabricmc:fabric-language-kotlin:1.11.0+kotlin.2.0.0") modImplementation("dev.isxander:yet-another-config-lib:${property("deps.yacl")!!}") - modImplementation("com.terraformersmc:modmenu:${property("deps.modMenu")!!}") + modCompileOnly("com.terraformersmc:modmenu:${property("deps.modMenu")!!}") include(implementation(annotationProcessor("com.github.bawnorton.mixinsquared:mixinsquared-fabric:0.1.1")!!)!!) include(implementation("com.akuleshov7:ktoml-core-jvm:0.5.1")!!) - - // Integration - // modCompileOnly("maven.modrinth:abooMhox:c2klaSgQ") // tree-harvester by ricksouth wait for 1.20.5 - // modCompileOnly("maven.modrinth:MpzVLzy5:9kJblF2V") // better nether by quickueck wait for 1.20.5 - // modCompileOnly("maven.modrinth:EFtixeiF:Gcai736Z") // levelz by Globox1997 wait for 1.20.5 } val javaVersion = property("javaVer")!!.toString() @@ -94,15 +93,14 @@ tasks { val modName = "telekinesis" val modDescription = "Adds a telekinesis enchantment to minecraft" - val props = - mapOf( - "id" to modId, - "name" to modName, - "description" to modDescription, - "version" to project.version, - "github" to githubRepo, - "mc" to mcVersionRange - ) + val props = mapOf( + "id" to modId, + "name" to modName, + "description" to modDescription, + "version" to project.version, + "github" to githubRepo, + "mc" to mcVersionRange + ) props.forEach(inputs::property) @@ -123,17 +121,19 @@ tasks { } withType { - kotlinOptions.jvmTarget = javaVersion + compilerOptions { + jvmTarget = JvmTarget.fromTarget(javaVersion) + } } } -val changelogText = - buildString { - append("# v${project.version}\n") - file("../../../changelog.md").readText().also { append(it) } - } +val changelogText = buildString { + append("# v${project.version}\n") + rootProject.file("changelog.md").readText().also(::append) +} -val supportedMcVersions: List = property("supportedMcVersions")!!.toString().split(',').map(String::trim).filter(String::isNotEmpty) +val supportedMcVersions: List = + property("supportedMcVersions")!!.toString().split(',').map(String::trim).filter(String::isNotEmpty) publishMods { displayName = "v${project.version}" @@ -149,7 +149,7 @@ publishMods { requires { slug = "fabric-api" } requires { slug = "yacl" } - requires { slug = "fabric-language-kotlin" } + requires { slug = "fabric-language-kotlin" } optional { slug = "modmenu" } } @@ -158,12 +158,6 @@ publishMods { accessToken = providers.environmentVariable("GITHUB_TOKEN") commitish = "master" } - - discord { - webhookUrl = providers.environmentVariable("DISCORD_WEBHOOK") - username = "Release Notifier" - content = "# A new version of Telekinesis released!\n$changelogText" - } } publishing { @@ -190,18 +184,12 @@ publishing { java { withSourcesJar() - javaVersion.toInt() - .let { JavaVersion.values()[it - 1] } - .let { + javaVersion.toInt().let { JavaVersion.values()[it - 1] }.let { sourceCompatibility = it targetCompatibility = it } } -kotlin { - jvmToolchain(javaVersion.toInt()) -} - /* signing { val signingKey: String? by project diff --git a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/AbstractChestedHorseMixin.java b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/AbstractChestedHorseMixin.java index f5759ab..a05205b 100644 --- a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/AbstractChestedHorseMixin.java +++ b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/AbstractChestedHorseMixin.java @@ -1,8 +1,9 @@ package dev.nyon.telekinesis.mixins; import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; -import dev.nyon.telekinesis.utils.EntityUtils; +import dev.nyon.telekinesis.utils.MixinHelper; import net.minecraft.world.entity.animal.horse.AbstractChestedHorse; +import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.ItemLike; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -17,10 +18,10 @@ public class AbstractChestedHorseMixin { target = "Lnet/minecraft/world/entity/animal/horse/AbstractChestedHorse;spawnAtLocation(Lnet/minecraft/world/level/ItemLike;)Lnet/minecraft/world/entity/item/ItemEntity;" ) ) - public boolean redirectEquipmentDrop( + public boolean modifyEquipmentDrop( AbstractChestedHorse instance, ItemLike item ) { - return EntityUtils.spawnAtLocationInject(instance, item); + return MixinHelper.entityDropEquipmentSingle(instance, new ItemStack(item)); } } diff --git a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/AbstractHorseMixin.java b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/AbstractHorseMixin.java index 2c98427..04febc9 100644 --- a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/AbstractHorseMixin.java +++ b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/AbstractHorseMixin.java @@ -1,7 +1,7 @@ package dev.nyon.telekinesis.mixins; import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; -import dev.nyon.telekinesis.utils.EntityUtils; +import dev.nyon.telekinesis.utils.MixinHelper; import net.minecraft.world.entity.animal.horse.AbstractHorse; import net.minecraft.world.item.ItemStack; import org.spongepowered.asm.mixin.Mixin; @@ -17,10 +17,24 @@ public class AbstractHorseMixin { target = "Lnet/minecraft/world/entity/animal/horse/AbstractHorse;spawnAtLocation(Lnet/minecraft/world/item/ItemStack;)Lnet/minecraft/world/entity/item/ItemEntity;" ) ) - public boolean redirectEquipmentDrop( + public boolean modifyEquipmentDrop( AbstractHorse instance, ItemStack stack ) { - return EntityUtils.spawnAtLocationInject(instance, stack); + return MixinHelper.entityDropEquipmentSingle(instance, stack); + } + + @WrapWithCondition( + method = "dropEquipment", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/world/entity/animal/horse/AbstractHorse;spawnAtLocation(Lnet/minecraft/world/item/ItemStack;)Lnet/minecraft/world/entity/item/ItemEntity;" + ) + ) + public boolean modifyEquipmentDrops( + AbstractHorse instance, + ItemStack itemStack + ) { + return MixinHelper.entityDropEquipmentSingle(instance, itemStack); } } diff --git a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/AbstractMinecartMixin.java b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/AbstractMinecartMixin.java index 96d49d8..4c02df5 100644 --- a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/AbstractMinecartMixin.java +++ b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/AbstractMinecartMixin.java @@ -3,19 +3,19 @@ import net.minecraft.world.entity.vehicle.AbstractMinecart; import org.spongepowered.asm.mixin.Mixin; -/*? <=1.20.2 {*/ +/*? <=1.20.2 {*//* import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; import dev.nyon.telekinesis.utils.EntityUtils; import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.item.ItemStack; import org.spongepowered.asm.mixin.injection.At; -/*?}*/ +*//*?}*/ @Mixin(AbstractMinecart.class) public class AbstractMinecartMixin { - /*? <=1.20.2 {*/ + /*? <=1.20.2 {*//* @WrapWithCondition(method = "destroy", at = @At( value = "INVOKE", target = "Lnet/minecraft/world/entity/vehicle/AbstractMinecart;spawnAtLocation(Lnet/minecraft/world/item/ItemStack;)Lnet/minecraft/world/entity/item/ItemEntity;" @@ -28,5 +28,5 @@ private boolean redirectMinecartDrops( if (!(damageSource.getEntity() instanceof LivingEntity livingEntity)) return true; return EntityUtils.spawnAtLocationAttacker(livingEntity, itemStack); } - /*?}*/ + *//*?}*/ } diff --git a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/AllayMixin.java b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/AllayMixin.java index 05abdff..4523d24 100644 --- a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/AllayMixin.java +++ b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/AllayMixin.java @@ -1,25 +1,21 @@ package dev.nyon.telekinesis.mixins; +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; -import dev.nyon.telekinesis.TelekinesisPolicy; -import dev.nyon.telekinesis.utils.EntityUtils; -import dev.nyon.telekinesis.utils.TelekinesisUtils; -import net.minecraft.server.level.ServerPlayer; +import dev.nyon.telekinesis.utils.MixinHelper; import net.minecraft.world.entity.animal.allay.Allay; import net.minecraft.world.item.ItemStack; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; import java.util.List; -import java.util.function.Consumer; @Mixin(Allay.class) public class AllayMixin { @Unique - final Allay allay = (Allay) (Object) this; + final Allay instance = (Allay) (Object) this; @WrapWithCondition( method = "dropEquipment", @@ -28,38 +24,23 @@ public class AllayMixin { target = "Lnet/minecraft/world/entity/animal/allay/Allay;spawnAtLocation(Lnet/minecraft/world/item/ItemStack;)Lnet/minecraft/world/entity/item/ItemEntity;" ) ) - public boolean redirectEquipmentDrop( + public boolean modifyEquipmentDrop( Allay instance, ItemStack stack ) { - return EntityUtils.spawnAtLocationInject(instance, stack); + return MixinHelper.entityDropEquipmentSingle(instance, stack); } - @Redirect( + @ModifyExpressionValue( method = "dropEquipment", at = @At( value = "INVOKE", - target = "Ljava/util/List;forEach(Ljava/util/function/Consumer;)V" + target = "Lnet/minecraft/world/SimpleContainer;removeAllItems()Ljava/util/List;" ) ) - public void redirectInventoryDrops( - List instance, - Consumer consumer + public List modifyEquipmentDrops( + List original ) { - final var attacker = allay.getLastAttacker(); - if (!(attacker instanceof ServerPlayer serverPlayer)) { - instance.forEach(consumer); - return; - } - - boolean hasTelekinesis = TelekinesisUtils.handleTelekinesis(TelekinesisPolicy.MobDrops, - serverPlayer, - serverPlayer.getMainHandItem(), - player -> instance.forEach(item -> { - if (!player.addItem(item)) consumer.accept(item); - }) - ); - - if (!hasTelekinesis) instance.forEach(consumer); + return MixinHelper.entityDropEquipmentMultiple(instance, original); } } diff --git a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/BlockMixin.java b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/BlockMixin.java index 37695ad..d3c99c9 100644 --- a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/BlockMixin.java +++ b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/BlockMixin.java @@ -1,89 +1,118 @@ package dev.nyon.telekinesis.mixins; -import dev.nyon.telekinesis.TelekinesisPolicy; -import dev.nyon.telekinesis.utils.PlayerUtils; -import dev.nyon.telekinesis.utils.TelekinesisUtils; +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import dev.nyon.telekinesis.DropEvent; import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; -import net.minecraft.util.valueproviders.ConstantInt; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.util.valueproviders.IntProvider; import net.minecraft.world.entity.Entity; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.enchantment.EnchantmentHelper; import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.*; +import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; +import org.apache.commons.lang3.mutable.MutableInt; import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.ModifyArgs; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.invoke.arg.Args; -import java.util.function.Consumer; +import java.util.ArrayList; +import java.util.List; @Mixin(Block.class) public abstract class BlockMixin { - @ModifyArgs( + @Unique + private static final ThreadLocal threadLocal = new ThreadLocal<>(); + + @ModifyExpressionValue( method = "dropResources(Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/entity/BlockEntity;Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/item/ItemStack;)V", at = @At( value = "INVOKE", - target = "Ljava/util/List;forEach(Ljava/util/function/Consumer;)V" + target = "Lnet/minecraft/world/level/block/Block;getDrops(Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/entity/BlockEntity;Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/item/ItemStack;)Ljava/util/List;" ) ) - private static void redirectDrops( - Args args, - BlockState blockState, + private static List modifyDrops( + List original, + BlockState state, Level level, - BlockPos blockPos, - @Nullable BlockEntity blockEntity, - @Nullable Entity entity, - ItemStack itemStack + BlockPos pos, + @Nullable + BlockEntity blockEntity, + @Nullable + Entity entity, + ItemStack tool ) { - args.>set(0, item -> { - if (!TelekinesisUtils.handleTelekinesisBlock(TelekinesisPolicy.BlockDrops, entity, itemStack, player -> { - if (!player.addItem(item)) Block.popResource(level, blockPos, item); - })) Block.popResource(level, blockPos, item); - }); + if (!(entity instanceof ServerPlayer player)) return original; + + ArrayList mutableList = new ArrayList<>(original); + DropEvent.INSTANCE.getEvent() + .invoker() + .invoke(mutableList, new MutableInt(0), player, tool); + + return mutableList; } - @Inject( + @WrapOperation( method = "dropResources(Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/entity/BlockEntity;Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/item/ItemStack;)V", at = @At( value = "INVOKE", target = "Lnet/minecraft/world/level/block/state/BlockState;spawnAfterBreak(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/item/ItemStack;Z)V" - ), - cancellable = true + ) ) - private static void manipulateDrops( - BlockState blockState, - Level level, + private static void checkForPlayerBreak( + BlockState instance, + ServerLevel serverLevel, BlockPos blockPos, + ItemStack itemStack, + boolean b, + Operation original, + BlockState state, + Level level, + BlockPos pos, + @Nullable BlockEntity blockEntity, + @Nullable Entity entity, - ItemStack itemStack, - CallbackInfo ci + ItemStack tool + ) { + if (!(entity instanceof ServerPlayer player)) return; + + ServerPlayer previous = threadLocal.get(); + threadLocal.set(player); + try { + original.call(instance, serverLevel, blockPos, itemStack, b); + } finally { + threadLocal.set(previous); + } + } + + @ModifyExpressionValue( + method = "tryDropExperience", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/world/item/enchantment/EnchantmentHelper;processBlockExperience(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/world/item/ItemStack;I)I" + ) + ) + private int modifyExp( + int original, + ServerLevel level, + BlockPos pos, + ItemStack heldItem, + IntProvider amount ) { - if (!(level instanceof ServerLevel serverLevel)) return; - Block block = blockState.getBlock(); - if (EnchantmentHelper.hasSilkTouch(itemStack)) return; - boolean hasTelekinesis = TelekinesisUtils.handleTelekinesisBlock(TelekinesisPolicy.ExpDrops, entity, itemStack, player -> { - int expToAdd = 0; - if (block instanceof DropExperienceBlock expBlock) expToAdd = ((DropExperienceBlockAccessor) expBlock).getXpRange() - .sample(level.random); - if (block instanceof RedStoneOreBlock) expToAdd = 1 + level.random.nextInt(5); - if (block instanceof SculkCatalystBlock catalystBlock) expToAdd = ((CatalystBlockAccessor) catalystBlock).getXpRange() - .sample(level.random); - if (block instanceof SculkSensorBlock || block instanceof SculkShriekerBlock) expToAdd = ConstantInt.of(5) - .sample(level.random); - if (block instanceof SpawnerBlock) expToAdd = level.random.nextInt(15) + level.random.nextInt(15); - if (block instanceof InfestedBlock infestedBlock) - infestedBlock.spawnAfterBreak(blockState, serverLevel, blockPos, itemStack, true); - PlayerUtils.addExpToPlayer(player, expToAdd); - }); + ServerPlayer player = threadLocal.get(); + if (player == null) return original; + + MutableInt mutableInt = new MutableInt(original); + DropEvent.INSTANCE.getEvent() + .invoker() + .invoke(new ArrayList<>(), mutableInt, player, heldItem); - if (hasTelekinesis) ci.cancel(); + return mutableInt.getValue(); } } diff --git a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/BoatMixin.java b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/BoatMixin.java index 330867c..8a281f9 100644 --- a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/BoatMixin.java +++ b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/BoatMixin.java @@ -3,17 +3,17 @@ import net.minecraft.world.entity.vehicle.Boat; import org.spongepowered.asm.mixin.Mixin; -/*? <=1.20.2 {*/ +/*? <=1.20.2 {*//* import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import dev.nyon.telekinesis.utils.EntityUtils; import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.item.Item; import org.spongepowered.asm.mixin.injection.At; -/*?}*/ +*//*?}*/ @Mixin(Boat.class) public class BoatMixin { - /*? <=1.20.2 {*/ + /*? <=1.20.2 {*//* @ModifyExpressionValue( method = "destroy(Lnet/minecraft/world/damagesource/DamageSource;)V", at = @At( @@ -27,5 +27,5 @@ private Item changeDroppedItem( ) { return EntityUtils.getDropItemInject(original, damageSource); } - /*?}*/ + *//*?}*/ } diff --git a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/CatalystBlockAccessor.java b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/CatalystBlockAccessor.java deleted file mode 100644 index cf5a0f8..0000000 --- a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/CatalystBlockAccessor.java +++ /dev/null @@ -1,13 +0,0 @@ -package dev.nyon.telekinesis.mixins; - -import net.minecraft.util.valueproviders.IntProvider; -import net.minecraft.world.level.block.SculkCatalystBlock; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -@Mixin(SculkCatalystBlock.class) -public interface CatalystBlockAccessor { - - @Accessor - IntProvider getXpRange(); -} diff --git a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/ChestBoatMixin.java b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/ChestBoatMixin.java index 0fd5b5b..69e2aa1 100644 --- a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/ChestBoatMixin.java +++ b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/ChestBoatMixin.java @@ -1,32 +1,41 @@ package dev.nyon.telekinesis.mixins; +import dev.nyon.telekinesis.utils.MixinHelper; import net.minecraft.world.entity.vehicle.ChestBoat; import org.spongepowered.asm.mixin.Mixin; -/*? if >1.20.2 {*//* -import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import dev.nyon.telekinesis.utils.EntityUtils; +/*? if >1.20.2 {*/ +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.item.Item; +import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; - *//*?}*/ + /*?}*/ @Mixin(ChestBoat.class) public class ChestBoatMixin { - /*? if >1.20.2 {*//* - @ModifyExpressionValue( + /*? if >1.20.2 {*/ + @Unique + private static final ThreadLocal threadLocal = new ThreadLocal<>(); + + @WrapOperation( method = "destroy(Lnet/minecraft/world/damagesource/DamageSource;)V", at = @At( value = "INVOKE", - target = "Lnet/minecraft/world/entity/vehicle/ChestBoat;getDropItem()Lnet/minecraft/world/item/Item;" + target = "Lnet/minecraft/world/entity/vehicle/VehicleEntity;destroy(Lnet/minecraft/world/item/Item;)V" ) ) - private Item changeDroppedItem( - Item original, - DamageSource damageSource + private void checkForPlayer( + ChestBoat instance, + Item item, + Operation original, + DamageSource source ) { - return EntityUtils.getDropItemInject(original, damageSource); + MixinHelper.prepareVehicleServerPlayer(instance, item, original, source, threadLocal); } - *//*?}*/ + + /*?}*/ } diff --git a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/DropExperienceBlockAccessor.java b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/DropExperienceBlockAccessor.java deleted file mode 100644 index 4220a5b..0000000 --- a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/DropExperienceBlockAccessor.java +++ /dev/null @@ -1,13 +0,0 @@ -package dev.nyon.telekinesis.mixins; - -import net.minecraft.util.valueproviders.IntProvider; -import net.minecraft.world.level.block.DropExperienceBlock; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -@Mixin(DropExperienceBlock.class) -public interface DropExperienceBlockAccessor { - - @Accessor - IntProvider getXpRange(); -} diff --git a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/EnchantmentsMixin.java b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/EnchantmentsMixin.java index 7eb9455..39b5974 100644 --- a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/EnchantmentsMixin.java +++ b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/EnchantmentsMixin.java @@ -1,21 +1,24 @@ package dev.nyon.telekinesis.mixins; +/*? if <1.21 {*//* import dev.nyon.telekinesis.MainKt; import dev.nyon.telekinesis.TelekinesisEnchantment; import net.minecraft.core.Registry; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.enchantment.Enchantment; -import net.minecraft.world.item.enchantment.Enchantments; -import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +*//*?}*/ +import net.minecraft.world.item.enchantment.Enchantments; +import org.spongepowered.asm.mixin.Mixin; @Mixin(Enchantments.class) public abstract class EnchantmentsMixin { + /*? if <1.21 {*//* @Unique private static boolean isTelekinesisRegistered = false; @@ -34,4 +37,5 @@ private static void registerTelekinesis( Registry.register(BuiltInRegistries.ENCHANTMENT, new ResourceLocation("telekinesis", "telekinesis"), MainKt.getTelekinesis()); } } + *//*?}*/ } diff --git a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/EnderManMixin.java b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/EnderManMixin.java index 8b91cfa..3346926 100644 --- a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/EnderManMixin.java +++ b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/EnderManMixin.java @@ -1,7 +1,8 @@ package dev.nyon.telekinesis.mixins; import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; -import dev.nyon.telekinesis.utils.EntityUtils; +import dev.nyon.telekinesis.utils.MixinHelper; +import net.minecraft.server.level.ServerLevel; import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.entity.monster.EnderMan; import net.minecraft.world.item.ItemStack; @@ -20,11 +21,11 @@ public class EnderManMixin { ) public boolean redirectEquipmentDrop( EnderMan instance, - ItemStack stack, + ItemStack itemStack, + ServerLevel serverLevel, DamageSource damageSource, - int lootingMultiplier, - boolean allowDrops + boolean bl ) { - return EntityUtils.spawnAtLocationInject(instance, stack); + return MixinHelper.entityCustomDeathLootSingle(damageSource, itemStack); } } diff --git a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/FishingHookMixin.java b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/FishingHookMixin.java index 1a0fca9..26738e4 100644 --- a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/FishingHookMixin.java +++ b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/FishingHookMixin.java @@ -1,64 +1,55 @@ package dev.nyon.telekinesis.mixins; -import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; -import dev.nyon.telekinesis.TelekinesisPolicy; -import dev.nyon.telekinesis.utils.PlayerUtils; -import dev.nyon.telekinesis.utils.TelekinesisUtils; +import com.llamalad7.mixinextras.injector.ModifyReceiver; +import dev.nyon.telekinesis.DropEvent; import net.minecraft.server.level.ServerPlayer; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.ExperienceOrb; -import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.util.RandomSource; import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.projectile.FishingHook; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.Level; +import org.apache.commons.lang3.mutable.MutableInt; import org.jetbrains.annotations.Nullable; +import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; +import java.util.ArrayList; +import java.util.List; + @Mixin(FishingHook.class) public abstract class FishingHookMixin { - @Shadow - @Nullable - public abstract Player getPlayerOwner(); - - @WrapWithCondition( + @ModifyReceiver( method = "retrieve", at = @At( value = "INVOKE", - target = "Lnet/minecraft/world/level/Level;addFreshEntity(Lnet/minecraft/world/entity/Entity;)Z" + target = "Ljava/util/List;iterator()Ljava/util/Iterator;" ) ) - private boolean redirectFishingHookDrops( - Level instance, - Entity entity, - ItemStack stack + public List modifyFishingDrops( + List instance, + ItemStack fishingHook ) { - if (!(getPlayerOwner() instanceof ServerPlayer _serverPlayer)) return true; - - if (entity instanceof ExperienceOrb expOrb) { - final var hasTelekinesis = TelekinesisUtils.handleTelekinesis(TelekinesisPolicy.ExpDrops, - _serverPlayer, - stack, - serverPlayer -> PlayerUtils.addExpToPlayer(serverPlayer, expOrb.getValue()) - ); - - return !hasTelekinesis; - } + if (!(getPlayerOwner() instanceof ServerPlayer player)) return instance; + + ArrayList mutableList = new ArrayList<>(instance); + mutableList.removeIf(item -> { + ArrayList singleList = new ArrayList<>(List.of(item)); + DropEvent.INSTANCE.getEvent() + .invoker() + .invoke(singleList, new MutableInt(syncronizedRandom.nextInt(6) + 1), player, fishingHook); + return singleList.isEmpty(); + }); + + return mutableList; + } - if (entity instanceof ItemEntity itemEntity) { - final var hasTelekinesis = TelekinesisUtils.handleTelekinesis(TelekinesisPolicy.FishingDrops, - _serverPlayer, - stack, - serverPlayer -> { - if (!serverPlayer.addItem(itemEntity.getItem())) instance.addFreshEntity(itemEntity); - } - ); + @Shadow + @Nullable + public abstract Player getPlayerOwner(); - return !hasTelekinesis; - } - return true; - } + @Shadow + @Final + private RandomSource syncronizedRandom; } diff --git a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/InventoryMixin.java b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/InventoryMixin.java index d2b7c47..e9b2cdc 100644 --- a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/InventoryMixin.java +++ b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/InventoryMixin.java @@ -1,7 +1,6 @@ package dev.nyon.telekinesis.mixins; import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; -import dev.nyon.telekinesis.utils.EntityUtils; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; diff --git a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/LivingEntityMixin.java b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/LivingEntityMixin.java index 03b1f98..1ef91af 100644 --- a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/LivingEntityMixin.java +++ b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/LivingEntityMixin.java @@ -2,8 +2,6 @@ import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; import dev.nyon.telekinesis.TelekinesisPolicy; -import dev.nyon.telekinesis.utils.PlayerUtils; -import dev.nyon.telekinesis.utils.TelekinesisUtils; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.damagesource.DamageSource; diff --git a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/MinecartTNTMixin.java b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/MinecartTNTMixin.java index ce6b015..555daf3 100644 --- a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/MinecartTNTMixin.java +++ b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/MinecartTNTMixin.java @@ -3,18 +3,17 @@ import net.minecraft.world.entity.vehicle.MinecartTNT; import org.spongepowered.asm.mixin.Mixin; -/*? if >1.20.2 {*//* +/*? if >1.20.2 {*/ import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import dev.nyon.telekinesis.utils.EntityUtils; import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.item.Item; import org.spongepowered.asm.mixin.injection.At; - *//*?}*/ + /*?}*/ @Mixin(MinecartTNT.class) public class MinecartTNTMixin { - /*? if >1.20.2 {*//* + /*? if >1.20.2 {*/ @ModifyExpressionValue( method = "destroy(Lnet/minecraft/world/damagesource/DamageSource;)V", at = @At( @@ -28,5 +27,5 @@ private Item changeDroppedItem( ) { return EntityUtils.getDropItemInject(original, damageSource); } - *//*?}*/ + /*?}*/ } diff --git a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/MinecraftServerMixin.java b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/MinecraftServerMixin.java deleted file mode 100644 index 64420eb..0000000 --- a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/MinecraftServerMixin.java +++ /dev/null @@ -1,24 +0,0 @@ -package dev.nyon.telekinesis.mixins; - -import dev.nyon.telekinesis.MainKt; -import net.minecraft.server.MinecraftServer; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(MinecraftServer.class) -public class MinecraftServerMixin { - - @Inject( - method = "runServer", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/server/MinecraftServer;initServer()Z", - shift = At.Shift.BEFORE - ) - ) - private void onBeforeInit(CallbackInfo ci) { - MainKt.setServer((MinecraftServer) (Object) this); - } -} diff --git a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/MobMixin.java b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/MobMixin.java index a224ec3..2b1148c 100644 --- a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/MobMixin.java +++ b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/MobMixin.java @@ -1,7 +1,8 @@ package dev.nyon.telekinesis.mixins; import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; -import dev.nyon.telekinesis.utils.EntityUtils; +import dev.nyon.telekinesis.utils.MixinHelper; +import net.minecraft.server.level.ServerLevel; import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.entity.Mob; import net.minecraft.world.item.ItemStack; @@ -18,13 +19,27 @@ public class MobMixin { target = "Lnet/minecraft/world/entity/Mob;spawnAtLocation(Lnet/minecraft/world/item/ItemStack;)Lnet/minecraft/world/entity/item/ItemEntity;" ) ) - public boolean redirectEquipmentDrop( + public boolean modifyCustomDeathLoot( Mob instance, - ItemStack stack, + ItemStack itemStack, + ServerLevel serverLevel, DamageSource damageSource, - int lootingMultiplier, - boolean allowDrops + boolean bl ) { - return EntityUtils.spawnAtLocationInject(instance, stack); + return MixinHelper.entityCustomDeathLootSingle(damageSource, itemStack); + } + + @WrapWithCondition( + method = "dropPreservedEquipment(Ljava/util/function/Predicate;)Ljava/util/Set;", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/world/entity/Mob;spawnAtLocation(Lnet/minecraft/world/item/ItemStack;)Lnet/minecraft/world/entity/item/ItemEntity;" + ) + ) + public boolean modifyCustomDeathLoot( + Mob instance, + ItemStack itemStack + ) { + return MixinHelper.entityDropEquipmentSingle(instance, itemStack); } } diff --git a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/PigMixin.java b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/PigMixin.java index c7bf7b9..b5bf54c 100644 --- a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/PigMixin.java +++ b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/PigMixin.java @@ -1,8 +1,9 @@ package dev.nyon.telekinesis.mixins; import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; -import dev.nyon.telekinesis.utils.EntityUtils; +import dev.nyon.telekinesis.utils.MixinHelper; import net.minecraft.world.entity.animal.Pig; +import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.ItemLike; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -17,10 +18,10 @@ public class PigMixin { target = "Lnet/minecraft/world/entity/animal/Pig;spawnAtLocation(Lnet/minecraft/world/level/ItemLike;)Lnet/minecraft/world/entity/item/ItemEntity;" ) ) - public boolean redirectEquipmentDrop( + public boolean modifyEquipmentDrop( Pig instance, ItemLike item ) { - return EntityUtils.spawnAtLocationInject(instance, item); + return MixinHelper.entityDropEquipmentSingle(instance, new ItemStack(item)); } } diff --git a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/PiglinMixin.java b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/PiglinMixin.java index a57939f..fbf9a1f 100644 --- a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/PiglinMixin.java +++ b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/PiglinMixin.java @@ -1,43 +1,32 @@ package dev.nyon.telekinesis.mixins; -import dev.nyon.telekinesis.TelekinesisPolicy; -import dev.nyon.telekinesis.utils.TelekinesisUtils; +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import dev.nyon.telekinesis.utils.MixinHelper; +import net.minecraft.server.level.ServerLevel; import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.entity.monster.piglin.Piglin; import net.minecraft.world.item.ItemStack; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; import java.util.List; -import java.util.function.Consumer; @Mixin(Piglin.class) public class PiglinMixin { - @Redirect( + @ModifyExpressionValue( method = "dropCustomDeathLoot", at = @At( value = "INVOKE", - target = "Ljava/util/List;forEach(Ljava/util/function/Consumer;)V" + target = "Lnet/minecraft/world/SimpleContainer;removeAllItems()Ljava/util/List;" ) ) - public void redirectDrops( - List instance, - Consumer consumer, + public List redirectDrops( + List original, + ServerLevel serverLevel, DamageSource damageSource, - int i, boolean bl ) { - var piglin = (Piglin) (Object) this; - - boolean hasTelekinesis = TelekinesisUtils.handleTelekinesis(TelekinesisPolicy.MobDrops, - damageSource, - player -> instance.forEach(item -> { - if (!player.addItem(item)) piglin.spawnAtLocation(item); - }) - ); - - if (!hasTelekinesis) instance.forEach(piglin::spawnAtLocation); + return MixinHelper.entityCustomDeathLootMultiple(damageSource, original); } } diff --git a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/PlayerMixin.java b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/PlayerMixin.java new file mode 100644 index 0000000..49ee534 --- /dev/null +++ b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/PlayerMixin.java @@ -0,0 +1,40 @@ +package dev.nyon.telekinesis.mixins; + +import dev.nyon.telekinesis.utils.MixinHelper; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.ArrayList; +import java.util.List; + +@Mixin(Player.class) +public class PlayerMixin { + + @Shadow + @Final + Inventory inventory; + @Unique + final Player instance = (Player) (Object) this; + + @Inject( + method = "dropEquipment", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/world/entity/player/Inventory;dropAll()V" + ) + ) + public void modifyEquipmentDrops(CallbackInfo ci) { + ArrayList items = new ArrayList<>(inventory.items); + List processedItems = MixinHelper.entityDropEquipmentMultiple(instance, items); + inventory.clearContent(); + inventory.items.addAll(processedItems); + } +} diff --git a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/SheepMixin.java b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/SheepMixin.java index 304a1c5..67d08c1 100644 --- a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/SheepMixin.java +++ b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/SheepMixin.java @@ -1,7 +1,6 @@ package dev.nyon.telekinesis.mixins; import dev.nyon.telekinesis.TelekinesisPolicy; -import dev.nyon.telekinesis.utils.TelekinesisUtils; import net.minecraft.server.level.ServerPlayer; import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundSource; diff --git a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/SnowgolemMixin.java b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/SnowGolemMixin.java similarity index 95% rename from telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/SnowgolemMixin.java rename to telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/SnowGolemMixin.java index 574a010..464ef17 100644 --- a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/SnowgolemMixin.java +++ b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/SnowGolemMixin.java @@ -1,7 +1,6 @@ package dev.nyon.telekinesis.mixins; import dev.nyon.telekinesis.TelekinesisPolicy; -import dev.nyon.telekinesis.utils.TelekinesisUtils; import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundSource; import net.minecraft.world.InteractionHand; @@ -14,7 +13,7 @@ import org.spongepowered.asm.mixin.injection.Redirect; @Mixin(SnowGolem.class) -public class SnowgolemMixin { +public class SnowGolemMixin { @Redirect( method = "mobInteract", diff --git a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/SpawnerBlockMixin.java b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/SpawnerBlockMixin.java new file mode 100644 index 0000000..4b5c8ed --- /dev/null +++ b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/SpawnerBlockMixin.java @@ -0,0 +1,49 @@ +package dev.nyon.telekinesis.mixins; + +import dev.nyon.telekinesis.DropEvent; +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.SpawnerBlock; +import net.minecraft.world.level.block.state.BlockState; +import org.apache.commons.lang3.mutable.MutableInt; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyArgs; +import org.spongepowered.asm.mixin.injection.invoke.arg.Args; + +import java.util.ArrayList; + +@Mixin(SpawnerBlock.class) +public class SpawnerBlockMixin { + @Unique + private static final ThreadLocal threadLocal = new ThreadLocal<>(); + + @ModifyArgs( + method = "spawnAfterBreak", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/world/level/block/SpawnerBlock;popExperience(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/core/BlockPos;I)V" + ) + ) + private void modifyDroppedExp( + Args args, + BlockState state, + ServerLevel level, + BlockPos pos, + ItemStack stack, + boolean dropExperience + ) { + ServerPlayer player = threadLocal.get(); + if (player == null) return; + + MutableInt mutableInt = new MutableInt((int) args.get(2)); + DropEvent.INSTANCE.getEvent() + .invoker() + .invoke(new ArrayList<>(), mutableInt, player, stack); + + args.set(2, mutableInt.getValue()); + } +} diff --git a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/StriderMixin.java b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/StriderMixin.java index 0599c7f..6e4e0cd 100644 --- a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/StriderMixin.java +++ b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/StriderMixin.java @@ -1,8 +1,9 @@ package dev.nyon.telekinesis.mixins; import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; -import dev.nyon.telekinesis.utils.EntityUtils; +import dev.nyon.telekinesis.utils.MixinHelper; import net.minecraft.world.entity.monster.Strider; +import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.ItemLike; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -21,6 +22,6 @@ public boolean redirectEquipmentDrop( Strider instance, ItemLike item ) { - return EntityUtils.spawnAtLocationInject(instance, item); + return MixinHelper.entityDropEquipmentSingle(instance, new ItemStack(item)); } } diff --git a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/SweetBerryBushBlockMixin.java b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/SweetBerryBushBlockMixin.java index fd40d74..348148a 100644 --- a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/SweetBerryBushBlockMixin.java +++ b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/SweetBerryBushBlockMixin.java @@ -1,11 +1,11 @@ package dev.nyon.telekinesis.mixins; import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; +import dev.nyon.telekinesis.DropEvent; import dev.nyon.telekinesis.TelekinesisPolicy; -import dev.nyon.telekinesis.utils.TelekinesisUtils; +import dev.nyon.telekinesis.utils.MixinHelper; import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerPlayer; -import net.minecraft.world.InteractionHand; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; @@ -13,14 +13,19 @@ import net.minecraft.world.level.block.SweetBerryBushBlock; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.BlockHitResult; +import org.apache.commons.lang3.mutable.MutableInt; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + @Mixin(SweetBerryBushBlock.class) public class SweetBerryBushBlockMixin { - /*? >1.20.5 {*//* + @WrapWithCondition( - method = "useWithoutItem", + method = /*? >1.20.5 {*/ "useWithoutItem" /*?} else {*//* "use" *//*?}*/, at = @At( value = "INVOKE", target = "Lnet/minecraft/world/level/block/SweetBerryBushBlock;popResource(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/item/ItemStack;)V" @@ -38,46 +43,6 @@ private boolean manipulateBerryDrops( ) { if (!(player instanceof ServerPlayer serverPlayer)) return true; - boolean hasTelekinesis = TelekinesisUtils.handleTelekinesis(TelekinesisPolicy.BlockDrops, - serverPlayer, - serverPlayer.getMainHandItem(), - cPlayer -> { - if (!player.addItem(itemStack)) Block.popResource(level, blockPos, itemStack); - } - ); - - return !hasTelekinesis; - } - *//*?} else {*/ - @WrapWithCondition( - method = "use", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/world/level/block/SweetBerryBushBlock;popResource(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/item/ItemStack;)V" - ) - ) - private boolean manipulateBerryDrops( - Level level, - BlockPos blockPos, - ItemStack itemStack, - BlockState state, - Level _level, - BlockPos pos, - Player player, - InteractionHand hand, - BlockHitResult hit - ) { - if (!(player instanceof ServerPlayer serverPlayer)) return true; - - boolean hasTelekinesis = TelekinesisUtils.handleTelekinesis(TelekinesisPolicy.BlockDrops, - serverPlayer, - serverPlayer.getMainHandItem(), - cPlayer -> { - if (!player.addItem(itemStack)) Block.popResource(level, blockPos, itemStack); - } - ); - - return !hasTelekinesis; + return MixinHelper.wrapWithConditionPlayerItemSingle(serverPlayer, itemStack); } - /*?}*/ } diff --git a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/VehicleEntityMixin.java b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/VehicleEntityMixin.java index 7f44166..518d977 100644 --- a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/VehicleEntityMixin.java +++ b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/VehicleEntityMixin.java @@ -1,28 +1,56 @@ package dev.nyon.telekinesis.mixins; -import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import dev.nyon.telekinesis.utils.EntityUtils; +import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import dev.nyon.telekinesis.utils.MixinHelper; +import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.entity.vehicle.VehicleEntity; import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Pseudo; +import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; @Pseudo @Mixin(targets = "net.minecraft.world.entity.vehicle.VehicleEntity") public class VehicleEntityMixin { - @ModifyExpressionValue( + @Unique + private static final ThreadLocal threadLocal = new ThreadLocal<>(); + + @WrapOperation( method = "destroy(Lnet/minecraft/world/damagesource/DamageSource;)V", at = @At( value = "INVOKE", - target = "Lnet/minecraft/world/entity/vehicle/VehicleEntity;getDropItem()Lnet/minecraft/world/item/Item;" + target = "Lnet/minecraft/world/entity/vehicle/VehicleEntity;destroy(Lnet/minecraft/world/item/Item;)V" ) ) - private Item changeDroppedItem( - Item original, - DamageSource damageSource + private void checkForPlayer( + VehicleEntity instance, + Item dropItem, + Operation original, + DamageSource source ) { - return EntityUtils.getDropItemInject(original, damageSource); + MixinHelper.prepareVehicleServerPlayer(instance, dropItem, original, source, threadLocal); + } + + @WrapWithCondition( + method = "destroy(Lnet/minecraft/world/item/Item;)V", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/world/entity/vehicle/VehicleEntity;spawnAtLocation(Lnet/minecraft/world/item/ItemStack;)Lnet/minecraft/world/entity/item/ItemEntity;" + ) + ) + private boolean replaceDropItem( + VehicleEntity instance, + ItemStack itemStack + ) { + ServerPlayer player = threadLocal.get(); + if (player == null) return true; + + return MixinHelper.wrapWithConditionPlayerItemSingle(player, itemStack); } } diff --git a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/WitherBossMixin.java b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/WitherBossMixin.java index 996ef00..9a00cf0 100644 --- a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/WitherBossMixin.java +++ b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/WitherBossMixin.java @@ -1,39 +1,31 @@ package dev.nyon.telekinesis.mixins; -import com.llamalad7.mixinextras.injector.wrapoperation.Operation; -import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; -import dev.nyon.telekinesis.TelekinesisPolicy; -import dev.nyon.telekinesis.utils.TelekinesisUtils; -import net.minecraft.server.level.ServerPlayer; +import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; +import dev.nyon.telekinesis.utils.MixinHelper; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.entity.boss.wither.WitherBoss; -import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.ItemLike; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @Mixin(WitherBoss.class) public abstract class WitherBossMixin { - @WrapOperation( + @WrapWithCondition( method = "dropCustomDeathLoot", at = @At( value = "INVOKE", target = "net/minecraft/world/entity/boss/wither/WitherBoss.spawnAtLocation (Lnet/minecraft/world/level/ItemLike;)Lnet/minecraft/world/entity/item/ItemEntity;" ) ) - protected ItemEntity redirectEquipmentDrop( + protected boolean redirectEquipmentDrop( WitherBoss instance, - ItemLike stack, - Operation original + ItemLike itemLike, + ServerLevel serverLevel, + DamageSource damageSource, + boolean bl ) { - final var attacker = instance.getLastAttacker(); - if (!(attacker instanceof ServerPlayer serverPlayer)) return original.call(instance, stack); - - boolean hasTelekinesis = TelekinesisUtils.handleTelekinesis(TelekinesisPolicy.MobDrops, serverPlayer, null, player -> { - if (!player.addItem(stack.asItem() - .getDefaultInstance())) instance.spawnAtLocation(stack); - }); - - if (!hasTelekinesis) return original.call(instance, stack); - else return null; + return MixinHelper.entityCustomDeathLootSingle(damageSource, new ItemStack(itemLike)); } } diff --git a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/compat/betternether/BetterNetherMixinPlugin.java b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/compat/betternether/BetterNetherMixinPlugin.java deleted file mode 100644 index c72730d..0000000 --- a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/compat/betternether/BetterNetherMixinPlugin.java +++ /dev/null @@ -1,60 +0,0 @@ -package dev.nyon.telekinesis.mixins.compat.betternether; - -import net.fabricmc.loader.api.FabricLoader; -import org.objectweb.asm.tree.ClassNode; -import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin; -import org.spongepowered.asm.mixin.extensibility.IMixinInfo; - -import java.util.List; -import java.util.Set; - -@SuppressWarnings("unused") -public class BetterNetherMixinPlugin implements IMixinConfigPlugin { - @Override - public void onLoad(String mixinPackage) { - } - - @Override - public String getRefMapperConfig() { - return null; - } - - @Override - public boolean shouldApplyMixin( - String targetClassName, - String mixinClassName - ) { - return FabricLoader.getInstance() - .isModLoaded("betternether"); - } - - @Override - public void acceptTargets( - Set myTargets, - Set otherTargets - ) { - } - - @Override - public List getMixins() { - return null; - } - - @Override - public void preApply( - String targetClassName, - ClassNode targetClass, - String mixinClassName, - IMixinInfo mixinInfo - ) { - } - - @Override - public void postApply( - String targetClassName, - ClassNode targetClass, - String mixinClassName, - IMixinInfo mixinInfo - ) { - } -} \ No newline at end of file diff --git a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/compat/betternether/RubyFireMixin.java b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/compat/betternether/RubyFireMixin.java deleted file mode 100644 index 9322d91..0000000 --- a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/compat/betternether/RubyFireMixin.java +++ /dev/null @@ -1,99 +0,0 @@ -package dev.nyon.telekinesis.mixins.compat.betternether; - -/* - * @Pseudo - * @Mixin(targets = "org.betterx.betternether.enchantments.RubyFire") - * public class RubyFireMixin { - * @WrapWithCondition( method = "getDrops", - * at = @At( - * value = "INVOKE", - * target = "Lorg/betterx/betternether/enchantments/RubyFire;popExperience(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/core/BlockPos;I)V" - * ) - * ) - * private static boolean redirectExp( - * ServerLevel level, - * BlockPos blockPos, - * int amount, - * BlockState brokenBlock, - * ServerLevel level1, - * BlockPos blockPos1, - * Player player, - * ItemStack breakingItem - * ) { - * if (!(player instanceof ServerPlayer _serverPlayer)) return true; - * final var hasTelekinesis = TelekinesisUtils.handleTelekinesis( - * TelekinesisPolicy.ExpDrops, - * _serverPlayer, - * breakingItem, - * serverPlayer -> PlayerUtils.addExpToPlayer(serverPlayer, amount)); - * return !hasTelekinesis; - * } - * @Redirect( method = "getDrops", - * at = @At( - * value = "INVOKE", - * target = "Ljava/util/List;forEach(Ljava/util/function/Consumer;)V" - * ) - * ) - * private static void redirectCommonDrops( - * List instance, Consumer consumer, BlockState brokenBlock, ServerLevel level, BlockPos blockPos, Player player, ItemStack breakingItem - * ) { - * if (!(player instanceof ServerPlayer _serverPlayer)) { - * instance.forEach(consumer); - * return; - * } - * boolean hasTelekinesis = TelekinesisUtils.handleTelekinesis( - * TelekinesisPolicy.MobDrops, - * _serverPlayer, - * breakingItem, - * serverPlayer -> instance.forEach(item -> { - * if (!serverPlayer.addItem(item)) consumer.accept(item); - * }) - * ); - *

- * if (!hasTelekinesis) instance.forEach(consumer); - * } - * @WrapWithCondition( method = "getDrops", - * at = @At( - * value = "INVOKE", - * target = "Lnet/minecraft/world/level/block/state/BlockState;spawnAfterBreak(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/item/ItemStack;Z)V" - * ) - * ) - * private static boolean redirectAfterDrops( - * BlockState instance, - * ServerLevel world, - * BlockPos pos, - * ItemStack tool, - * boolean dropExperience, - * BlockState brokenBlock, - * ServerLevel level, - * BlockPos blockPos, - * Player _player, - * ItemStack breakingItem - * ) { - * if (!(_player instanceof ServerPlayer _serverPlayer)) return true; - *

- * Block block = brokenBlock.getBlock(); - * if (EnchantmentHelper.hasSilkTouch(breakingItem)) return true; - * boolean hasTelekinesis = TelekinesisUtils.handleTelekinesisBlock( - * TelekinesisPolicy.ExpDrops, - * _serverPlayer, - * breakingItem, - * player -> { - * int expToAdd = 0; - * if (block instanceof DropExperienceBlock expBlock) - * expToAdd = ((DropExperienceBlockAccessor) expBlock).getXpRange().sample(level.random); - * if (block instanceof RedStoneOreBlock) expToAdd = 1 + level.random.nextInt(5); - * if (block instanceof SculkCatalystBlock catalystBlock) - * expToAdd = ((CatalystBlockAccessor) catalystBlock).getXpRange().sample(level.random); - * if (block instanceof SculkSensorBlock || block instanceof SculkShriekerBlock) - * expToAdd = ConstantInt.of(5).sample(level.random); - * if (block instanceof SpawnerBlock) expToAdd = level.random.nextInt(15) + level.random.nextInt(15); - * if (block instanceof InfestedBlock infestedBlock) - * infestedBlock.spawnAfterBreak(brokenBlock, level, blockPos, breakingItem, true); - * PlayerUtils.addExpToPlayer(player, expToAdd); - * }); - *

- * return !hasTelekinesis; - * } - * } - */ \ No newline at end of file diff --git a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/compat/levelz/BlockMixinMixin.java b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/compat/levelz/BlockMixinMixin.java deleted file mode 100644 index 70f155f..0000000 --- a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/compat/levelz/BlockMixinMixin.java +++ /dev/null @@ -1,88 +0,0 @@ -package dev.nyon.telekinesis.mixins.compat.levelz; - -/* -@Pseudo -@Mixin( - value = Block.class, - priority = 1500 -) -public abstract class BlockMixinMixin { - @Unique - private static @Nullable ServerPlayer serverPlayer; - - @TargetHandler( - mixin = "net.levelz.mixin.block.BlockMixin", - name = "getDroppedStacksMixin" - ) - @WrapWithCondition( - method = "@MixinSquared:Handler", - at = @At( - value = "INVOKE", - target = "net/minecraft/world/level/block/Block.popResource (Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/item/ItemStack;)V" - ) - ) - private static boolean redirectDroppedStacks( - Level world, - BlockPos pos, - ItemStack stack, - BlockState state, - ServerLevel world1, - BlockPos pos1, - @Nullable BlockEntity blockEntity, - @Nullable Entity entity, - ItemStack tool, - CallbackInfoReturnable> info, - LootParams.Builder builder - ) { - if (!(entity instanceof ServerPlayer _serverPlayer)) return true; - final var hasTelekinesis = TelekinesisUtils.handleTelekinesis(TelekinesisPolicy.BlockDrops, - _serverPlayer, - tool, - serverPlayer -> { - if (!_serverPlayer.addItem(stack)) Block.popResource(world, pos, stack); - } - ); - return !hasTelekinesis; - } - - @TargetHandler( - mixin = "net.levelz.mixin.block.BlockMixin", - name = "dropExperienceMixin" - ) - @WrapWithCondition( - method = "@MixinSquared:Handler", - at = @At( - value = "INVOKE", - target = "net/levelz/entity/LevelExperienceOrbEntity.spawn (Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/world/phys/Vec3;I)V" - ) - ) - private static boolean redirectExp( - ServerLevel world, - Vec3 pos, - int amount - ) { - final var hasTelekinesis = TelekinesisUtils.handleTelekinesis(TelekinesisPolicy.ExpDrops, - serverPlayer, - null, - serverPlayer -> ((PlayerSyncAccess) serverPlayer).addLevelExperience(amount) - ); - return !hasTelekinesis; - } - - @Inject( - method = "playerWillDestroy", - at = { @At("HEAD") } - ) - private void onDestroy( - Level world, - BlockPos pos, - BlockState state, - Player player, - CallbackInfo info - ) { - if (!world.isClientSide) { - serverPlayer = (ServerPlayer) player; - } - } -} -*/ \ No newline at end of file diff --git a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/compat/levelz/EnderDragonEntityMixinMixin.java b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/compat/levelz/EnderDragonEntityMixinMixin.java deleted file mode 100644 index 4d19f98..0000000 --- a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/compat/levelz/EnderDragonEntityMixinMixin.java +++ /dev/null @@ -1,55 +0,0 @@ -package dev.nyon.telekinesis.mixins.compat.levelz; - -/* - * @Pseudo - * @Mixin( value = EnderDragon.class, - * priority = 1500 - * ) - * public class EnderDragonEntityMixinMixin { - * @Unique final EnderDragon instance = (EnderDragon) (Object) this; - * @TargetHandler( mixin = "net.levelz.mixin.entity.EnderDragonEntityMixin", - * name = "updatePostDeathMixin" - * ) - * @WrapWithCondition( method = "@MixinSquared:Handler", - * at = @At( - * value = "INVOKE", - * target = "net/levelz/entity/LevelExperienceOrbEntity.spawn (Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/world/phys/Vec3;I)V" - * ) - * ) - * private boolean redirectExp( - * ServerLevel world, - * Vec3 pos, - * int amount - * ) { - * if (!(instance.getLastAttacker() instanceof ServerPlayer _serverPlayer)) return true; - * final var hasTelekinesis = TelekinesisUtils.handleTelekinesis(TelekinesisPolicy.ExpDrops, - * _serverPlayer, - * null, - * serverPlayer -> ((PlayerSyncAccess) serverPlayer).addLevelExperience(amount) - * ); - * return !hasTelekinesis; - * } - * @TargetHandler( mixin = "net.levelz.mixin.entity.EnderDragonEntityMixin", - * name = "updatePostDeathXPMixin" - * ) - * @WrapWithCondition( method = "@MixinSquared:Handler", - * at = @At( - * value = "INVOKE", - * target = "net/levelz/entity/LevelExperienceOrbEntity.spawn (Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/world/phys/Vec3;I)V" - * ) - * ) - * private boolean redirectExp1( - * ServerLevel world, - * Vec3 pos, - * int amount - * ) { - * if (!(instance.getLastAttacker() instanceof ServerPlayer _serverPlayer)) return true; - * final var hasTelekinesis = TelekinesisUtils.handleTelekinesis(TelekinesisPolicy.ExpDrops, - * _serverPlayer, - * null, - * serverPlayer -> ((PlayerSyncAccess) serverPlayer).addLevelExperience(amount) - * ); - * return !hasTelekinesis; - * } - * } - */ diff --git a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/compat/levelz/FishingBobberEntityMixinMixin.java b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/compat/levelz/FishingBobberEntityMixinMixin.java deleted file mode 100644 index 39235fd..0000000 --- a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/compat/levelz/FishingBobberEntityMixinMixin.java +++ /dev/null @@ -1,36 +0,0 @@ -package dev.nyon.telekinesis.mixins.compat.levelz; - -/* - * @Pseudo - * @Mixin( value = FishingHook.class, - * priority = 1500 - * ) - * public abstract class FishingBobberEntityMixinMixin { - * @Shadow - * @Nullable public abstract Player getPlayerOwner(); - * @TargetHandler( mixin = "net.levelz.mixin.entity.FishingBobberEntityMixin", - * name = "useMixin" - * ) - * @WrapWithCondition( method = "@MixinSquared:Handler", - * at = @At( - * value = "INVOKE", - * target = "net/levelz/entity/LevelExperienceOrbEntity.spawn (Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/world/phys/Vec3;I)V" - * ) - * ) - * private boolean redirectExp( - * ServerLevel world, - * Vec3 pos, - * int amount, - * ItemStack usedItem, - * CallbackInfoReturnable info - * ) { - * if (!(getPlayerOwner() instanceof ServerPlayer _serverPlayer)) return true; - * final var hasTelekinesis = TelekinesisUtils.handleTelekinesis(TelekinesisPolicy.ExpDrops, - * _serverPlayer, - * usedItem, - * serverPlayer -> ((PlayerSyncAccess) serverPlayer).addLevelExperience(amount) - * ); - * return !hasTelekinesis; - * } - * } - */ diff --git a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/compat/levelz/LevelExperienceOrbAccessor.java b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/compat/levelz/LevelExperienceOrbAccessor.java deleted file mode 100644 index b070c36..0000000 --- a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/compat/levelz/LevelExperienceOrbAccessor.java +++ /dev/null @@ -1,9 +0,0 @@ -package dev.nyon.telekinesis.mixins.compat.levelz; - -/* - * @Pseudo - * @Mixin(LevelExperienceOrbEntity.class) public interface LevelExperienceOrbAccessor { - * @Accessor Player getTarget(); - * @Invoker("getClumpedMap") Map invokeGetClumpedMap(); - * } - */ \ No newline at end of file diff --git a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/compat/levelz/LevelExperienceOrbEntityMixin.java b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/compat/levelz/LevelExperienceOrbEntityMixin.java deleted file mode 100644 index 2e62593..0000000 --- a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/compat/levelz/LevelExperienceOrbEntityMixin.java +++ /dev/null @@ -1,34 +0,0 @@ -package dev.nyon.telekinesis.mixins.compat.levelz; - -/* - * @Pseudo - * @Mixin(net.levelz.entity.LevelExperienceOrbEntity.class) public class LevelExperienceOrbEntityMixin { - * @WrapWithCondition( method = "spawn", - * at = @At( - * value = "INVOKE", - * target = "Lnet/minecraft/server/level/ServerLevel;addFreshEntity(Lnet/minecraft/world/entity/Entity;)Z" - * ) - * ) - * private static boolean redirectSpawnOnTelekinesis( - * ServerLevel level, - * Entity entity - * ) { - * if (!(entity instanceof LevelExperienceOrbEntity expOrb)) return true; - *

- * Player target = ((LevelExperienceOrbAccessor) expOrb).getTarget(); - * if (target == null || target.distanceToSqr(expOrb) > 64.0) { - * target = level.getNearestPlayer(expOrb, 8.0); - * } - * if (!(target instanceof ServerPlayer _serverPlayer)) return true; - *

- * final var hasTelekinesis = TelekinesisUtils.handleTelekinesis( - * TelekinesisPolicy.ExpDrops, - * _serverPlayer, - * null, - * serverPlayer -> ((LevelExperienceOrbAccessor) expOrb).invokeGetClumpedMap() - * .forEach((value, amount) -> ((PlayerSyncAccess) serverPlayer).addLevelExperience(value * amount)) - * ); - * return !hasTelekinesis; - * } - * } - */ \ No newline at end of file diff --git a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/compat/levelz/LevelZMixinPlugin.java b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/compat/levelz/LevelZMixinPlugin.java deleted file mode 100644 index 680ca49..0000000 --- a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/compat/levelz/LevelZMixinPlugin.java +++ /dev/null @@ -1,61 +0,0 @@ -package dev.nyon.telekinesis.mixins.compat.levelz; - -import net.fabricmc.loader.api.FabricLoader; -import org.objectweb.asm.tree.ClassNode; -import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin; -import org.spongepowered.asm.mixin.extensibility.IMixinInfo; - -import java.util.List; -import java.util.Set; - -@SuppressWarnings("unused") -public class LevelZMixinPlugin implements IMixinConfigPlugin { - @Override - public void onLoad(String mixinPackage) { - - } - - @Override - public String getRefMapperConfig() { - return null; - } - - @Override - public boolean shouldApplyMixin( - String targetClassName, - String mixinClassName - ) { - return FabricLoader.getInstance() - .isModLoaded("levelz"); - } - - @Override - public void acceptTargets( - Set myTargets, - Set otherTargets - ) { - } - - @Override - public List getMixins() { - return null; - } - - @Override - public void preApply( - String targetClassName, - ClassNode targetClass, - String mixinClassName, - IMixinInfo mixinInfo - ) { - } - - @Override - public void postApply( - String targetClassName, - ClassNode targetClass, - String mixinClassName, - IMixinInfo mixinInfo - ) { - } -} diff --git a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/compat/levelz/LivingEntityMixinMixin.java b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/compat/levelz/LivingEntityMixinMixin.java deleted file mode 100644 index e40ac1d..0000000 --- a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/compat/levelz/LivingEntityMixinMixin.java +++ /dev/null @@ -1,35 +0,0 @@ -package dev.nyon.telekinesis.mixins.compat.levelz; - -/* - * @Pseudo - * @Mixin( value = LivingEntity.class, - * priority = 1500 - * ) - * public class LivingEntityMixinMixin { - * @Unique final LivingEntity instance = (LivingEntity) (Object) this; - * @TargetHandler( mixin = "net.levelz.mixin.entity.LivingEntityMixin", - * name = "dropXpMixin" - * ) - * @WrapWithCondition( method = "@MixinSquared:Handler", - * at = @At( - * value = "INVOKE", - * target = "net/levelz/entity/LevelExperienceOrbEntity.spawn (Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/world/phys/Vec3;I)V" - * ) - * ) - * protected boolean redirectLevelZExpDrop( - * ServerLevel world, - * Vec3 pos, - * int amount - * ) { - * if (!(instance.getLastAttacker() instanceof ServerPlayer _serverPlayer)) return true; - * System.out.println("wtf" + amount); - * System.out.println(amount); - * final var hasTelekinesis = TelekinesisUtils.handleTelekinesis(TelekinesisPolicy.ExpDrops, - * _serverPlayer, - * null, - * serverPlayer -> ((PlayerSyncAccess) serverPlayer).addLevelExperience(amount) - * ); - * return !hasTelekinesis; - * } - * } - */ \ No newline at end of file diff --git a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/compat/levelz/PlantBlockMixinMixin.java b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/compat/levelz/PlantBlockMixinMixin.java deleted file mode 100644 index 4b5704e..0000000 --- a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/compat/levelz/PlantBlockMixinMixin.java +++ /dev/null @@ -1,39 +0,0 @@ -package dev.nyon.telekinesis.mixins.compat.levelz; - -/* - * @Pseudo - * @Mixin( value = BushBlock.class, - * priority = 1500 - * ) - * public class PlantBlockMixinMixin extends Block { - *

- * public PlantBlockMixinMixin(Properties properties) { - * super(properties); - * } - * @WrapWithCondition( method = "playerWillDestroy(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/entity/player/Player;)V", - * at = @At( - * value = "INVOKE", - * target = "net/minecraft/world/level/block/Block.popResource (Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/item/ItemStack;)V" - * ) - * ) - * private boolean checkTelekinesisAndRedirect( - * Level world, - * BlockPos pos, - * ItemStack stack, - * Level world1, - * BlockPos pos1, - * BlockState state, - * Player player - * ) { - * if (!(player instanceof ServerPlayer _serverPlayer)) return true; - * final var hasTelekinesis = TelekinesisUtils.handleTelekinesis(TelekinesisPolicy.BlockDrops, - * _serverPlayer, - * null, - * serverPlayer -> { - * if (!serverPlayer.addItem(stack)) Block.popResource(world, pos, stack); - * } - * ); - * return !hasTelekinesis; - * } - * } - */ \ No newline at end of file diff --git a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/compat/treeharvester/TreeCutEventsMixin.java b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/compat/treeharvester/TreeCutEventsMixin.java deleted file mode 100644 index 2da886a..0000000 --- a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/compat/treeharvester/TreeCutEventsMixin.java +++ /dev/null @@ -1,44 +0,0 @@ -package dev.nyon.telekinesis.mixins.compat.treeharvester; - -/* -@Pseudo -@Mixin(targets = "com.natamus.treeharvester_common_fabric.events.TreeCutEvents") -public class TreeCutEventsMixin { - - @Redirect( - method = "onTreeHarvest", - at = @At( - value = "INVOKE", - target = "Lcom/natamus/collective_common_fabric/functions/BlockFunctions;dropBlock(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;)V" - ) - ) - private static void redirectDrop( - Level level, - BlockPos blockPos, - Level _level, - Player player, - BlockPos bpos, - BlockState state, - BlockEntity blockEntity - ) { - if ((EnchantmentHelper.getItemEnchantmentLevel( - MainKt.getTelekinesis(), - player.getItemInHand(InteractionHand.MAIN_HAND) - ) == 0 && !TelekinesisConfigKt.getConfig() - .getOnByDefault()) || !TelekinesisConfigKt.getConfig() - .getBlockDrops() || !(level instanceof ServerLevel serverLevel)) return; - - BlockState blockState = level.getBlockState(blockPos); - BlockEntity tileEntity = level.getBlockEntity(blockPos); - - List drops = Block.getDrops(blockState, serverLevel, blockPos, tileEntity); - - drops.forEach(item -> { - if (!player.addItem(item)) Block.popResource(serverLevel, blockPos, item); - }); - - serverLevel.setBlock(blockPos, Blocks.AIR.defaultBlockState(), 3); - } -} - - */ \ No newline at end of file diff --git a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/compat/treeharvester/TreeHarvesterMixinPlugin.java b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/compat/treeharvester/TreeHarvesterMixinPlugin.java deleted file mode 100644 index e1d653f..0000000 --- a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/mixins/compat/treeharvester/TreeHarvesterMixinPlugin.java +++ /dev/null @@ -1,60 +0,0 @@ -package dev.nyon.telekinesis.mixins.compat.treeharvester; - -import net.fabricmc.loader.api.FabricLoader; -import org.objectweb.asm.tree.ClassNode; -import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin; -import org.spongepowered.asm.mixin.extensibility.IMixinInfo; - -import java.util.List; -import java.util.Set; - -@SuppressWarnings("unused") -public class TreeHarvesterMixinPlugin implements IMixinConfigPlugin { - @Override - public void onLoad(String mixinPackage) { - } - - @Override - public String getRefMapperConfig() { - return null; - } - - @Override - public boolean shouldApplyMixin( - String targetClassName, - String mixinClassName - ) { - return FabricLoader.getInstance() - .isModLoaded("treeharvester"); - } - - @Override - public void acceptTargets( - Set myTargets, - Set otherTargets - ) { - } - - @Override - public List getMixins() { - return null; - } - - @Override - public void preApply( - String targetClassName, - ClassNode targetClass, - String mixinClassName, - IMixinInfo mixinInfo - ) { - } - - @Override - public void postApply( - String targetClassName, - ClassNode targetClass, - String mixinClassName, - IMixinInfo mixinInfo - ) { - } -} diff --git a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/utils/EntityUtils.java b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/utils/EntityUtils.java deleted file mode 100644 index f06e1a9..0000000 --- a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/utils/EntityUtils.java +++ /dev/null @@ -1,65 +0,0 @@ -package dev.nyon.telekinesis.utils; - -import dev.nyon.telekinesis.TelekinesisPolicy; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.world.damagesource.DamageSource; -import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.ItemLike; - -import java.util.concurrent.atomic.AtomicReference; - -public class EntityUtils { - - public static boolean spawnAtLocationInject( - LivingEntity entity, - ItemLike item - ) { - return spawnAtLocationInject( - entity, - item.asItem() - .getDefaultInstance() - ); - } - - public static boolean spawnAtLocationInject( - LivingEntity entity, - ItemStack item - ) { - final var attacker = entity.getLastAttacker(); - - return spawnAtLocationAttacker(attacker, item); - } - - public static boolean spawnAtLocationAttacker(LivingEntity attacker, ItemStack item) { - if (!(attacker instanceof ServerPlayer serverPlayer)) return true; - - boolean hasTelekinesis = TelekinesisUtils.handleTelekinesis(TelekinesisPolicy.MobDrops, - serverPlayer, - serverPlayer.getMainHandItem(), - player -> { - if (!player.addItem(item)) attacker.spawnAtLocation(item); - } - ); - - return !hasTelekinesis; - } - - public static Item getDropItemInject( - Item original, - DamageSource source - ) { - final var attacker = source.getEntity(); - if (!(attacker instanceof ServerPlayer)) return original; - - AtomicReference toReturn = new AtomicReference<>(original); - - TelekinesisUtils.handleTelekinesis(TelekinesisPolicy.VehicleDrops, source, player -> { - if (player.addItem(original.asItem() - .getDefaultInstance())) toReturn.set(ItemStack.EMPTY.getItem()); - }); - - return toReturn.get(); - } -} diff --git a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/utils/MixinHelper.java b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/utils/MixinHelper.java new file mode 100644 index 0000000..33c0960 --- /dev/null +++ b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/utils/MixinHelper.java @@ -0,0 +1,114 @@ +package dev.nyon.telekinesis.utils; + +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import dev.nyon.telekinesis.DropEvent; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.vehicle.ChestBoat; +import net.minecraft.world.entity.vehicle.VehicleEntity; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import org.apache.commons.lang3.mutable.MutableInt; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +public class MixinHelper { + public static boolean wrapWithConditionPlayerItemSingle( + ServerPlayer player, + ItemStack item + ) { + ArrayList mutableList = new ArrayList<>(List.of(item)); + DropEvent.INSTANCE.getEvent() + .invoker() + .invoke(mutableList, new MutableInt(0), player, player.getMainHandItem()); + + return !mutableList.isEmpty(); + } + + public static boolean entityDropEquipmentSingle( + LivingEntity entity, + ItemStack item + ) { + LivingEntity lastAttacker = entity.getLastAttacker(); + if (!(lastAttacker instanceof ServerPlayer player)) return true; + return wrapWithConditionPlayerItemSingle(player, item); + } + + public static List entityDropEquipmentMultiple( + LivingEntity entity, + List items + ) { + LivingEntity lastAttacker = entity.getLastAttacker(); + if (!(lastAttacker instanceof ServerPlayer player)) return items; + + ArrayList mutableList = new ArrayList<>(items); + DropEvent.INSTANCE.getEvent() + .invoker() + .invoke(mutableList, new MutableInt(0), player, player.getMainHandItem()); + + return mutableList; + } + + public static boolean entityCustomDeathLootSingle( + DamageSource source, + ItemStack item + ) { + Entity lastAttacker = source.getEntity(); + if (!(lastAttacker instanceof ServerPlayer player)) return true; + + ArrayList mutableList = new ArrayList<>(List.of(item)); + DropEvent.INSTANCE.getEvent() + .invoker() + .invoke(mutableList, + new MutableInt(0), + player, + Objects.requireNonNullElseGet(source.getWeaponItem(), player::getMainHandItem) + ); + + return !mutableList.isEmpty(); + } + + public static List entityCustomDeathLootMultiple( + DamageSource source, + List items + ) { + Entity lastAttacker = source.getEntity(); + if (!(lastAttacker instanceof ServerPlayer player)) return items; + + ArrayList mutableList = new ArrayList<>(items); + DropEvent.INSTANCE.getEvent() + .invoker() + .invoke(mutableList, + new MutableInt(0), + player, + Objects.requireNonNullElseGet(source.getWeaponItem(), player::getMainHandItem) + ); + + return mutableList; + } + + public static void prepareVehicleServerPlayer( + VehicleEntity instance, + Item item, + Operation original, + DamageSource source, + ThreadLocal threadLocal + ) { + if (!(source.getEntity() instanceof ServerPlayer player)) { + original.call(instance, item); + return; + } + + ServerPlayer previous = threadLocal.get(); + threadLocal.set(player); + try { + original.call(instance, item); + } finally { + threadLocal.set(previous); + } + } +} diff --git a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/utils/PlayerUtils.java b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/utils/PlayerUtils.java deleted file mode 100644 index e6ad9ba..0000000 --- a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/utils/PlayerUtils.java +++ /dev/null @@ -1,33 +0,0 @@ -package dev.nyon.telekinesis.utils; - -import net.minecraft.world.entity.EquipmentSlot; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.enchantment.EnchantmentHelper; -import net.minecraft.world.item.enchantment.Enchantments; - -import java.util.Map; - -public class PlayerUtils { - public static void addExpToPlayer( - Player player, - Integer exp - ) { - var remainingExp = repairPlayerItems(player, exp); - if (remainingExp > 0) player.giveExperiencePoints(remainingExp); - } - - private static int repairPlayerItems( - Player player, - Integer exp - ) { - Map.Entry entry = EnchantmentHelper.getRandomItemWith(Enchantments.MENDING, player, ItemStack::isDamaged); - if (entry != null) { - ItemStack itemStack = entry.getValue(); - int j = Math.min(exp * 2, itemStack.getDamageValue()); - itemStack.setDamageValue(itemStack.getDamageValue() - j); - int k = exp - j * 2; - return k > 0 ? repairPlayerItems(player, k) : 0; - } else return exp; - } -} diff --git a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/utils/TelekinesisUtils.java b/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/utils/TelekinesisUtils.java deleted file mode 100644 index 0be0142..0000000 --- a/telekinesis-fabric/src/main/java/dev/nyon/telekinesis/utils/TelekinesisUtils.java +++ /dev/null @@ -1,94 +0,0 @@ -package dev.nyon.telekinesis.utils; - -import dev.nyon.telekinesis.MainKt; -import dev.nyon.telekinesis.TelekinesisConfigKt; -import dev.nyon.telekinesis.TelekinesisPolicy; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.world.damagesource.DamageSource; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.enchantment.EnchantmentHelper; -import org.jetbrains.annotations.Nullable; - -import java.util.function.Consumer; - -public class TelekinesisUtils { - - public static boolean handleTelekinesisBlock( - TelekinesisPolicy neededPolicy, - Entity entity, - ItemStack tool, - Consumer consumer - ) { - if (!(entity instanceof ServerPlayer serverPlayer)) return false; - return handleTelekinesis(neededPolicy, serverPlayer, tool, consumer); - } - - public static boolean handleTelekinesis( - TelekinesisPolicy neededPolicy, - LivingEntity target, - Consumer consumer - ) { - LivingEntity attacker = target.getLastAttacker(); - if (attacker == null) return false; - if (!(attacker instanceof ServerPlayer serverPlayer)) return false; - return handleTelekinesis(neededPolicy, serverPlayer, null, consumer); - } - - public static boolean handleTelekinesis( - TelekinesisPolicy neededPolicy, - DamageSource source, - Consumer consumer - ) { - if (source == null) return false; - Entity attacker = source.getEntity(); - if (attacker == null) return false; - if (!(attacker instanceof ServerPlayer serverPlayer)) return false; - return handleTelekinesis(neededPolicy, serverPlayer, null, consumer); - } - - - public static boolean handleTelekinesis( - TelekinesisPolicy neededPolicy, - ServerPlayer player, - @Nullable ItemStack itemStack, - Consumer consumer - ) { - if (!neededPolicy.isEnabled()) return false; - if (!playerMeetsConditions(neededPolicy, player, itemStack)) return false; - - consumer.accept(player); - return true; - } - - private static boolean playerMeetsConditions( - TelekinesisPolicy policy, - ServerPlayer player, - @Nullable ItemStack itemStack - ) { - boolean conditionsMet = false; - - boolean isEnabledByDefault = TelekinesisConfigKt.getConfig() - .getOnByDefault(); - - boolean hasArmorTelekinesis = player.getInventory().armor.stream() - .allMatch(item -> EnchantmentHelper.getItemEnchantmentLevel(MainKt.getTelekinesis(), item) > 0); - boolean hasMainHandTelekinesis = (itemStack != null && EnchantmentHelper.getItemEnchantmentLevel(MainKt.getTelekinesis(), - itemStack - ) > 0) || EnchantmentHelper.getItemEnchantmentLevel(MainKt.getTelekinesis(), player.getMainHandItem()) > 0; - boolean hasOffHandTelekinesis = EnchantmentHelper.getItemEnchantmentLevel(MainKt.getTelekinesis(), player.getOffhandItem()) > 0; - - if (isEnabledByDefault) conditionsMet = true; - else switch (policy) { - case ExpDrops -> conditionsMet = hasArmorTelekinesis || hasMainHandTelekinesis || hasOffHandTelekinesis; - case MobDrops, ShearingDrops, VehicleDrops, FishingDrops -> conditionsMet = hasMainHandTelekinesis || hasOffHandTelekinesis; - case BlockDrops -> conditionsMet = hasMainHandTelekinesis; - } - - if (TelekinesisConfigKt.getConfig() - .getOnlyOnSneak() && !player.isCrouching()) conditionsMet = false; - - return conditionsMet; - } -} diff --git a/telekinesis-fabric/src/main/kotlin/dev/nyon/telekinesis/DropEvent.kt b/telekinesis-fabric/src/main/kotlin/dev/nyon/telekinesis/DropEvent.kt new file mode 100644 index 0000000..7082181 --- /dev/null +++ b/telekinesis-fabric/src/main/kotlin/dev/nyon/telekinesis/DropEvent.kt @@ -0,0 +1,21 @@ +package dev.nyon.telekinesis + +import net.fabricmc.fabric.api.event.Event +import net.fabricmc.fabric.api.event.EventFactory +import net.minecraft.server.level.ServerPlayer +import net.minecraft.world.item.ItemStack +import org.apache.commons.lang3.mutable.MutableInt + +object DropEvent { + val event: Event = EventFactory.createArrayBacked(DropEventConsumer::class.java) { listeners -> + DropEventConsumer { items, exp, player, tool -> + listeners.forEach { + it(items, exp, player, tool) + } + } + } +} + +fun interface DropEventConsumer { + operator fun invoke(items: MutableList, exp: MutableInt, player: ServerPlayer, tool: ItemStack) +} \ No newline at end of file diff --git a/telekinesis-fabric/src/main/kotlin/dev/nyon/telekinesis/Main.kt b/telekinesis-fabric/src/main/kotlin/dev/nyon/telekinesis/Main.kt index 6c67387..62a6a0c 100644 --- a/telekinesis-fabric/src/main/kotlin/dev/nyon/telekinesis/Main.kt +++ b/telekinesis-fabric/src/main/kotlin/dev/nyon/telekinesis/Main.kt @@ -2,10 +2,9 @@ package dev.nyon.telekinesis -import net.minecraft.server.MinecraftServer - -var server: MinecraftServer? = null +/*? if <=1.20.6 {*//* lateinit var telekinesis: TelekinesisEnchantment +*//*?}*/ fun init() { loadConfig() diff --git a/telekinesis-fabric/src/main/kotlin/dev/nyon/telekinesis/TelekinesisEnchantment.kt b/telekinesis-fabric/src/main/kotlin/dev/nyon/telekinesis/TelekinesisEnchantment.kt index 899024c..1c47db6 100644 --- a/telekinesis-fabric/src/main/kotlin/dev/nyon/telekinesis/TelekinesisEnchantment.kt +++ b/telekinesis-fabric/src/main/kotlin/dev/nyon/telekinesis/TelekinesisEnchantment.kt @@ -1,20 +1,22 @@ package dev.nyon.telekinesis +/*? if <1.21 {*//* import net.minecraft.network.chat.Component import net.minecraft.network.chat.Style import net.minecraft.world.item.enchantment.Enchantment import net.minecraft.world.entity.EquipmentSlot -/*? >1.20.5 {*//* +*//*?}*/ +/*? >1.20.5 {*/ import net.minecraft.tags.ItemTags -*//*?} else {*/ +/*?} else {*//* import net.minecraft.world.damagesource.DamageSource import net.minecraft.world.entity.MobType import net.minecraft.world.item.enchantment.EnchantmentCategory -/*?}*/ +*//*?}*/ -/*? >1.20.5 {*//* +/*? if =1.20.6 {*//* class TelekinesisEnchantment : Enchantment( definition( ItemTags.DURABILITY_ENCHANTABLE, @@ -29,7 +31,7 @@ class TelekinesisEnchantment : Enchantment( override fun getFullname(i: Int): Component = Component.translatable("enchantment.telekinesis.telekinesis.name").withStyle(Style.EMPTY.withColor(0xFFB64C)) } -*//*?} else {*/ +*//*?} elif <1.20.5 {*//* class TelekinesisEnchantment : Enchantment( Rarity.RARE, EnchantmentCategory.BREAKABLE, listOf(EquipmentSlot.OFFHAND, EquipmentSlot.MAINHAND).toTypedArray() ) { @@ -46,4 +48,4 @@ class TelekinesisEnchantment : Enchantment( override fun getFullname(i: Int): Component = Component.translatable("enchantment.telekinesis.telekinesis.name").withStyle(Style.EMPTY.withColor(0xFFB64C)) } -/*?}*/ +*//*?}*/ diff --git a/telekinesis-fabric/src/main/kotlin/dev/nyon/telekinesis/TelekinesisEnchantmentGenerator.kt b/telekinesis-fabric/src/main/kotlin/dev/nyon/telekinesis/TelekinesisEnchantmentGenerator.kt new file mode 100644 index 0000000..9b14656 --- /dev/null +++ b/telekinesis-fabric/src/main/kotlin/dev/nyon/telekinesis/TelekinesisEnchantmentGenerator.kt @@ -0,0 +1,60 @@ +package dev.nyon.telekinesis + +import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint +import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator +import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput +import net.fabricmc.fabric.api.datagen.v1.provider.FabricDynamicRegistryProvider +import net.minecraft.core.HolderLookup +import net.minecraft.core.RegistrySetBuilder +import net.minecraft.core.registries.Registries +import net.minecraft.resources.ResourceKey +import net.minecraft.resources.ResourceLocation +import net.minecraft.tags.ItemTags +import net.minecraft.world.entity.EquipmentSlotGroup +import net.minecraft.world.item.enchantment.Enchantment +import net.minecraft.world.item.enchantment.Enchantment.EnchantmentDefinition +import net.minecraft.world.item.enchantment.Enchantment.dynamicCost +import java.util.concurrent.CompletableFuture + +class TelekinesisEnchantmentGenerator : DataGeneratorEntrypoint { + override fun onInitializeDataGenerator(generator: FabricDataGenerator) {/*? if >=1.21 {*/ + val pack = generator.createPack() + + pack.addProvider(::EnchantmentProvider)/*?}*/ + } + + override fun buildRegistry(registryBuilder: RegistrySetBuilder) { + registryBuilder.add(Registries.ENCHANTMENT) { context -> + val enchantmentDefinition: EnchantmentDefinition = Enchantment.definition( + context.lookup(Registries.ITEM).getOrThrow(ItemTags.DURABILITY_ENCHANTABLE), + 2, + 1, + dynamicCost(25, 25), + dynamicCost(75, 25), + 5, + EquipmentSlotGroup.ANY + ) + + context.register( + ResourceKey.create( + Registries.ENCHANTMENT, ResourceLocation.fromNamespaceAndPath("telekinesis", "telekinesis") + ), Enchantment.enchantment(enchantmentDefinition).build( + ResourceLocation.fromNamespaceAndPath("telekinesis", "telekinesis.name") + ) + ) + } + } +} + +private class EnchantmentProvider( + output: FabricDataOutput, registriesFuture: CompletableFuture +) : FabricDynamicRegistryProvider(output, registriesFuture) { + override fun getName(): String { + return "Enchantment" + } + + override fun configure(registries: HolderLookup.Provider, entries: Entries) { + entries.addAll(registries.lookupOrThrow(Registries.ENCHANTMENT)) + } +} + diff --git a/telekinesis-fabric/src/main/resources/compat.betternether.mixins.json b/telekinesis-fabric/src/main/resources/compat.betternether.mixins.json deleted file mode 100644 index f6e04f8..0000000 --- a/telekinesis-fabric/src/main/resources/compat.betternether.mixins.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "required": true, - "minVersion": "0.8", - "plugin": "dev.nyon.telekinesis.mixins.compat.betternether.BetterNetherMixinPlugin", - "package": "dev.nyon.telekinesis.mixins.compat.betternether", - "compatibilityLevel": "JAVA_17", - "client": [ - ], - "injectors": { - "defaultRequire": 1 - }, - "mixins": [ - "RubyFireMixin" - ] -} \ No newline at end of file diff --git a/telekinesis-fabric/src/main/resources/compat.levelz.mixins.json b/telekinesis-fabric/src/main/resources/compat.levelz.mixins.json deleted file mode 100644 index 1ffe7fc..0000000 --- a/telekinesis-fabric/src/main/resources/compat.levelz.mixins.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "required": true, - "minVersion": "0.8", - "plugin": "dev.nyon.telekinesis.mixins.compat.levelz.LevelZMixinPlugin", - "package": "dev.nyon.telekinesis.mixins.compat.levelz", - "compatibilityLevel": "JAVA_17", - "client": [ - ], - "injectors": { - "defaultRequire": 1 - }, - "mixins": [ - "BlockMixinMixin", - "EnderDragonEntityMixinMixin", - "FishingBobberEntityMixinMixin", - "LevelExperienceOrbAccessor", - "LevelExperienceOrbEntityMixin", - "LivingEntityMixinMixin", - "PlantBlockMixinMixin" - ] -} \ No newline at end of file diff --git a/telekinesis-fabric/src/main/resources/compat.treeharvester.mixins.json b/telekinesis-fabric/src/main/resources/compat.treeharvester.mixins.json deleted file mode 100644 index 6e3a838..0000000 --- a/telekinesis-fabric/src/main/resources/compat.treeharvester.mixins.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "required": true, - "minVersion": "0.8", - "plugin": "dev.nyon.telekinesis.mixins.compat.treeharvester.TreeHarvesterMixinPlugin", - "package": "dev.nyon.telekinesis.mixins.compat.treeharvester", - "compatibilityLevel": "JAVA_17", - "client": [ - "TreeCutEventsMixin" - ], - "injectors": { - "defaultRequire": 1 - } -} \ No newline at end of file diff --git a/telekinesis-fabric/src/main/resources/fabric.mod.json b/telekinesis-fabric/src/main/resources/fabric.mod.json index 5a0749f..f5e931a 100644 --- a/telekinesis-fabric/src/main/resources/fabric.mod.json +++ b/telekinesis-fabric/src/main/resources/fabric.mod.json @@ -1,53 +1,56 @@ { - "schemaVersion": 1, - "id": "${id}", - "name": "${name}", - "description": "${description}", - "contact": { - "issues": "https://github.com/btwonion/telekinesis/issues", - "sources": "https://github.com/btwonion/telekinesis" - }, - "icon": "assets/telekinesis/icon.png", - "authors": [ - "btwonion" - ], - "contributors": [], - "license": [ - "GNU General Public License v3.0" - ], - "version": "${version}", - "environment": "*", - "depends": { - "fabric-language-kotlin": ">=1.10.20+kotlin.1.9.24", - "yet_another_config_lib_v3": "*", - "minecraft": "${mc}" - }, - "suggests": { - "modmenu": "*" - }, - "entrypoints": { - "main": [ - { - "adapter": "kotlin", - "value": "dev.nyon.telekinesis.MainKt::init" - } + "schemaVersion": 1, + "id": "${id}", + "name": "${name}", + "description": "${description}", + "contact": { + "issues": "https://github.com/btwonion/telekinesis/issues", + "sources": "https://github.com/btwonion/telekinesis" + }, + "icon": "assets/telekinesis/icon.png", + "authors": [ + "btwonion" ], - "modmenu": [ - { - "adapter": "kotlin", - "value": "dev.nyon.telekinesis.ModMenuImpl" - } - ] - }, - "mixins": [ - "telekinesis.mixins.json" - ], - "accessWidener": "telekinesis.accesswidener", - "custom": { - "modmenu": { - "links": { - "modmenu.discord": "https://discord.gg/pmHTtZnMd3" - } + "contributors": [], + "license": [ + "GNU General Public License v3.0" + ], + "version": "${version}", + "environment": "*", + "depends": { + "fabric-language-kotlin": ">=1.11.0+kotlin.2.0.0", + "yet_another_config_lib_v3": "*", + "minecraft": "${mc}" + }, + "suggests": { + "modmenu": "*" + }, + "entrypoints": { + "fabric-datagen": [ + "dev.nyon.telekinesis.TelekinesisEnchantmentGenerator" + ], + "main": [ + { + "adapter": "kotlin", + "value": "dev.nyon.telekinesis.MainKt::init" + } + ], + "modmenu": [ + { + "adapter": "kotlin", + "value": "dev.nyon.telekinesis.ModMenuImpl" + } + ] + }, + "mixins": [ + "telekinesis.mixins.json" + ], + "accessWidener": "telekinesis.accesswidener", + "custom": { + "modmenu": { + "links": { + "modmenu.discord": "https://discord.gg/pmHTtZnMd3" + } + } } - } } diff --git a/telekinesis-fabric/src/main/resources/telekinesis.mixins.json b/telekinesis-fabric/src/main/resources/telekinesis.mixins.json index 4c5bf60..c5121f2 100644 --- a/telekinesis-fabric/src/main/resources/telekinesis.mixins.json +++ b/telekinesis-fabric/src/main/resources/telekinesis.mixins.json @@ -1,36 +1,35 @@ { - "required": true, - "minVersion": "0.8", - "package": "dev.nyon.telekinesis.mixins", - "compatibilityLevel": "JAVA_17", - "mixins": [ - "AbstractChestedHorseMixin", - "AbstractHorseMixin", - "AbstractMinecartMixin", - "AllayMixin", - "BlockMixin", - "BoatMixin", - "CatalystBlockAccessor", - "ChestBoatMixin", - "DropExperienceBlockAccessor", - "EnchantmentsMixin", - "EnderManMixin", - "FishingHookMixin", - "InventoryMixin", - "LivingEntityMixin", - "MinecartTNTMixin", - "MinecraftServerMixin", - "MobMixin", - "PiglinMixin", - "PigMixin", - "SheepMixin", - "SnowgolemMixin", - "StriderMixin", - "SweetBerryBushBlockMixin", - "VehicleEntityMixin", - "WitherBossMixin" - ], - "injectors": { - "defaultRequire": 1 + "required": true, + "minVersion": "0.8", + "package": "dev.nyon.telekinesis.mixins", + "compatibilityLevel": "JAVA_17", + "mixins": [ + "AbstractChestedHorseMixin", + "AbstractHorseMixin", + "AbstractMinecartMixin", + "AllayMixin", + "BlockMixin", + "BoatMixin", + "ChestBoatMixin", + "EnchantmentsMixin", + "EnderManMixin", + "FishingHookMixin", + "InventoryMixin", + "LivingEntityMixin", + "MinecartTNTMixin", + "MobMixin", + "PiglinMixin", + "PigMixin", + "PlayerMixin", + "SheepMixin", + "SnowGolemMixin", + "SpawnerBlockMixin", + "StriderMixin", + "SweetBerryBushBlockMixin", + "VehicleEntityMixin", + "WitherBossMixin" + ], + "injectors": { + "defaultRequire": 1 } } diff --git a/telekinesis-fabric/stonecutter.gradle.kts b/telekinesis-fabric/stonecutter.gradle.kts index 495263e..49c570e 100644 --- a/telekinesis-fabric/stonecutter.gradle.kts +++ b/telekinesis-fabric/stonecutter.gradle.kts @@ -1,7 +1,20 @@ +import kotlinx.serialization.ExperimentalSerializationApi +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.buildJsonArray +import kotlinx.serialization.json.buildJsonObject +import kotlinx.serialization.json.put +import kotlinx.serialization.json.putJsonArray +import java.net.URI +import java.net.http.HttpClient +import java.net.http.HttpRequest +import java.net.http.HttpResponse +import java.time.Instant + plugins { id("dev.kikugie.stonecutter") } -stonecutter active "1.20.1" /* [SC] DO NOT EDIT */ +stonecutter active "1.21" /* [SC] DO NOT EDIT */ stonecutter registerChiseled tasks.register("buildAllVersions", stonecutter.chiseled) { @@ -14,3 +27,77 @@ stonecutter registerChiseled group = "mod" ofTask("releaseMod") } + +private data class Field(val name: String, val value: String, val inline: Boolean) + +private data class Embed( + val title: String, val description: String, val timestamp: String, val color: Int, val fields: List +) + +private data class DiscordWebhook( + val username: String, val avatarUrl: String, val embeds: List +) + +tasks.register("postUpdate") { + group = "mod" + + val version = project(stonecutter.versions.first().project).version.toString() + val featureVersion = version.split('-').first() + + val url = providers.environmentVariable("DISCORD_WEBHOOK").orNull ?: return@register + val changelogText = rootProject.file("changelog.md").readText() + val webhook = DiscordWebhook( + username = "${rootProject.name} Release Notifier", + avatarUrl = "https://raw.githubusercontent.com/btwonion/skylper/master/src/main/resources/assets/skylper/icon/icon.png", + embeds = listOf( + Embed( + title = "v$featureVersion of ${rootProject.name} released!", + description = "# Changelog\n$changelogText", + timestamp = Instant.now().toString(), + color = 0xff0080, + fields = listOf( + Field( + "Supported versions", stonecutter.versions.joinToString { it.version }, false + ), + Field("Modrinth", "https://modrinth.com/mod/telekinesis", true), + Field("GitHub", "https://github.com/btwonion/telekinesis", true) + ), + ) + ) + ) + + @OptIn(ExperimentalSerializationApi::class) + val embedsJson = buildJsonArray { + webhook.embeds.map { embed -> + add(buildJsonObject { + put("title", embed.title) + put("description", embed.description) + put("timestamp", embed.timestamp) + put("color", embed.color) + putJsonArray("fields") { + addAll(embed.fields.map { field -> + buildJsonObject { + put("name", field.name) + put("value", field.value) + put("inline", field.inline) + } + }) + } + }) + } + } + + val json = buildJsonObject { + put("username", webhook.username) + put("avatar_url", webhook.avatarUrl) + put("embeds", embedsJson) + } + + val jsonString = Json.encodeToString(json) + val response = HttpClient.newHttpClient().send( + HttpRequest.newBuilder(URI.create(url)).header("Content-Type", "application/json") + .POST(HttpRequest.BodyPublishers.ofString(jsonString)).build(), HttpResponse.BodyHandlers.ofString() + ) + + println(response.body()) +} diff --git a/telekinesis-fabric/versions/1.21/gradle.properties b/telekinesis-fabric/versions/1.21/gradle.properties new file mode 100644 index 0000000..e99c8c7 --- /dev/null +++ b/telekinesis-fabric/versions/1.21/gradle.properties @@ -0,0 +1,10 @@ +mcVersion=1.21-rc1 +mcVersionRange=>=1.20.6 <=1.21 +supportedMcVersions=1.21-rc1 + +deps.parchment= +deps.fapi=0.100.1+1.21 +deps.yacl=3.4.4+1.21-fabric +deps.modMenu=10.0.0-beta.1 + +javaVer=21