package mcjty.rftools.blocks.dimlets; import mcjty.lib.container.InventoryHelper; import mcjty.lib.entity.GenericTileEntity; import mcjty.lib.network.Argument; import mcjty.lib.varia.Logging; import mcjty.rftools.dimension.DimensionInformation; import mcjty.rftools.dimension.RfToolsDimensionManager; import mcjty.rftools.dimension.description.DimensionDescriptor; import mcjty.rftools.dimension.world.types.SpecialType; import mcjty.rftools.items.dimlets.*; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.inventory.ISidedInventory; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.world.World; import net.minecraftforge.common.util.Constants; import java.util.ArrayList; import java.util.List; import java.util.Map; public class DimensionEnscriberTileEntity extends GenericTileEntity implements ISidedInventory { public static final String CMD_STORE = "store"; public static final String CMD_EXTRACT = "extract"; public static final String CMD_SETNAME = "setName"; private boolean tabSlotHasChanged = false; private InventoryHelper inventoryHelper = new InventoryHelper(this, DimensionEnscriberContainer.factory, DimensionEnscriberContainer.SIZE_DIMLETS+1); @Override public int[] getAccessibleSlotsFromSide(int side) { return DimensionEnscriberContainer.factory.getAccessibleSlots(); } @Override public boolean canInsertItem(int index, ItemStack item, int side) { return DimensionEnscriberContainer.factory.isInputSlot(index); } @Override public boolean canExtractItem(int index, ItemStack item, int side) { return DimensionEnscriberContainer.factory.isOutputSlot(index); } @Override public int getSizeInventory() { return inventoryHelper.getCount(); } @Override public ItemStack getStackInSlot(int index) { return inventoryHelper.getStackInSlot(index); } @Override public ItemStack decrStackSize(int index, int amount) { return inventoryHelper.decrStackSize(index, amount); } @Override public ItemStack getStackInSlotOnClosing(int index) { return null; } @Override public void setInventorySlotContents(int index, ItemStack stack) { inventoryHelper.setInventorySlotContents(getInventoryStackLimit(), index, stack); } @Override public String getInventoryName() { return "Enscriber Inventory"; } @Override public boolean hasCustomInventoryName() { return false; } @Override public int getInventoryStackLimit() { return 1; } @Override public boolean isUseableByPlayer(EntityPlayer player) { return canPlayerAccess(player); } @Override public void openInventory() { } @Override public void closeInventory() { } @Override public boolean isItemValidForSlot(int index, ItemStack stack) { return true; } @Override public void readFromNBT(NBTTagCompound tagCompound) { super.readFromNBT(tagCompound); } @Override public void readRestorableFromNBT(NBTTagCompound tagCompound) { super.readRestorableFromNBT(tagCompound); readBufferFromNBT(tagCompound); } private void readBufferFromNBT(NBTTagCompound tagCompound) { NBTTagList bufferTagList = tagCompound.getTagList("Items", Constants.NBT.TAG_COMPOUND); for (int i = 0 ; i < bufferTagList.tagCount() ; i++) { NBTTagCompound nbtTagCompound = bufferTagList.getCompoundTagAt(i); inventoryHelper.setStackInSlot(i, ItemStack.loadItemStackFromNBT(nbtTagCompound)); } } @Override public void writeToNBT(NBTTagCompound tagCompound) { super.writeToNBT(tagCompound); } @Override public void writeRestorableToNBT(NBTTagCompound tagCompound) { super.writeRestorableToNBT(tagCompound); writeBufferToNBT(tagCompound); } private void writeBufferToNBT(NBTTagCompound tagCompound) { NBTTagList bufferTagList = new NBTTagList(); for (int i = 0 ; i < inventoryHelper.getCount() ; i++) { ItemStack stack = inventoryHelper.getStackInSlot(i); NBTTagCompound nbtTagCompound = new NBTTagCompound(); if (stack != null) { stack.writeToNBT(nbtTagCompound); } bufferTagList.appendTag(nbtTagCompound); } tagCompound.setTag("Items", bufferTagList); } private void storeDimlets(EntityPlayerMP player) { if (DimletConfiguration.ownerDimletsNeeded) { if (checkOwnerDimlet()) { Logging.warn(player, "You need an owner dimlet to make a dimension!"); return; } } DimensionDescriptor descriptor = convertToDimensionDescriptor(); ItemStack realizedTab = createRealizedTab(descriptor, worldObj); inventoryHelper.setStackInSlot(DimensionEnscriberContainer.SLOT_TAB, realizedTab); markDirty(); } private boolean checkOwnerDimlet() { boolean owner = false; for (int i = 0 ; i < DimensionEnscriberContainer.SIZE_DIMLETS ; i++) { ItemStack stack = inventoryHelper.getStackInSlot(i + DimensionEnscriberContainer.SLOT_DIMLETS); if (stack != null && stack.stackSize > 0) { DimletKey key = KnownDimletConfiguration.getDimletKey(stack, worldObj); if (key.getType() == DimletType.DIMLET_SPECIAL && DimletObjectMapping.idToSpecialType.get(key) == SpecialType.SPECIAL_OWNER) { owner = true; break; } } } return !owner; } /** * Create a realized dimension tab by taking a map of ids per type and storing * that in the NBT of the realized dimension tab. */ public static ItemStack createRealizedTab(DimensionDescriptor descriptor, World world) { ItemStack realizedTab = new ItemStack(DimletSetup.realizedDimensionTab, 1, 0); NBTTagCompound tagCompound = new NBTTagCompound(); descriptor.writeToNBT(tagCompound); // Check if the dimension already exists and if so set the progress to 100%. RfToolsDimensionManager manager = RfToolsDimensionManager.getDimensionManager(world); Integer id = manager.getDimensionID(descriptor); if (id != null) { // The dimension was already created. tagCompound.setInteger("ticksLeft", 0); tagCompound.setInteger("id", id); } realizedTab.setTagCompound(tagCompound); return realizedTab; } /** * Convert the dimlets in the inventory to a dimension descriptor. */ private DimensionDescriptor convertToDimensionDescriptor() { List<DimletKey> descriptors = new ArrayList<DimletKey>(); long forcedSeed = 0; for (int i = 0 ; i < DimensionEnscriberContainer.SIZE_DIMLETS ; i++) { ItemStack stack = inventoryHelper.getStackInSlot(i + DimensionEnscriberContainer.SLOT_DIMLETS); if (stack != null && stack.stackSize > 0) { DimletKey key = KnownDimletConfiguration.getDimletKey(stack, worldObj); DimletEntry entry = KnownDimletConfiguration.getEntry(key); if (entry != null) { // Make sure the dimlet is not blacklisted. descriptors.add(key); NBTTagCompound tagCompound = stack.getTagCompound(); if (tagCompound != null && tagCompound.getLong("forcedSeed") != 0) { forcedSeed = tagCompound.getLong("forcedSeed"); } } } inventoryHelper.setStackInSlot(i + DimensionEnscriberContainer.SLOT_DIMLETS, null); } return new DimensionDescriptor(descriptors, forcedSeed); } private void extractDimlets() { ItemStack realizedTab = inventoryHelper.getStackInSlot(DimensionEnscriberContainer.SLOT_TAB); NBTTagCompound tagCompound = realizedTab.getTagCompound(); if (tagCompound != null) { int idx = DimensionEnscriberContainer.SLOT_DIMLETS; String descriptionString = tagCompound.getString("descriptionString"); for (DimletKey descriptor : DimensionDescriptor.parseDescriptionString(descriptionString)) { int id = tagCompound.getInteger("id"); if (DimletConfiguration.ownerDimletsNeeded && id != 0) { // If we need owner dimlets and the dimension is created we don't extract the owern dimlet. if (descriptor.getType() == DimletType.DIMLET_SPECIAL && DimletObjectMapping.idToSpecialType.get(descriptor) == SpecialType.SPECIAL_OWNER) { continue; } } inventoryHelper.setStackInSlot(idx++, KnownDimletConfiguration.makeKnownDimlet(descriptor, worldObj)); } } inventoryHelper.setStackInSlot(DimensionEnscriberContainer.SLOT_TAB, new ItemStack(DimletSetup.emptyDimensionTab)); markDirty(); } private void setName(String name) { ItemStack realizedTab = inventoryHelper.getStackInSlot(DimensionEnscriberContainer.SLOT_TAB); if (realizedTab != null) { NBTTagCompound tagCompound = realizedTab.getTagCompound(); if (tagCompound == null) { tagCompound = new NBTTagCompound(); realizedTab.setTagCompound(tagCompound); } tagCompound.setString("name", name); if (tagCompound.hasKey("id")) { Integer id = tagCompound.getInteger("id"); RfToolsDimensionManager dimensionManager = RfToolsDimensionManager.getDimensionManager(worldObj); DimensionInformation information = dimensionManager.getDimensionInformation(id); if (information != null) { information.setName(name); dimensionManager.save(worldObj); } } markDirty(); } } @Override public void onSlotChanged(int index, ItemStack stack) { if (worldObj.isRemote && index == DimensionEnscriberContainer.SLOT_TAB) { tabSlotHasChanged = true; } } public boolean hasTabSlotChangedAndClear() { boolean rc = tabSlotHasChanged; tabSlotHasChanged = false; return rc; } @Override public boolean execute(EntityPlayerMP playerMP, String command, Map<String, Argument> args) { boolean rc = super.execute(playerMP, command, args); if (rc) { return true; } if (CMD_STORE.equals(command)) { storeDimlets(playerMP); setName(args.get("name").getString()); return true; } else if (CMD_EXTRACT.equals(command)) { extractDimlets(); return true; } else if (CMD_SETNAME.equals(command)) { setName(args.get("name").getString()); return true; } return false; } }