From 3a06a3f03f672b775ee3256a10c4f6aa8478c791 Mon Sep 17 00:00:00 2001 From: Liyan Zhao Date: Sun, 23 Jun 2024 10:58:44 +0800 Subject: [PATCH 1/6] fix: auto switch elytra dont check if player isOnGround() --- .../mixin/MixinClientPlayerEntity.java | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/main/java/fi/dy/masa/tweakeroo/mixin/MixinClientPlayerEntity.java b/src/main/java/fi/dy/masa/tweakeroo/mixin/MixinClientPlayerEntity.java index 542267f96..152aeab56 100644 --- a/src/main/java/fi/dy/masa/tweakeroo/mixin/MixinClientPlayerEntity.java +++ b/src/main/java/fi/dy/masa/tweakeroo/mixin/MixinClientPlayerEntity.java @@ -132,10 +132,13 @@ private void onFallFlyingCheckChestSlot(CallbackInfo ci) { if (FeatureToggle.TWEAK_AUTO_SWITCH_ELYTRA.getBooleanValue()) { - // auto switch if it is not elytra after falling more than 20 blocks, or is totally broken. - // This also shouldn't activate on the Ground if the Chest Equipment is EMPTY, or not an Elytra - // To be swapped back. - if ((!this.getEquippedStack(EquipmentSlot.CHEST).isOf(Items.ELYTRA) && this.fallDistance > 20.0f) + // Auto switch if it is not elytra after falling, or is totally broken. + // This also shouldn't activate on the Ground if the Chest Equipment is EMPTY, + // or not an Elytra to be swapped back. + // + // !isOnGround(): Minecraft also check elytra even if the player is on the ground, skip it. + if (!isOnGround() + && (!this.getEquippedStack(EquipmentSlot.CHEST).isOf(Items.ELYTRA)) || (this.getEquippedStack(EquipmentSlot.CHEST).getDamage() > this.getEquippedStack(EquipmentSlot.CHEST).getMaxDamage() - 10) && (!this.getEquippedStack(EquipmentSlot.CHEST).isEmpty() || this.autoSwitchElytraChestplate.isOf(Items.ELYTRA))) { @@ -154,16 +157,19 @@ private void onFallFlyingCheckChestSlot(CallbackInfo ci) private void onMovementEnd(CallbackInfo ci) { if (FeatureToggle.TWEAK_AUTO_SWITCH_ELYTRA.getBooleanValue()) { - if (!this.autoSwitchElytraChestplate.isEmpty() && !this.isFallFlying() && this.getEquippedStack(EquipmentSlot.CHEST).isOf(Items.ELYTRA)) + if (!this.isFallFlying() && this.getEquippedStack(EquipmentSlot.CHEST).isOf(Items.ELYTRA)) { - if (this.playerScreenHandler.getCursorStack().isEmpty()) + if (!this.autoSwitchElytraChestplate.isEmpty()) { - int targetSlot = InventoryUtils.findSlotWithItem(this.playerScreenHandler, this.autoSwitchElytraChestplate, true, false); - - if (targetSlot >= 0) + if (this.playerScreenHandler.getCursorStack().isEmpty()) { - InventoryUtils.swapItemToEquipmentSlot(this, EquipmentSlot.CHEST, targetSlot); - this.autoSwitchElytraChestplate = ItemStack.EMPTY; + int targetSlot = InventoryUtils.findSlotWithItem(this.playerScreenHandler, this.autoSwitchElytraChestplate, true, false); + + if (targetSlot >= 0) + { + InventoryUtils.swapItemToEquipmentSlot(this, EquipmentSlot.CHEST, targetSlot); + this.autoSwitchElytraChestplate = ItemStack.EMPTY; + } } } } From df8f1c1bf3a6b4dc6116970c86e6545348b80514 Mon Sep 17 00:00:00 2001 From: Liyan Zhao Date: Sun, 23 Jun 2024 10:59:11 +0800 Subject: [PATCH 2/6] fix: auto switch elytra switch back to default chestplate --- .../fi/dy/masa/tweakeroo/mixin/MixinClientPlayerEntity.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/fi/dy/masa/tweakeroo/mixin/MixinClientPlayerEntity.java b/src/main/java/fi/dy/masa/tweakeroo/mixin/MixinClientPlayerEntity.java index 152aeab56..96ceecde1 100644 --- a/src/main/java/fi/dy/masa/tweakeroo/mixin/MixinClientPlayerEntity.java +++ b/src/main/java/fi/dy/masa/tweakeroo/mixin/MixinClientPlayerEntity.java @@ -172,6 +172,10 @@ private void onMovementEnd(CallbackInfo ci) { } } } + else { + // if cached previous item is empty, try to swap back to the default chest plate. + InventoryUtils.swapElytraWithChestPlate(this); + } } } } From 29b24b764b82ff6adcc4b22595632f616c96ab97 Mon Sep 17 00:00:00 2001 From: Liyan Zhao Date: Sun, 23 Jun 2024 10:59:48 +0800 Subject: [PATCH 3/6] fix: improve InventoryUtils.swapElytraWithChestPlate --- .../masa/tweakeroo/util/InventoryUtils.java | 31 +++++++++++++++++-- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/src/main/java/fi/dy/masa/tweakeroo/util/InventoryUtils.java b/src/main/java/fi/dy/masa/tweakeroo/util/InventoryUtils.java index 8ce0e4358..18325bbe9 100644 --- a/src/main/java/fi/dy/masa/tweakeroo/util/InventoryUtils.java +++ b/src/main/java/fi/dy/masa/tweakeroo/util/InventoryUtils.java @@ -2,7 +2,6 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; -import java.io.ObjectInputFilter; import java.util.*; import java.util.function.Predicate; import java.util.regex.Matcher; @@ -862,9 +861,29 @@ public static void swapElytraWithChestPlate(@Nullable PlayerEntity player) Predicate stackFilterChestPlate = (s) -> s.getItem() instanceof ArmorItem && ((ArmorItem) s.getItem()).getSlotType() == EquipmentSlot.CHEST; Predicate stackFilterElytra = (s) -> s.getItem() instanceof ElytraItem && ElytraItem.isUsable(s); - Predicate stackFilter = (currentStack.isEmpty() || stackFilterChestPlate.test(currentStack)) ? stackFilterElytra : stackFilterChestPlate; + boolean switchingToElytra = (currentStack.isEmpty() || stackFilterChestPlate.test(currentStack)); + Predicate stackFilter = switchingToElytra ? stackFilterElytra : stackFilterChestPlate; Predicate finalFilter = (s) -> s.isEmpty() == false && stackFilter.test(s) && s.getDamage() < s.getMaxDamage() - 10; - int targetSlot = findSuitableSlot(container, finalFilter); + int targetSlot = findSlotWithBestItemMatch(container, (testedStack, previousBestMatch) -> { + if (!finalFilter.test(testedStack)) return false; + if (switchingToElytra) { + if (getEnchantmentLevel(testedStack, Enchantments.UNBREAKING) > getEnchantmentLevel(previousBestMatch, Enchantments.UNBREAKING)) { + return true; + } + else if (testedStack.getDamage() < previousBestMatch.getDamage()) { + return true; + } + } + else { + if (getArmorValue(previousBestMatch, 1, EquipmentSlot.CHEST) < getArmorValue(testedStack, 1, EquipmentSlot.CHEST)) { + return true; + } + else if (getEnchantmentLevel(previousBestMatch, Enchantments.PROTECTION) < getEnchantmentLevel(testedStack, Enchantments.PROTECTION)) { + return true; + } + } + return false; + }, UniformIntProvider.create(9, container.slots.size() - 1)); if (targetSlot >= 0) { @@ -873,6 +892,12 @@ public static void swapElytraWithChestPlate(@Nullable PlayerEntity player) } } + private static double getArmorValue(ItemStack stack, double base, EquipmentSlot slot) + { + AttributeModifiersComponent attributeModifiersComponent = stack.getOrDefault(DataComponentTypes.ATTRIBUTE_MODIFIERS, AttributeModifiersComponent.DEFAULT); + return attributeModifiersComponent.applyOperations(base, slot); + } + /** * * Finds a slot with an identical item than stackReference, ignoring the durability From b4bb90c3b1ae840599f0887b2f7a9fa30b5d6eb4 Mon Sep 17 00:00:00 2001 From: Liyan Zhao Date: Sun, 23 Jun 2024 11:29:47 +0800 Subject: [PATCH 4/6] fix: improve InventoryUtils.swapElytraWithChestPlate --- .../masa/tweakeroo/util/InventoryUtils.java | 55 ++++++++++++++----- 1 file changed, 41 insertions(+), 14 deletions(-) diff --git a/src/main/java/fi/dy/masa/tweakeroo/util/InventoryUtils.java b/src/main/java/fi/dy/masa/tweakeroo/util/InventoryUtils.java index 18325bbe9..d7e432074 100644 --- a/src/main/java/fi/dy/masa/tweakeroo/util/InventoryUtils.java +++ b/src/main/java/fi/dy/masa/tweakeroo/util/InventoryUtils.java @@ -9,6 +9,7 @@ import net.minecraft.block.BlockState; import net.minecraft.client.MinecraftClient; import net.minecraft.component.DataComponentTypes; +import net.minecraft.component.type.AttributeModifierSlot; import net.minecraft.component.type.AttributeModifiersComponent; import net.minecraft.component.type.ItemEnchantmentsComponent; import net.minecraft.enchantment.Enchantment; @@ -866,23 +867,30 @@ public static void swapElytraWithChestPlate(@Nullable PlayerEntity player) Predicate finalFilter = (s) -> s.isEmpty() == false && stackFilter.test(s) && s.getDamage() < s.getMaxDamage() - 10; int targetSlot = findSlotWithBestItemMatch(container, (testedStack, previousBestMatch) -> { if (!finalFilter.test(testedStack)) return false; - if (switchingToElytra) { - if (getEnchantmentLevel(testedStack, Enchantments.UNBREAKING) > getEnchantmentLevel(previousBestMatch, Enchantments.UNBREAKING)) { - return true; + if (!finalFilter.test(previousBestMatch)) return true; + if (switchingToElytra) + { + if (getEnchantmentLevel(testedStack, Enchantments.UNBREAKING) < getEnchantmentLevel(previousBestMatch, Enchantments.UNBREAKING)) + { + return false; } - else if (testedStack.getDamage() < previousBestMatch.getDamage()) { - return true; + if (testedStack.getDamage() > previousBestMatch.getDamage()) + { + return false; } } - else { - if (getArmorValue(previousBestMatch, 1, EquipmentSlot.CHEST) < getArmorValue(testedStack, 1, EquipmentSlot.CHEST)) { - return true; + else + { + if (getArmorAndArmorToughnessValue(previousBestMatch, 1, AttributeModifierSlot.CHEST) > getArmorAndArmorToughnessValue(testedStack, 1, AttributeModifierSlot.CHEST)) + { + return false; } - else if (getEnchantmentLevel(previousBestMatch, Enchantments.PROTECTION) < getEnchantmentLevel(testedStack, Enchantments.PROTECTION)) { - return true; + if (getEnchantmentLevel(previousBestMatch, Enchantments.PROTECTION) > getEnchantmentLevel(testedStack, Enchantments.PROTECTION)) + { + return false; } } - return false; + return true; }, UniformIntProvider.create(9, container.slots.size() - 1)); if (targetSlot >= 0) @@ -892,10 +900,29 @@ else if (getEnchantmentLevel(previousBestMatch, Enchantments.PROTECTION) < getEn } } - private static double getArmorValue(ItemStack stack, double base, EquipmentSlot slot) + private static double getArmorAndArmorToughnessValue(ItemStack stack, double base, AttributeModifierSlot slot) { - AttributeModifiersComponent attributeModifiersComponent = stack.getOrDefault(DataComponentTypes.ATTRIBUTE_MODIFIERS, AttributeModifiersComponent.DEFAULT); - return attributeModifiersComponent.applyOperations(base, slot); + final double[] total = {base}; + stack.applyAttributeModifier(slot, (entry, modifier) -> { + if (entry.getKey().orElseThrow() == EntityAttributes.GENERIC_ARMOR + || entry.getKey().orElseThrow() == EntityAttributes.GENERIC_ARMOR_TOUGHNESS) + { + switch (modifier.operation()) { + case ADD_VALUE: + total[0] += modifier.value(); + break; + case ADD_MULTIPLIED_BASE: + total[0] += modifier.value() * base; + break; + case ADD_MULTIPLIED_TOTAL: + total[0] += modifier.value() * total[0]; + break; + default: + throw new MatchException(null, null); + } + } + }); + return total[0]; } /** From 1ba13dc442a5b71c5139558cf360e186cdf86ab0 Mon Sep 17 00:00:00 2001 From: Sakura Ryoko Date: Sun, 23 Jun 2024 01:53:40 -0400 Subject: [PATCH 5/6] Reformatting --- gradle.properties | 2 +- .../fi/dy/masa/tweakeroo/mixin/MixinClientPlayerEntity.java | 3 ++- src/main/java/fi/dy/masa/tweakeroo/util/InventoryUtils.java | 6 +++++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/gradle.properties b/gradle.properties index 5e3362fb4..31b273378 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,7 +9,7 @@ author = masa mod_file_name = tweakeroo-fabric # Current mod version -mod_version = 0.20.999-sakura.7 +mod_version = 0.20.999-sakura.7-pr6 # Required malilib version malilib_version = 0.19.999-sakura.3 diff --git a/src/main/java/fi/dy/masa/tweakeroo/mixin/MixinClientPlayerEntity.java b/src/main/java/fi/dy/masa/tweakeroo/mixin/MixinClientPlayerEntity.java index 9ea53652e..2496a595a 100644 --- a/src/main/java/fi/dy/masa/tweakeroo/mixin/MixinClientPlayerEntity.java +++ b/src/main/java/fi/dy/masa/tweakeroo/mixin/MixinClientPlayerEntity.java @@ -179,7 +179,8 @@ private void onMovementEnd(CallbackInfo ci) { } } } - else { + else + { // if cached previous item is empty, try to swap back to the default chest plate. InventoryUtils.swapElytraWithChestPlate(this); } diff --git a/src/main/java/fi/dy/masa/tweakeroo/util/InventoryUtils.java b/src/main/java/fi/dy/masa/tweakeroo/util/InventoryUtils.java index d7e432074..df418a83f 100644 --- a/src/main/java/fi/dy/masa/tweakeroo/util/InventoryUtils.java +++ b/src/main/java/fi/dy/masa/tweakeroo/util/InventoryUtils.java @@ -865,6 +865,7 @@ public static void swapElytraWithChestPlate(@Nullable PlayerEntity player) boolean switchingToElytra = (currentStack.isEmpty() || stackFilterChestPlate.test(currentStack)); Predicate stackFilter = switchingToElytra ? stackFilterElytra : stackFilterChestPlate; Predicate finalFilter = (s) -> s.isEmpty() == false && stackFilter.test(s) && s.getDamage() < s.getMaxDamage() - 10; + int targetSlot = findSlotWithBestItemMatch(container, (testedStack, previousBestMatch) -> { if (!finalFilter.test(testedStack)) return false; if (!finalFilter.test(previousBestMatch)) return true; @@ -903,11 +904,13 @@ public static void swapElytraWithChestPlate(@Nullable PlayerEntity player) private static double getArmorAndArmorToughnessValue(ItemStack stack, double base, AttributeModifierSlot slot) { final double[] total = {base}; + stack.applyAttributeModifier(slot, (entry, modifier) -> { if (entry.getKey().orElseThrow() == EntityAttributes.GENERIC_ARMOR || entry.getKey().orElseThrow() == EntityAttributes.GENERIC_ARMOR_TOUGHNESS) { - switch (modifier.operation()) { + switch (modifier.operation()) + { case ADD_VALUE: total[0] += modifier.value(); break; @@ -922,6 +925,7 @@ private static double getArmorAndArmorToughnessValue(ItemStack stack, double bas } } }); + return total[0]; } From 3f7fb69dca852a2d2abde0b6c9ce20f43e988077 Mon Sep 17 00:00:00 2001 From: Sakura Ryoko Date: Sun, 23 Jun 2024 02:02:23 -0400 Subject: [PATCH 6/6] Reformatting --- .../mixin/MixinClientPlayerEntity.java | 24 +++++++------------ .../masa/tweakeroo/util/InventoryUtils.java | 1 + 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/src/main/java/fi/dy/masa/tweakeroo/mixin/MixinClientPlayerEntity.java b/src/main/java/fi/dy/masa/tweakeroo/mixin/MixinClientPlayerEntity.java index 2496a595a..482beaf86 100644 --- a/src/main/java/fi/dy/masa/tweakeroo/mixin/MixinClientPlayerEntity.java +++ b/src/main/java/fi/dy/masa/tweakeroo/mixin/MixinClientPlayerEntity.java @@ -33,17 +33,12 @@ public abstract class MixinClientPlayerEntity extends AbstractClientPlayerEntity { @Shadow public Input input; @Shadow protected int ticksLeftToDoubleTapSprint; - @Shadow public float prevNauseaIntensity; @Shadow public float nauseaIntensity; - @Unique - private final DummyMovementInput dummyMovementInput = new DummyMovementInput(null); - @Unique - private Input realInput; - @Unique - private float realNauseaIntensity; - @Unique - private ItemStack autoSwitchElytraChestplate = ItemStack.EMPTY; + @Unique private final DummyMovementInput dummyMovementInput = new DummyMovementInput(null); + @Unique private Input realInput; + @Unique private float realNauseaIntensity; + @Unique private ItemStack autoSwitchElytraChestplate = ItemStack.EMPTY; private MixinClientPlayerEntity(ClientWorld world, GameProfile profile) { @@ -133,18 +128,14 @@ private void onFallFlyingCheckChestSlot(CallbackInfo ci) if (FeatureToggle.TWEAK_AUTO_SWITCH_ELYTRA.getBooleanValue()) { // Sakura's version calculating fall distance... - /* - if ((!this.getEquippedStack(EquipmentSlot.CHEST).isOf(Items.ELYTRA) && this.fallDistance > 20.0f) - || (this.getEquippedStack(EquipmentSlot.CHEST).getDamage() > this.getEquippedStack(EquipmentSlot.CHEST).getMaxDamage() - 10) - && (!this.getEquippedStack(EquipmentSlot.CHEST).isEmpty() || this.autoSwitchElytraChestplate.isOf(Items.ELYTRA))) - */ + //if ((!this.getEquippedStack(EquipmentSlot.CHEST).isOf(Items.ELYTRA) && this.fallDistance > 20.0f) // Auto switch if it is not elytra after falling, or is totally broken. // This also shouldn't activate on the Ground if the Chest Equipment is EMPTY, // or not an Elytra to be swapped back. // // !isOnGround(): Minecraft also check elytra even if the player is on the ground, skip it. - if (!isOnGround() + if (!this.isOnGround() && (!this.getEquippedStack(EquipmentSlot.CHEST).isOf(Items.ELYTRA)) || (this.getEquippedStack(EquipmentSlot.CHEST).getDamage() > this.getEquippedStack(EquipmentSlot.CHEST).getMaxDamage() - 10) && (!this.getEquippedStack(EquipmentSlot.CHEST).isEmpty() || this.autoSwitchElytraChestplate.isOf(Items.ELYTRA))) @@ -161,7 +152,8 @@ private void onFallFlyingCheckChestSlot(CallbackInfo ci) } @Inject(method = "tickMovement", at = @At("RETURN")) - private void onMovementEnd(CallbackInfo ci) { + private void onMovementEnd(CallbackInfo ci) + { if (FeatureToggle.TWEAK_AUTO_SWITCH_ELYTRA.getBooleanValue()) { if (!this.isFallFlying() && this.getEquippedStack(EquipmentSlot.CHEST).isOf(Items.ELYTRA)) diff --git a/src/main/java/fi/dy/masa/tweakeroo/util/InventoryUtils.java b/src/main/java/fi/dy/masa/tweakeroo/util/InventoryUtils.java index df418a83f..6d1c76659 100644 --- a/src/main/java/fi/dy/masa/tweakeroo/util/InventoryUtils.java +++ b/src/main/java/fi/dy/masa/tweakeroo/util/InventoryUtils.java @@ -891,6 +891,7 @@ public static void swapElytraWithChestPlate(@Nullable PlayerEntity player) return false; } } + return true; }, UniformIntProvider.create(9, container.slots.size() - 1));