Skip to content

Commit

Permalink
add autoSwitchElytra
Browse files Browse the repository at this point in the history
  • Loading branch information
plusls committed Aug 30, 2021
1 parent 2b0796e commit c60470e
Show file tree
Hide file tree
Showing 11 changed files with 146 additions and 8 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ Make Minecraft Client Great Again!

## Feature

### 自动切换鞘翅

自动切换鞘翅和胸甲(支持原地起飞)

### 禁止破坏特定方块

玩家无法破坏在 **破坏方块黑名单** 中的方块
Expand Down
4 changes: 4 additions & 0 deletions README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ Support empty shulker box stack when sort inventory.

## Features

### Auto Switch Elytra

Auto Switch elytra and chestplate.

### Disable Break Block

You can't break blocks in **breakBlockBlackList**.
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ minecraft_version=1.17.1
yarn_mappings=1.17.1+build.10
loader_version=0.11.6
# Mod Properties
mod_version=0.3.4
mod_version=0.3.5
maven_group=com.plusls
archives_base_name=oh-my-minecraft-client
# Dependencies
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/com/plusls/ommc/config/Configs.java
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ public static class Generic {

public static class FeatureToggle {
private static final String PREFIX = String.format("%s.config.feature_toggle", ModInfo.MOD_ID);
public static final ConfigBooleanHotkeyed AUTO_SWITCH_ELYTRA = new TranslatableConfigBooleanHotkeyed(PREFIX, "autoSwitchElytra", false, "");
public static final ConfigBooleanHotkeyed DISABLE_BREAK_BLOCK = new TranslatableConfigBooleanHotkeyed(PREFIX, "disableBreakBlock", false, "");
public static final ConfigBooleanHotkeyed DISABLE_BREAK_SCAFFOLDING = new TranslatableConfigBooleanHotkeyed(PREFIX, "disableBreakScaffolding", false, "");
public static final ConfigBooleanHotkeyed DISABLE_MOVE_DOWN_IN_SCAFFOLDING = new TranslatableConfigBooleanHotkeyed(PREFIX, "disableMoveDownInScaffolding", false, "");
Expand All @@ -103,6 +104,7 @@ public static class FeatureToggle {
public static final ConfigBooleanHotkeyed WORLD_EATER_MINE_HELPER = new TranslatableConfigBooleanHotkeyed(PREFIX, "worldEaterMineHelper", false, "");

public static final ImmutableList<ConfigBooleanHotkeyed> OPTIONS = ImmutableList.of(
AUTO_SWITCH_ELYTRA,
DISABLE_BREAK_BLOCK,
DISABLE_BREAK_SCAFFOLDING,
DISABLE_MOVE_DOWN_IN_SCAFFOLDING,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package com.plusls.ommc.feature.autoSwitchElytra;

import com.plusls.ommc.ModInfo;
import com.plusls.ommc.feature.sortInventory.SortInventoryUtil;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.entity.effect.StatusEffects;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.screen.ScreenHandler;

import java.util.ArrayList;
import java.util.function.Predicate;

public class AutoSwitchElytraUtil {
public static final int CHEST_SLOT_IDX = 6;

public static boolean myCheckFallFlying(PlayerEntity player) {
if (!player.isOnGround() && !player.isFallFlying() && !player.isTouchingWater() && !player.hasStatusEffect(StatusEffects.LEVITATION)) {
return true;
}
return false;
}

public static void autoSwitch(int sourceSlot, MinecraftClient client, ClientPlayerEntity clientPlayerEntity, Predicate<ItemStack> check) {
if (client.interactionManager == null) {
return;
}
ScreenHandler screenHandler = clientPlayerEntity.currentScreenHandler;
ArrayList<Integer> clickQueue = new ArrayList<>();
ItemStack cursorStack = screenHandler.getCursorStack().copy();
ArrayList<ItemStack> itemStacks = new ArrayList<>();
int playerInventoryStartIdx = SortInventoryUtil.getPlayerInventoryStartIdx(screenHandler);
for (int i = 0; i < screenHandler.slots.size(); ++i) {
itemStacks.add(screenHandler.slots.get(i).getStack().copy());
}
if (!cursorStack.isEmpty()) {
// 把鼠标的物品放到玩家仓库中
clickQueue.addAll(SortInventoryUtil.addItemStack(itemStacks, cursorStack, playerInventoryStartIdx, screenHandler.slots.size()));
}
if (!cursorStack.isEmpty()) {
// 放不下了就扔出去
clickQueue.add(ScreenHandler.EMPTY_SPACE_SLOT_INDEX);
}
int idxToSwitch = -1;
for (int i = 0; i < itemStacks.size(); ++i) {
if (check.test(itemStacks.get(i))) {
idxToSwitch = i;
break;
}
}
boolean sourceSlotEmpty = itemStacks.get(sourceSlot).isEmpty();
if (idxToSwitch != -1) {
clickQueue.add(idxToSwitch);
clickQueue.add(sourceSlot);
if (!sourceSlotEmpty) {
clickQueue.add(idxToSwitch);
}
SortInventoryUtil.doClick(clientPlayerEntity, screenHandler.syncId, client.interactionManager, clickQueue);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.client.network.ClientPlayerInteractionManager;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.BundleItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
Expand All @@ -12,13 +14,15 @@
import net.minecraft.screen.*;
import net.minecraft.screen.slot.Slot;
import net.minecraft.screen.slot.SlotActionType;
import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

public class SortInventoryUtil {

private static int getPlayerInventoryStartIdx(ScreenHandler screenHandler) {
public static int getPlayerInventoryStartIdx(ScreenHandler screenHandler) {
if (screenHandler instanceof PlayerScreenHandler) {
return 9;
} else if (screenHandler instanceof CraftingScreenHandler) {
Expand Down Expand Up @@ -120,14 +124,18 @@ public static boolean sort() {
clickQueue.addAll(quickSort(itemStacks, playerInventoryStartIdx + 27, r));
}

doClick(player, screenHandler.syncId, client.interactionManager, clickQueue);
return !clickQueue.isEmpty();
}

public static void doClick(PlayerEntity player, int syncId, @NotNull ClientPlayerInteractionManager interactionManager, List<Integer> clickQueue) {
for (Integer slotId : clickQueue) {
if (slotId < 0 && slotId != ScreenHandler.EMPTY_SPACE_SLOT_INDEX) {
client.interactionManager.clickSlot(screenHandler.syncId, -slotId, 1, SlotActionType.PICKUP, player);
interactionManager.clickSlot(syncId, -slotId, 1, SlotActionType.PICKUP, player);
} else {
client.interactionManager.clickSlot(screenHandler.syncId, slotId, 0, SlotActionType.PICKUP, player);
interactionManager.clickSlot(syncId, slotId, 0, SlotActionType.PICKUP, player);
}
}
return !clickQueue.isEmpty();
}

private static boolean canStackAddMore(ItemStack existingStack, ItemStack stack) {
Expand All @@ -138,7 +146,7 @@ private static boolean canStackAddMore(ItemStack existingStack, ItemStack stack)
existingStack.getCount() < 64;
}

private static ArrayList<Integer> addItemStack(ArrayList<ItemStack> itemStacks, ItemStack stackToAdd, int l, int r) {
public static ArrayList<Integer> addItemStack(ArrayList<ItemStack> itemStacks, ItemStack stackToAdd, int l, int r) {
// merge in [l, r)
ArrayList<Integer> ret = new ArrayList<>();
for (int i = l; i < r; ++i) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.plusls.ommc.mixin.feature.autoSwitchElytra;

import com.mojang.authlib.GameProfile;
import com.plusls.ommc.feature.autoSwitchElytra.AutoSwitchElytraUtil;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.AbstractClientPlayerEntity;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.util.registry.Registry;
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 org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(ClientPlayerEntity.class)
public abstract class MixinClientPlayerEntity extends AbstractClientPlayerEntity {
@Shadow
@Final
protected MinecraftClient client;

boolean prevFallFlying = false;

public MixinClientPlayerEntity(ClientWorld world, GameProfile profile) {
super(world, profile);
}

@Inject(method = "tickMovement", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;getEquippedStack(Lnet/minecraft/entity/EquipmentSlot;)Lnet/minecraft/item/ItemStack;", ordinal = 0))
private void autoSwitchElytra(CallbackInfo ci) {
ItemStack chestItemStack = this.getEquippedStack(EquipmentSlot.CHEST);
if (chestItemStack.isOf(Items.ELYTRA) || !AutoSwitchElytraUtil.myCheckFallFlying(this)) {
return;
}
AutoSwitchElytraUtil.autoSwitch(AutoSwitchElytraUtil.CHEST_SLOT_IDX, this.client, (ClientPlayerEntity) (Object) this, itemStack -> itemStack.isOf(Items.ELYTRA));
}

@Inject(method = "tickMovement", at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/client/network/ClientPlayerEntity;isFallFlying()Z", ordinal = 0))
private void autoSwitchChest(CallbackInfo ci) {
ItemStack chestItemStack = this.getEquippedStack(EquipmentSlot.CHEST);
if (!chestItemStack.isOf(Items.ELYTRA) || !prevFallFlying || this.isFallFlying()) {
prevFallFlying = this.isFallFlying();
return;
}
prevFallFlying = this.isFallFlying();
AutoSwitchElytraUtil.autoSwitch(AutoSwitchElytraUtil.CHEST_SLOT_IDX, this.client, (ClientPlayerEntity) (Object) this, itemStack -> Registry.ITEM.getId(itemStack.getItem()).toString().contains("_chestplate"));

}

}
2 changes: 2 additions & 0 deletions src/main/resources/assets/ommc/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
"ommc.config.generic.sortInventory.comment": "A hotkey to sort inventory.",
"ommc.config.generic.sortInventorySupportEmptyShulkerBoxStack.name": "sortInventorySupportEmptyShulkerBoxStack",
"ommc.config.generic.sortInventorySupportEmptyShulkerBoxStack.comment": "Support empty shulker box stack when sort inventory.",
"ommc.config.feature_toggle.autoSwitchElytra.name": "autoSwitchElytra",
"ommc.config.feature_toggle.autoSwitchElytra.comment": "Auto switch elytra and chestplate.",
"ommc.config.feature_toggle.disableBreakBlock.name": "disableBreakBlock",
"ommc.config.feature_toggle.disableBreakBlock.comment": "You can't break blocks in §6breakBlockBlackList§r.",
"ommc.config.feature_toggle.disableBreakScaffolding.name": "disableBreakScaffolding",
Expand Down
2 changes: 2 additions & 0 deletions src/main/resources/assets/ommc/lang/zh_cn.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
"ommc.config.generic.sortInventory.comment": "整理仓库的快捷键",
"ommc.config.generic.sortInventorySupportEmptyShulkerBoxStack.name": "整理仓库时支持空潜影盒堆叠",
"ommc.config.generic.sortInventorySupportEmptyShulkerBoxStack.comment": "整理仓库时支持空潜影盒堆叠(请配合 PCA 使用)",
"ommc.config.feature_toggle.autoSwitchElytra.name": "自动切换鞘翅",
"ommc.config.feature_toggle.autoSwitchElytra.comment": "自动切换鞘翅和胸甲",
"ommc.config.feature_toggle.disableBreakBlock.name": "禁止破坏特定方块",
"ommc.config.feature_toggle.disableBreakBlock.comment": "玩家无法破坏在 §6破坏方块黑名单§r 中的方块",
"ommc.config.feature_toggle.disableBreakScaffolding.name": "禁止破坏脚手架",
Expand Down
4 changes: 2 additions & 2 deletions src/main/resources/ommc.compat.canvas.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
"package": "com.plusls.ommc.compat.canvas.mixin",
"plugin": "com.plusls.ommc.OmmcCompatMixinPlugin",
"client": [
"MixinBlockRenderContext",
"MixinLavaFluidModel",
"MixinTerrainRenderContext",
"MixinBlockRenderContext"
"MixinTerrainRenderContext"
]
}
1 change: 1 addition & 0 deletions src/main/resources/ommc.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"client": [
"advancedIntegratedServer.MixinIntegratedServer",
"advancedIntegratedServer.MixinOpenToLanScreen",
"feature.autoSwitchElytra.MixinClientPlayerEntity",
"feature.disableBreakBlock.MixinClientPlayerInteractionManager",
"feature.disableBreakScaffolding.MixinClientPlayerInteractionManager",
"feature.disableMoveDownInScaffolding.MixinScaffoldingBlock",
Expand Down

0 comments on commit c60470e

Please sign in to comment.