mirror of
https://github.com/GTNewHorizons/Baubles-Expanded.git
synced 2026-11-14 01:04:01 +00:00
417 lines
16 KiB
Java
417 lines
16 KiB
Java
package baubles.common.container;
|
|
|
|
import baubles.api.IBauble;
|
|
import baubles.api.expanded.BaubleExpandedSlots;
|
|
import baubles.api.expanded.IBaubleExpanded;
|
|
import baubles.common.BaublesConfig;
|
|
import baubles.common.lib.PlayerHandler;
|
|
import cpw.mods.fml.relauncher.Side;
|
|
import cpw.mods.fml.relauncher.SideOnly;
|
|
import net.minecraft.entity.player.EntityPlayer;
|
|
import net.minecraft.entity.player.InventoryPlayer;
|
|
import net.minecraft.inventory.Container;
|
|
import net.minecraft.inventory.IInventory;
|
|
import net.minecraft.inventory.InventoryCraftResult;
|
|
import net.minecraft.inventory.InventoryCrafting;
|
|
import net.minecraft.inventory.Slot;
|
|
import net.minecraft.inventory.SlotCrafting;
|
|
import net.minecraft.item.Item;
|
|
import net.minecraft.item.ItemArmor;
|
|
import net.minecraft.item.ItemStack;
|
|
import net.minecraft.item.crafting.CraftingManager;
|
|
import net.minecraft.util.IIcon;
|
|
|
|
import static baubles.common.BaublesConfig.maxColumns;
|
|
import static baubles.common.BaublesConfig.useOldGuiRendering;
|
|
|
|
public class ContainerPlayerExpanded extends Container {
|
|
|
|
public InventoryCrafting craftMatrix = new InventoryCrafting(this, 2, 2);
|
|
public IInventory craftResult = new InventoryCraftResult();
|
|
public InventoryBaubles baubles;
|
|
|
|
private final EntityPlayer thePlayer;
|
|
|
|
private int slotsAdded = 0;
|
|
|
|
private int baubleFirstSlotIndex = -1;
|
|
private int baubleSlotCount = 0;
|
|
|
|
public ContainerPlayerExpanded(InventoryPlayer playerInv, boolean isClient, EntityPlayer player) {
|
|
this.thePlayer = player;
|
|
baubles = PlayerHandler.getPlayerBaubles(player);
|
|
baubles.setEventHandler(this);
|
|
|
|
int i;
|
|
int j;
|
|
|
|
// Crafting slots
|
|
if (!useOldGuiRendering) {
|
|
this.addSlotToContainer(new SlotCrafting(playerInv.player, this.craftMatrix, this.craftResult, 0, 144, 36));
|
|
|
|
for (i = 0; i < 2; ++i) {
|
|
for (j = 0; j < 2; ++j) {
|
|
this.addSlotToContainer(new Slot(this.craftMatrix, j + i * 2, 88 + j * 18, 26 + i * 18));
|
|
}
|
|
}
|
|
}
|
|
|
|
// Armor slots
|
|
for (i = 0; i < 4; ++i) {
|
|
final int k = i;
|
|
this.addSlotToContainer(new Slot(playerInv, playerInv.getSizeInventory() - 1 - i, 8, 8 + i * 18) {
|
|
@Override
|
|
public int getSlotStackLimit() { return 1; }
|
|
|
|
@Override
|
|
public boolean isItemValid(ItemStack itemStack) {
|
|
if (itemStack == null || itemStack.getItem() == null) return false;
|
|
return itemStack.getItem().isValidArmor(itemStack, k, thePlayer);
|
|
}
|
|
|
|
@Override
|
|
@SideOnly(Side.CLIENT)
|
|
public IIcon getBackgroundIconIndex() {
|
|
return ItemArmor.func_94602_b(k);
|
|
}
|
|
});
|
|
}
|
|
|
|
final int slotOffset = 18;
|
|
final int slotStartX = 80;
|
|
final int slotStartY = 8;
|
|
|
|
// Bauble slots
|
|
baubleFirstSlotIndex = slotsAdded;
|
|
String[] currentSlotAssignments = BaubleExpandedSlots.getCurrentSlotAssignments();
|
|
for (String slotType: currentSlotAssignments) {
|
|
if (BaublesConfig.showUnusedSlots || !slotType.equals(BaubleExpandedSlots.unknownType)) {
|
|
Slot slot = useOldGuiRendering
|
|
? new SlotBauble(baubles, slotType, baubleSlotCount, slotStartX + (slotOffset * (baubleSlotCount / 4)), slotStartY + (slotOffset * (baubleSlotCount % 4)))
|
|
: new SlotBauble(baubles, slotType, baubleSlotCount, -18 - (18 * (baubleSlotCount % getColumns())), 12 + (slotOffset * (baubleSlotCount / getColumns())));
|
|
addSlotToContainer(slot);
|
|
baubleSlotCount++;
|
|
}
|
|
}
|
|
|
|
// Inventory slots
|
|
for (i = 0; i < 3; ++i) {
|
|
for (j = 0; j < 9; ++j) {
|
|
this.addSlotToContainer(new Slot(playerInv, j + (i + 1) * 9, slotStartY + j * slotOffset, 84 + i * 18));
|
|
}
|
|
}
|
|
|
|
// Hotbar slots
|
|
for (i = 0; i < 9; ++i) {
|
|
this.addSlotToContainer(new Slot(playerInv, i, slotStartY + i * slotOffset, 142));
|
|
}
|
|
|
|
if (!useOldGuiRendering) {
|
|
this.onCraftMatrixChanged(this.craftMatrix);
|
|
this.scrollTo(0);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
protected Slot addSlotToContainer(Slot slot) {
|
|
// Count slots as we add them so we can determine what the first Bauble slot index will be
|
|
slotsAdded++;
|
|
return super.addSlotToContainer(slot);
|
|
}
|
|
|
|
@Override
|
|
public void onCraftMatrixChanged(IInventory par1IInventory) {
|
|
if (!useOldGuiRendering) {
|
|
this.craftResult.setInventorySlotContents(0, CraftingManager.getInstance().findMatchingRecipe(this.craftMatrix, this.thePlayer.worldObj));
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onContainerClosed(EntityPlayer player) {
|
|
super.onContainerClosed(player);
|
|
|
|
if (baubles != null && baubles.getEventHandler() == this) {
|
|
baubles.setEventHandler(null);
|
|
}
|
|
|
|
if (useOldGuiRendering) {
|
|
return;
|
|
}
|
|
for (int i = 0; i < 4; ++i) {
|
|
ItemStack itemstack = this.craftMatrix.getStackInSlotOnClosing(i);
|
|
|
|
if (itemstack != null) {
|
|
if (!player.inventory.addItemStackToInventory(itemstack)) {
|
|
player.dropPlayerItemWithRandomChoice(itemstack, false);
|
|
}
|
|
}
|
|
}
|
|
|
|
this.craftResult.setInventorySlotContents(0, null);
|
|
if (!player.worldObj.isRemote) {
|
|
PlayerHandler.setPlayerBaubles(player, baubles);
|
|
}
|
|
}
|
|
|
|
public int getBaubleSlotCount() {
|
|
return this.baubleSlotCount;
|
|
}
|
|
|
|
public SlotBauble getBaubleSlot(int slotIndex) {
|
|
if(slotIndex < 0 || slotIndex >= baubleSlotCount) return null;
|
|
return (SlotBauble) inventorySlots.get(baubleFirstSlotIndex + slotIndex);
|
|
}
|
|
|
|
public void scrollTo(float offset) {
|
|
if (!canScroll()) return;
|
|
final int activeBaubleSlots = BaubleExpandedSlots.slotsCurrentlyUsed();
|
|
final int columns = getColumns();
|
|
|
|
offset = Math.max(0, Math.min(1, offset));
|
|
|
|
int shownRows = 8;
|
|
int totalRows = (activeBaubleSlots + columns - 1) / columns;
|
|
int slotRowOffset = (int) (offset * (totalRows - shownRows) + 0.5F);
|
|
|
|
if (slotRowOffset < 0) {
|
|
slotRowOffset = 0;
|
|
}
|
|
|
|
for (int i = 0; i < activeBaubleSlots && i < BaubleExpandedSlots.slotsCurrentlyUsed(); i++) {
|
|
Slot slot = (Slot) this.inventorySlots.get(baubleFirstSlotIndex + i);
|
|
int row = i / columns;
|
|
int scrolledRow = row - slotRowOffset;
|
|
slot.yDisplayPosition = 12 + scrolledRow * 18;
|
|
if (slot.yDisplayPosition < 12 || slot.yDisplayPosition > 8 * 18) {
|
|
slot.yDisplayPosition = -2000;
|
|
}
|
|
}
|
|
}
|
|
|
|
public int getColumns() {
|
|
int activeBaubleSlots = BaubleExpandedSlots.slotsCurrentlyUsed();
|
|
for (int cols = 1; cols < maxColumns; cols++) {
|
|
if ((activeBaubleSlots + cols - 1) / cols <= 8) {
|
|
return cols;
|
|
}
|
|
}
|
|
return maxColumns;
|
|
}
|
|
|
|
public boolean canScroll() {
|
|
return BaubleExpandedSlots.slotsCurrentlyUsed() > maxColumns * 8 && !useOldGuiRendering;
|
|
}
|
|
|
|
@Override
|
|
public boolean canInteractWith(EntityPlayer player) {
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Called when a player shift-clicks on a slot. You must override this, or you will crash when someone does that.
|
|
*/
|
|
@Override
|
|
public ItemStack transferStackInSlot(EntityPlayer player, int slotIndex) {
|
|
ItemStack returnStack = null;
|
|
Slot slot = (Slot) inventorySlots.get(slotIndex);
|
|
final int visibleBaubleSlots = BaubleExpandedSlots.slotsCurrentlyUsed();
|
|
int craftingActive = 5;
|
|
if (useOldGuiRendering) {
|
|
craftingActive = 0;
|
|
}
|
|
|
|
if (slot == null || !slot.getHasStack()) {
|
|
return returnStack;
|
|
}
|
|
ItemStack originalStack = slot.getStack();
|
|
returnStack = originalStack.copy();
|
|
Item item = returnStack.getItem();
|
|
|
|
final int baubleStart = 4 + craftingActive;
|
|
final int baubleEnd = baubleStart + visibleBaubleSlots;
|
|
final int invEnd = baubleEnd + 27;
|
|
final int hotbarEnd = invEnd + 9;
|
|
|
|
if (!useOldGuiRendering && slotIndex == 0) {
|
|
if (!mergeItemStack(originalStack, baubleEnd, hotbarEnd, true)) {
|
|
return null;
|
|
}
|
|
slot.onSlotChange(originalStack, returnStack);
|
|
} else if (!useOldGuiRendering && slotIndex < 5) {
|
|
if (!mergeItemStack(originalStack, baubleEnd, hotbarEnd, false)) {
|
|
return null;
|
|
}
|
|
} else if (slotIndex >= baubleStart && slotIndex < baubleEnd) {
|
|
if (!mergeItemStack(originalStack, baubleEnd, hotbarEnd, false, slot)) {
|
|
returnStack = null;
|
|
}
|
|
} else if (item instanceof ItemArmor armor
|
|
&& !((Slot) inventorySlots.get(craftingActive + armor.armorType)).getHasStack()) {
|
|
int armorSlot = craftingActive + armor.armorType;
|
|
if (!mergeItemStack(originalStack, armorSlot, armorSlot + 1, false)) {
|
|
returnStack = null;
|
|
}
|
|
} else if (item instanceof IBauble bauble && bauble.canEquip(returnStack, thePlayer)) {
|
|
String[] types = item instanceof IBaubleExpanded
|
|
? ((IBaubleExpanded) item).getBaubleTypes(returnStack)
|
|
: new String[] {BaubleExpandedSlots.getTypeFromBaubleType(bauble.getBaubleType(returnStack))};
|
|
|
|
// Priority 2: direct slot matches (or universal items)
|
|
tryMergeIntoBaubleSlotsByPriority(originalStack, baubleStart, baubleEnd, types, 2);
|
|
|
|
// Priority 1: override matches (e.g. amulet/ring/belt into universal)
|
|
if (originalStack.stackSize > 0) {
|
|
tryMergeIntoBaubleSlotsByPriority(originalStack, baubleStart, baubleEnd, types, 1);
|
|
}
|
|
} else if (slotIndex >= baubleEnd && slotIndex < invEnd) {
|
|
if (!mergeItemStack(originalStack, invEnd, hotbarEnd, false)) {
|
|
returnStack = null;
|
|
}
|
|
} else if (slotIndex >= invEnd && slotIndex < hotbarEnd) {
|
|
if (!mergeItemStack(originalStack, baubleEnd, invEnd, false)) {
|
|
returnStack = null;
|
|
}
|
|
} else if (!mergeItemStack(originalStack, baubleEnd, hotbarEnd, false, slot)) {
|
|
returnStack = null;
|
|
}
|
|
|
|
if (originalStack.stackSize <= 0) {
|
|
slot.putStack(null);
|
|
} else {
|
|
slot.onSlotChanged();
|
|
}
|
|
|
|
if (returnStack != null && originalStack.stackSize == returnStack.stackSize) {
|
|
returnStack = null;
|
|
}
|
|
|
|
slot.onPickupFromSlot(player, originalStack);
|
|
|
|
return returnStack;
|
|
}
|
|
|
|
private void unequipBauble(ItemStack stack) {
|
|
//if (stack.getItem() instanceof IBauble) {
|
|
// ((IBauble)stack.getItem()).onUnequipped(stack, thePlayer);
|
|
//}
|
|
}
|
|
|
|
@Override
|
|
public void putStacksInSlots(ItemStack[] p_75131_1_) {
|
|
baubles.blockEvents=true;
|
|
super.putStacksInSlots(p_75131_1_);
|
|
}
|
|
|
|
private void tryMergeIntoBaubleSlotsByPriority(ItemStack sourceStack, int baubleStart, int baubleEnd, String[] itemTypes, int priority) {
|
|
// First pass: merge into occupied, compatible bauble slots.
|
|
for (int baubleSlot = baubleStart; baubleSlot < baubleEnd && sourceStack.stackSize > 0; baubleSlot++) {
|
|
Slot targetInventorySlot = (Slot) inventorySlots.get(baubleSlot);
|
|
if (!targetInventorySlot.getHasStack()) {
|
|
continue;
|
|
}
|
|
String targetSlotType = targetInventorySlot instanceof SlotBauble
|
|
? ((SlotBauble) targetInventorySlot).getSlotType()
|
|
: BaubleExpandedSlots.unknownType;
|
|
if (getBestMatchPriority(itemTypes, targetSlotType) != priority) {
|
|
continue;
|
|
}
|
|
mergeItemStack(sourceStack, baubleSlot, baubleSlot + 1, false);
|
|
}
|
|
|
|
// Second pass: place remaining items into empty, compatible bauble slots.
|
|
for (int baubleSlot = baubleStart; baubleSlot < baubleEnd && sourceStack.stackSize > 0; baubleSlot++) {
|
|
Slot targetInventorySlot = (Slot) inventorySlots.get(baubleSlot);
|
|
if (targetInventorySlot.getHasStack()) {
|
|
continue;
|
|
}
|
|
String targetSlotType = targetInventorySlot instanceof SlotBauble
|
|
? ((SlotBauble) targetInventorySlot).getSlotType()
|
|
: BaubleExpandedSlots.unknownType;
|
|
if (getBestMatchPriority(itemTypes, targetSlotType) != priority) {
|
|
continue;
|
|
}
|
|
mergeItemStack(sourceStack, baubleSlot, baubleSlot + 1, false);
|
|
}
|
|
}
|
|
|
|
private int getBestMatchPriority(String[] itemTypes, String slotType) {
|
|
int best = 0;
|
|
for (String type : itemTypes) {
|
|
if (type == null) {
|
|
continue;
|
|
}
|
|
if (type.equals(BaubleExpandedSlots.universalType) || type.equals(slotType)) {
|
|
return 2;
|
|
}
|
|
if (BaublesConfig.canTypeFitSlot(type, slotType)) {
|
|
best = 1;
|
|
}
|
|
}
|
|
return best;
|
|
}
|
|
|
|
protected boolean mergeItemStack(ItemStack sourceStack, int startIndex, int endIndex, boolean reverse, Slot sourceSlot) {
|
|
boolean merged = false;
|
|
int index = reverse ? endIndex - 1 : startIndex;
|
|
|
|
Slot targetSlot;
|
|
ItemStack targetStack;
|
|
|
|
// First pass: try stacking into existing stacks
|
|
if (sourceStack.isStackable()) {
|
|
while (sourceStack.stackSize > 0 && (!reverse && index < endIndex || reverse && index >= startIndex)) {
|
|
targetSlot = (Slot) inventorySlots.get(index);
|
|
targetStack = targetSlot.getStack();
|
|
|
|
if (targetStack != null && targetStack.getItem() == sourceStack.getItem() &&
|
|
(!sourceStack.getHasSubtypes() || sourceStack.getItemDamage() == targetStack.getItemDamage()) &&
|
|
ItemStack.areItemStackTagsEqual(sourceStack, targetStack)) {
|
|
|
|
int combinedSize = targetStack.stackSize + sourceStack.stackSize;
|
|
|
|
if (combinedSize <= sourceStack.getMaxStackSize()) {
|
|
if (sourceSlot instanceof SlotBauble) {
|
|
unequipBauble(sourceStack);
|
|
}
|
|
sourceStack.stackSize = 0;
|
|
targetStack.stackSize = combinedSize;
|
|
targetSlot.onSlotChanged();
|
|
return true;
|
|
} else if (targetStack.stackSize < sourceStack.getMaxStackSize()) {
|
|
if (sourceSlot instanceof SlotBauble) {
|
|
unequipBauble(sourceStack);
|
|
}
|
|
sourceStack.stackSize -= sourceStack.getMaxStackSize() - targetStack.stackSize;
|
|
targetStack.stackSize = sourceStack.getMaxStackSize();
|
|
targetSlot.onSlotChanged();
|
|
merged = true;
|
|
}
|
|
}
|
|
|
|
index = reverse ? index - 1 : index + 1;
|
|
}
|
|
}
|
|
|
|
// Second pass: put into empty slots
|
|
index = reverse ? endIndex - 1 : startIndex;
|
|
while (!reverse && index < endIndex || reverse && index >= startIndex) {
|
|
targetSlot = (Slot) inventorySlots.get(index);
|
|
targetStack = targetSlot.getStack();
|
|
|
|
if (targetStack == null) {
|
|
if (sourceSlot instanceof SlotBauble) {
|
|
unequipBauble(sourceStack);
|
|
}
|
|
targetSlot.putStack(sourceStack.copy());
|
|
targetSlot.onSlotChanged();
|
|
sourceStack.stackSize = 0;
|
|
return true;
|
|
}
|
|
|
|
index = reverse ? index - 1 : index + 1;
|
|
}
|
|
|
|
return merged;
|
|
}
|
|
}
|