diff --git a/src/main/java/dev/hephaestus/glowcase/Glowcase.java b/src/main/java/dev/hephaestus/glowcase/Glowcase.java index 986ee86c..b9c70579 100644 --- a/src/main/java/dev/hephaestus/glowcase/Glowcase.java +++ b/src/main/java/dev/hephaestus/glowcase/Glowcase.java @@ -13,6 +13,7 @@ import dev.hephaestus.glowcase.block.entity.SpriteBlockEntity; import dev.hephaestus.glowcase.block.entity.TextBlockEntity; import dev.hephaestus.glowcase.compat.PolydexCompatibility; +import dev.hephaestus.glowcase.item.LockItem; import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroup; import net.fabricmc.loader.api.FabricLoader; @@ -58,6 +59,8 @@ public class Glowcase implements ModInitializer { public static final Supplier SPRITE_BLOCK_ITEM = registerItem("sprite_block", () -> new BlockItem(SPRITE_BLOCK.get(), new Item.Settings())); public static final Supplier> SPRITE_BLOCK_ENTITY = registerBlockEntity("sprite_block", () -> BlockEntityType.Builder.create(SpriteBlockEntity::new, SPRITE_BLOCK.get()).build(null)); + public static final Supplier LOCK_ITEM = registerItem("lock", () -> new LockItem(new Item.Settings())); + public static final Supplier ITEM_GROUP = registerItemGroup("items", () -> FabricItemGroup.builder() .displayName(Text.translatable("itemGroup.glowcase.items")) .icon(() -> new ItemStack(Items.GLOWSTONE)) @@ -67,6 +70,7 @@ public class Glowcase implements ModInitializer { entries.add(TEXT_BLOCK_ITEM.get()); entries.add(POPUP_BLOCK_ITEM.get()); entries.add(SPRITE_BLOCK_ITEM.get()); + entries.add(LOCK_ITEM.get()); }) .build() ); diff --git a/src/main/java/dev/hephaestus/glowcase/item/LockItem.java b/src/main/java/dev/hephaestus/glowcase/item/LockItem.java new file mode 100644 index 00000000..f30487f1 --- /dev/null +++ b/src/main/java/dev/hephaestus/glowcase/item/LockItem.java @@ -0,0 +1,62 @@ +package dev.hephaestus.glowcase.item; + +import dev.hephaestus.glowcase.mixin.LockableContainerBlockEntityAccessor; +import net.minecraft.block.entity.LockableContainerBlockEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.inventory.ContainerLock; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.item.ItemUsageContext; +import net.minecraft.item.tooltip.TooltipType; +import net.minecraft.sound.SoundCategory; +import net.minecraft.sound.SoundEvent; +import net.minecraft.sound.SoundEvents; +import net.minecraft.text.Text; +import net.minecraft.util.ActionResult; +import net.minecraft.util.Formatting; +import net.minecraft.world.World; + +import java.util.List; + +public class LockItem extends Item { + public LockItem(Settings settings) { + super(settings); + } + + @Override + public ActionResult useOnBlock(ItemUsageContext context) { + World world = context.getWorld(); + PlayerEntity player = context.getPlayer(); + if (world.isClient || + player == null || + !player.isCreative() || + !(world.getBlockEntity(context.getBlockPos()) instanceof LockableContainerBlockEntity be)) { + return ActionResult.PASS; + } + + var bea = (LockableContainerBlockEntityAccessor) be; + Text message; + SoundEvent soundEvent; + + if (bea.getLock().equals(ContainerLock.EMPTY)) { + bea.setLock(new ContainerLock("glowcase")); + message = Text.translatable("gui.glowcase.locked_block", be.getDisplayName()); + soundEvent = SoundEvents.BLOCK_WOODEN_TRAPDOOR_CLOSE; + } else { + bea.setLock(ContainerLock.EMPTY); + message = Text.translatable("gui.glowcase.unlocked_block", be.getDisplayName()); + soundEvent = SoundEvents.BLOCK_WOODEN_TRAPDOOR_OPEN; + } + + player.sendMessage(message, true); + player.playSoundToPlayer(soundEvent, SoundCategory.BLOCKS, 1.0F, 1.0F); + be.markDirty(); + + return ActionResult.SUCCESS; + } + + @Override + public void appendTooltip(ItemStack itemStack, Item.TooltipContext context, List tooltip, TooltipType options) { + tooltip.add(Text.translatable("item.glowcase.lock.tooltip.0").formatted(Formatting.GRAY)); + } +} diff --git a/src/main/java/dev/hephaestus/glowcase/mixin/LockableContainerBlockEntityAccessor.java b/src/main/java/dev/hephaestus/glowcase/mixin/LockableContainerBlockEntityAccessor.java new file mode 100644 index 00000000..8b95c099 --- /dev/null +++ b/src/main/java/dev/hephaestus/glowcase/mixin/LockableContainerBlockEntityAccessor.java @@ -0,0 +1,15 @@ +package dev.hephaestus.glowcase.mixin; + +import net.minecraft.block.entity.LockableContainerBlockEntity; +import net.minecraft.inventory.ContainerLock; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(LockableContainerBlockEntity.class) +public interface LockableContainerBlockEntityAccessor { + @Accessor + ContainerLock getLock(); + + @Accessor + void setLock(ContainerLock lock); +} diff --git a/src/main/java/dev/hephaestus/glowcase/mixin/PlayerEntityMixin.java b/src/main/java/dev/hephaestus/glowcase/mixin/PlayerEntityMixin.java new file mode 100644 index 00000000..5d2879c8 --- /dev/null +++ b/src/main/java/dev/hephaestus/glowcase/mixin/PlayerEntityMixin.java @@ -0,0 +1,24 @@ +package dev.hephaestus.glowcase.mixin; + +import com.llamalad7.mixinextras.injector.ModifyReturnValue; +import dev.hephaestus.glowcase.Glowcase; +import net.minecraft.entity.EquipmentSlot; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(PlayerEntity.class) +public abstract class PlayerEntityMixin { + @Shadow + public abstract ItemStack getEquippedStack(EquipmentSlot slot); + + @ModifyReturnValue( + method = "shouldCancelInteraction", + at = @At(value = "RETURN") + ) + private boolean directLockInteraction(boolean original) { + return getEquippedStack(EquipmentSlot.MAINHAND).getItem().equals(Glowcase.LOCK_ITEM.get()) || original; + } +} diff --git a/src/main/resources/assets/glowcase/lang/en_us.json b/src/main/resources/assets/glowcase/lang/en_us.json index ef5ff021..84c8cecc 100644 --- a/src/main/resources/assets/glowcase/lang/en_us.json +++ b/src/main/resources/assets/glowcase/lang/en_us.json @@ -15,6 +15,9 @@ "gui.glowcase.none": "(None)", "item.glowcase.text_block": "Text Block", "item.glowcase.hyperlink_block": "Hyperlink Block", + "item.glowcase.lock": "Lock", + "gui.glowcase.locked_block": "%s is now locked \uD83D\uDD12", + "gui.glowcase.unlocked_block": "%s is now unlocked \uD83D\uDD13", "gui.glowcase.title": "Title", "gui.glowcase.url": "URL", "block.glowcase.generic.tooltip": "Interact with a glowcase item to edit", @@ -27,5 +30,6 @@ "block.glowcase.popup_block.tooltip.0": "Displays formatted text when interacted", "block.glowcase.popup_block.tooltip.1": "Supports Placeholder QuickText", "block.glowcase.sprite_block.tooltip.0": "Displays a sprite", - "block.glowcase.sprite_block.tooltip.1": "Can be extended with resource packs" + "block.glowcase.sprite_block.tooltip.1": "Can be extended with resource packs", + "item.glowcase.lock.tooltip.0": "Locks and unlocks containers" } diff --git a/src/main/resources/assets/glowcase/models/item/lock.json b/src/main/resources/assets/glowcase/models/item/lock.json new file mode 100644 index 00000000..1467ebc1 --- /dev/null +++ b/src/main/resources/assets/glowcase/models/item/lock.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "glowcase:item/lock" + } +} diff --git a/src/main/resources/assets/glowcase/textures/item/lock.png b/src/main/resources/assets/glowcase/textures/item/lock.png new file mode 100644 index 00000000..d69f1e30 Binary files /dev/null and b/src/main/resources/assets/glowcase/textures/item/lock.png differ diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 6aa5b52a..0c0ad98e 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -17,6 +17,9 @@ }, "license": "${license}", "icon": "assets/${modId}/icon.png", + "mixins": [ + "${modId}.mixins.json" + ], "depends": { "minecraft": ">=${mc}", "fabricloader": ">=${fl}", diff --git a/src/main/resources/glowcase.mixins.json b/src/main/resources/glowcase.mixins.json new file mode 100644 index 00000000..bf5db56e --- /dev/null +++ b/src/main/resources/glowcase.mixins.json @@ -0,0 +1,15 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "dev.hephaestus.glowcase.mixin", + "compatibilityLevel": "JAVA_21", + "mixins": [ + "LockableContainerBlockEntityAccessor", + "PlayerEntityMixin" + ], + "client": [], + "server": [], + "injectors": { + "defaultRequire": 1 + } +}