Jump to content

[1.7.10]MapGenStructure locations not getting saved when minecraft exits[Solved]


Recommended Posts

Posted

I have a structure generation in my mod

 

public class MapGenEntropyTemple extends MapGenStructure {
}

 

and it works beautifully, it generates the entropy temple as it should.

 

There is only one caveat, the MapGenStructureData doesn't get saved the moment minecraft closes and then gets started again.

 

Al the locations I could poll(very accurately, I have my boundingboxes fit nice and tight around my sections)

 

StuffLoader.worldGenerator.genEntropyTemple.hasStructureAt(player.worldObj,(int)player.posX, (int)player.posY, (int)player.posZ)

 

suddenly return false in the new minecraft session.

 

So they return true in the minecraft play session that generated the entropy temple.

But if the world is reloaded in a freshly (rebooted) minecraft, the lists are empty.

 

I kinda need to know what the trigger is so I can make sure minecraft actually saves the locations of the gen structure. This also is the cause why sometimes only half my entropy temples render, because it doesn't save its progress as it should to file.

 

So I might be missing something, a trigger, a value, and i'm hoping someone here knows what to do.

 

 

I have tried to trace it, and I found this in MapGenStructure

 

this.field_143029_e = (MapGenStructureData)p_143027_1_.perWorldStorage.loadData(MapGenStructureData.class, this.func_143025_a());

            if (this.field_143029_e == null)
            {
                this.field_143029_e = new MapGenStructureData(this.func_143025_a());
                p_143027_1_.perWorldStorage.setData(this.func_143025_a(), this.field_143029_e);
            }

 

and it seems to save and set everything, register it to the perWorldstorage, so it should be saved on world nbt save run. since i'm polling on player tick where the player is.

 

Yet when I poll the file directly after a minecraft restart, I get

 

x = (MapGenStructureData)player.worldObj.perWorldStorage.loadData(MapGenStructureData.class, "EntropyTemple");
				NBTTagCompound y = new NBTTagCompound();
				x.writeToNBT(y);
				MagicCookie.log.warn(y.toString());

{Features:{},} 

 

 

package tschallacka.magiccookies.worldgen.entropytemple;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Random;

import tschallacka.magiccookies.MagicCookie;
import tschallacka.magiccookies.settings.Preferences;
import net.minecraft.entity.monster.EntityBlaze;
import net.minecraft.entity.monster.EntityMagmaCube;
import net.minecraft.entity.monster.EntityPigZombie;
import net.minecraft.entity.monster.EntitySkeleton;
import net.minecraft.world.World;
import net.minecraft.world.biome.BiomeGenBase;
import net.minecraft.world.gen.structure.MapGenStructure;
import net.minecraft.world.gen.structure.StructureBoundingBox;
import net.minecraft.world.gen.structure.StructureComponent;
import net.minecraft.world.gen.structure.StructureStart;

public class MapGenEntropyTemple extends MapGenStructure
{

    private List<BiomeGenBase.SpawnListEntry> spawnList = new ArrayList<BiomeGenBase.SpawnListEntry>();
    private ArrayList<String> entitySpawns = new ArrayList<String>();
    private int spawnCounter = 0;

    public MapGenEntropyTemple()
    {
    	this.spawnList.add(new BiomeGenBase.SpawnListEntry(EntitySkeleton.class, 10, 4, 12));
        this.spawnList.add(new BiomeGenBase.SpawnListEntry(EntityBlaze.class, 10, 4, );
        //this.spawnList.add(new BiomeGenBase.SpawnListEntry(EntityPigZombie.class, 5, 4, 4));
        this.spawnList.add(new BiomeGenBase.SpawnListEntry(EntityMagmaCube.class, 3, 4, );
        this.entitySpawns.add("Skeleton");
        this.entitySpawns.add("Blaze");
        this.entitySpawns.add("Skeleton");
        this.entitySpawns.add("LavaSlime");
        this.entitySpawns.add("Skeleton");
        
    }
    public List<String> getSpawnEntities() {
    	return this.entitySpawns;
    }
    /** Unique save name for structure, used in MapGenStructure.func_143027_a() for loading/setting save handler **/
    public String func_143025_a()
    {
        return "EntropyTemple";
    }
    
    public boolean hasStructureAt(World world, int x, int y, int z)
    {
    	if(this.worldObj == null)
    		this.worldObj = world;
        return this.hasStructureAt(x, y, z);
    }

    public List getSpawnList()
    {
        return this.spawnList;
    }

    protected boolean canSpawnStructureAtCoords(int chunkX, int chunkZ)
    {
    	
        int x = chunkX >> 4;
        int z = chunkZ >> 4;
        this.rand.setSeed((long)(x ^ z << 4) ^ this.worldObj.getSeed());
        this.rand.nextInt();
        final boolean canSpawn = this.rand.nextInt( != 0 ? 
        												false : 
        												(chunkX != (x << 4) + 4 + this.rand.nextInt( ? 
        														false : 
        															chunkZ == (z << 4) + 4 + this.rand.nextInt();
        //boolean canSpawn = false;
        /*++this.spawnCounter;
        if(this.spawnCounter == (4096*45)) {
        	canSpawn = true;
        	this.spawnCounter = 0;
        	//MagicCookie.log.warn("Can spawn structure? "+(chunkX*16) + " : "+(chunkZ*16) +" =" + canSpawn);
        }*/
         
        return canSpawn; 
    }

    protected StructureStart getStructureStart(int chunkX, int chunkZ)
    {
        return new MapGenEntropyTemple.Start(this.worldObj, this.rand, chunkX, chunkZ);
    }

    public static class Start extends StructureStart
        {
    	
            public Start() {}

            public Start(World world, Random rand, int chunkX, int chunkZ)
            {
                super(chunkX, chunkZ);																	//zelfde als ChunkX * 16
                // retrieve the singular start piece
                StructureEntropyTemplePieces.Start start = new StructureEntropyTemplePieces.Start(rand, (chunkX << 4) + 2, (chunkZ << 4) + 2);
                // add the singular start piece to the components
                this.components.add(start);
                // place the blocks into the list. The entire primary structure is being built here.
                // the arraylist is being filled here, but also the list of components filled with the same things
                // This only utilised the primary pieces list
                start.buildComponent(start, this.components, rand);
                if(Preferences.entropyTempleSpawnLogging) {
                	MagicCookie.log.info("Entropy temple spawned at " + start.getBoundingBox().toString());
                }

                this.updateBoundingBox();
                //MagicCookie.log.warn("Complete structure bounding box = ");
                //MagicCookie.log.warn(this.getBoundingBox().toString());
                this.setRandomHeight(world, rand, 70, 128);
            }
        }
}

 

 

So, anyone know which methond/function I should trigger in MapGenStructure to make sure it saves to disk and gets read to disk? Any event handlers I should hook into for this?

 

Of course I can make my own save handlers for my own purposes, but i'd rather have it that this works so minecraft can keep my rather sizeable structures in account when placing nether fortresses or other generated structures.

 

It does that now in the same session, but not if the minecraft server or single player client gets restarted.

How much wood could a woodchuck chuck if a wood chuck could chuck wood - Guybrush Treepwood

 

I wrote my own mod ish... still a few bugs to fix. http://thaumcraft.duckdns.org/downloads/MagicCookies-1.0.6.4.jar

Posted

for those wondering how, you need to invoke func_143026_a of MapGenStructure in your structure gen class when you give back the start piece in the  protected StructureStart getStructureStart(int chunkX, int chunkZ) method.

 

 

How much wood could a woodchuck chuck if a wood chuck could chuck wood - Guybrush Treepwood

 

I wrote my own mod ish... still a few bugs to fix. http://thaumcraft.duckdns.org/downloads/MagicCookies-1.0.6.4.jar

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

    • If you’ve lost crypto to a scam, don’t let shame or fear keep you silent. There are real experts out there who know how to fight back. Dexdert Net Recovery did the impossible for me, and they can do it for others too. Contact Dexdet Net Recovery For Help Visa Information Below:    
    • Hi everyone, I'm currently developing a Forge 1.21 mod for Minecraft and I want to display a custom HUD overlay for a minigame. My goal: When the game starts, all players should see an item/block icon (from the base game, not a custom texture) plus its name/text in the HUD – similar to how the bossbar overlay works. The HUD should appear centered above the hotbar (or at a similar prominent spot), and update dynamically (icon and name change as the target item changes). What I've tried: I looked at many online tutorials and several GitHub repos (e.g. SeasonHUD, MiniHUD), but most of them use NeoForge or Forge versions <1.20 that provide the IGuiOverlay API (e.g. implements IGuiOverlay, RegisterGuiOverlaysEvent). In Forge 1.21, it seems that neither IGuiOverlay nor RegisterGuiOverlaysEvent exist anymore – at least, I can't import them and they are missing from the docs and code completion. I tried using RenderLevelStageEvent as a workaround but it is probably not intended for custom HUDs. I am not using NeoForge, and switching the project to NeoForge is currently not an option for me. I tried to look at the original minecraft source code to see how elements like hearts, hotbar etc are drawn on the screen but I am too new to Minecraft modding to understand. What I'm looking for: What is the correct way to add a custom HUD element (icon + text) in Forge 1.21, given that the previous overlay API is missing? Is there a new recommended event, callback, or method in Forge 1.21 for custom HUD overlays, or is everyone just using a workaround? Is there a minimal open-source example repo for Forge 1.21 that demonstrates a working HUD overlay without relying on NeoForge or deprecated Forge APIs? My ideal solution: Centered HUD element with an in-game item/block icon (from the base game's assets, e.g. a diamond or any ItemStack / Item) and its name as text, with a transparent background rectangle. It should be visible to the players when the mini game is running. Easy to update the item (e.g. static variable or other method), so it can change dynamically during the game. Any help, code snippets, or up-to-date references would be really appreciated! If this is simply not possible right now in Forge 1.21, it would also help to know that for sure. Thank you very much in advance!
    • The simple answer is there is not an easy way. You would need to know how to program in Java, as well as at least some familiarity with how Forge works so you could port the differences. You would also need the sourcecode for the original mod, and permission from the author to modify it, if they did not use some sort of open source license. So it's not impossible, but it would take some effort, but doing so would open up a whole new world of possibilities for you!
    • Does it still crash if you remove holdmyitems? Looks like that mod doesn't work on a server as far as I can tell from the error.  
  • Topics

×
×
  • Create New...

Important Information

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