diff --git a/src/main/java/wayoftime/bloodmagic/BloodMagic.java b/src/main/java/wayoftime/bloodmagic/BloodMagic.java index 46d3432b..e4575033 100644 --- a/src/main/java/wayoftime/bloodmagic/BloodMagic.java +++ b/src/main/java/wayoftime/bloodmagic/BloodMagic.java @@ -36,6 +36,8 @@ import net.minecraftforge.fml.event.server.FMLServerStartingEvent; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import wayoftime.bloodmagic.client.ClientEvents; import wayoftime.bloodmagic.client.hud.Elements; +import wayoftime.bloodmagic.client.key.BloodMagicKeyHandler; +import wayoftime.bloodmagic.client.key.KeyBindings; import wayoftime.bloodmagic.client.model.MimicModelLoader; import wayoftime.bloodmagic.common.block.BloodMagicBlocks; import wayoftime.bloodmagic.common.data.GeneratorBaseRecipes; @@ -249,6 +251,8 @@ public class BloodMagic ClientEvents.initClientEvents(event); Elements.registerElements(); MinecraftForge.EVENT_BUS.register(new ClientEvents()); + KeyBindings.initializeKeys(); + new BloodMagicKeyHandler(); // IEventBus modBus = FMLJavaModLoadingContext.get().getModEventBus(); // @@ -306,4 +310,5 @@ public class BloodMagic return new ItemStack(BloodMagicBlocks.BLOOD_ALTAR.get()); } }; + public static final String NAME = "Blood Magic: Alchemical Wizardry"; } diff --git a/src/main/java/wayoftime/bloodmagic/client/key/BloodMagicKeyHandler.java b/src/main/java/wayoftime/bloodmagic/client/key/BloodMagicKeyHandler.java new file mode 100644 index 00000000..f3b2ab92 --- /dev/null +++ b/src/main/java/wayoftime/bloodmagic/client/key/BloodMagicKeyHandler.java @@ -0,0 +1,82 @@ +package wayoftime.bloodmagic.client.key; + +import java.util.BitSet; + +import org.lwjgl.glfw.GLFW; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.settings.KeyBinding; +import net.minecraft.client.util.InputMappings; +import net.minecraftforge.client.event.InputEvent; +import net.minecraftforge.common.MinecraftForge; + +public class BloodMagicKeyHandler +{ + + private final BitSet keyDown; + + private final BitSet repeatings; + + public BloodMagicKeyHandler() + { + this.keyDown = new BitSet(); + this.repeatings = new BitSet(); + MinecraftForge.EVENT_BUS.addListener(this::keyTick); + } + + public static boolean isKeyDown(KeyBinding keyBinding) + { + InputMappings.Input key = keyBinding.getKey(); + int keyCode = key.getKeyCode(); + if (keyCode != InputMappings.INPUT_INVALID.getKeyCode()) + { + long windowHandle = Minecraft.getInstance().getMainWindow().getHandle(); + try + { + if (key.getType() == InputMappings.Type.KEYSYM) + { + return InputMappings.isKeyDown(windowHandle, keyCode); + } else if (key.getType() == InputMappings.Type.MOUSE) + { + return GLFW.glfwGetMouseButton(windowHandle, keyCode) == GLFW.GLFW_PRESS; + } + } catch (Exception ignored) + { + } + } + return false; + } + + public void keyTick(InputEvent.KeyInputEvent event) + { +// System.out.println("Pressing the key handlers"); + for (int i = 0; i < KeyBindings.values().length; i++) + { + KeyBindings keyBindings = KeyBindings.values()[i]; + KeyBinding keyBinding = keyBindings.getKey(); + boolean state = keyBinding.isKeyDown(); + boolean lastState = keyDown.get(i); + if (state != lastState || (state && repeatings.get(i))) + { + if (state) + { + keyDown(keyBindings, lastState); + } else + { + keyUp(keyBindings); + } + keyDown.set(i, state); + } + } + } + + public void keyDown(KeyBindings kb, boolean isRepeat) + { + kb.handleKeybind(); + } + + public void keyUp(KeyBindings kb) + { + + } +} diff --git a/src/main/java/wayoftime/bloodmagic/client/key/IKeybindable.java b/src/main/java/wayoftime/bloodmagic/client/key/IKeybindable.java new file mode 100644 index 00000000..35eddcd0 --- /dev/null +++ b/src/main/java/wayoftime/bloodmagic/client/key/IKeybindable.java @@ -0,0 +1,9 @@ +package wayoftime.bloodmagic.client.key; + +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; + +public interface IKeybindable +{ + void onKeyPressed(ItemStack stack, PlayerEntity player, KeyBindings key, boolean showInChat); +} diff --git a/src/main/java/wayoftime/bloodmagic/client/key/KeyBindingBloodMagic.java b/src/main/java/wayoftime/bloodmagic/client/key/KeyBindingBloodMagic.java new file mode 100644 index 00000000..b48666a1 --- /dev/null +++ b/src/main/java/wayoftime/bloodmagic/client/key/KeyBindingBloodMagic.java @@ -0,0 +1,17 @@ +package wayoftime.bloodmagic.client.key; + +import net.minecraft.client.settings.KeyBinding; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.fml.client.registry.ClientRegistry; + +@OnlyIn(Dist.CLIENT) +public class KeyBindingBloodMagic extends KeyBinding +{ + public KeyBindingBloodMagic(KeyBindings key) + { + super(key.getDescription(), -1, "key.bloodmagic.category"); + + ClientRegistry.registerKeyBinding(this); + } +} diff --git a/src/main/java/wayoftime/bloodmagic/client/key/KeyBindings.java b/src/main/java/wayoftime/bloodmagic/client/key/KeyBindings.java new file mode 100644 index 00000000..fe6c0224 --- /dev/null +++ b/src/main/java/wayoftime/bloodmagic/client/key/KeyBindings.java @@ -0,0 +1,110 @@ +package wayoftime.bloodmagic.client.key; + +import java.util.Locale; + +import net.minecraft.client.settings.KeyBinding; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.client.settings.IKeyConflictContext; +import net.minecraftforge.client.settings.KeyConflictContext; +import net.minecraftforge.client.settings.KeyModifier; +import wayoftime.bloodmagic.BloodMagic; +import wayoftime.bloodmagic.network.KeyProcessorPacket; + +public enum KeyBindings +{ + // @formatter:off + OPEN_HOLDING(KeyConflictContext.IN_GAME, KeyModifier.NONE, -1) + { + @OnlyIn(Dist.CLIENT) + @Override + public void handleKeybind() + { + BloodMagic.packetHandler.sendToServer(new KeyProcessorPacket(this.ordinal(), false)); + System.out.println("I is on the client."); +// ItemStack itemStack = ClientHandler.minecraft.player.getHeldItemMainhand(); +// if (itemStack.getItem() instanceof IKeybindable) +// BloodMagicPacketHandler.INSTANCE.sendToServer(new KeyProcessorPacket(this, false)); + } + }, + CYCLE_HOLDING_POS(KeyConflictContext.IN_GAME, KeyModifier.SHIFT, -1) + { + @OnlyIn(Dist.CLIENT) + @Override + public void handleKeybind() + { +// ClientPlayerEntity player = Minecraft.getInstance().player; +// if (player.getHeldItemMainhand().getItem() instanceof ItemSigilHolding) +// ClientHandler.cycleSigil(player.getHeldItemMainhand(), player, -1); + } + }, + CYCLE_HOLDING_NEG(KeyConflictContext.IN_GAME, KeyModifier.SHIFT, -1) + { + @OnlyIn(Dist.CLIENT) + @Override + public void handleKeybind() + { +// ClientPlayerEntity player = Minecraft.getInstance().player; +// if (player.getHeldItemMainhand().getItem() instanceof ItemSigilHolding) +// ClientHandler.cycleSigil(player.getHeldItemMainhand(), player, 1); + } + },; + // @formatter:on + + private final IKeyConflictContext keyConflictContext; + private final KeyModifier keyModifier; + private final int keyCode; + + @OnlyIn(Dist.CLIENT) + private KeyBinding key; + + KeyBindings(IKeyConflictContext keyConflictContext, KeyModifier keyModifier, int keyCode) + { + this.keyConflictContext = keyConflictContext; + this.keyModifier = keyModifier; + this.keyCode = keyCode; + } + + @OnlyIn(Dist.CLIENT) + public abstract void handleKeybind(); + + public IKeyConflictContext getKeyConflictContext() + { + return keyConflictContext; + } + + public KeyModifier getKeyModifier() + { + return keyModifier; + } + + public int getKeyCode() + { + return keyCode; + } + + @OnlyIn(Dist.CLIENT) + public KeyBinding getKey() + { + if (key == null) + key = new KeyBindingBloodMagic(this); + + return key; + } + + @OnlyIn(Dist.CLIENT) + public void setKey(KeyBinding key) + { + this.key = key; + } + + public String getDescription() + { + return BloodMagic.MODID + ".keybind." + name().toLowerCase(Locale.ENGLISH); + } + + public static void initializeKeys() + { + OPEN_HOLDING.getKey(); + } +} \ No newline at end of file diff --git a/src/main/java/wayoftime/bloodmagic/common/block/BloodMagicBlocks.java b/src/main/java/wayoftime/bloodmagic/common/block/BloodMagicBlocks.java index 120ebb55..5c9101e0 100644 --- a/src/main/java/wayoftime/bloodmagic/common/block/BloodMagicBlocks.java +++ b/src/main/java/wayoftime/bloodmagic/common/block/BloodMagicBlocks.java @@ -33,6 +33,7 @@ import wayoftime.bloodmagic.api.compat.EnumDemonWillType; import wayoftime.bloodmagic.block.enums.BloodRuneType; import wayoftime.bloodmagic.common.block.base.BlockPillarCap; import wayoftime.bloodmagic.common.item.BloodMagicItems; +import wayoftime.bloodmagic.common.item.inventory.ContainerHolding; import wayoftime.bloodmagic.ritual.EnumRuneType; import wayoftime.bloodmagic.tile.container.ContainerAlchemicalReactionChamber; import wayoftime.bloodmagic.tile.container.ContainerAlchemyTable; @@ -131,6 +132,7 @@ public class BloodMagicBlocks public static final RegistryObject> SOUL_FORGE_CONTAINER = CONTAINERS.register("soul_forge_container", () -> IForgeContainerType.create(ContainerSoulForge::new)); public static final RegistryObject> ARC_CONTAINER = CONTAINERS.register("arc_container", () -> IForgeContainerType.create(ContainerAlchemicalReactionChamber::new)); public static final RegistryObject> ALCHEMY_TABLE_CONTAINER = CONTAINERS.register("alchemy_table_container", () -> IForgeContainerType.create(ContainerAlchemyTable::new)); + public static final RegistryObject> HOLDING_CONTAINER = CONTAINERS.register("holding_container", () -> IForgeContainerType.create(ContainerHolding::new)); // Dungeon Blocks public static final RegistryObject DUNGEON_BRICK_1 = DUNGEONBLOCKS.register("dungeon_brick1", () -> new Block(Properties.create(Material.ROCK).hardnessAndResistance(2.0F, 5.0F).sound(SoundType.STONE).harvestTool(ToolType.PICKAXE).harvestLevel(2).setRequiresTool())); diff --git a/src/main/java/wayoftime/bloodmagic/common/item/inventory/ContainerHolding.java b/src/main/java/wayoftime/bloodmagic/common/item/inventory/ContainerHolding.java new file mode 100644 index 00000000..3e207e89 --- /dev/null +++ b/src/main/java/wayoftime/bloodmagic/common/item/inventory/ContainerHolding.java @@ -0,0 +1,202 @@ +package wayoftime.bloodmagic.common.item.inventory; + +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.container.Container; +import net.minecraft.inventory.container.Slot; +import net.minecraft.item.ItemStack; +import net.minecraft.network.PacketBuffer; +import net.minecraftforge.fml.common.thread.EffectiveSide; +import wayoftime.bloodmagic.common.block.BloodMagicBlocks; +import wayoftime.bloodmagic.common.item.sigil.ISigil; +import wayoftime.bloodmagic.common.item.sigil.ItemSigilHolding; + +public class ContainerHolding extends Container +{ + public final InventoryHolding inventoryHolding; + private final int PLAYER_INVENTORY_ROWS = 3; + private final int PLAYER_INVENTORY_COLUMNS = 9; + private final PlayerEntity player; + + public ContainerHolding(int windowId, PlayerInventory playerInventory, PacketBuffer extraData) + { + this(windowId, playerInventory.player, playerInventory, new InventoryHolding(extraData.readItemStack())); + } + + public ContainerHolding(int windowId, PlayerEntity player, PlayerInventory playerInventory, InventoryHolding inventoryHolding) + { + super(BloodMagicBlocks.HOLDING_CONTAINER.get(), windowId); + this.player = player; + this.inventoryHolding = inventoryHolding; + int currentSlotHeldIn = player.inventory.currentItem; + this.setup(playerInventory, currentSlotHeldIn); + } + + public void setup(PlayerInventory inventory, int currentSlotHeldIn) + { + for (int columnIndex = 0; columnIndex < ItemSigilHolding.inventorySize; ++columnIndex) + { + this.addSlot(new SlotHolding(this, inventoryHolding, player, columnIndex, 8 + columnIndex * 36, 17)); + } + + for (int rowIndex = 0; rowIndex < PLAYER_INVENTORY_ROWS; ++rowIndex) + { + for (int columnIndex = 0; columnIndex < PLAYER_INVENTORY_COLUMNS; ++columnIndex) + { + this.addSlot(new Slot(player.inventory, columnIndex + rowIndex * 9 + 9, 8 + columnIndex * 18, 41 + rowIndex * 18)); + } + } + + for (int actionBarIndex = 0; actionBarIndex < PLAYER_INVENTORY_COLUMNS; ++actionBarIndex) + { + if (actionBarIndex == currentSlotHeldIn) + { + this.addSlot(new SlotDisabled(player.inventory, actionBarIndex, 8 + actionBarIndex * 18, 99)); + } else + { + this.addSlot(new Slot(player.inventory, actionBarIndex, 8 + actionBarIndex * 18, 99)); + } + } + } + + @Override + public boolean canInteractWith(PlayerEntity entityPlayer) + { + return true; + } + + @Override + public void onContainerClosed(PlayerEntity entityPlayer) + { + super.onContainerClosed(entityPlayer); + + if (!entityPlayer.getEntityWorld().isRemote) + { + saveInventory(entityPlayer); + } + } + + @Override + public void detectAndSendChanges() + { + super.detectAndSendChanges(); + + if (!player.getEntityWorld().isRemote) + { + saveInventory(player); + } + } + + @Override + public ItemStack transferStackInSlot(PlayerEntity entityPlayer, int slotIndex) + { + ItemStack stack = ItemStack.EMPTY; + Slot slotObject = inventorySlots.get(slotIndex); + int slots = inventorySlots.size(); + + if (slotObject != null && slotObject.getHasStack()) + { + ItemStack stackInSlot = slotObject.getStack(); + stack = stackInSlot.copy(); + + if (stack.getItem() instanceof ISigil) + { + if (slotIndex < ItemSigilHolding.inventorySize) + { + if (!this.mergeItemStack(stackInSlot, ItemSigilHolding.inventorySize, slots, false)) + { + return ItemStack.EMPTY; + } + } else if (!this.mergeItemStack(stackInSlot, 0, ItemSigilHolding.inventorySize, false)) + { + return ItemStack.EMPTY; + } + } else if (stack.getItem() instanceof ItemSigilHolding) + { + if (slotIndex < ItemSigilHolding.inventorySize + (PLAYER_INVENTORY_ROWS * PLAYER_INVENTORY_COLUMNS)) + { + if (!this.mergeItemStack(stackInSlot, ItemSigilHolding.inventorySize + (PLAYER_INVENTORY_ROWS * PLAYER_INVENTORY_COLUMNS), inventorySlots.size(), false)) + { + return ItemStack.EMPTY; + } + } else if (!this.mergeItemStack(stackInSlot, ItemSigilHolding.inventorySize, ItemSigilHolding.inventorySize + (PLAYER_INVENTORY_ROWS * PLAYER_INVENTORY_COLUMNS), false)) + { + return ItemStack.EMPTY; + } + } + + if (stackInSlot.isEmpty()) + { + slotObject.putStack(ItemStack.EMPTY); + } else + { + slotObject.onSlotChanged(); + } + + if (stackInSlot.getCount() == stack.getCount()) + { + return ItemStack.EMPTY; + } + + slotObject.onTake(player, stackInSlot); + } + + return stack; + } + + public void saveInventory(PlayerEntity entityPlayer) + { + inventoryHolding.onGuiSaved(entityPlayer); + } + + private class SlotHolding extends Slot + { + private final PlayerEntity player; + private ContainerHolding containerHolding; + + public SlotHolding(ContainerHolding containerHolding, IInventory inventory, PlayerEntity player, int slotIndex, int x, int y) + { + super(inventory, slotIndex, x, y); + this.player = player; + this.containerHolding = containerHolding; + } + + @Override + public void onSlotChanged() + { + super.onSlotChanged(); + + if (EffectiveSide.get().isServer()) + { + containerHolding.saveInventory(player); + } + } + + @Override + public boolean isItemValid(ItemStack itemStack) + { + return itemStack.getItem() instanceof ISigil && !(itemStack.getItem() instanceof ItemSigilHolding); + } + } + + private class SlotDisabled extends Slot + { + public SlotDisabled(IInventory inventory, int slotIndex, int x, int y) + { + super(inventory, slotIndex, x, y); + } + + @Override + public boolean isItemValid(ItemStack itemStack) + { + return false; + } + + @Override + public boolean canTakeStack(PlayerEntity player) + { + return false; + } + } +} diff --git a/src/main/java/wayoftime/bloodmagic/common/item/inventory/InventoryHolding.java b/src/main/java/wayoftime/bloodmagic/common/item/inventory/InventoryHolding.java new file mode 100644 index 00000000..218cd152 --- /dev/null +++ b/src/main/java/wayoftime/bloodmagic/common/item/inventory/InventoryHolding.java @@ -0,0 +1,82 @@ +package wayoftime.bloodmagic.common.item.inventory; + +import java.util.UUID; + +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.CompoundNBT; +import wayoftime.bloodmagic.common.item.sigil.ISigil; +import wayoftime.bloodmagic.common.item.sigil.ItemSigilHolding; +import wayoftime.bloodmagic.util.Constants; +import wayoftime.bloodmagic.util.Utils; + +public class InventoryHolding extends ItemInventory +{ +// protected ItemStack[] inventory; + + public InventoryHolding(ItemStack itemStack) + { + super(itemStack, ItemSigilHolding.inventorySize, "SigilOfHolding"); + } + + public void onGuiSaved(PlayerEntity entityPlayer) + { + masterStack = findParentStack(entityPlayer); + + if (!masterStack.isEmpty()) + { + save(); + } + } + + public ItemStack findParentStack(PlayerEntity entityPlayer) + { + if (Utils.hasUUID(masterStack)) + { + UUID parentStackUUID = new UUID(masterStack.getTag().getLong(Constants.NBT.MOST_SIG), masterStack.getTag().getLong(Constants.NBT.LEAST_SIG)); + for (int i = 0; i < entityPlayer.inventory.getSizeInventory(); i++) + { + ItemStack itemStack = entityPlayer.inventory.getStackInSlot(i); + + if (!itemStack.isEmpty() && Utils.hasUUID(itemStack)) + { + if (itemStack.getTag().getLong(Constants.NBT.MOST_SIG) == parentStackUUID.getMostSignificantBits() && itemStack.getTag().getLong(Constants.NBT.LEAST_SIG) == parentStackUUID.getLeastSignificantBits()) + { + return itemStack; + } + } + } + } + + return ItemStack.EMPTY; + } + + public void save() + { + CompoundNBT nbtTagCompound = masterStack.getTag(); + + if (nbtTagCompound == null) + { + nbtTagCompound = new CompoundNBT(); + + UUID uuid = UUID.randomUUID(); + nbtTagCompound.putLong(Constants.NBT.MOST_SIG, uuid.getMostSignificantBits()); + nbtTagCompound.putLong(Constants.NBT.LEAST_SIG, uuid.getLeastSignificantBits()); + } + + writeToNBT(nbtTagCompound); + masterStack.setTag(nbtTagCompound); + } + + @Override + public boolean isItemValidForSlot(int slotIndex, ItemStack itemStack) + { + return itemStack.getItem() instanceof ISigil && !(itemStack.getItem() instanceof ItemSigilHolding); + } + + @Override + public int getInventoryStackLimit() + { + return 1; + } +} \ No newline at end of file diff --git a/src/main/java/wayoftime/bloodmagic/common/item/inventory/ItemInventory.java b/src/main/java/wayoftime/bloodmagic/common/item/inventory/ItemInventory.java new file mode 100644 index 00000000..2b739f8a --- /dev/null +++ b/src/main/java/wayoftime/bloodmagic/common/item/inventory/ItemInventory.java @@ -0,0 +1,252 @@ +package wayoftime.bloodmagic.common.item.inventory; + +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.ItemStackHelper; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.util.NonNullList; +import wayoftime.bloodmagic.util.Constants; +import wayoftime.bloodmagic.util.helper.NBTHelper; + +public class ItemInventory implements IInventory +{ + protected int[] syncedSlots = new int[0]; + protected ItemStack masterStack; + private NonNullList inventory; + private int size; + private String name; + + public ItemInventory(ItemStack masterStack, int size, String name) + { + this.inventory = NonNullList.withSize(size, ItemStack.EMPTY); + this.size = size; + this.name = name; + this.masterStack = masterStack; + + if (!masterStack.isEmpty()) + this.readFromStack(masterStack); + } + + public void initializeInventory(ItemStack masterStack) + { + this.masterStack = masterStack; + this.clear(); + this.readFromStack(masterStack); + } + + private boolean isSyncedSlot(int slot) + { + for (int s : this.syncedSlots) + { + if (s == slot) + { + return true; + } + } + return false; + } + + public void readFromNBT(CompoundNBT tagCompound) + { + this.inventory = NonNullList.withSize(this.getSizeInventory(), ItemStack.EMPTY); + + ItemStackHelper.loadAllItems(tagCompound, this.inventory); + } + + public void writeToNBT(CompoundNBT tagCompound) + { + ItemStackHelper.saveAllItems(tagCompound, this.inventory); +// ListNBT tags = new ListNBT(); +// +// for (int i = 0; i < inventory.size(); i++) +// { +// if ((!inventory.get(i).isEmpty()) && !isSyncedSlot(i)) +// { +// CompoundNBT data = new CompoundNBT(); +// data.putByte(Constants.NBT.SLOT, (byte) i); +// inventory.get(i).write(data); +// tags.add(data); +//// tags.appendTag(data); +// } +// } +// +// tagCompound.put(Constants.NBT.ITEMS, tags); + } + + public void readFromStack(ItemStack masterStack) + { + if (masterStack != null) + { + NBTHelper.checkNBT(masterStack); + CompoundNBT tag = masterStack.getTag(); + readFromNBT(tag.getCompound(Constants.NBT.ITEM_INVENTORY)); + } + } + + public void writeToStack(ItemStack masterStack) + { + if (masterStack != null) + { + NBTHelper.checkNBT(masterStack); + CompoundNBT tag = masterStack.getTag(); + CompoundNBT invTag = new CompoundNBT(); + writeToNBT(invTag); + tag.put(Constants.NBT.ITEM_INVENTORY, invTag); + } + } + + @Override + public int getSizeInventory() + { + return size; + } + + @Override + public ItemStack getStackInSlot(int index) + { + return inventory.get(index); + } + + @Override + public ItemStack decrStackSize(int index, int count) + { + if (!inventory.get(index).isEmpty()) + { +// if (!worldObj.isRemote) +// worldObj.markBlockForUpdate(this.pos); + + if (inventory.get(index).getCount() <= count) + { + ItemStack itemStack = inventory.get(index); + inventory.set(index, ItemStack.EMPTY); + markDirty(); + return itemStack; + } + + ItemStack itemStack = inventory.get(index).split(count); + if (inventory.get(index).isEmpty()) + inventory.set(index, ItemStack.EMPTY); + + markDirty(); + return itemStack; + } + + return null; + } + + @Override + public ItemStack removeStackFromSlot(int slot) + { + if (!inventory.get(slot).isEmpty()) + { + ItemStack itemStack = inventory.get(slot); + setInventorySlotContents(slot, ItemStack.EMPTY); + return itemStack; + } + return ItemStack.EMPTY; + } + + @Override + public void setInventorySlotContents(int slot, ItemStack stack) + { + inventory.set(slot, stack); + if (stack.getCount() > getInventoryStackLimit()) + stack.setCount(getInventoryStackLimit()); + markDirty(); +// if (!worldObj.isRemote) +// worldObj.markBlockForUpdate(this.pos); + } + + @Override + public int getInventoryStackLimit() + { + return 64; + } + + @Override + public boolean isUsableByPlayer(PlayerEntity player) + { + return true; + } + + @Override + public void openInventory(PlayerEntity player) + { + + } + + @Override + public void closeInventory(PlayerEntity player) + { + + } + + @Override + public boolean isItemValidForSlot(int index, ItemStack stack) + { + return true; + } + +// @Override +// public int getField(int id) +// { +// return 0; +// } +// +// @Override +// public void setField(int id, int value) +// { +// +// } +// +// @Override +// public int getFieldCount() +// { +// return 0; +// } + + @Override + public void clear() + { + this.inventory = NonNullList.withSize(getSizeInventory(), ItemStack.EMPTY); + } + +// @Override +// public String getName() +// { +// return name; +// } +// +// @Override +// public boolean hasCustomName() +// { +// return false; +// } +// +// @Override +// public ITextComponent getDisplayName() +// { +// return new StringTextComponent(getName()); +// } + + @Override + public void markDirty() + { + if (masterStack != null) + { + this.writeToStack(masterStack); + } + } + + @Override + public boolean isEmpty() + { + return false; + } + + public boolean canInventoryBeManipulated() + { + return masterStack != null; + } +} \ No newline at end of file diff --git a/src/main/java/wayoftime/bloodmagic/common/item/sigil/ItemSigilHolding.java b/src/main/java/wayoftime/bloodmagic/common/item/sigil/ItemSigilHolding.java new file mode 100644 index 00000000..4d48ada4 --- /dev/null +++ b/src/main/java/wayoftime/bloodmagic/common/item/sigil/ItemSigilHolding.java @@ -0,0 +1,385 @@ +package wayoftime.bloodmagic.common.item.sigil; + +import java.util.List; + +import javax.annotation.Nonnull; + +import net.minecraft.client.util.ITooltipFlag; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.entity.player.ServerPlayerEntity; +import net.minecraft.inventory.ItemStackHelper; +import net.minecraft.inventory.container.Container; +import net.minecraft.inventory.container.INamedContainerProvider; +import net.minecraft.item.ItemStack; +import net.minecraft.item.ItemUseContext; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.util.ActionResult; +import net.minecraft.util.ActionResultType; +import net.minecraft.util.Hand; +import net.minecraft.util.NonNullList; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.StringTextComponent; +import net.minecraft.util.text.TranslationTextComponent; +import net.minecraft.world.World; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.fml.network.NetworkHooks; +import wayoftime.bloodmagic.api.compat.IAltarReader; +import wayoftime.bloodmagic.client.key.IKeybindable; +import wayoftime.bloodmagic.client.key.KeyBindings; +import wayoftime.bloodmagic.common.item.IBindable; +import wayoftime.bloodmagic.common.item.inventory.ContainerHolding; +import wayoftime.bloodmagic.common.item.inventory.InventoryHolding; +import wayoftime.bloodmagic.core.data.Binding; +import wayoftime.bloodmagic.util.Constants; +import wayoftime.bloodmagic.util.Utils; +import wayoftime.bloodmagic.util.helper.NBTHelper; +import wayoftime.bloodmagic.util.helper.PlayerHelper; + +public class ItemSigilHolding extends ItemSigilBase implements IKeybindable, IAltarReader, ISigil.Holding, INamedContainerProvider +{ + public static final int inventorySize = 5; + + public ItemSigilHolding() + { + super("holding"); + } + + @Override + public void onKeyPressed(ItemStack stack, PlayerEntity player, KeyBindings key, boolean showInChat) + { + if (stack == player.getHeldItemMainhand() && stack.getItem() instanceof ItemSigilHolding && key.equals(KeyBindings.OPEN_HOLDING)) + { + Utils.setUUID(stack); + + if (player instanceof ServerPlayerEntity) + { + NetworkHooks.openGui((ServerPlayerEntity) player, this, buf -> buf.writeItemStack(stack, false)); + } +// player.openGui(BloodMagic.instance, Constants.Gui.SIGIL_HOLDING_GUI, player.getEntityWorld(), (int) player.posX, (int) player.posY, (int) player.posZ); + } + } + +// @Override +// public String getHighlightTip(ItemStack stack, String displayName) +// { +// List inv = getInternalInventory(stack); +// int currentSlot = getCurrentItemOrdinal(stack); +// ItemStack item = inv.get(currentSlot); +// +// if (item.isEmpty()) +// return displayName; +// else +// return TextHelper.localizeEffect("item.bloodmagic.sigil.holding.display", displayName, item.getDisplayName()); +// } + + @Override + @OnlyIn(Dist.CLIENT) + public void addInformation(ItemStack stack, World world, List tooltip, ITooltipFlag flag) + { + super.addInformation(stack, world, tooltip, flag); + tooltip.add(new TranslationTextComponent("tooltip.bloodmagic.sigil.holding.press", KeyBindings.OPEN_HOLDING.getKey())); + + if (!stack.hasTag()) + return; + + List inv = getInternalInventory(stack); + int currentSlot = getCurrentItemOrdinal(stack); + ItemStack item = inv.get(currentSlot); + + for (int i = 0; i < inventorySize; i++) + { + ItemStack invStack = inv.get(i); + if (!invStack.isEmpty()) + if (!item.isEmpty() && invStack == item) + tooltip.add(new TranslationTextComponent("tooltip.bloodmagic.sigil.holding.sigilInSlot", i + 1, "&o&n" + invStack.getDisplayName())); + else + tooltip.add(new TranslationTextComponent("tooltip.bloodmagic.sigil.holding.sigilInSlot", i + 1, invStack.getDisplayName())); + } + } + + @Override + public ActionResultType onItemUse(ItemUseContext context) + { +// BlockPos pos = context.getPos(); +// Direction facing = context.getFace(); +// pos = pos.offset(facing); + PlayerEntity player = context.getPlayer(); + Hand hand = context.getHand(); + ItemStack stack = player.getHeldItem(hand); + +// ItemStack stack = player.getHeldItem(hand); + if (PlayerHelper.isFakePlayer(player)) + return ActionResultType.FAIL; + + int currentSlot = getCurrentItemOrdinal(stack); + NonNullList inv = getInternalInventory(stack); + ItemStack itemUsing = inv.get(currentSlot); + + if (itemUsing.isEmpty() || ((IBindable) itemUsing.getItem()).getBinding(itemUsing) == null) + return ActionResultType.PASS; + + ActionResultType result = itemUsing.getItem().onItemUse(context); + saveInventory(stack, inv); + + return result; + } + + @Override + public ActionResult onItemRightClick(World world, PlayerEntity player, Hand hand) + { + ItemStack stack = player.getHeldItem(hand); + if (PlayerHelper.isFakePlayer(player)) + return ActionResult.resultFail(stack); + + int currentSlot = getCurrentItemOrdinal(stack); + NonNullList inv = getInternalInventory(stack); + ItemStack itemUsing = inv.get(currentSlot); + + if (itemUsing.isEmpty() || ((IBindable) itemUsing.getItem()).getBinding(itemUsing) == null) + return ActionResult.resultPass(stack); + + itemUsing.getItem().onItemRightClick(world, player, hand); + + saveInventory(stack, inv); + + return ActionResult.resultPass(stack); + } + + @Nonnull + @Override + public ItemStack getHeldItem(ItemStack holdingStack, PlayerEntity player) + { + return getInternalInventory(holdingStack).get(getCurrentItemOrdinal(holdingStack)); + } + + public void saveInventory(ItemStack itemStack, NonNullList inventory) + { + CompoundNBT itemTag = itemStack.getTag(); + + if (itemTag == null) + itemStack.setTag(itemTag = new CompoundNBT()); + + ItemStackHelper.saveAllItems(itemTag, inventory); + +// CompoundNBT inventoryTag = new CompoundNBT(); +// ListNBT itemList = new ListNBT(); +// +// for (int i = 0; i < inventorySize; i++) +// { +// if (!inventory.get(i).isEmpty()) +// { +// CompoundNBT tag = new CompoundNBT(); +// tag.putByte(Constants.NBT.SLOT, (byte) i); +// inventory.get(i).writeToNBT(tag); +// itemList.appendTag(tag); +// } +// } +// +// inventoryTag.put(Constants.NBT.ITEMS, itemList); +// itemTag.put(Constants.NBT.ITEM_INVENTORY, inventoryTag); + } + + @Override + public void inventoryTick(ItemStack stack, World world, Entity entity, int itemSlot, boolean isSelected) + { + if (stack.hasTag()) + tickInternalInventory(stack, world, entity, itemSlot, isSelected); + } + + public void tickInternalInventory(ItemStack itemStack, World world, Entity entity, int itemSlot, boolean isSelected) + { + for (ItemStack stack : getInternalInventory(itemStack)) + { + if (stack.isEmpty() || !(stack.getItem() instanceof IBindable) || !(stack.getItem() instanceof ISigil)) + continue; + + Binding binding = ((IBindable) stack.getItem()).getBinding(stack); + if (binding == null) + continue; + + stack.getItem().inventoryTick(stack, world, entity, itemSlot, isSelected); + } + } + +// @Override +// public void gatherVariants(@Nonnull Int2ObjectMap variants) +// { +// // No-op - Just here to stop the super from running since we're using a mesh +// // provider +// } + +// @Override +// public ItemMeshDefinition getMeshDefinition() +// { +// return stack -> { +// if (stack.hasTag() && stack.getTag().hasKey("color")) +// return new ModelResourceLocation(getRegistryName(), "type=color"); +// return new ModelResourceLocation(getRegistryName(), "type=normal"); +// }; +// } +// +// @Override +// public void gatherVariants(Consumer variants) +// { +// variants.accept("type=normal"); +// variants.accept("type=color"); +// } + + public static int next(int mode) + { + int index = mode + 1; + + if (index >= inventorySize) + { + index = 0; + } + + return index; + } + + public static int prev(int mode) + { + int index = mode - 1; + + if (index < 0) + { + index = inventorySize; + } + + return index; + } + + private static void initModeTag(ItemStack stack) + { + if (!stack.hasTag()) + { + stack = NBTHelper.checkNBT(stack); + stack.getTag().putInt(Constants.NBT.CURRENT_SIGIL, inventorySize); + } + } + + public static ItemStack getItemStackInSlot(ItemStack itemStack, int slot) + { + if (itemStack.getItem() instanceof ItemSigilHolding) + { + List inv = getInternalInventory(itemStack); + if (inv != null) + return inv.get(slot == 5 ? 4 : slot); + else + return ItemStack.EMPTY; + } + + return ItemStack.EMPTY; + } + + public static int getCurrentItemOrdinal(ItemStack stack) + { + if (stack.getItem() instanceof ItemSigilHolding) + { + initModeTag(stack); + int currentSigil = stack.getTag().getInt(Constants.NBT.CURRENT_SIGIL); + currentSigil = MathHelper.clamp(currentSigil, 0, inventorySize - 1); + return currentSigil; + } + + return 0; + } + + public static NonNullList getInternalInventory(ItemStack stack) + { + initModeTag(stack); + CompoundNBT tagCompound = stack.getTag(); + + if (tagCompound == null) + { + return NonNullList.withSize(inventorySize, ItemStack.EMPTY); + } + + NonNullList inv = NonNullList.withSize(inventorySize, ItemStack.EMPTY); + + ItemStackHelper.loadAllItems(tagCompound, inv); + +// CompoundNBT inventoryTag = tagCompound.getCompound(Constants.NBT.ITEM_INVENTORY); +// ListNBT tagList = inventoryTag.getList(Constants.NBT.ITEMS, 10); +// +// if (tagList.isEmpty()) +// { +// return NonNullList.withSize(inventorySize, ItemStack.EMPTY); +// } +// +// List inv = NonNullList.withSize(inventorySize, ItemStack.EMPTY); +// +// for (int i = 0; i < tagList.tagCount(); i++) +// { +// CompoundNBT data = tagList.getCompoundTagAt(i); +// byte j = data.getByte(Constants.NBT.SLOT); +// +// if (j >= 0 && j < inv.size()) +// { +// inv.set(j, new ItemStack(data)); +// } +// } + + return inv; + } + + public static void cycleToNextSigil(ItemStack itemStack, int mode) + { + if (itemStack.getItem() instanceof ItemSigilHolding) + { + initModeTag(itemStack); + + int index = mode; + if (mode == 120 || mode == -120) + { + int currentIndex = getCurrentItemOrdinal(itemStack); + ItemStack currentItemStack = getItemStackInSlot(itemStack, currentIndex); + if (currentItemStack.isEmpty()) + return; + if (mode < 0) + { + index = next(currentIndex); + currentItemStack = getItemStackInSlot(itemStack, index); + + while (currentItemStack.isEmpty()) + { + index = next(index); + currentItemStack = getItemStackInSlot(itemStack, index); + } + } else + { + index = prev(currentIndex); + currentItemStack = getItemStackInSlot(itemStack, index); + + while (currentItemStack.isEmpty()) + { + index = prev(index); + currentItemStack = getItemStackInSlot(itemStack, index); + } + } + } + + itemStack.getTag().putInt(Constants.NBT.CURRENT_SIGIL, index); + } + } + + @Override + public Container createMenu(int p_createMenu_1_, PlayerInventory p_createMenu_2_, PlayerEntity player) + { + // TODO Auto-generated method stub + assert player.getEntityWorld() != null; + return new ContainerHolding(p_createMenu_1_, player, p_createMenu_2_, new InventoryHolding(player.getHeldItemMainhand())); + } + + @Override + public ITextComponent getDisplayName() + { + // TODO Auto-generated method stub + return new StringTextComponent("Sigil of Holding"); + } + +} \ No newline at end of file diff --git a/src/main/java/wayoftime/bloodmagic/network/BloodMagicPacketHandler.java b/src/main/java/wayoftime/bloodmagic/network/BloodMagicPacketHandler.java index 089ae21d..d33f0ca2 100644 --- a/src/main/java/wayoftime/bloodmagic/network/BloodMagicPacketHandler.java +++ b/src/main/java/wayoftime/bloodmagic/network/BloodMagicPacketHandler.java @@ -17,6 +17,8 @@ public class BloodMagicPacketHandler extends BasePacketHandler registerServerToClient(ARCTanksPacket.class, ARCTanksPacket::encode, ARCTanksPacket::decode, ARCTanksPacket::handle); registerServerToClient(DemonAuraClientPacket.class, DemonAuraClientPacket::encode, DemonAuraClientPacket::decode, DemonAuraClientPacket::handle); registerServerToClient(SetClientHealthPacket.class, SetClientHealthPacket::encode, SetClientHealthPacket::decode, SetClientHealthPacket::handle); + + registerClientToServer(KeyProcessorPacket.class, KeyProcessorPacket::encode, KeyProcessorPacket::decode, KeyProcessorPacket::handle); // INSTANCE.registerMessage(id, messageType, encoder, decoder, messageConsumer); // INSTANCE.registerMessage(ChatUtil.PacketNoSpamChat.Handler.class, ChatUtil.PacketNoSpamChat.class, 0, Side.CLIENT); // INSTANCE.registerMessage(ItemRouterButtonPacketProcessor.class, ItemRouterButtonPacketProcessor.class, 1, Side.SERVER); diff --git a/src/main/java/wayoftime/bloodmagic/network/KeyProcessorPacket.java b/src/main/java/wayoftime/bloodmagic/network/KeyProcessorPacket.java new file mode 100644 index 00000000..02f30330 --- /dev/null +++ b/src/main/java/wayoftime/bloodmagic/network/KeyProcessorPacket.java @@ -0,0 +1,71 @@ +package wayoftime.bloodmagic.network; + +import java.util.function.Supplier; + +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.network.PacketBuffer; +import net.minecraftforge.fml.network.NetworkEvent.Context; +import wayoftime.bloodmagic.client.key.IKeybindable; +import wayoftime.bloodmagic.client.key.KeyBindings; + +public class KeyProcessorPacket +{ + public int keyId; + public boolean showInChat; + + public KeyProcessorPacket(int keyId, boolean showInChat) + { + this.keyId = keyId; + this.showInChat = showInChat; + } + + public KeyProcessorPacket(KeyBindings key, boolean showInChat) + { + this(key.ordinal(), showInChat); + } + + public static void encode(KeyProcessorPacket pkt, PacketBuffer buf) + { + buf.writeInt(pkt.keyId); + buf.writeBoolean(pkt.showInChat); + } + + public static KeyProcessorPacket decode(PacketBuffer buf) + { + KeyProcessorPacket pkt = new KeyProcessorPacket(buf.readInt(), buf.readBoolean()); + + return pkt; + } + + public static void handle(KeyProcessorPacket message, Supplier context) + { + context.get().enqueueWork(() -> sendKeyToServer(message, context.get().getSender())); + context.get().setPacketHandled(true); + } + + public static void sendKeyToServer(KeyProcessorPacket msg, PlayerEntity playerEntity) + { + System.out.println("Hoiiiii"); + if (playerEntity != null) + { + ItemStack heldStack = playerEntity.getHeldItemMainhand(); + if (heldStack.getItem() instanceof IKeybindable) + { + if (msg.keyId < 0 || msg.keyId >= KeyBindings.values().length) + { + return; + } + KeyBindings key = KeyBindings.values()[msg.keyId]; + + ((IKeybindable) heldStack.getItem()).onKeyPressed(heldStack, playerEntity, key, msg.showInChat); + } + } + } + +// @OnlyIn(Dist.CLIENT) +// public static void updateClientHolder(DemonWillHolder holder) +// { +// ClientHandler.currentAura = holder; +// } +} diff --git a/src/main/java/wayoftime/bloodmagic/util/Utils.java b/src/main/java/wayoftime/bloodmagic/util/Utils.java index d47d024c..cfcf2328 100644 --- a/src/main/java/wayoftime/bloodmagic/util/Utils.java +++ b/src/main/java/wayoftime/bloodmagic/util/Utils.java @@ -2,6 +2,7 @@ package wayoftime.bloodmagic.util; import java.util.List; import java.util.Locale; +import java.util.UUID; import javax.annotation.Nullable; @@ -38,6 +39,7 @@ import net.minecraftforge.items.wrapper.PlayerMainInvWrapper; import net.minecraftforge.items.wrapper.SidedInvWrapper; import wayoftime.bloodmagic.api.compat.IDemonWillViewer; import wayoftime.bloodmagic.tile.TileInventory; +import wayoftime.bloodmagic.util.helper.NBTHelper; public class Utils { @@ -731,4 +733,31 @@ public class Utils // } // } // } + + public static boolean hasUUID(ItemStack stack) + { + return stack.hasTag() && stack.getTag().contains(Constants.NBT.MOST_SIG) && stack.getTag().contains(Constants.NBT.LEAST_SIG); + } + + public static UUID getUUID(ItemStack stack) + { + if (!hasUUID(stack)) + { + return null; + } + + return new UUID(stack.getTag().getLong(Constants.NBT.MOST_SIG), stack.getTag().getLong(Constants.NBT.LEAST_SIG)); + } + + public static void setUUID(ItemStack stack) + { + stack = NBTHelper.checkNBT(stack); + + if (!stack.getTag().contains(Constants.NBT.MOST_SIG) && !stack.getTag().contains(Constants.NBT.LEAST_SIG)) + { + UUID itemUUID = UUID.randomUUID(); + stack.getTag().putLong(Constants.NBT.MOST_SIG, itemUUID.getMostSignificantBits()); + stack.getTag().putLong(Constants.NBT.LEAST_SIG, itemUUID.getLeastSignificantBits()); + } + } }