Jump to content
Search In
  • More options...
Find results that contain...
Find results in...

Am I able to save a list of TileEntities to CompoundNBT


CriscoMods
 Share

Recommended Posts

//saving all tile entities
List<CompoundNBT> connectedEntities = new ArrayList<>();
CompoundNBT entity;
for (int entityInList = 0; entityInList <= this.masterEntity.connectedEntities.size();entityInList++)
{
    entity = new CompoundNBT();
    entity.putInt("x",this.masterEntity.connectedEntities.get(entityInList).pos.getX());
    entity.putInt("y",this.masterEntity.connectedEntities.get(entityInList).pos.getY());
    entity.putInt("z",this.masterEntity.connectedEntities.get(entityInList).pos.getZ());
    connectedEntities.add(entity);
}
compound.put("connectedEntities", (INBT) connectedEntities);  
 //restore saved entities
    List<CompoundNBT> connectedEntities = (List<CompoundNBT>) compound.get("connectedEntities");
    CompoundNBT entity;
   if (connectedEntities!= null){
    for (int entityInList = 0; entityInList < connectedEntities.size();entityInList++ )
{
    entity = connectedEntities.get(entityInList);
    this.masterEntity.connectedEntities.add((EngineeringBlockTileEntity)this.world.getTileEntity(new BlockPos(entity.getInt("x"),entity.getInt("y"),entity.getInt("z"))));
}}

 

So I'm trying to save list of TileEntities to a block, because the block uses the list to determine the number of blocks connected to each other. As the blocks are being placed the list expands. If I exit the world and comeback I cannot remove blocks that have already been placed.  It crashes when it attempts to remove that block from the connectedEntities list because the list is empty.

I'm trying to save it using the code above but it's not working. I just need some to be point me in the right direction.

@Override
public void onBlockHarvested(World worldIn, BlockPos pos, BlockState state, PlayerEntity player) {
    EngineeringBlockTileEntity entityRemoved = (EngineeringBlockTileEntity) worldIn.getTileEntity(pos);
   entityRemoved.masterEntity.connectedEntities.remove(entityRemoved);
   entityRemoved.masterEntity.blockCount = entityRemoved.masterEntity.connectedEntities.size();
    super.onBlockHarvested(worldIn, pos, state, player);
}

 

 

Link to comment
Share on other sites

Several issues:

  • For a start onBlockHarvested is not at all the right hook here. You need TileEntity#remove.
  • Your connections need to be lazy. As in: The TEs need to know only the positions and lazily query the world. During readFromNBT there is no world yet, you can't query the world for other TEs.
  • Like 1
Link to comment
Share on other sites

On 12/9/2020 at 8:17 AM, diesieben07 said:

Several issues:

  • For a start onBlockHarvested is not at all the right hook here. You need TileEntity#remove.
  • Your connections need to be lazy. As in: The TEs need to know only the positions and lazily query the world. During readFromNBT there is no world yet, you can't query the world for other TEs.

Okay so I've simplified my connections a great deal. I've Overrided neighborChange. As blocks are added I pass a "masterEntity" to each block so that everyone is capable of updating this multiBlock blockCount to the masterEntity. Instead of having a list of tileEntities I opted for a list of BlockPos like you mentioned.  As I'm writing this I realize I can pass a blockCount to each block instead meaning that I could maybe remove the blockPos list (still not sure what I will do). Then I can use the NBT system to store the block count.

@Override
public void onNeighborChange(BlockState state, IWorldReader world, BlockPos pos, BlockPos neighbor){


        if (world.getTileEntity(neighbor) instanceof EngineeringBlockTileEntity)
        {
            //pass master from this block to the next
            EngineeringBlockTileEntity neighborEntity = (EngineeringBlockTileEntity) world.getTileEntity(neighbor);
            EngineeringBlockTileEntity thisEntity = (EngineeringBlockTileEntity)world.getTileEntity(pos);
            neighborEntity.masterEntity = thisEntity.masterEntity;
            //add neighbor block position to list of master list
            if (!thisEntity.masterEntity.connectedBlocks.contains(neighbor)) {
                neighborEntity.masterEntity.connectedBlocks.add(neighbor);
            }
            //update blockCount
            neighborEntity.masterEntity.blockCount = neighborEntity.masterEntity.connectedBlocks.size();
            System.out.println(neighborEntity.masterEntity.blockCount);
        }
   }

Then for removing blocks from the list  I used remove() as you suggested and woah simple as heck

@Override
public void remove() {

    if (this.masterEntity != null)
    {
        this.masterEntity.connectedBlocks.remove(this.getPos());
    }
    super.remove();
}

I may not have completly understood and implemented a lazy query as you suggested but I was able to get this to work using

less code because of your suggestion. I'm still trying to figure out how to have the block query around them upon reloading of a world.

 Thank you for your help it is much appreciated.

Edited by CriscoMods
Link to comment
Share on other sites

5 hours ago, Vinyarion said:

Your tile entity could have a flag that starts as true at construction, then in the tick method, if(flag){flag=false;/* check for surrounding blocks */}

Good Idea. Works :) Ended up doing this 

 

if (this.InitializeBlocks)
{
    if (this.isMaster) {this.setMaster(); }
    this.lazyQuery();
    this.updateMasterBlockList();

}

IntializeBlocks is set to true upon initialization, but to prevent this piece of code from running in a tick when the block is placed for the first time I set it to false . The flag is also set false in function updateMasterBlockList

@Override
public void onBlockPlacedBy(World worldIn, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) {
    EngineeringBlockTileEntity thisBlock = ((EngineeringBlockTileEntity) worldIn.getTileEntity(pos));
    if (stack.hasDisplayName()) { TileEntity tile = worldIn.getTileEntity(pos);
        if (tile instanceof EngineeringBlockTileEntity) { thisBlock.setCustomName(stack.getDisplayName()); }
    }
    //don't initialize blocks upon placement
    thisBlock.InitializeBlocks = false;
    if (thisBlock.isAlone()) { thisBlock.setMaster(); System.out.println(thisBlock.isMaster);}
    super.onBlockPlacedBy(worldIn, pos, state, placer, stack);

}

 

Edited by CriscoMods
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
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.

 Share



×
×
  • Create New...

Important Information

By using this site, you agree to our Privacy Policy.