mirror of
https://github.com/chylex/Hardcore-Ender-Expansion-2.git
synced 2025-04-11 03:15:44 +02:00
Allow opening Shulker Boxes without placing them down
This commit is contained in:
parent
8bdb13519a
commit
dedae0695b
src/main
java/chylex/hee
game
init
resources/assets/hee/lang
@ -0,0 +1,13 @@
|
||||
package chylex.hee.game.container
|
||||
import chylex.hee.game.container.util.DetectSlotChangeListener
|
||||
import chylex.hee.game.item.ItemShulkerBoxOverride
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.inventory.ContainerShulkerBox
|
||||
|
||||
class ContainerShulkerBoxInInventory(player: EntityPlayer, private val boxInventory: ItemShulkerBoxOverride.Inventory) : ContainerShulkerBox(player.inventory, boxInventory, player){
|
||||
private val slotChangeListener = DetectSlotChangeListener()
|
||||
|
||||
override fun detectAndSendChanges(){
|
||||
slotChangeListener.restart(listeners){ super.detectAndSendChanges() }?.let(boxInventory::validatePlayerItemOnModification)
|
||||
}
|
||||
}
|
175
src/main/java/chylex/hee/game/item/ItemShulkerBoxOverride.kt
Normal file
175
src/main/java/chylex/hee/game/item/ItemShulkerBoxOverride.kt
Normal file
@ -0,0 +1,175 @@
|
||||
package chylex.hee.game.item
|
||||
import chylex.hee.HEE
|
||||
import chylex.hee.client.util.MC
|
||||
import chylex.hee.game.container.base.IInventoryFromPlayerItem
|
||||
import chylex.hee.init.ModGuiHandler.GuiType.SHULKER_BOX
|
||||
import chylex.hee.network.server.PacketServerOpenGui
|
||||
import chylex.hee.system.util.allSlots
|
||||
import chylex.hee.system.util.getCompoundOrNull
|
||||
import chylex.hee.system.util.getStack
|
||||
import chylex.hee.system.util.isNotEmpty
|
||||
import chylex.hee.system.util.nbt
|
||||
import chylex.hee.system.util.nbtOrNull
|
||||
import chylex.hee.system.util.nonEmptySlots
|
||||
import chylex.hee.system.util.setStack
|
||||
import chylex.hee.system.util.size
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap
|
||||
import net.minecraft.block.Block
|
||||
import net.minecraft.client.gui.GuiScreen
|
||||
import net.minecraft.client.gui.inventory.GuiInventory
|
||||
import net.minecraft.client.resources.I18n
|
||||
import net.minecraft.client.util.ITooltipFlag
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.inventory.InventoryBasic
|
||||
import net.minecraft.inventory.ItemStackHelper
|
||||
import net.minecraft.item.ItemShulkerBox
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.util.ActionResult
|
||||
import net.minecraft.util.EnumActionResult.PASS
|
||||
import net.minecraft.util.EnumActionResult.SUCCESS
|
||||
import net.minecraft.util.EnumHand
|
||||
import net.minecraft.util.NonNullList
|
||||
import net.minecraft.util.text.TextFormatting
|
||||
import net.minecraft.world.World
|
||||
import net.minecraftforge.client.event.GuiScreenEvent
|
||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber
|
||||
import net.minecraftforge.fml.common.eventhandler.EventPriority.LOWEST
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
|
||||
import net.minecraftforge.fml.relauncher.Side
|
||||
import net.minecraftforge.fml.relauncher.SideOnly
|
||||
import org.lwjgl.input.Mouse
|
||||
|
||||
class ItemShulkerBoxOverride(block: Block) : ItemShulkerBox(block){
|
||||
private companion object{
|
||||
private const val TILE_ENTITY_TAG = "BlockEntityTag"
|
||||
private const val TOOLTIP_ENTRY_COUNT = 5
|
||||
|
||||
private fun isStackValid(stack: ItemStack): Boolean{
|
||||
return stack.item is ItemShulkerBoxOverride
|
||||
}
|
||||
}
|
||||
|
||||
enum class BoxSize(val slots: Int){
|
||||
LARGE(27)
|
||||
}
|
||||
|
||||
class Inventory(override val player: EntityPlayer, private val inventorySlot: Int) : InventoryBasic("", false, BoxSize.LARGE.slots), IInventoryFromPlayerItem{
|
||||
private val boxStack
|
||||
get() = player.inventory.getStack(inventorySlot)
|
||||
|
||||
init{
|
||||
val boxStack = boxStack
|
||||
|
||||
if (isStackValid(boxStack)){
|
||||
NonNullList.withSize(size, ItemStack.EMPTY).also {
|
||||
ItemStackHelper.loadAllItems(boxStack.nbt.getCompoundTag(TILE_ENTITY_TAG), it)
|
||||
it.forEachIndexed(::setStack)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun tryUpdatePlayerItem(): Boolean{
|
||||
val boxStack = boxStack
|
||||
|
||||
if (!isStackValid(boxStack)){
|
||||
return false
|
||||
}
|
||||
|
||||
NonNullList.withSize(size, ItemStack.EMPTY).also {
|
||||
for((slot, stack) in allSlots){
|
||||
it[slot] = stack
|
||||
}
|
||||
|
||||
ItemStackHelper.saveAllItems(boxStack.nbt.getCompoundTag(TILE_ENTITY_TAG), it)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun getName(): String{
|
||||
return boxStack.let { if (it.hasDisplayName()) it.displayName else "${it.translationKey}.name" }
|
||||
}
|
||||
|
||||
override fun hasCustomName(): Boolean{
|
||||
return boxStack.hasDisplayName()
|
||||
}
|
||||
}
|
||||
|
||||
// Use handling
|
||||
|
||||
override fun onItemRightClick(world: World, player: EntityPlayer, hand: EnumHand): ActionResult<ItemStack>{
|
||||
val stack = player.getHeldItem(hand)
|
||||
val slot = player.inventory.nonEmptySlots.asSequence().find { it.stack === stack }
|
||||
|
||||
if (slot == null){
|
||||
return ActionResult(PASS, stack)
|
||||
}
|
||||
|
||||
SHULKER_BOX.open(player, slot.slot) // TODO it'd be pretty funny if the open animation was shown in inventory/held model but holy shit effort
|
||||
return ActionResult(SUCCESS, stack)
|
||||
}
|
||||
|
||||
// Client side
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
@EventBusSubscriber(Side.CLIENT, modid = HEE.ID)
|
||||
object EventHandler{
|
||||
@JvmStatic
|
||||
@SubscribeEvent(priority = LOWEST)
|
||||
fun onMouseInputPre(e: GuiScreenEvent.MouseInputEvent.Pre){
|
||||
val gui = e.gui
|
||||
|
||||
if (gui is GuiInventory && Mouse.getEventButton() == 1 && Mouse.getEventButtonState() && !GuiScreen.isShiftKeyDown()){
|
||||
val hoveredSlot = gui.slotUnderMouse
|
||||
|
||||
if (hoveredSlot != null && isStackValid(hoveredSlot.stack)){
|
||||
PacketServerOpenGui(SHULKER_BOX, hoveredSlot.slotIndex).sendToServer()
|
||||
e.isCanceled = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun shouldCauseReequipAnimation(oldStack: ItemStack, newStack: ItemStack, slotChanged: Boolean): Boolean{
|
||||
return slotChanged && super.shouldCauseReequipAnimation(oldStack, newStack, slotChanged)
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
override fun addInformation(stack: ItemStack, world: World?, lines: MutableList<String>, flags: ITooltipFlag){
|
||||
if (MC.currentScreen is GuiInventory){
|
||||
lines.add(I18n.format("item.hee.shulker_box.tooltip"))
|
||||
lines.add("")
|
||||
}
|
||||
|
||||
val contentsTag = stack.nbtOrNull?.getCompoundOrNull(TILE_ENTITY_TAG)
|
||||
|
||||
if (contentsTag != null){
|
||||
val inventory = NonNullList.withSize(BoxSize.LARGE.slots, ItemStack.EMPTY)
|
||||
ItemStackHelper.loadAllItems(contentsTag, inventory)
|
||||
|
||||
if (inventory.any { it.isNotEmpty }){
|
||||
val counts = Object2IntOpenHashMap<String>()
|
||||
|
||||
for(invStack in inventory){
|
||||
if (invStack.isNotEmpty){
|
||||
counts.addTo(invStack.displayName, invStack.count)
|
||||
}
|
||||
}
|
||||
|
||||
val sorted = counts.entries.sortedWith(compareBy({ -it.value }, { it.key }))
|
||||
|
||||
for((name, count) in sorted.take(TOOLTIP_ENTRY_COUNT)){
|
||||
lines.add("%s x%d".format(name, count))
|
||||
}
|
||||
|
||||
if (sorted.size > TOOLTIP_ENTRY_COUNT){
|
||||
lines.add("${TextFormatting.ITALIC}${I18n.format("container.shulkerBox.more", sorted.size - TOOLTIP_ENTRY_COUNT)}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lines.lastOrNull()?.isEmpty() == true){
|
||||
lines.removeAt(lines.lastIndex)
|
||||
}
|
||||
}
|
||||
}
|
@ -12,9 +12,12 @@ import chylex.hee.game.container.ContainerAmuletOfRecovery
|
||||
import chylex.hee.game.container.ContainerBrewingStandCustom
|
||||
import chylex.hee.game.container.ContainerLootChest
|
||||
import chylex.hee.game.container.ContainerPortalTokenStorage
|
||||
import chylex.hee.game.container.ContainerShulkerBoxInInventory
|
||||
import chylex.hee.game.container.ContainerTrinketPouch
|
||||
import chylex.hee.game.item.ItemShulkerBoxOverride
|
||||
import chylex.hee.system.util.Pos
|
||||
import chylex.hee.system.util.getTile
|
||||
import net.minecraft.client.gui.inventory.GuiShulkerBox
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.tileentity.TileEntity
|
||||
import net.minecraft.util.EnumHand
|
||||
@ -38,6 +41,11 @@ object ModGuiHandler : IGuiHandler{
|
||||
createContainer = { player, hand, _, _ -> ContainerAmuletOfRecovery(player, EnumHand.values()[hand]) }
|
||||
),
|
||||
|
||||
SHULKER_BOX(
|
||||
createInterface = { player, slot, _, _ -> GuiShulkerBox(player.inventory, ItemShulkerBoxOverride.Inventory(player, slot)) },
|
||||
createContainer = { player, slot, _, _ -> ContainerShulkerBoxInInventory(player, ItemShulkerBoxOverride.Inventory(player, slot)) }
|
||||
),
|
||||
|
||||
TRINKET_POUCH(
|
||||
createInterface = { player, slot, _, _ -> GuiTrinketPouch(player, slot) },
|
||||
createContainer = { player, slot, _, _ -> ContainerTrinketPouch(player, slot) }
|
||||
|
@ -22,6 +22,7 @@ import chylex.hee.game.item.ItemRingOfPreservation
|
||||
import chylex.hee.game.item.ItemScaleOfFreefall
|
||||
import chylex.hee.game.item.ItemScorchingSword
|
||||
import chylex.hee.game.item.ItemScorchingTool
|
||||
import chylex.hee.game.item.ItemShulkerBoxOverride
|
||||
import chylex.hee.game.item.ItemSpatialDashGem
|
||||
import chylex.hee.game.item.ItemTableLink
|
||||
import chylex.hee.game.item.ItemTalismanOfGriefing
|
||||
@ -37,8 +38,10 @@ import chylex.hee.game.item.util.Tool.Type.SHOVEL
|
||||
import chylex.hee.init.ModCreativeTabs.OrderedCreativeTab
|
||||
import chylex.hee.system.Resource
|
||||
import chylex.hee.system.util.useVanillaName
|
||||
import net.minecraft.block.BlockShulkerBox
|
||||
import net.minecraft.creativetab.CreativeTabs
|
||||
import net.minecraft.init.Items
|
||||
import net.minecraft.item.EnumDyeColor
|
||||
import net.minecraft.item.Item
|
||||
import net.minecraftforge.event.RegistryEvent
|
||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber
|
||||
@ -196,6 +199,11 @@ object ModItems{
|
||||
register(ItemElytraOverride().apply { override(Items.ELYTRA) })
|
||||
register(ItemEyeOfEnderOverride().apply { override(Items.ENDER_EYE) })
|
||||
register(ItemTotemOfUndyingOverride().apply { override(Items.TOTEM_OF_UNDYING, newCreativeTab = null) })
|
||||
|
||||
for(color in EnumDyeColor.values()){
|
||||
val box = BlockShulkerBox.getBlockByColor(color)
|
||||
register(ItemShulkerBoxOverride(box).apply { override(Item.getItemFromBlock(box)) })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -162,6 +162,7 @@ item.hee.talisman_of_griefing.name=Talisman of Griefing
|
||||
item.hee.scale_of_freefall.name=Scale of Freefall
|
||||
|
||||
item.hee.chorus_berry.name=Chorus Berry
|
||||
item.hee.shulker_box.tooltip=Right-click to open
|
||||
|
||||
item.tooltip.hee.energy.level=§9Energy: §3%s§9 / §3%s
|
||||
item.tooltip.hee.energy.uses=§9Uses Left: §3%s
|
||||
|
Loading…
Reference in New Issue
Block a user