Skip to content

Commit

Permalink
fix: elytra (#29)
Browse files Browse the repository at this point in the history
* fix: elytra issues

* fix

* fix

* fix
  • Loading branch information
zly2006 authored Jul 18, 2024
1 parent 5be4f39 commit e6dbfb9
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 48 deletions.
2 changes: 1 addition & 1 deletion src/main/java/fi/dy/masa/tweakeroo/config/Callbacks.java
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ else if (key == Hotkeys.OPEN_CONFIG_GUI.getKeybind())
}
else if (key == Hotkeys.SWAP_ELYTRA_CHESTPLATE.getKeybind())
{
InventoryUtils.swapElytraWithChestPlate(this.mc.player);
InventoryUtils.swapElytraAndChestPlate(this.mc.player);
return true;
}
else if (key == Hotkeys.TOGGLE_GRAB_CURSOR.getKeybind())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,22 +129,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)

// 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.
// !isSwimming(): Check if the Player is swimming so, it doesn't perform the Elytra Swap while underwater.
if (!this.isOnGround() && !this.isSwimming()
&& (!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)))
// PlayerEntity#checkFallFlying
if (!this.isOnGround() && !this.isFallFlying() && !this.isInFluid() && !this.hasStatusEffect(StatusEffects.LEVITATION))
{
this.autoSwitchElytraChestplate = this.getEquippedStack(EquipmentSlot.CHEST).copy();
InventoryUtils.swapElytraWithChestPlate(this);
if (!this.getEquippedStack(EquipmentSlot.CHEST).isOf(Items.ELYTRA) ||
this.getEquippedStack(EquipmentSlot.CHEST).getDamage() > this.getEquippedStack(EquipmentSlot.CHEST).getMaxDamage() - 10)
{
InventoryUtils.equipBestElytra(this);
}
}
}
else
Expand Down Expand Up @@ -180,7 +172,7 @@ private void onStopFlying(TrackedData<?> data, CallbackInfo ci)
else
{
// if cached previous item is empty, try to swap back to the default chest plate.
InventoryUtils.swapElytraWithChestPlate(this);
InventoryUtils.swapElytraAndChestPlate(this);
}
}
}
Expand Down
81 changes: 50 additions & 31 deletions src/main/java/fi/dy/masa/tweakeroo/util/InventoryUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -865,58 +865,77 @@ private static int findRepairableItemNotInRepairableSlot(Slot targetSlot, Player
return -1;
}

public static void swapElytraWithChestPlate(@Nullable PlayerEntity player)
public static void equipBestElytra(PlayerEntity player)
{
if (player == null || GuiUtils.getCurrentScreen() != null)
{
return;
}

ScreenHandler container = player.currentScreenHandler;
ItemStack currentStack = player.getEquippedStack(EquipmentSlot.CHEST);

Predicate<ItemStack> stackFilterChestPlate = (s) -> s.getItem() instanceof ArmorItem && ((ArmorItem) s.getItem()).getSlotType() == EquipmentSlot.CHEST;
Predicate<ItemStack> stackFilterElytra = (s) -> s.getItem() instanceof ElytraItem && ElytraItem.isUsable(s);
boolean switchingToElytra = (currentStack.isEmpty() || stackFilterChestPlate.test(currentStack));
Predicate<ItemStack> stackFilter = switchingToElytra ? stackFilterElytra : stackFilterChestPlate;
Predicate<ItemStack> finalFilter = (s) -> s.isEmpty() == false && stackFilter.test(s) && s.getDamage() < s.getMaxDamage() - 10;

Predicate<ItemStack> filter = (s) -> s.getItem() instanceof ElytraItem && ElytraItem.isUsable(s) && s.getDamage() < s.getMaxDamage() - 10;
int targetSlot = findSlotWithBestItemMatch(container, (testedStack, previousBestMatch) -> {
if (!finalFilter.test(testedStack)) return false;
if (!finalFilter.test(previousBestMatch)) return true;
if (switchingToElytra)
if (!filter.test(testedStack)) return false;
if (!filter.test(previousBestMatch)) return true;
if (getEnchantmentLevel(testedStack, Enchantments.UNBREAKING) > getEnchantmentLevel(previousBestMatch, Enchantments.UNBREAKING))
{
if (getEnchantmentLevel(testedStack, Enchantments.UNBREAKING) < getEnchantmentLevel(previousBestMatch, Enchantments.UNBREAKING))
{
return false;
}
if (testedStack.getDamage() > previousBestMatch.getDamage())
{
return false;
}
return true;
}
else
if (getEnchantmentLevel(testedStack, Enchantments.UNBREAKING) < getEnchantmentLevel(previousBestMatch, Enchantments.UNBREAKING))
{
if (getArmorAndArmorToughnessValue(previousBestMatch, 1, AttributeModifierSlot.CHEST) > getArmorAndArmorToughnessValue(testedStack, 1, AttributeModifierSlot.CHEST))
{
return false;
}
if (getEnchantmentLevel(previousBestMatch, Enchantments.PROTECTION) > getEnchantmentLevel(testedStack, Enchantments.PROTECTION))
{
return false;
}
return false;
}

return true;
return testedStack.getDamage() <= previousBestMatch.getDamage();
}, UniformIntProvider.create(9, container.slots.size() - 1));

if (targetSlot >= 0)
{
//targetSlots.sort();
swapItemToEquipmentSlot(player, EquipmentSlot.CHEST, targetSlot);
}
}

public static void swapElytraAndChestPlate(@Nullable PlayerEntity player)
{
if (player == null || GuiUtils.getCurrentScreen() != null)
{
return;
}

ScreenHandler container = player.currentScreenHandler;
ItemStack currentStack = player.getEquippedStack(EquipmentSlot.CHEST);

Predicate<ItemStack> stackFilterChestPlate = (s) -> s.getItem() instanceof ArmorItem && ((ArmorItem) s.getItem()).getSlotType() == EquipmentSlot.CHEST;

if (currentStack.isEmpty() || stackFilterChestPlate.test(currentStack))
{
equipBestElytra(player);
}
else
{
Predicate<ItemStack> finalFilter = (s) -> stackFilterChestPlate.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;
if (getArmorAndArmorToughnessValue(previousBestMatch, 1, AttributeModifierSlot.CHEST) < getArmorAndArmorToughnessValue(testedStack, 1, AttributeModifierSlot.CHEST))
{
return true;
}
if (getArmorAndArmorToughnessValue(previousBestMatch, 1, AttributeModifierSlot.CHEST) > getArmorAndArmorToughnessValue(testedStack, 1, AttributeModifierSlot.CHEST))
{
return false;
}
return getEnchantmentLevel(previousBestMatch, Enchantments.PROTECTION) <= getEnchantmentLevel(testedStack, Enchantments.PROTECTION);
}, UniformIntProvider.create(9, container.slots.size() - 1));

if (targetSlot >= 0)
{
swapItemToEquipmentSlot(player, EquipmentSlot.CHEST, targetSlot);
}
}
}

private static double getArmorAndArmorToughnessValue(ItemStack stack, double base, AttributeModifierSlot slot)
{
final double[] total = {base};
Expand Down

0 comments on commit e6dbfb9

Please sign in to comment.