Итак, начнём с того что я пытаюсь сделать контейнер, который пока-что ничего не делает, а просто имеет слоты игрока и слоты тайла, слоты игрока нормально работают, в отличии от вторых, когда я кладу любой предмет в слот тайла, то он просто выпадает, либо дюпается, но когда я повторно нажимаю по нему, то он просто пропадает..
P.S. Это аддон для AE2, так что тут много странных методов, по типу "getGridNode", на них можно не обращать внимание, как я убедился они никак не влияют на проблему
Код:
public class TileServerCore extends AITile implements IAIMultiBlock, ICellContainer, INetworkToolAgent, IInventoryHost {
public static final int BLOCKS_IN_STRUCTURE = Patterns.ME_SERVER.length+1;
// List of blocks in multiblock
public Vector<IAIMultiBlock> Slaves = new Vector<>();
public AIGridNodeInventory inv = new AIGridNodeInventory("ME Server",30,1,this){
@Override
public boolean isItemValidForSlot(int i, ItemStack itemstack) {
return AEApi.instance().registries().cell().isCellHandled(itemstack);
}
};
// ME Inventories
private List<IMEInventoryHandler> items = new LinkedList<>();
private List<IMEInventoryHandler> fluids = new LinkedList<>();
// Networks in ports
public Vector<IGrid> portNetworks = new Vector<>();
// Network of owner
public IGrid MainNetwork;
private boolean tryForm;
public boolean isFormed;
public boolean isConflicting;
private short[] blinkTimers;
private byte[] cellStatuses = new byte[6];
// Wait for updating
public int blocksToPlace = 0;
@Override
public void updateEntity() {
super.updateEntity();
if (isFormed) {
for (IAIMultiBlock slave : Slaves) {
slave.notifyBlock();
}
/*if (MainNetwork != null) {
for (IGrid grid : portNetworks) {
if (grid == MainNetwork) {
for (IAIMultiBlock slave : Slaves) {
if (slave instanceof TileServerRib) {
if (!isConflicting) {
TileServerRib rib = (TileServerRib) slave;
rib.notifyConflict();
isConflicting = true;
return;
}
}
}
}
}
}*/
/*if(tryForm){
isFormed = false;
if(worldObj != null) {
this.tryConstruct(null);
tryForm = false;
}
}*/
}
}
@Override
public void validate(){
tryForm = true;
}
@Override
public void notifyBlock(){
worldObj.markBlockForUpdate(xCoord,yCoord,zCoord);
}
@Override
public void tryConstruct(EntityPlayer p) {
if(!isFormed) {
// For 4d humans =)
blocksToPlace = BLOCKS_IN_STRUCTURE - 1;
int count = 0;
List<IAIMultiBlock> toUpdate = new ArrayList<>();
for (int i = 0; i < Patterns.ME_SERVER.length; i++) {
if (!this.worldObj.isRemote) {
int x, y, z;
Block block;
x = this.xCoord + Patterns.ME_SERVER[blocksToPlace - 1].x;
y = this.yCoord + Patterns.ME_SERVER[blocksToPlace - 1].y;
z = this.zCoord + Patterns.ME_SERVER[blocksToPlace - 1].z;
block = Patterns.ME_SERVER[blocksToPlace - 1].b;
if (worldObj.getBlock(x, y, z) == block) {
count++;
toUpdate.add((IAIMultiBlock) worldObj.getTileEntity(x, y, z));
blocksToPlace--;
}
}
}
int counter = 0;
for (int i = 0; i < Patterns.ME_SERVER.length; i++)
if (Patterns.ME_SERVER[i] != null)
counter++;
int BlocksToPlace = Patterns.ME_SERVER_FILL.length - 1;
if (counter == count) {
for (int i = 0; i < Patterns.ME_SERVER_FILL.length; i++) {
int x, y, z, meta;
Block block = Patterns.ME_SERVER_FILL[BlocksToPlace].b;
x = this.xCoord + Patterns.ME_SERVER_FILL[BlocksToPlace].x;
y = this.yCoord + Patterns.ME_SERVER_FILL[BlocksToPlace].y;
z = this.zCoord + Patterns.ME_SERVER_FILL[BlocksToPlace].z;
meta = Patterns.ME_SERVER_FILL[BlocksToPlace].meta;
worldObj.setBlock(x, y, z, Blocks.air);
worldObj.setBlock(x, y, z, block, meta, meta);
worldObj.markBlockForUpdate(x, y, z);
toUpdate.add((TileServerRib) worldObj.getTileEntity(x, y, z));
((TileServerRib) worldObj.getTileEntity(x, y, z)).changeAlt(true);
BlocksToPlace--;
}
for (int i = 0; i < toUpdate.size(); i++) {
toUpdate.get(i).setMaster(this);
if (toUpdate.get(i) instanceof TileServerPort) {
TileServerPort port = (TileServerPort) toUpdate.get(i);
port.createAELink();
} else if (toUpdate.get(i) instanceof TileServerRib) {
TileServerRib rib = (TileServerRib) toUpdate.get(i);
rib.createAELink();
}
Slaves.add(toUpdate.get(i));
}
}
isFormed = true;
if(p!=null)
p.addChatComponentMessage(new ChatComponentText("ME Server Formed!"));
}
}
public void DestroyMultiBlock(){
for(IAIMultiBlock tile : Slaves){
if(tile instanceof TileServerRib){
TileServerRib Rib = (TileServerRib)tile;
Rib.changeAlt(false);
Rib.destroyAELink();
}
if(tile instanceof TileServerPort){
TileServerPort port = (TileServerPort)tile;
port.destroyAELink();
}
tile.setMaster(null);
if(((AIMultiBlockTile)tile).getGridNode(ForgeDirection.UNKNOWN) != null)
((AIMultiBlockTile)tile).getGridNode(ForgeDirection.UNKNOWN).updateState();
}
isFormed = false;
}
@Override
public boolean hasMaster() {
return true;
}
@Override
public TileServerCore getMaster() {
return this;
}
@Override
public void setMaster(TileServerCore tileServerCore) { }
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
}
@Override
public void writeToNBT(NBTTagCompound nbt) {
super.writeToNBT(nbt);
}
@Override
public Object getServerGuiElement( final EntityPlayer player ) {
return new ContainerMEServer(player,this);
}
@Override
public Object getClientGuiElement( final EntityPlayer player )
{
return new GuiMEServer((ContainerMEServer)this.getServerGuiElement(player));
}
@Override
public void blinkCell(int slot) {
if (slot > 0 && slot < this.blinkTimers.length)
this.blinkTimers[slot] = 15;
}
@Override
public void securityBreak() {
}
@Override
public EnumSet<ForgeDirection> getConnectableSides() {
if(isFormed)
return EnumSet.allOf(ForgeDirection.class);
return EnumSet.of(SOUTH,EAST,WEST,NORTH,UP,DOWN);
}
@Override
public EnumSet<GridFlags> getFlags() {
return EnumSet.of(GridFlags.REQUIRE_CHANNEL);
}
// Drive
@Override
public int getPriority() {
return 0;
}
@Override
public void onInventoryChanged() {
this.items = updateHandlers(StorageChannel.ITEMS);
this.fluids = updateHandlers(StorageChannel.FLUIDS);
for (int i = 0; i < this.cellStatuses.length; i++) {
ItemStack stackInSlot = this.inv.getStackInSlot(i);
IMEInventoryHandler inventoryHandler = AEApi.instance()
.registries().cell()
.getCellInventory(stackInSlot, null, StorageChannel.ITEMS);
if (inventoryHandler == null)
inventoryHandler = AEApi
.instance()
.registries()
.cell()
.getCellInventory(stackInSlot, null,
StorageChannel.FLUIDS);
ICellHandler cellHandler = AEApi.instance().registries().cell()
.getHandler(stackInSlot);
if (cellHandler == null || inventoryHandler == null) {
this.cellStatuses[i] = 0;
} else {
this.cellStatuses[i] = (byte) cellHandler.getStatusForCell(
stackInSlot, inventoryHandler);
}
}
IGridNode node = getGridNode(ForgeDirection.UNKNOWN);
if (node != null) {
IGrid grid = node.getGrid();
if (grid != null) {
grid.postEvent(new MENetworkCellArrayUpdate());
}
getWorldObj().markBlockForUpdate(xCoord, yCoord, zCoord);
}
}
private List<IMEInventoryHandler> updateHandlers(StorageChannel channel) {
ICellRegistry cellRegistry = AEApi.instance().registries().cell();
List<IMEInventoryHandler> handlers = new ArrayList<IMEInventoryHandler>();
for (int i = 0; i < this.inv.getSizeInventory(); i++) {
ItemStack cell = this.inv.getStackInSlot(i);
if (cellRegistry.isCellHandled(cell)) {
IMEInventoryHandler cellInventory = cellRegistry
.getCellInventory(cell, null, channel);
if (cellInventory != null)
handlers.add(cellInventory);
}
}
return handlers;
}
@Override
public List<IMEInventoryHandler> getCellArray(StorageChannel channel) {
if (!theGridNode.isActive())
return new ArrayList<IMEInventoryHandler>();
return channel == StorageChannel.ITEMS ? this.items : this.fluids;
}
@Override
public void saveChanges(IMEInventory cellInventory) {
}
@Override
public void invalidate() {
super.invalidate();
if (worldObj != null && !worldObj.isRemote) {
destroyAELink();
}
if(isFormed)
this.DestroyMultiBlock();
}
@Override
public boolean showNetworkInfo(MovingObjectPosition where) {
return true;
}
public void addSlave(AIMultiBlockTile slave) {
Slaves.add(slave);
}
}
Код:
public abstract class AITile extends TileEntity implements IActionHost,IGridHost,IGridBlock {
public IGridNode theGridNode = null;
public IGridConnection theConnection;
private IGridBlock gridBlock;
private IGridNode node = null;
protected boolean loaded = false;
private boolean cached = false;
public Object getServerGuiElement( final EntityPlayer player )
{
return null;
}
public Object getClientGuiElement( final EntityPlayer player )
{
return null;
}
/**
* Prepare a Packet to send the state of the {@link TileEntity} to the Client
*/
@Override
public Packet getDescriptionPacket() {
NBTTagCompound nbt = new NBTTagCompound();
writeToNBT(nbt);
return new S35PacketUpdateTileEntity(xCoord, yCoord, zCoord, 1, nbt);
}
/**
* Process a Packet to update the state of the {@link TileEntity} on the Client
*/
@Override
public void onDataPacket(NetworkManager pNet, S35PacketUpdateTileEntity pPacket) {
super.onDataPacket(pNet, pPacket);
NBTTagCompound nbt = pPacket.func_148857_g();
readFromNBT(nbt);
}
@Override
public double getIdlePowerUsage() {
// TODO Auto-generated method stub
return 1;
}
@Override
public EnumSet<GridFlags> getFlags() {
// TODO Auto-generated method stub
return EnumSet.of(GridFlags.REQUIRE_CHANNEL);
}
@Override
public boolean isWorldAccessible() {
// TODO Auto-generated method stub
return true;
}
@Override
public DimensionalCoord getLocation() {
// TODO Auto-generated method stub
return new DimensionalCoord(this);
}
@Override
public AEColor getGridColor() {
// TODO Auto-generated method stub
return AEColor.Transparent;
}
@Override
public void onGridNotification(GridNotification notification) {
}
@Override
public void setNetworkStatus(IGrid grid, int channelsInUse) {
}
@Override
public EnumSet<ForgeDirection> getConnectableSides() {
return EnumSet.of(ForgeDirection.SOUTH,ForgeDirection.DOWN,ForgeDirection.EAST,ForgeDirection.UP,ForgeDirection.NORTH,ForgeDirection.WEST);
}
public void createAELink() {
if(worldObj != null) {
if (isServer()) {
try{
node = AEApi.instance().createGridNode(gridBlock);
node.updateState();
}catch (Exception e){
}
}
}
}
public void destroyAELink() {
if (theGridNode != null) theGridNode.destroy();
}
@Override
public IGridHost getMachine() {
return this;
}
@Override
public void gridChanged() {
}
public boolean isServer() {
return !isClient();
}
public boolean isClient() {
return getWorldObj().isRemote;
}
@Override
public ItemStack getMachineRepresentation() {
return null;
}
@Override
public IGridNode getGridNode(ForgeDirection dir) {
if(theGridNode==null) createAELink();
return theGridNode;
}
@Override
public AECableType getCableConnectionType(ForgeDirection dir) {
return AECableType.DENSE;
}
@Override
public void securityBreak() {
}
@Override
public IGridNode getActionableNode() {
if (FMLCommonHandler.instance().getEffectiveSide().isClient())
return null;
if (this.node == null) {
this.node = AEApi.instance().createGridNode(this.gridBlock);
}
return this.node;
}
@Override
public void updateEntity() {
//create grid node on add to world
if (!loaded && hasWorldObj() && !worldObj.isRemote) {
loaded = true;
createAELink();
}
}
public void notifyBlock(){
worldObj.markBlockForUpdate(xCoord,yCoord,zCoord);
}
}
Код:
public class ContainerMEServer extends Container
{
private TileServerCore master;
public ContainerMEServer(EntityPlayer player, TileServerCore master) {
this.master = master;
this.bindPlayerInventory(player.inventory);
this.addDriveSlots(master.inv);
master.inv.openInventory();
}
private void addDriveSlots(IInventory master) {
int i=0;
for (int y = 0; y<5; y++){
for(int x = 0; x<6; x++){
if(master != null) {
this.addSlotToContainer( new SlotMEServer(master, i, 35 + x * 18, y * 18 - 1 ) );
i++;
}
}
}
i=0;
}
protected void bindPlayerInventory(IInventory inventoryPlayer) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 9; j++) {
addSlotToContainer(new Slot(inventoryPlayer, j + i * 9 + 9,
8 + j * 18, (i * 18 + 149)-47));
}
}
for (int i = 0; i < 9; i++) {
addSlotToContainer(new Slot(inventoryPlayer, i, 8 + i * 18, (207)-47));
}
}
@Override
public boolean canInteractWith(EntityPlayer p) {
return true;
}
@Override
public ItemStack transferStackInSlot(EntityPlayer p, int i)
{
ItemStack itemstack = null;
Slot slot = (Slot)inventorySlots.get(i);
if (slot != null && slot.getHasStack())
{
ItemStack itemstack1 = slot.getStack();
itemstack = itemstack1.copy();
if (AEApi.instance().registries().cell().isCellHandled(itemstack))
{
if (i < 3)
{
if (!mergeItemStack(itemstack1, 3, 38, false))
{
return null;
}
} else if (!mergeItemStack(itemstack1, 0, 3, false))
{
return null;
}
if (itemstack1.stackSize == 0)
{
slot.putStack(null);
} else
{
slot.onSlotChanged();
}
}
}
return itemstack;
}
}
Код:
public class GuiMEServer extends AIBaseGui {
private static final ResourceLocation texture = new ResourceLocation(AppliedIntegrations.modid, "textures/gui/Server/ServerStorage.png");
public GuiMEServer(ContainerMEServer container) {
super(container);
}
@Override
public AIContainer getNodeContainer() {
return null;
}
@Override
protected void drawGuiContainerBackgroundLayer(float p_146976_1_, int p_146976_2_, int p_146976_3_) {
drawDefaultBackground();
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
Minecraft.getMinecraft().renderEngine.bindTexture(this.texture);
this.drawTexturedModalRect(this.guiLeft, this.guiTop-15, 0, 0, 200, 200);
}
@Override
protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) {
super.drawGuiContainerForegroundLayer(mouseX, mouseY);
this.fontRendererObj.drawString("ME Server Drive", 9, -12, 4210752);
}
}
Код:
public class AIGridNodeInventory implements IInventory {
public ItemStack[] slots;
public String customName;
private int stackLimit;
private IInventoryHost receiver;
public AIGridNodeInventory(String _customName, int _size, int _stackLimit) {
this(_customName, _size, _stackLimit, null);
}
public AIGridNodeInventory(String _customName, int _size, int _stackLimit,
IInventoryHost _receiver) {
this.slots = new ItemStack[_size];
this.customName = _customName;
this.stackLimit = _stackLimit;
this.receiver = _receiver;
}
@Override
public void closeInventory() {
// NOBODY needs this!
}
@Override
public ItemStack decrStackSize(int slotId, int amount) {
if (this.slots[slotId] == null)
return null;
ItemStack itemstack;
if (this.slots[slotId].stackSize <= amount) {
itemstack = this.slots[slotId];
this.slots[slotId] = null;
markDirty();
return itemstack;
} else {
ItemStack temp = this.slots[slotId];
itemstack = temp.splitStack(amount);
this.slots[slotId] = temp;
if (temp.stackSize == 0) {
this.slots[slotId] = null;
} else {
this.slots[slotId] = temp;
}
markDirty();
return itemstack;
}
}
@Override
public String getInventoryName() {
return this.customName;
}
@Override
public int getInventoryStackLimit() {
return this.stackLimit;
}
@Override
public int getSizeInventory() {
return this.slots.length;
}
@Override
public ItemStack getStackInSlot(int i) {
return this.slots[i];
}
@Override
public ItemStack getStackInSlotOnClosing(int slotId) {
return this.slots[slotId];
}
@Override
public boolean hasCustomInventoryName() {
return false;
}
public ItemStack incrStackSize(int slotId, int amount) {
ItemStack slot = this.slots[slotId];
if (slot == null)
return null;
int stackLimit = getInventoryStackLimit();
if (stackLimit > slot.getMaxStackSize())
stackLimit = slot.getMaxStackSize();
ItemStack added = slot.copy();
added.stackSize = slot.stackSize + amount > stackLimit ? stackLimit
: amount;
slot.stackSize += added.stackSize;
return added;
}
@Override
public boolean isItemValidForSlot(int i, ItemStack itemstack) {
return true;
}
@Override
public boolean isUseableByPlayer(EntityPlayer entityplayer) {
return true;
}
@Override
public void markDirty() {
if (this.receiver != null)
this.receiver.onInventoryChanged();
}
@Override
public void openInventory() {
// NOBODY needs this!
}
public void readFromNBT(NBTTagList nbtList) {
if(nbtList == null){
for(int i = 0; i < slots.length; i++){
slots[i] = null;
}
return;
}
for (int i = 0; i < nbtList.tagCount(); ++i) {
NBTTagCompound nbttagcompound = nbtList.getCompoundTagAt(i);
int j = nbttagcompound.getByte("Slot") & 255;
if (j >= 0 && j < this.slots.length) {
this.slots[j] = ItemStack.loadItemStackFromNBT(nbttagcompound);
}
}
}
@Override
public void setInventorySlotContents(int slotId, ItemStack itemstack) {
if (itemstack != null && itemstack.stackSize > getInventoryStackLimit()) {
itemstack.stackSize = getInventoryStackLimit();
}
this.slots[slotId] = itemstack;
markDirty();
}
public NBTTagList writeToNBT() {
NBTTagList nbtList = new NBTTagList();
for (int i = 0; i < this.slots.length; ++i) {
if (this.slots[i] != null) {
NBTTagCompound nbttagcompound = new NBTTagCompound();
nbttagcompound.setByte("Slot", (byte) i);
this.slots[i].writeToNBT(nbttagcompound);
nbtList.appendTag(nbttagcompound);
}
}
return nbtList;
}
}
P.S. Это аддон для AE2, так что тут много странных методов, по типу "getGridNode", на них можно не обращать внимание, как я убедился они никак не влияют на проблему
Последнее редактирование: