-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: middle mouse to select blocks in build mode
- Loading branch information
Showing
5 changed files
with
184 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
96 changes: 96 additions & 0 deletions
96
src/main/java/com/lovetropics/gamemodebuild/message/SetGamemodeBuildSlotPacket.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
package com.lovetropics.gamemodebuild.message; | ||
|
||
import com.lovetropics.gamemodebuild.GBConfigs; | ||
import com.lovetropics.gamemodebuild.GamemodeBuild; | ||
import com.lovetropics.gamemodebuild.container.BuildContainer; | ||
import com.lovetropics.gamemodebuild.state.GBPlayerStore; | ||
import com.lovetropics.gamemodebuild.state.GBServerState; | ||
import net.minecraft.core.BlockPos; | ||
import net.minecraft.core.RegistryAccess; | ||
import net.minecraft.core.component.DataComponents; | ||
import net.minecraft.network.RegistryFriendlyByteBuf; | ||
import net.minecraft.network.codec.ByteBufCodecs; | ||
import net.minecraft.network.codec.StreamCodec; | ||
import net.minecraft.network.protocol.PacketUtils; | ||
import net.minecraft.network.protocol.common.custom.CustomPacketPayload; | ||
import net.minecraft.network.protocol.game.ServerboundSetCreativeModeSlotPacket; | ||
import net.minecraft.server.level.ServerPlayer; | ||
import net.minecraft.world.SimpleMenuProvider; | ||
import net.minecraft.world.flag.FeatureFlagSet; | ||
import net.minecraft.world.item.ItemStack; | ||
import net.minecraft.world.item.component.CustomData; | ||
import net.minecraft.world.level.block.entity.BlockEntity; | ||
import net.neoforged.neoforge.network.handling.IPayloadContext; | ||
|
||
import java.util.List; | ||
|
||
public record SetGamemodeBuildSlotPacket(short slotNum, ItemStack itemStack) implements CustomPacketPayload { | ||
public static final Type<SetGamemodeBuildSlotPacket> TYPE = new Type<>(GamemodeBuild.rl("set_slot")); | ||
public static final StreamCodec<RegistryFriendlyByteBuf, SetGamemodeBuildSlotPacket> CODEC; | ||
static { | ||
CODEC = StreamCodec.composite(ByteBufCodecs.SHORT, SetGamemodeBuildSlotPacket::slotNum, ItemStack.validatedStreamCodec(ItemStack.OPTIONAL_STREAM_CODEC), SetGamemodeBuildSlotPacket::itemStack, SetGamemodeBuildSlotPacket::new); | ||
} | ||
|
||
public SetGamemodeBuildSlotPacket(short slotNum, ItemStack itemStack) { | ||
this.slotNum = slotNum; | ||
this.itemStack = itemStack; | ||
} | ||
|
||
public static void handle(SetGamemodeBuildSlotPacket packet, IPayloadContext ctx) { | ||
var player = ctx.player(); | ||
|
||
if (player instanceof ServerPlayer serverPlayer) { | ||
ctx.enqueueWork(() -> { | ||
if (GBServerState.isActiveFor(serverPlayer)) { | ||
ItemStack itemstack = packet.itemStack(); | ||
|
||
FeatureFlagSet featureFlags = player.level().enabledFeatures(); | ||
RegistryAccess registryAccess = player.level().registryAccess(); | ||
List<ItemStack> itemStacks = GBConfigs.SERVER.getFilter(GBPlayerStore.getList(player)).getAllStacks(featureFlags, registryAccess); | ||
|
||
if(!itemStacks.stream().anyMatch(stack -> stack.is(packet.itemStack.getItem()))) { | ||
player.inventoryMenu.setRemoteSlot(packet.slotNum, packet.itemStack); | ||
player.inventoryMenu.broadcastChanges(); | ||
return; | ||
} | ||
|
||
if (!itemstack.isItemEnabled(player.level().enabledFeatures())) { | ||
return; | ||
} | ||
|
||
CustomData customdata = itemstack.getOrDefault(DataComponents.BLOCK_ENTITY_DATA, CustomData.EMPTY); | ||
if (customdata.contains("x") && customdata.contains("y") && customdata.contains("z")) { | ||
BlockPos blockpos = BlockEntity.getPosFromTag(customdata.getUnsafe()); | ||
if (player.level().isLoaded(blockpos)) { | ||
BlockEntity blockentity = player.level().getBlockEntity(blockpos); | ||
if (blockentity != null) { | ||
blockentity.saveToItem(itemstack, player.level().registryAccess()); | ||
} | ||
} | ||
} | ||
|
||
boolean flag1 = packet.slotNum() >= 1 && packet.slotNum() <= 45; | ||
boolean flag2 = itemstack.isEmpty() || itemstack.getCount() <= itemstack.getMaxStackSize(); | ||
if (flag1 && flag2) { | ||
player.inventoryMenu.getSlot(packet.slotNum()).setByPlayer(itemstack); | ||
player.inventoryMenu.broadcastChanges(); | ||
} | ||
} | ||
}); | ||
} | ||
} | ||
|
||
@Override | ||
public Type<? extends CustomPacketPayload> type() { | ||
return TYPE; | ||
} | ||
|
||
|
||
public short slotNum() { | ||
return this.slotNum; | ||
} | ||
|
||
public ItemStack itemStack() { | ||
return this.itemStack; | ||
} | ||
} |
52 changes: 52 additions & 0 deletions
52
src/main/java/com/lovetropics/gamemodebuild/mixin/MinecraftMixin.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package com.lovetropics.gamemodebuild.mixin; | ||
|
||
import com.llamalad7.mixinextras.sugar.Local; | ||
import com.lovetropics.gamemodebuild.container.GBStackMarker; | ||
import com.lovetropics.gamemodebuild.state.GBClientState; | ||
import net.minecraft.client.Minecraft; | ||
import net.minecraft.client.gui.screens.Screen; | ||
import net.minecraft.client.player.LocalPlayer; | ||
import net.minecraft.world.item.ItemStack; | ||
import net.minecraft.world.phys.HitResult; | ||
import org.spongepowered.asm.mixin.Debug; | ||
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.ModifyVariable; | ||
import org.spongepowered.asm.mixin.injection.Redirect; | ||
|
||
import javax.annotation.Nullable; | ||
|
||
@Debug(export = true) | ||
@Mixin(Minecraft.class) | ||
public class MinecraftMixin { | ||
|
||
@Shadow @Nullable public LocalPlayer player; | ||
|
||
@ModifyVariable(method = "pickBlock", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/phys/HitResult;getType()Lnet/minecraft/world/phys/HitResult$Type;", shift = At.Shift.BY, by = 2)) | ||
private boolean flagInsta(boolean value, @Local(ordinal = 0) HitResult.Type type) { | ||
if(GBClientState.isActive() && type == HitResult.Type.BLOCK) { | ||
return true; | ||
} | ||
return value; | ||
} | ||
|
||
@ModifyVariable(method = "pickBlock", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/item/ItemStack;isEmpty()Z", ordinal = 0)) | ||
private ItemStack addTag(ItemStack itemStack) { | ||
if(GBClientState.isActive()) { | ||
GBStackMarker.mark(itemStack); | ||
} | ||
return itemStack; | ||
} | ||
|
||
@Redirect( | ||
method = "pickBlock", | ||
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/Screen;hasControlDown()Z") | ||
) | ||
private boolean redirectHasControlDown() { | ||
if(GBClientState.isActive()) { | ||
return false; | ||
} | ||
return Screen.hasControlDown(); | ||
} | ||
} |
26 changes: 26 additions & 0 deletions
26
src/main/java/com/lovetropics/gamemodebuild/mixin/MultiPlayerGameModeMixin.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package com.lovetropics.gamemodebuild.mixin; | ||
|
||
import com.lovetropics.gamemodebuild.message.SetGamemodeBuildSlotPacket; | ||
import com.lovetropics.gamemodebuild.state.GBClientState; | ||
import net.minecraft.client.multiplayer.MultiPlayerGameMode; | ||
import net.minecraft.world.item.ItemStack; | ||
import net.minecraft.world.level.GameType; | ||
import net.neoforged.neoforge.network.PacketDistributor; | ||
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(MultiPlayerGameMode.class) | ||
public class MultiPlayerGameModeMixin { | ||
|
||
@Shadow private GameType localPlayerMode; | ||
|
||
@Inject(method = "handleCreativeModeItemAdd", at = @At(value = "HEAD")) | ||
private void redirectIsCreative(ItemStack stack, int slotId, CallbackInfo ci) { | ||
if(this.localPlayerMode != GameType.CREATIVE && GBClientState.isActive()) { | ||
PacketDistributor.sendToServer(new SetGamemodeBuildSlotPacket((short) slotId, stack)); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters