Jump to content

Any way to store unique data per block placement?


Lycanus Darkbinder

Recommended Posts

Given that Minecraft only uses one instance of a particular Block class, it makes it difficult to save unique data each time a block is placed in the world.

 

I'm trying to save some data about a block (two booleans and an array of neighboring block IDs and metadata) when onBlockAdded() is called. Naturally this information can't simply be stored in a local variable because each time onBlockAdded() is called it overwrites the previous data.

 

Is there any storage mechanism besides metadata that allows us to save unique data about an instance of a block?

 

Thanks.

 

 

PS:

 

I know I can write lookup functions to accomplish the same as the boolean values but I figured it would be a performance hit to drill down into World() for some info when I can just look it up once and save it until the block is destroyed.

 

The array is used by a lookup function called WhichBlockChanged() which is called from onNeighborBlockChange() since this function oddly gives the block its own coordinates instead of those of the block that changed.

Link to comment
Share on other sites

Given that Minecraft only uses one instance of a particular Block class, it makes it difficult to save unique data each time a block is placed in the world.

 

I'm trying to save some data about a block (two booleans and an array of neighboring block IDs and metadata) when onBlockAdded() is called. Naturally this information can't simply be stored in a local variable because each time onBlockAdded() is called it overwrites the previous data.

 

Is there any storage mechanism besides metadata that allows us to save unique data about an instance of a block?

 

Thanks.

 

 

PS:

 

I know I can write lookup functions to accomplish the same as the boolean values but I figured it would be a performance hit to drill down into World() for some info when I can just look it up once and save it until the block is destroyed.

 

The array is used by a lookup function called WhichBlockChanged() which is called from onNeighborBlockChange() since this function oddly gives the block its own coordinates instead of those of the block that changed.

Link to comment
Share on other sites

Sounds like you want to make a tile entity.  Try the wiki page on it.

 

http://www.minecraftforge.net/wiki/Tile_Entities

 

Interesting. I just came back to reply that I had figured it out by creating my own ArrayList to track the info I needed. From the link you provided it's similar to a TileEntity.

 

In case anyone is interested, here's my code. It can be used as a blueprint where all you need to do is create your own "FencePostInfo" class (or whatever).

 

 

I created a class called FencePostInfo that contains two booleans and an array of 6 integers. I then store this in an ArrayList in my FencePost class and use accessor functions to add / remove instances of FencePostInfo.

 

    private static ArrayList<FencePostInfo> infList = new ArrayList<FencePostInfo>();
    private static ArrayList<String> infListIdx = new ArrayList<String>();

 

infListIdx is used as a lookup table for indices into infList by converting the xyz of the block into a string and using infListIdx.indexOf().

 

    private int addToInfList(int x, int y, int z)
    {
        // Adds an instance of FencePostInfo to the list
        //  and tracks the lookup key using the block's coordinates
        
        // Initialize private info for this block
        FencePostInfo i = new FencePostInfo (this.blockID, x, y, z);
        infList.add(i);
        infListIdx.add(coordsToString(x, y, z));

        return getInfListIdx(x, y, z); // return the index of our new entry
    }

    private void removeFromInfList(int x, int y, int z)
    {
        // Removes an instance of FencePostInfo from the list
        //  and delete it's index tracking entry

        int i = getInfListIdx(x, y, z);
        
        // If object doesn't exist, i = -1
        if (i > -1)
        {
            FencePostInfo ri = infList.get(i);
        
            if (ri != null)
            {
                infList.remove(i); // remove the instance
                infListIdx.remove(i); // remove the index tracker
                ri = null;
            }
        }
    }
    
    private FencePostInfo getInfo(int x, int y, int z)
    {
        // Allows access to a FencePostInfo instance

        int i = this.getInfListIdx(x, y, z);
        
        if (i == -1)
        {
            // instance didn't exist, make one so we don't crash
            addToInfList(x, y, z);
            i = this.getInfListIdx(x, y, z);
        }
        
        return infList.get(i);
    }

    private int getInfListIdx(int x, int y, int z)
    {
        // Returns the index of the FencePostInfo represented
        //  by the coordinate string so we can retrieve it from infList

        return infListIdx.indexOf(coordsToString(x, y, z));
    }

    private String coordsToString(int x, int y, int z)
    {
        // Converts a coordinate to a string
        //  in the format xN, yN, zN
        
        return "x" + x + "y" + y + "z" + z;
    }

 

 

I can then use it anywhere in my class like this:

 

boolean isBottom = getInfo(par1, par2, par3).isOnBottom()

 

It has quite a bit of flexibility. For example, I can add any fields and methods to FencePostInfo that I want such as a unique GUID for the block using Math.Random() and then use that info to make decisions when the block is destroyed, etc.

 

Note: The current implementation does not save ArrayList...it only works if you only "quit to title" and don't close Minecraft. Need to implement saving this to disk (it's more lightweight than a TileEntity).

Link to comment
Share on other sites

Sounds like you want to make a tile entity.  Try the wiki page on it.

 

http://www.minecraftforge.net/wiki/Tile_Entities

 

Interesting. I just came back to reply that I had figured it out by creating my own ArrayList to track the info I needed. From the link you provided it's similar to a TileEntity.

 

In case anyone is interested, here's my code. It can be used as a blueprint where all you need to do is create your own "FencePostInfo" class (or whatever).

 

 

I created a class called FencePostInfo that contains two booleans and an array of 6 integers. I then store this in an ArrayList in my FencePost class and use accessor functions to add / remove instances of FencePostInfo.

 

    private static ArrayList<FencePostInfo> infList = new ArrayList<FencePostInfo>();
    private static ArrayList<String> infListIdx = new ArrayList<String>();

 

infListIdx is used as a lookup table for indices into infList by converting the xyz of the block into a string and using infListIdx.indexOf().

 

    private int addToInfList(int x, int y, int z)
    {
        // Adds an instance of FencePostInfo to the list
        //  and tracks the lookup key using the block's coordinates
        
        // Initialize private info for this block
        FencePostInfo i = new FencePostInfo (this.blockID, x, y, z);
        infList.add(i);
        infListIdx.add(coordsToString(x, y, z));

        return getInfListIdx(x, y, z); // return the index of our new entry
    }

    private void removeFromInfList(int x, int y, int z)
    {
        // Removes an instance of FencePostInfo from the list
        //  and delete it's index tracking entry

        int i = getInfListIdx(x, y, z);
        
        // If object doesn't exist, i = -1
        if (i > -1)
        {
            FencePostInfo ri = infList.get(i);
        
            if (ri != null)
            {
                infList.remove(i); // remove the instance
                infListIdx.remove(i); // remove the index tracker
                ri = null;
            }
        }
    }
    
    private FencePostInfo getInfo(int x, int y, int z)
    {
        // Allows access to a FencePostInfo instance

        int i = this.getInfListIdx(x, y, z);
        
        if (i == -1)
        {
            // instance didn't exist, make one so we don't crash
            addToInfList(x, y, z);
            i = this.getInfListIdx(x, y, z);
        }
        
        return infList.get(i);
    }

    private int getInfListIdx(int x, int y, int z)
    {
        // Returns the index of the FencePostInfo represented
        //  by the coordinate string so we can retrieve it from infList

        return infListIdx.indexOf(coordsToString(x, y, z));
    }

    private String coordsToString(int x, int y, int z)
    {
        // Converts a coordinate to a string
        //  in the format xN, yN, zN
        
        return "x" + x + "y" + y + "z" + z;
    }

 

 

I can then use it anywhere in my class like this:

 

boolean isBottom = getInfo(par1, par2, par3).isOnBottom()

 

It has quite a bit of flexibility. For example, I can add any fields and methods to FencePostInfo that I want such as a unique GUID for the block using Math.Random() and then use that info to make decisions when the block is destroyed, etc.

 

Note: The current implementation does not save ArrayList...it only works if you only "quit to title" and don't close Minecraft. Need to implement saving this to disk (it's more lightweight than a TileEntity).

Link to comment
Share on other sites

Note: The current implementation does not save ArrayList...it only works if you only "quit to title" and don't close Minecraft. Need to implement saving this to disk.

 

This is all handled by the Tile Entity.  I know it's a pain to implement, but it means it gets saved with the world file. 

Link to comment
Share on other sites

Note: The current implementation does not save ArrayList...it only works if you only "quit to title" and don't close Minecraft. Need to implement saving this to disk.

 

This is all handled by the Tile Entity.  I know it's a pain to implement, but it means it gets saved with the world file. 

Link to comment
Share on other sites

Your supposed 'saving of resources' is flawed. if someone where to build a massive fence based structure and then those chunks where unloaded, rinse lather repeat, you would leave the print of all of those blocks in the system(the more you put, the slower saving and loading gets...), unless you used system resources to load and offload the values as needed, basically you either suffer one way or another... so tile entity is your best bet.

I think its my java of the variables.

Link to comment
Share on other sites

Your supposed 'saving of resources' is flawed. if someone where to build a massive fence based structure and then those chunks where unloaded, rinse lather repeat, you would leave the print of all of those blocks in the system(the more you put, the slower saving and loading gets...), unless you used system resources to load and offload the values as needed, basically you either suffer one way or another... so tile entity is your best bet.

I think its my java of the variables.

Link to comment
Share on other sites

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.



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Considering the financial revolution sparked by cryptocurrencies like Bitcoin, the digital era has opened up a plethora of opportunities. But this exciting new world also comes with a terrible reality: in the harsh, brutal blockchain environment, there's always a danger you could lose your precious digital assets. Services like ADWARE RECOVERY SPECIALIST are not merely recovery agents in this case; they are crypto lifelines, and my own experience attests to their vital importance. I had an amazing time exploring the world of Bitcoin on my own; it was exciting to be in a completely new place and to see the possibility of independent money. However, a careless mistake of choosing the incorrect platform for my investment sent me into total despair. It seemed as though my digital lifeblood, Bitcoin, had been devoured by the blockchain's vicious maw. Overwhelmed with hope, I began a frantic quest for solutions, looking up any clue of assistance on the internet. I discovered  ADWARE RECOVERY SPECIALIST at that point.  Initially, I was filled with misgivings, but their unwavering professionalism and clear communication offered me a glimpse of hope. I set them the very impossible task of locating my missing fortune. The ADWARE RECOVERY SPECIALIST team of professionals meticulously penetrated the labyrinthine depths of the blockchain with the aid of cutting-edge technology and years of honed experience, treating my case with the utmost care and respect and keeping me informed at every turn. I had never encountered anything like the recuperation process. The days of confusing technical jargon and excruciatingly long wait times were over. And then the miraculous happened. My Bitcoin miraculously reappeared in my wallet, coming safe and sound from the digital void in an almost amazing length of time. Integrating  ADWARE RECOVERY SPECIALIST into your Bitcoin recovery process is not as magical as waving a wand, but it sure feels like it with the seamless and effective tools it offers. By following best practices, training your staff, and learning from successful case studies, you can optimize your Bitcoin recovery efforts and stay ahead of potential risks. The future outlook for Bitcoin recovery with ADWARE RECOVERY SPECIALIST looks promising, providing users with the confidence and tools they need to navigate the ever-evolving landscape of digital assets. It was a very happy moment that showcased the ADWARE RECOVERY SPECIALIST team's remarkable talent and dedication. However, my experience serves more purposes than just self-interest; it serves as a sobering reminder of the expanding demand for dependable and trustworthy bitcoin recovery services, such as ADWARE online recovery.
    • Quick-Books is great with regards to coordinating your monetary data. You can decide to live talk with a specialist at Quick-Books to get the answer for your questions. You will actually want to get to the talk going to the landing page and call us +1855-210-1428.
    • Update: I managed to make the item not disappear after crafting, but it doesn't remove any durability. import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.enchantment.Enchantments; import net.minecraft.enchantment.UnbreakingEnchantment; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; public class NuggetHammer extends Item { private boolean damage; public NuggetHammer(Properties p_i48487_1_) { super(p_i48487_1_); } @Override public int getMaxDamage(ItemStack stack) { return 54 - 1; } public boolean isBarVisible(ItemStack stack) { return false; } @Override public ItemStack getContainerItem(ItemStack stack) { ItemStack copy = stack.copy(); copy.setCount(1); if (!this.damage) return copy; int unbreaking = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.UNBREAKING, stack); for (int i = 0; i < unbreaking; i++) { if (UnbreakingEnchantment.shouldIgnoreDurabilityDrop(stack, unbreaking, random)) return copy; } copy.setDamageValue(stack.getDamageValue() + 1); if (copy.getDamageValue() > stack.getMaxDamage()) return ItemStack.EMPTY; return copy; } }  
  • Topics

×
×
  • Create New...

Important Information

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