Jump to content

Recommended Posts

Posted

Hello, I have a custom furnace were the gui does not not rely on the block or a Tile Entity, similar to the way that the Crafting Table is coded, but I have a strange bug, it smelts the item fine and appears to delete what is in the first slot but when you click on the slot a item just appears and can bee smelted again. I have made sure that I am deleting what is in the first slot, but it does not seem to work. I am pretty sure that the handling of inventories and this sort of stuff is done on the server side and I do believe that is being called on the server side because I have my tick handler handle the updating of the inventory. I would appreciate any help that anyone can give because I have had this bug for a week and I have spent hours upon hours to try and figure it out, but I can't seem to figure it out.

 

(Note Code May Be Messy Due To Testing and Lazyness)

 

Inventory Code

 

package mod.xtronius.rc_mod.inventory;

 

import mod.xtronius.rc_mod.rc_mod;

import mod.xtronius.rc_mod.container.Furnace1Container;

import mod.xtronius.rc_mod.furnaceRecipies.RCCastFurnace1Recipes;

import mod.xtronius.rc_mod.furnaceRecipies.RCIngotFurnace1Recipes;

import mod.xtronius.rc_mod.handlers.ServerTickHandler;

import net.minecraft.entity.Entity;

import net.minecraft.entity.player.EntityPlayer;

import net.minecraft.entity.player.EntityPlayerMP;

import net.minecraft.inventory.Container;

import net.minecraft.inventory.IInventory;

import net.minecraft.item.Item;

import net.minecraft.item.ItemStack;

import net.minecraft.item.crafting.FurnaceRecipes;

import net.minecraft.nbt.NBTTagCompound;

import net.minecraft.nbt.NBTTagList;

import net.minecraft.world.World;

import net.minecraftforge.common.IExtendedEntityProperties;

 

public class InvFurnace1 implements IExtendedEntityProperties ,  IInventory

{

 

private Furnace1Container eventHandler;

 

private static final int[] slots_side_left= new int[] {0};

    private static final int[] slots_mid = new int[] {1};

    private static final int[] slots_side_right = new int[] {2};

   

    private ServerTickHandler tick = rc_mod.proxy.getServerTickHandler();

   

    private ItemStack[] furnaceItemStacks = new ItemStack[3];

   

public InvFurnace1(Container container, World world, EntityPlayer player, int x, int y, int z) {

 

tick.furnace1ContainerMap.put(player, (Furnace1Container) container);

this.eventHandler = (Furnace1Container) container;

}

 

/**

    * Returns the number of slots in the inventory.

    */

    public int getSizeInventory()

    {

        return this.furnaceItemStacks.length;

    }

 

    /**

    * Returns the stack in slot i

    */

    public ItemStack getStackInSlot(int par1)

    {

        return par1 >= this.getSizeInventory() ? null : this.furnaceItemStacks[par1];

    }

 

    /**

    * Returns the name of the inventory.

    */

    public String getInvName()

    {

        return "container.furnace";

    }

 

    /**

    * If this returns false, the inventory name will be used as an unlocalized name, and translated into the player's

    * language. Otherwise it will be used directly.

    */

    public boolean isInvNameLocalized()

    {

        return false;

    }

 

    /**

    * 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 par1)

    {

        if (this.furnaceItemStacks[par1] != null)

        {

            ItemStack itemstack = this.furnaceItemStacks[par1];

            this.furnaceItemStacks[par1] = null;

            return itemstack;

        }

        else

        {

            return null;

        }

    }

 

    /**

    * Removes from an inventory slot (first arg) up to a specified number (second arg) of items and returns them in a

    * new stack.

    */

    public ItemStack decrStackSize(int par1, int par2)

    {

        if (this.furnaceItemStacks[par1] != null)

        {

            ItemStack itemstack;

 

            if (this.furnaceItemStacks[par1].stackSize <= par2)

            {

                itemstack = this.furnaceItemStacks[par1];

                this.furnaceItemStacks[par1] = null;

                this.eventHandler.onCraftMatrixChanged(this);

                return itemstack;

            }

            else

            {

                itemstack = this.furnaceItemStacks[par1].splitStack(par2);

 

                if (this.furnaceItemStacks[par1].stackSize == 0)

                {

                    this.furnaceItemStacks[par1] = null;

                }

 

                this.eventHandler.onCraftMatrixChanged(this);

                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 par1, ItemStack par2ItemStack)

    {

        this.furnaceItemStacks[par1] = par2ItemStack;

        this.eventHandler.onCraftMatrixChanged(this);

    }

 

    /**

    * Returns the maximum stack size for a inventory slot. Seems to always be 64, possibly will be extended. *Isn't

    * this more of a set than a get?*

    */

    public int getInventoryStackLimit()

    {

        return 1;

    }

 

    /**

    * Called when an the contents of an Inventory change, usually

    */

    public void onInventoryChanged() {}

 

    /**

    * Do not make give this method the name canInteractWith because it clashes with Container

    */

    public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer)

    {

        return true;

    }

 

    public void openChest() {}

 

    public void closeChest() {}

 

    /**

    * Returns true if automation is allowed to insert the given stack (ignoring stack size) into the given slot.

    */

    public boolean isItemValidForSlot(int par1, ItemStack par2ItemStack)

    {

        return true;

    }

 

@Override

public void saveNBTData(NBTTagCompound compound) {

 

}

 

@Override

public void loadNBTData(NBTTagCompound compound) {

 

}

 

@Override

public void init(Entity entity, World world) {

 

}

}

 

 

Container Code

 

//TODO I just statrted converting the classes to have a better stucture, basically I need the container to handle all of the smelting because it is server side and ther inv needs to be clutter free and there was no definitive way to tell if the client or the server was calling the methods

 

 

package mod.xtronius.rc_mod.container;

 

import mod.xtronius.rc_mod.furnaceRecipies.RCCastFurnace1Recipes;

import mod.xtronius.rc_mod.furnaceRecipies.RCIngotFurnace1Recipes;

import mod.xtronius.rc_mod.inventory.InvFurnace1;

import net.minecraft.entity.player.EntityPlayer;

import net.minecraft.entity.player.EntityPlayerMP;

import net.minecraft.entity.player.InventoryPlayer;

import net.minecraft.inventory.Container;

import net.minecraft.inventory.ICrafting;

import net.minecraft.inventory.Slot;

import net.minecraft.item.Item;

import net.minecraft.item.ItemStack;

import net.minecraft.item.crafting.FurnaceRecipes;

import net.minecraft.world.World;

import cpw.mods.fml.relauncher.Side;

import cpw.mods.fml.relauncher.SideOnly;

 

public class Furnace1Container extends Container

{

private InvFurnace1 invFurnace;

public int furnaceCookTime;

    private int lastCookTime;

    private World worldObj;

    private int xPos;

    private int yPos;

    private int zPos;

   

    private Item itemToBeSmelted;

    private boolean hasItemBeenSmelted = false;

   

    public static final int SMELT_INGOT = 0;

    public static final int SMELT_CAST = 1;

    public static int  SMELT_TYPE;

 

    public Furnace1Container(InventoryPlayer playerInv, World world, int x, int y, int z)

    {

    this.invFurnace = new InvFurnace1(this, world, playerInv.player, x, y, z);

   

    this.worldObj = world;

    this.xPos = x;

    this.yPos = y;

    this.xPos = z;

   

        this.addSlotToContainer(new Slot(this.invFurnace, 0, 60, 110));

        this.addSlotToContainer(new Slot(this.invFurnace, 1, 88, 110));

      // this.addSlotToContainer(new SlotFurnace1(playerInv.player, inv, 2, 156, 110));

       

        byte b0 = 36;

        short short1 = 137;

        int i;

 

        for (i = 0; i < 3; ++i)

        {

            for (int j = 0; j < 9; ++j)

            {

                this.addSlotToContainer(new Slot(playerInv, j + i * 9 + 9, b0 + j * 18, short1 + i * 18));

            }

        }

 

        for (i = 0; i < 9; ++i)

        {

            this.addSlotToContainer(new Slot(playerInv, i, b0 + i * 18, 58 + short1));

        }

    }

    public Item getItemToBeSmelted() {

if(this.itemToBeSmelted != null)

return itemToBeSmelted;

else return Item.arrow;

}

 

public void setItemToBeSmelted(Item item) {

if(item != null)

this.itemToBeSmelted = item;

}

    public InvFurnace1 getInv() {

    return this.invFurnace;

    }

 

    public void addCraftingToCrafters(ICrafting par1ICrafting)

    {

        super.addCraftingToCrafters(par1ICrafting);

        par1ICrafting.sendProgressBarUpdate(this, 0, this.furnaceCookTime);

    }

 

    /**

    * Looks for changes made in the container, sends them to every listener.

    */

    public void detectAndSendChanges()

    {

        super.detectAndSendChanges();

 

        for (int i = 0; i < this.crafters.size(); ++i)

        {

            ICrafting icrafting = (ICrafting)this.crafters.get(i);

 

            if (this.lastCookTime != this.furnaceCookTime)

            {

                icrafting.sendProgressBarUpdate(this, 0, this.furnaceCookTime);

            }

        }

 

        this.lastCookTime = this.furnaceCookTime;

    }

 

    @SideOnly(Side.CLIENT)

    public void updateProgressBar(int par1, int par2)

    {

        if (par1 == 0)

        {

            this.furnaceCookTime = par2;

        }

    }

 

    public boolean canInteractWith(EntityPlayer par1EntityPlayer)

    {

        return this.invFurnace.isUseableByPlayer(par1EntityPlayer);

    }

   

    public void onContainerClosed(EntityPlayer player)

    {

        super.onContainerClosed(player);

 

        if (!player.worldObj.isRemote)

        {

            for (int i = 0; i < 3; ++i)

            {

                ItemStack itemstack = this.invFurnace.getStackInSlotOnClosing(i);

 

                if (itemstack != null)

                {

                    player.dropPlayerItem(itemstack);

                }

            }

        }

    }

 

    /**

    * Called when a player shift-clicks on a slot. You must override this or you will crash when someone does that.

    */

    public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int par2)

    {

        ItemStack itemstack = null;

        Slot slot = (Slot)this.inventorySlots.get(par2);

 

        if (slot == null && !slot.getHasStack())

        {

            ItemStack itemstack1 = slot.getStack();

            itemstack = itemstack1.copy();

            return null;

        }

        return null;

    }

   

    public boolean hasStackInSlots() {

 

for (int i = 0; i < 3; i++) {

if(this.invFurnace.getStackInSlot(i) != null) {

return true;

}

}

return false;

}

   

    public int getCookProgressScaled(int par1)

    {

        return this.furnaceCookTime * par1 / 200;

    }

   

    private boolean canSmelt()

    {

        if (this.invFurnace.getStackInSlot(0) == null)

        {

            return false;

        }

        else

        {

        ItemStack itemstack = RCIngotFurnace1Recipes.smelting().getSmeltingResult(this.invFurnace.getStackInSlot(0));

    ItemStack itemstack2 = RCCastFurnace1Recipes.smelting().getSmeltingResult(this.invFurnace.getStackInSlot(1));

       

        if (this.invFurnace.getStackInSlot(0) != null && this.invFurnace.getStackInSlot(1) == null) {

        SMELT_TYPE = SMELT_INGOT;

        }

       

        if (this.invFurnace.getStackInSlot(0) != null && this.invFurnace.getStackInSlot(1) != null) {

        SMELT_TYPE = SMELT_CAST;

        }

 

        if (SMELT_TYPE == SMELT_INGOT) {

        if (itemstack != null) {

                if (this.invFurnace.getStackInSlot(2) != null && this.invFurnace.getStackInSlot(2).isItemEqual(itemstack)) {

                int result = this.invFurnace.getStackInSlot(2).stackSize + itemstack.stackSize;

                return (result <= this.invFurnace.getInventoryStackLimit() && result <= itemstack.getMaxStackSize());

                } else if(this.invFurnace.getStackInSlot(2) == null){

                return true;

                }

        }

        }

        else if (SMELT_TYPE == SMELT_CAST) {

       

        if(itemstack != null && itemstack2 != null) {

       

        if(itemstack == itemstack2) {

        if (this.invFurnace.getStackInSlot(2) == null) return true;

                    if (!this.invFurnace.getStackInSlot(2).isItemEqual(itemstack)) return false;

                    int result = this.invFurnace.getStackInSlot(2).stackSize + itemstack.stackSize;

                    return (result <= this.invFurnace.getInventoryStackLimit() && result <= itemstack.getMaxStackSize());

            }

            else if(itemstack != itemstack){

            if (this.invFurnace.getStackInSlot(2) == null) return true;

                        if (!this.invFurnace.getStackInSlot(2).isItemEqual(itemstack)) return false;

                        int result = this.invFurnace.getStackInSlot(20).stackSize + itemstack.stackSize;

                        return (result <= this.invFurnace.getInventoryStackLimit() && result <= itemstack.getMaxStackSize());

            }

        }

        }

        }

return false;

    }

 

    public void smeltItem(EntityPlayer player)

    {

    System.out.println(player.username);

        if (this.canSmelt())

        {

            ItemStack itemstack = FurnaceRecipes.smelting().getSmeltingResult(this.invFurnace.getStackInSlotOnClosing(0));

 

            this.setItemToBeSmelted(itemstack.getItem());

           

//            if (this.furnaceItemStacks[2] == null)

//            {

//                this.furnaceItemStacks[2] = itemstack.copy();

//            }

//            else if (this.furnaceItemStacks[2].isItemEqual(itemstack))

//            {

//                furnaceItemStacks[2].stackSize += itemstack.stackSize;

//            }

           

            if(!(player.inventory.getFirstEmptyStack() < 0)) {

            if(player != null && player.inventory != null && player.inventory.getStackInSlot(player.inventory.getFirstEmptyStack()) == null) {

                player.inventory.addItemStackToInventory(itemstack.copy());

                System.out.println("Num: 1");

                this.invFurnace.setInventorySlotContents(0, null);

                this.onCraftMatrixChanged(this.invFurnace);

            }

            else {

            this.invFurnace.setInventorySlotContents(2, itemstack.copy());

            System.out.println("Num: 2");

            this.onCraftMatrixChanged(this.invFurnace);

            }

            }

            else if (player.inventory.getFirstEmptyStack() < 0) {

            if(this.invFurnace.getStackInSlot(2) == null) {

            this.invFurnace.setInventorySlotContents(2, itemstack.copy());

            System.out.println("Num: 3");

            this.onCraftMatrixChanged(this.invFurnace);

            }

            }

        }

    }

   

    public void update(EntityPlayerMP player) {

if(this.invFurnace.getStackInSlot(2) != null && !(player.inventory.getFirstEmptyStack() < 0)) {

if(player != null && player.inventory != null && player.inventory.getStackInSlot(player.inventory.getFirstEmptyStack()) == null) {

player.inventory.addItemStackToInventory(this.invFurnace.getStackInSlot(2).copy());

this.invFurnace.setInventorySlotContents(2, null);

}

        }

        boolean flag = false;

 

            if (this.canSmelt())

            {

                ++this.furnaceCookTime;

 

                if (this.furnaceCookTime == 5)

                {

                    this.furnaceCookTime = 0;

                    this.smeltItem(player);

                    flag = true;

                }

            }

            else

                this.furnaceCookTime = 0;

           

            if(flag)

            this.hasItemBeenSmelted = true;

        }

}

 

 

 

Tick handler

 

package mod.xtronius.rc_mod.handlers;

 

import java.util.EnumSet;

import java.util.HashMap;

 

import mod.xtronius.rc_mod.commands.Tutorial;

import mod.xtronius.rc_mod.container.Furnace1Container;

import mod.xtronius.rc_mod.inventory.InvFurnace1;

import mod.xtronius.rc_mod.util.RCPlayer;

import mod.xtronius.rc_mod.util.event.EventBlockReplace;

import net.minecraft.entity.player.EntityPlayer;

import net.minecraft.entity.player.EntityPlayerMP;

import cpw.mods.fml.common.ITickHandler;

import cpw.mods.fml.common.TickType;

import cpw.mods.fml.relauncher.Side;

import cpw.mods.fml.relauncher.SideOnly;

 

public class ServerTickHandler implements ITickHandler {

 

public static HashMap<EntityPlayer, Furnace1Container> furnace1ContainerMap = new HashMap<EntityPlayer, Furnace1Container>();

 

@Override

public void tickStart(EnumSet<TickType> type, Object... tickData) {

 

if (type.equals(EnumSet.of(TickType.PLAYER))) {

onEntityPlayerTick((EntityPlayer) tickData[0]);

onEntityPlayerMPTick((EntityPlayerMP) tickData[0]);

}

}

 

@Override

public void tickEnd(EnumSet<TickType> type, Object... tickData) {

}

 

@Override

public EnumSet<TickType> ticks() {

 

return EnumSet.of(TickType.PLAYER, TickType.SERVER, TickType.CLIENT);

}

 

@Override

public String getLabel() {

return null;

}

 

private void onEntityPlayerTick(EntityPlayer player) {

 

managePlayerXP(player);

}

 

private void tickFurnace1(EntityPlayerMP player) {

 

if(furnace1ContainerMap.get(player) != null) {

Furnace1Container container = furnace1ContainerMap.get(player);

if(container.hasStackInSlots()) {

container.update(player);

System.out.println("ticking");

}

}

}

 

 

 

private void onEntityPlayerMPTick(EntityPlayerMP player) {

 

if(!player.worldObj.isRemote) {

tickFurnace1(player);

}

}

 

 

 

I think that is all the code that is needed, but please ask if you need more!

 

Thank You!!!

 

Don't be afraid to ask question when modding, there are no stupid question! Unless you don't know java then all your questions are stupid!

Posted

Can some one please help me with my problem?

Don't be afraid to ask question when modding, there are no stupid question! Unless you don't know java then all your questions are stupid!

Posted

I don't think that that is the solution because I got the inv. code from the crafting table and that is what it had in the the class. Plus I tested it and it was returning null all the time because the slot number would always be less than 2, which is the number of slots, and that made it return null all of the time.

Don't be afraid to ask question when modding, there are no stupid question! Unless you don't know java then all your questions are stupid!

Posted

Does anyone have any other solutions that can work for my problem. I would really appreciate the help.

Don't be afraid to ask question when modding, there are no stupid question! Unless you don't know java then all your questions are stupid!

  • 2 weeks later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • This is the last line before the crash: [ebwizardry]: Synchronising spell emitters for PixelTraveler But I have no idea what this means
    • What in particular? I barely used that mod this time around, and it's never been a problem in the past.
    • Im trying to build my mod using shade since i use the luaj library however i keep getting this error Reason: Task ':reobfJar' uses this output of task ':shadowJar' without declaring an explicit or implicit dependency. This can lead to incorrect results being produced, depending on what order the tasks are executed. So i try adding reobfJar.dependsOn shadowJar  Could not get unknown property 'reobfJar' for object of type org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler. my gradle file plugins { id 'eclipse' id 'idea' id 'maven-publish' id 'net.minecraftforge.gradle' version '[6.0,6.2)' id 'com.github.johnrengelman.shadow' version '7.1.2' id 'org.spongepowered.mixin' version '0.7.+' } apply plugin: 'net.minecraftforge.gradle' apply plugin: 'org.spongepowered.mixin' apply plugin: 'com.github.johnrengelman.shadow' version = mod_version group = mod_group_id base { archivesName = mod_id } // Mojang ships Java 17 to end users in 1.18+, so your mod should target Java 17. java.toolchain.languageVersion = JavaLanguageVersion.of(17) //jarJar.enable() println "Java: ${System.getProperty 'java.version'}, JVM: ${System.getProperty 'java.vm.version'} (${System.getProperty 'java.vendor'}), Arch: ${System.getProperty 'os.arch'}" minecraft { mappings channel: mapping_channel, version: mapping_version copyIdeResources = true runs { configureEach { workingDirectory project.file('run') property 'forge.logging.markers', 'REGISTRIES' property 'forge.logging.console.level', 'debug' arg "-mixin.config=derp.mixin.json" mods { "${mod_id}" { source sourceSets.main } } } client { // Comma-separated list of namespaces to load gametests from. Empty = all namespaces. property 'forge.enabledGameTestNamespaces', mod_id } server { property 'forge.enabledGameTestNamespaces', mod_id args '--nogui' } gameTestServer { property 'forge.enabledGameTestNamespaces', mod_id } data { workingDirectory project.file('run-data') args '--mod', mod_id, '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/') } } } sourceSets.main.resources { srcDir 'src/generated/resources' } repositories { flatDir { dirs './libs' } maven { url = "https://jitpack.io" } } configurations { shade implementation.extendsFrom shade } dependencies { minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}" implementation 'org.luaj:luaj-jse-3.0.2' implementation fg.deobf("com.github.Virtuoel:Pehkui:${pehkui_version}") annotationProcessor 'org.spongepowered:mixin:0.8.5:processor' minecraftLibrary 'luaj:luaj-jse:3.0.2' shade 'luaj:luaj-jse:3.0.2' } // Example for how to get properties into the manifest for reading at runtime. tasks.named('jar', Jar).configure { manifest { attributes([ 'Specification-Title' : mod_id, 'Specification-Vendor' : mod_authors, 'Specification-Version' : '1', // We are version 1 of ourselves 'Implementation-Title' : project.name, 'Implementation-Version' : project.jar.archiveVersion, 'Implementation-Vendor' : mod_authors, 'Implementation-Timestamp': new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"), "TweakClass" : "org.spongepowered.asm.launch.MixinTweaker", "TweakOrder" : 0, "MixinConfigs" : "derp.mixin.json" ]) } rename 'mixin.refmap.json', 'derp.mixin-refmap.json' } shadowJar { archiveClassifier = '' configurations = [project.configurations.shade] finalizedBy 'reobfShadowJar' } assemble.dependsOn shadowJar reobf { re shadowJar {} } publishing { publications { mavenJava(MavenPublication) { artifact jar } } repositories { maven { url "file://${project.projectDir}/mcmodsrepo" } } } my entire project:https://github.com/kevin051606/DERP-Mod/tree/Derp-1.0-1.20
    • All versions of Minecraft Forge suddenly black screen even without mods (tried reinstalling original Minecraft, Java, updating drivers doesn't work)
  • Topics

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.