Здраствуйте!
Ох, оптимистичное начало тут ни к чему... Я уже 2 дня долблюсь над одной и той же проблемой...
Суть в том что это кароч как печка но не печка. Блок процессинга.
Скажите что делать а то я уже почти отчаялся...
Сорцы:
ChronodialProcessor.java
ChronodialProcessorTileEntity.java
[merge_posts_bbcode]Добавлено: 30.12.2015 02:47:19[/merge_posts_bbcode]
(Продолжение)
ChronodialConatiner.java
GuiChronodial.java
GuiHandler.java
[merge_posts_bbcode]Добавлено: 30.12.2015 02:50:54[/merge_posts_bbcode]
(Продолжение 2)
Регистрация хандлера (на крайняк)
Я уверен на 100500% что проблема именно в ChronodialConatiner.java, я ж не глупый и вижу, но как его написать правильно? Может можно готовый вариант?
Ох, оптимистичное начало тут ни к чему... Я уже 2 дня долблюсь над одной и той же проблемой...
Код:
[01:15:35] [Client thread/FATAL]: Unreported exception thrown!
java.lang.ArrayIndexOutOfBoundsException: 3
at alexsocol.osm.blocks.tileentity.ChronodialProcessorTileEntity.setInventorySlotContents(ChronodialProcessorTileEntity.java:92) ~[ChronodialProcessorTileEntity.class:?]
at net.minecraft.inventory.Slot.putStack(Slot.java:104) ~[Slot.class:?]
at net.minecraft.inventory.Container.putStacksInSlots(Container.java:558) ~[Container.class:?]
at net.minecraft.client.network.NetHandlerPlayClient.handleWindowItems(NetHandlerPlayClient.java:1202) ~[NetHandlerPlayClient.class:?]
at net.minecraft.network.play.server.S30PacketWindowItems.processPacket(S30PacketWindowItems.java:70) ~[S30PacketWindowItems.class:?]
at net.minecraft.network.play.server.S30PacketWindowItems.processPacket(S30PacketWindowItems.java:78) ~[S30PacketWindowItems.class:?]
at net.minecraft.network.NetworkManager.processReceivedPackets(NetworkManager.java:241) ~[NetworkManager.class:?]
at net.minecraft.client.multiplayer.PlayerControllerMP.updateController(PlayerControllerMP.java:317) ~[PlayerControllerMP.class:?]
[...]
Скажите что делать а то я уже почти отчаялся...
Сорцы:
ChronodialProcessor.java
Код:
import java.util.Random;
import alexsocol.osm.ModInfo;
import alexsocol.osm.OSMMain;
import alexsocol.osm.blocks.tileentity.ChronodialProcessorTileEntity;
import net.minecraft.block.Block;
import net.minecraft.block.BlockContainer;
import net.minecraft.block.material.Material;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
public class ChronodialProcessor extends BlockContainer {
private static boolean hasTileEntity;
private final Random rnd = new Random();
private final boolean work;
private static boolean isActive;
public ChronodialProcessor() {
super(Material.iron);
this.setBlockName("ChronodialProcessor");
this.setBlockTextureName(ModInfo.MODID + ":ChronodialProcessorIcon");
this.setCreativeTab(OSMMain.osmTab);
this.setHardness(1.0F);
this.setHarvestLevel("pickaxe", 2);
this.setLightLevel(15.0F);
this.setLightOpacity(1);
this.setResistance(6000.F);
this.setStepSound(soundTypeMetal);
this.blockParticleGravity = 1.0F;
this.slipperiness = 0.6F;
this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
this.lightOpacity = 20;
this.setTickRandomly(false);
this.useNeighborBrightness = false;
this.isActive = false;
this.work = isActive;
}
@Override
public void breakBlock(World par1World, int par2, int par3, int par4, Block par5, int par6) {
dropItemsOnBlockBreak(par1World, par2, par3, par4, par5, par6);
ChronodialProcessorTileEntity table = (ChronodialProcessorTileEntity) par1World.getTileEntity(par2, par3, par4);
super.breakBlock(par1World, par2, par3, par4, par5, par6);
}
public static void dropItemsOnBlockBreak(World par1World, int par2, int par3, int par4, Block par5, int par6) {
try {
IInventory inv = (IInventory) par1World.getTileEntity(par2, par3, par4);
if (inv != null) {
for (int j1 = 0; j1 < inv.getSizeInventory(); ++j1) {
ItemStack itemstack = inv.getStackInSlot(j1);
if (itemstack != null) {
float f = par1World.rand.nextFloat() * 0.8F + 0.1F;
float f1 = par1World.rand.nextFloat() * 0.8F + 0.1F;
float f2 = par1World.rand.nextFloat() * 0.8F + 0.1F;
while (itemstack.stackSize > 0) {
int k1 = par1World.rand.nextInt(21) + 10;
if (k1 > itemstack.stackSize) {
k1 = itemstack.stackSize;
}
itemstack.stackSize -= k1;
EntityItem entityitem = new EntityItem(par1World, (double) ((float) par2 + f),
(double) ((float) par3 + f1), (double) ((float) par4 + f2),
new ItemStack(itemstack.getItem(), k1, itemstack.getItemDamage()));
if (itemstack.hasTagCompound()) {
entityitem.getEntityItem()
.setTagCompound((NBTTagCompound) itemstack.getTagCompound().copy());
}
float f3 = 0.05F;
entityitem.motionX = (double) ((float) par1World.rand.nextGaussian() * f3);
entityitem.motionY = (double) ((float) par1World.rand.nextGaussian() * f3 + 0.2F);
entityitem.motionZ = (double) ((float) par1World.rand.nextGaussian() * f3);
par1World.spawnEntityInWorld(entityitem);
}
}
}
}
} catch (Exception ex) {
ex.printStackTrace();
return;
}
}
@Override
public int getRenderBlockPass() {
return 0;
}
@Override
public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer,
int par6, float par7, float par8, float par9) {
if (par1World.isRemote) {
return true;
} else {
if (!par5EntityPlayer.isSneaking()) {
ItemStack currentItem = par5EntityPlayer.getCurrentEquippedItem();
par5EntityPlayer.openGui(OSMMain.instance, 0, par1World, par2, par3, par4);
return true;
} else {
ChronodialProcessorTileEntity table = (ChronodialProcessorTileEntity) par1World.getTileEntity(par2,
par3, par4);
return false;
}
}
}
@Override
public int getRenderType() {
return 2634;
}
@Override
public boolean isOpaqueCube() {
return false;
}
@Override
public boolean renderAsNormalBlock() {
return false;
}
@Override
public TileEntity createNewTileEntity(World p_149915_1_, int p_149915_2_) {
return new ChronodialProcessorTileEntity();
}
}
Код:
import alexsocol.osm.crafting.ProcessorRecipes;
import alexsocol.osm.proxy.CommonProxy;
import cpw.mods.fml.common.registry.GameRegistry;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.block.Block;
import net.minecraft.block.BlockFurnace;
import net.minecraft.block.material.Material;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
public class ChronodialProcessorTileEntity extends TileEntity implements ISidedInventory {
private static final int[] slotsTop = new int[] { 0 };
private static final int[] slotsBottom = new int[] { 2, 1 };
private static final int[] slotsSides = new int[] { 1 };
/**
* The ItemStacks that hold the items currently being used in the furnace
*/
private ItemStack[] itemStacks = new ItemStack[3];
/**
* The number of ticks that a fresh copy of the currently-burning item would
* keep the furnace burning for
*/
public int currentItemProcessingTime;
/** The number of ticks that the current item has been cooking for */
public int processingTime = 0;
public int completedTime = 1;
private String name;
public int getSizeInventory() {
return this.itemStacks.length;
}
public ItemStack getStackInSlot(int slot) {
return this.itemStacks[slot];
}
public ItemStack decrStackSize(int slot, int amount) {
if (this.itemStacks[slot] != null) {
ItemStack itemstack;
if (this.itemStacks[slot].stackSize <= amount) {
itemstack = this.itemStacks[slot];
this.itemStacks[slot] = null;
return itemstack;
} else {
itemstack = this.itemStacks[slot].splitStack(amount);
if (this.itemStacks[slot].stackSize == 0) {
this.itemStacks[slot] = null;
}
return itemstack;
}
} else {
return null;
}
}
/**
* When some containers are closed they call this on each slot, then drop
* whatever it returns as an EntityItem - like when you close a workbench
* GUI.
*/
public ItemStack getStackInSlotOnClosing(int slot) {
if (this.itemStacks[slot] != null) {
ItemStack itemstack = this.itemStacks[slot];
this.itemStacks[slot] = null;
return itemstack;
} else {
return null;
}
}
/**
* Sets the given item stack to the specified slot in the inventory (can be
* crafting or armor sections).
*/
public void setInventorySlotContents(int slot, ItemStack stack) {
this.itemStacks[slot] = stack;
if (stack != null && stack.stackSize > this.getInventoryStackLimit()) {
stack.stackSize = this.getInventoryStackLimit();
}
}
/**
* Returns the name of the inventory
*/
public String getInventoryName() {
return this.hasCustomInventoryName() ? this.name : "container.processor";
}
/**
* Returns if the inventory is named
*/
public boolean hasCustomInventoryName() {
return this.name != null && this.name.length() > 0;
}
public void getName(String str) {
this.name = str;
}
public void readFromNBT(NBTTagCompound tag) {
super.readFromNBT(tag);
NBTTagList nbttaglist = tag.getTagList("Items", 10);
this.itemStacks = new ItemStack[this.getSizeInventory()];
for (int i = 0; i < nbttaglist.tagCount(); ++i) {
NBTTagCompound nbttagcompound1 = nbttaglist.getCompoundTagAt(i);
byte b0 = nbttagcompound1.getByte("Slot");
if (b0 >= 0 && b0 < this.itemStacks.length) {
this.itemStacks[b0] = ItemStack.loadItemStackFromNBT(nbttagcompound1);
}
}
this.processingTime = tag.getShort("ProcessingTime");
this.currentItemProcessingTime = getItemWorkTime(this.itemStacks[1]);
if (tag.hasKey("CustomName", 8)) {
this.name = tag.getString("CustomName");
}
}
public void writeToNBT(NBTTagCompound tag) {
super.writeToNBT(tag);
tag.setShort("ProcessingTime", (short) this.processingTime);
NBTTagList nbttaglist = new NBTTagList();
for (int i = 0; i < this.itemStacks.length; ++i) {
if (this.itemStacks[i] != null) {
NBTTagCompound nbttagcompound1 = new NBTTagCompound();
nbttagcompound1.setByte("Slot", (byte) i);
this.itemStacks[i].writeToNBT(nbttagcompound1);
nbttaglist.appendTag(nbttagcompound1);
}
}
tag.setTag("Items", nbttaglist);
if (this.hasCustomInventoryName()) {
tag.setString("CustomName", this.name);
}
}
/**
* Returns the maximum stack size for a inventory slot.
*/
public int getInventoryStackLimit() {
return 64;
}
/**
* Returns an integer between 0 and the passed value representing how close
* the current item is to being completely cooked
*/
@SideOnly(Side.CLIENT)
public int getCookProgressScaled(int time) {
return this.processingTime * time / 200;
}
/**
* Returns an integer between 0 and the passed value representing how much
* burn time is left on the current fuel item, where 0 means that the item
* is exhausted and the passed value means that the item is fresh
*/
@SideOnly(Side.CLIENT)
public int getBurnTimeRemainingScaled(int time) {
if (this.currentItemProcessingTime == 0) {
this.currentItemProcessingTime = 200;
}
return this.processingTime * time / this.currentItemProcessingTime;
}
public boolean isProcessing() {
return this.processingTime > 0;
}
public void updateEntity() {
boolean flag = this.processingTime > 0;
boolean flag1 = false;
if (this.processingTime > 0) {
--this.processingTime;
}
if (!this.worldObj.isRemote) {
if (this.processingTime != 0 || this.itemStacks[1] != null && this.itemStacks[0] != null) {
if (this.processingTime == 0 && this.canProcess()) {
this.currentItemProcessingTime = this.processingTime = getItemWorkTime(this.itemStacks[1]);
if (this.processingTime > 0) {
flag1 = true;
if (this.itemStacks[1] != null) {
--this.itemStacks[1].stackSize;
if (this.itemStacks[1].stackSize == 0) {
this.itemStacks[1] = itemStacks[1].getItem().getContainerItem(itemStacks[1]);
}
}
}
}
if (this.isProcessing() && this.canProcess()) {
++this.completedTime;
if (this.completedTime == currentItemProcessingTime) {
this.completedTime = 0;
this.processItem();
flag1 = true;
}
} else {
this.completedTime = 0;
}
}
if (flag != this.processingTime > 0) {
flag1 = true;
BlockFurnace.updateFurnaceBlockState(this.processingTime > 0, this.worldObj, this.xCoord, this.yCoord,
this.zCoord);
}
}
if (flag1) {
this.markDirty();
}
}
private boolean canProcess() {
if (this.itemStacks[0] == null) {
return false;
} else {
ItemStack itemstack = ProcessorRecipes.processing().getProcessingResult(this.itemStacks[0]);
if (itemstack == null)
return false;
if (this.itemStacks[2] == null)
return true;
if (!this.itemStacks[2].isItemEqual(itemstack))
return false;
int result = itemStacks[2].stackSize + itemstack.stackSize;
return result <= getInventoryStackLimit() && result <= this.itemStacks[2].getMaxStackSize();
}
}
public void processItem() {
if (this.canProcess()) {
ItemStack itemstack = ProcessorRecipes.processing().getProcessingResult(this.itemStacks[0]);
if (this.itemStacks[2] == null) {
this.itemStacks[2] = itemstack.copy();
} else if (this.itemStacks[2].getItem() == itemstack.getItem()) {
this.itemStacks[2].stackSize += itemstack.stackSize;
}
--this.itemStacks[0].stackSize;
if (this.itemStacks[0].stackSize <= 0) {
this.itemStacks[0] = null;
}
}
}
public static int getItemWorkTime(ItemStack stack) {
if (stack.getItem() == CommonProxy.strangeMatter) {
return 800;
}
return 0;
}
public static boolean isItemFuel(ItemStack stack) {
return getItemWorkTime(stack) > 0;
}
/**
* Do not make give this method the name canInteractWith because it clashes
* with Container
*/
public boolean isUseableByPlayer(EntityPlayer player) {
return this.worldObj.getTileEntity(this.xCoord, this.yCoord, this.zCoord) != this ? false
: player.getDistanceSq((double) this.xCoord + 0.5D, (double) this.yCoord + 0.5D,
(double) this.zCoord + 0.5D) <= 64.0D;
}
public void openInventory() {
}
public void closeInventory() {
}
/**
* Returns true if automation is allowed to insert the given stack (ignoring
* stack size) into the given slot.
*/
public boolean isItemValidForSlot(int slot, ItemStack stack) {
return slot == 2 ? false : (slot == 1 ? isItemFuel(stack) : true);
}
/**
* Returns an array containing the indices of the slots that can be accessed
* by automation on the given side of this block.
*/
public int[] getAccessibleSlotsFromSide(int slot) {
return slot == 0 ? slotsBottom : (slot == 1 ? slotsTop : slotsSides);
}
/**
* Returns true if automation can insert the given item in the given slot
* from the given side. Args: Slot, item, side
*/
public boolean canInsertItem(int par1, ItemStack stack, int par3) {
return this.isItemValidForSlot(par1, stack);
}
/**
* Returns true if automation can extract the given item in the given slot
* from the given side. Args: Slot, item, side
*/
public boolean canExtractItem(int par1, ItemStack stack, int par3) {
return par3 != 0 || par1 != 1 || stack.getItem() == Items.bucket;
}
}
(Продолжение)
ChronodialConatiner.java
Код:
import alexsocol.osm.blocks.tileentity.ChronodialProcessorTileEntity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
public class ChronodialContainer extends Container {
protected ChronodialProcessorTileEntity te;
public ChronodialContainer(InventoryPlayer ip, ChronodialProcessorTileEntity tile) {
te = tile;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
addSlotToContainer(new Slot(te, j + i * 3, 62 + j * 18, 17 + i * 18));
}
}
bindPlayerInventory(ip);
}
@Override
public boolean canInteractWith(EntityPlayer player) {
return te.isUseableByPlayer(player);
}
protected void bindPlayerInventory(InventoryPlayer ip) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 9; j++) {
addSlotToContainer(new Slot(ip, j + i * 9 + 9, 8 + j * 18, 84 + i * 18));
}
}
for(int i = 0; i < 9; i++) {
addSlotToContainer(new Slot(ip, i, 8 + i * 18, 142));
}
}
@Override
public ItemStack transferStackInSlot(EntityPlayer player, int slot) {
ItemStack stack = null;
Slot slotObject = (Slot) inventorySlots.get(slot);
if (slotObject != null && slotObject.getHasStack()) {
ItemStack stackInSlot = slotObject.getStack();
stack = stackInSlot.copy();
if (slot < te.getSizeInventory()) {
if (!this.mergeItemStack(stackInSlot, te.getSizeInventory(), 36 + te.getSizeInventory(), true)) {
return null;
}
} else if (!this.mergeItemStack(stackInSlot, 0, te.getSizeInventory(), false)) {
return null;
}
if(stackInSlot.stackSize == 0) {
slotObject.putStack(null);
} else {
slotObject.onSlotChanged();
}
if(stackInSlot.stackSize == stack.stackSize) {
return null;
}
slotObject.onPickupFromSlot(player, stackInSlot);
}
return stack;
}
}
Код:
import org.lwjgl.opengl.GL11;
import alexsocol.osm.blocks.container.ChronodialContainer;
import alexsocol.osm.blocks.tileentity.ChronodialProcessorTileEntity;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.resources.I18n;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.util.ResourceLocation;
@SideOnly(Side.CLIENT)
public class GuiChronodial extends GuiContainer
{
private static final ResourceLocation furnaceGuiTextures = new ResourceLocation("textures/gui/container/furnace.png");
private ChronodialProcessorTileEntity tileProcessor;
public GuiChronodial(InventoryPlayer p_i1091_1_, ChronodialProcessorTileEntity p_i1091_2_)
{
super(new ChronodialContainer(p_i1091_1_, p_i1091_2_));
this.tileProcessor = p_i1091_2_;
}
protected void drawGuiContainerForegroundLayer(int p_146979_1_, int p_146979_2_)
{
String s = this.tileProcessor.hasCustomInventoryName() ? this.tileProcessor.getInventoryName() : I18n.format(this.tileProcessor.getInventoryName(), new Object[0]);
this.fontRendererObj.drawString(s, this.xSize / 2 - this.fontRendererObj.getStringWidth(s) / 2, 6, 4210752);
this.fontRendererObj.drawString(I18n.format("container.inventory", new Object[0]), 8, this.ySize - 96 + 2, 4210752);
}
protected void drawGuiContainerBackgroundLayer(float p_146976_1_, int p_146976_2_, int p_146976_3_)
{
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
this.mc.getTextureManager().bindTexture(furnaceGuiTextures);
int k = (this.width - this.xSize) / 2;
int l = (this.height - this.ySize) / 2;
this.drawTexturedModalRect(k, l, 0, 0, this.xSize, this.ySize);
if (this.tileProcessor.isProcessing())
{
int i1 = this.tileProcessor.getBurnTimeRemainingScaled(13);
this.drawTexturedModalRect(k + 56, l + 36 + 12 - i1, 176, 12 - i1, 14, i1 + 1);
i1 = this.tileProcessor.getCookProgressScaled(24);
this.drawTexturedModalRect(k + 79, l + 34, 176, 14, i1 + 1, 16);
}
}
}
Код:
import alexsocol.osm.blocks.container.ChronodialContainer;
import alexsocol.osm.blocks.tileentity.ChronodialProcessorTileEntity;
import alexsocol.osm.gui.GuiChronodial;
import cpw.mods.fml.common.network.IGuiHandler;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
public class GuiHandler implements IGuiHandler {
@Override
public Object getServerGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) {
TileEntity te = world.getTileEntity(x, y, z);
if(te instanceof ChronodialProcessorTileEntity) {
return new ChronodialContainer(player.inventory, (ChronodialProcessorTileEntity) te);
}
return null;
}
public Object getClientGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) {
TileEntity te = world.getTileEntity(x, y, z);
if(te instanceof ChronodialProcessorTileEntity) {
return new GuiChronodial(player.inventory, (ChronodialProcessorTileEntity) te);
}
return null;
}
}
[merge_posts_bbcode]Добавлено: 30.12.2015 02:50:54[/merge_posts_bbcode]
(Продолжение 2)
Регистрация хандлера (на крайняк)
Код:
NetworkRegistry.INSTANCE.registerGuiHandler(this, new GuiHandler());