package com.thebrokenrail.sorcerycraft.block; import com.thebrokenrail.sorcerycraft.SorceryCraft; import com.thebrokenrail.sorcerycraft.spell.Spell; import com.thebrokenrail.sorcerycraft.spell.SpellPlayerEntity; import com.thebrokenrail.sorcerycraft.spell.SpellRegistry; import com.thebrokenrail.sorcerycraft.spell.SpellTag; import net.minecraft.container.*; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.inventory.BasicInventory; import net.minecraft.inventory.CraftingResultInventory; import net.minecraft.inventory.Inventory; import net.minecraft.item.ItemStack; import net.minecraft.sound.SoundEvents; import java.util.ArrayList; import java.util.List; import java.util.Map; public class CastingTableContainer extends Container { private final Inventory inventory; private final Inventory result; private final Spell[] spells; private final BlockContext context; private int index = 0; public CastingTableContainer(int syncId, PlayerInventory playerInventory, BlockContext blockContext) { super(ContainerType.STONECUTTER, syncId); inventory = new BasicInventory(2) { public void markDirty() { super.markDirty(); CastingTableContainer.this.onContentChanged(this); } }; context = blockContext; result = new CraftingResultInventory(); if (playerInventory.player.isCreative()) { spells = SpellRegistry.getSpells(); } else { SpellPlayerEntity spellPlayer = (SpellPlayerEntity) playerInventory.player; Map spellsMap = spellPlayer.getSpells(); List spellsArray = new ArrayList<>(); Spell[] allSpells = SpellRegistry.getSpells(); for (Spell spell : allSpells) { if (spellsMap.containsKey(spell.getID()) && spellsMap.get(spell.getID()) >= spell.getLevel()) { spellsArray.add(spell); } } spells = spellsArray.toArray(new Spell[0]); } addSlot(new Slot(inventory, 0, 136, 37) { @Override public boolean canInsert(ItemStack stack) { return stack.getItem().equals(SorceryCraft.SPELL_ITEM); } @Override public int getMaxStackAmount() { return 1; } @Override public void onStackChanged(ItemStack originalItem, ItemStack itemStack) { super.onStackChanged(originalItem, itemStack); markDirty(); } }); addSlot(new Slot(inventory, 1, 162, 37) { @Override public void onStackChanged(ItemStack originalItem, ItemStack itemStack) { super.onStackChanged(originalItem, itemStack); markDirty(); } }); addSlot(new Slot(result, 2, 220, 37) { public boolean canInsert(ItemStack stack) { return false; } public boolean canTakeItems(PlayerEntity playerEntity) { return canTakeResult(playerEntity) && hasStack(); } public ItemStack onTakeItem(PlayerEntity player, ItemStack stack) { if (!player.isCreative()) { player.addExperienceLevels(-spells[index].getXPCost()); } player.playSound(SoundEvents.BLOCK_ENCHANTMENT_TABLE_USE, 1.0f, 1.0f); CastingTableContainer.this.inventory.setInvStack(0, ItemStack.EMPTY); CastingTableContainer.this.inventory.takeInvStack(1, spells[index].getItemCost().getCount()); return stack; } }); int k; for (k = 0; k < 3; ++k) { for(int j = 0; j < 9; ++j) { addSlot(new Slot(playerInventory, j + k * 9 + 9, 108 + j * 18, 84 + k * 18)); } } for (k = 0; k < 9; ++k) { addSlot(new Slot(playerInventory, k, 108 + k * 18, 142)); } } public boolean canTakeResult(PlayerEntity playerEntity) { return (playerEntity.isCreative() || playerEntity.experienceLevel >= spells[index].getXPCost()) && spells[index].getXPCost() > 0; } public void setIndex(int index) { this.index = index; onContentChanged(inventory); if (inventory.getInvStack(0).isEmpty() && inventory.getInvStack(1).isEmpty()) { ItemStack spellItem = new ItemStack(SorceryCraft.SPELL_ITEM); autoFill(0, spellItem, true); ItemStack paymentItem = getRecipes()[index].getItemCost(); autoFill(1, paymentItem, false); } } @Override public void close(PlayerEntity player) { super.close(player); context.run((world, blockPos) -> { dropInventory(player, world, inventory); }); } @Override public void onContentChanged(Inventory inventory) { super.onContentChanged(inventory); ItemStack item = inventory.getInvStack(0); ItemStack cost = inventory.getInvStack(1); if (inventory == this.inventory) { if (spells.length > 0 && !item.isEmpty() && cost.getItem() == spells[index].getItemCost().getItem() && cost.getCount() >= spells[index].getItemCost().getCount()) { ItemStack resultItem = item.copy(); Map resultSpells = SpellTag.getSpells(resultItem); if (!resultSpells.containsKey(spells[index].getID()) || resultSpells.get(spells[index].getID()) <= spells[index].getLevel()) { resultSpells.put(spells[index].getID(), spells[index].getLevel()); } SpellTag.setSpells(resultItem, resultSpells); result.setInvStack(2, resultItem); } else { result.setInvStack(2, ItemStack.EMPTY); } } } private void autoFill(int slot, ItemStack stack, boolean onlyOne) { if (!stack.isEmpty()) { for (int i = 3; i < 39; ++i) { ItemStack itemStack = slots.get(i).getStack(); if (!itemStack.isEmpty() && stack.getItem() == itemStack.getItem()) { ItemStack invSlot = inventory.getInvStack(slot); int count = invSlot.isEmpty() ? 0 : invSlot.getCount(); int requiredCount = Math.min((onlyOne ? 1 : stack.getMaxCount()) - count, itemStack.getCount()); ItemStack modifiedItem = itemStack.copy(); int totalCount = count + requiredCount; itemStack.decrement(requiredCount); modifiedItem.setCount(totalCount); inventory.setInvStack(slot, modifiedItem); if (totalCount >= stack.getMaxCount() || onlyOne) { break; } } } } } @Override public boolean canUse(PlayerEntity player) { return true; } public Spell[] getRecipes() { return spells; } }