-
Posts
440 -
Joined
-
Last visited
Everything posted by Flenix
-
I realized it was set as Plains as the default biome. Changed that to my custom one, and everything is peachy now. I don't know if multiple biomes work, as I don't have other biomes yet. I'll make one shortly and try it out... For now though, I have one last question. How do I assign a biome decorator? I've made my own one, and I want it to add all the ores etc, I can't figure out where I should reference it and how though. I'd assume somewhere in my biome class? In vanilla biomes, it has "theBiomeDecorator" which is from BiomeGenBase - How would I do that?
-
^I was about to post the same thing, but I thought I should scroll down to see if someone else did first. Took me a while but I got there eventually!
-
Such a simple fix, that fixed it! Now, all I need to do is disallow the standard biomes from spawning in my dimension and it'll be DONE. I tried using this: But on a new world, I landed in plains after going through the portal. Is there something else I need?
-
UPDATE in relation to #3 I was following another thread with a similar issue to one of mine. I'm now getting the "A mod tried to open a gui on the server without being a NetworkMod". However, I couldn't comment on there, because the thread author decided that as his problem was solved, noone else was ever going to get the issue and locked his thread. So, I've updated the GitHub. Only thing changed in the base class was the following line: The two packet handlers are here: https://github.com/Flenix/Remula/tree/master/co/uk/silvania/Remula/network Anyone able to help?
-
Hey guys, and welcome to my mod's WIP page. Note: screenshots are in a spoiler towards the end! I'm posting this here because more than anything, I need help with naming things! I need tonnes of things named, and I'm really not too good at naming stuff. I posted this on Minecraft Forums a few days ago, so I'll just stick the same thread here for now. I'll try and cut it down when I've got a bit more done - I always ramble on when I talk about the mod. Basically, the mod is a technology tree mod which incorporates space travel to new worlds. Each world system is called a "Phase", and those phases are broken down into Tiers. For example, Earth is Phase 1, with Tiers 1 2 and 3. Once you've successfully built tier 3 machines, you can build/upgrade your spaceship enough to reach the next location. The mod adds everything you'd expect from a technology mod; new furnaces, electricity, things which automate/speed up processes and generally give you more bang for your buck. It starts off slow compared to other mods (eg IC2), but once you've traveled the worlds a little things will really pick up. On top of the basics you'd expect, I'm trying to add new things not yet seen in other mods. For example, I've made some robot helper droids, who follow you around and obey your every command. Another example is I've planned some HUD units which you wear in your helmet slot, and it'll show various things of information on your screen. One last feature I feel is currently unique is Liquid Infusion crafting. This requires a special machine which infuses liquids into your crafting recipes. I've factored this in elsewhere too; I've made new chests which hold liquids, and I'll be adding a pipe system. It will, of course, be buildcraft-compatible. Right now I've planned to have 9 Phases, each harder than the last. The first part of Phase 2 is easier than Phase 1, just to help you get going. Each Phase consists of 1-3 worlds, and each world has it's own terrain generation, it's own life and so on. The mod goes much further than adding just technology, but adds entire life ecosystems and new potentials for building in general. I want the mod to be aesthetically pleasing as well as useful; you should be able to build amazing cities! The mod is nowhere near a releasable state, but I'm currently at around 10,000 lines of code. Right now, the only help I'm looking for is naming of planets, creatures, and the mod itself. See the spoiler below for the names I'll need help with! I also would like a Java mentor, if anyone is up to the challenge. This is my first real entry into the world of Modding with forge (I've done a few basic mods, but nothing on this scale), so I do have questions on how certain things work. If you think you can help me out a bit, send me a message! I am not looking for people to help with or do the code for me; just people to point me in the right direction. [spoiler=Name help!] Things I need names for, and names I already have: If something is blank, or says "name?", I need a name for it. I also list all the materials you can find/craft, but I'm open to suggestions on more! Also, as far as mobs go, I've not made them all yet, that is just the amount of life I feel there should be. So, if there's no description of the mob, feel free to suggest how it should look too! The Mod's Name: Phase 1 is simply on Earth. Earth's name will be configurable, that is simply the default. Earth already exists, so I haven't got much that needs a name here. Tier 1 Ore: Silvanite Tier 2 Ore: Mercilite Tier 3 Ore: Remula Phase 2 is split across two worlds: The moon Akatoe, orbitting the planet Baloinus. World: Akatoe Tier 1 Ore: Porinite Tier 2 Ore: Pilk Main Life: Akatonian Critter 1: Glog Critter 2: name? Critter 3: name? Critter 4: name? Plant 1: Porin Plant 2: Ulin Plant 3: Cir Plant 4: Boskin Tree 1: name? Tree 2: name? Materials: Stone, Dirt, Grass, Refined Stone, Bricks, Large Bricks, Decorative Bricks World: Baloinus Tier 3 Ore: name? Main Life: name? (Large hostile mob, very dangerous) Mob 1: name? (Smaller version of Main Life mob) Mob 2: name? (currently unmade) Phase 3: The phase 3 planet is entirely a dense Jungle, with huge trees. Think of the Forest Moon of Endor. World: name? Tier 1 Ore: name? Tier 2 Ore: name? Tier 3 Ore: name? Main Life: name? Critter 1: name? Critter 2: name? Mob 1: name? Mob 2: name? Mob 3: name? Mob 4: name? Tree 1: name? Tree 2: name? Tree 3: name? Tree 4: name? Tree 5: name? Tree 6: name? Plant 1: name? Plant 2: name? Plant 3: name? Plant 4: name? Crop 1: name? Crop 2: name? Crop 3: name? Crop 4: name? Crop 5: name? Crop 6: name? Crop 7: name? Materials: Suggest? Phase 4-9, I've got little to none planned, except the fact that they will exist. One of them will be called Xylexia, with T3 ore being Xylexite and the main hostile creature being a Xylexian. Other than that, suggest away! Click the spoiler to see some screenshots of things I have so far. [spoiler=Screenshots!] Akatonian terrain: Some Akatonians and Glogs enjoying a nice sunny day: A concept Robot: A Xylexian: The GUI for a Silvanite Chest: And finally, a few blocks and ores (I've not done much texturing yet else I'd show more): Finally, for more info... I will try and keep this thread up to date. However, there are other places that I post more! You can: Like me on Facebook: http://www.facebook.com/SilvaniaStudios/ Follow me on Twitter: @SilvaniaStudios Read my blog: http://www.silvania.co.uk/blog/ (Blog posts are auto-announced on the twitter!) Note that I refer to the mod as "Remula" in these places for now. That's just the working title http://static.minecraftforum.net//public/style_emoticons/default/smile.png[/img] Download, you say? Soon, very soon, I'll be releasing Pre-alpha 1. This is purely as a "Hey look, it actually exists" and should not be used on a world you like, or a server. In fact, I may disable servers altogether until it's at a relatively bug-free state. These versions may NOT be used in a modpack- I will allow it in the future though! The version is 1.4.7, because for now I'm developing this primarily for my own server, and releasing it because I want to share it. Once I've got the basics up and running, I'll keep up-to-date with the current Forge versions regardless of what my server is on. So yeah, thats all I have to say for now. I knew I'd ramble on! Comment, feedback etc is always nice... and names! I need names!
-
Hey, I figured I'll let the old thread die as it's bugs were fixed, but my TileEntity still has a few different bugs. 1. Firstly, if I shift-click from my inventory to the chest, it clones the item, leaving a ghost in my inventory. The inventory-side item is unusable (and if it's a block, it disappears when I try and place it) so it's only a graphical bug, but I'd still like to fix it. Any ideas? There is no stacktrace. 2. How do I set the texture I've tried various things that would usually work, but nothing does... (Nothing currently set) 3. How do I use multiple GUIs within my mod? Everyone I've asked makes it sound so simple, but I can't get it to work, so obviously I'm missing something. I can get one of the three chests I have to open at a time, but not all 3. FIXED There's quite a few classes that are relevant here, so the easiest way is to just link my github. Note that a lot of the unrelated code isn't done so ignore that Click here for the TileEntities | Click here for the main class. The main class is pretty big (as you see), so here's everything unimportant cut out: @Mod(modid="Remula", name="Remula", version="0.0.1") @NetworkMod(clientSideRequired=true, serverSideRequired=false) public class Remula { public static CreativeTabs tabRemula = new CreativeTabs("tabRemula") { public ItemStack getIconItemStack() { return new ItemStack(Remula.advancedP5RobotSpawner, 1, 0); } @Instance("Remula") public static Remula instance; //GUIs public static SilvaniteGuiHandler silvaniteGuiHandler = new SilvaniteGuiHandler(); public static MerciliteGuiHandler merciliteGuiHandler = new MerciliteGuiHandler(); public static RemulaGuiHandler remulaGuiHandler = new RemulaGuiHandler(); // Says where the client and server proxy code is loaded. @SidedProxy(clientSide="co.uk.silvania.Remula.client.ClientProxy", serverSide="co.uk.silvania.Remula.CommonProxy") public static CommonProxy proxy; //public static int blockRemulaID; @SideOnly(Side.CLIENT) @PreInit public void preInit(FMLPreInitializationEvent event) { NetworkRegistry.instance().registerGuiHandler(this, remulaGuiHandler); NetworkRegistry.instance().registerGuiHandler(this, merciliteGuiHandler); NetworkRegistry.instance().registerGuiHandler(this, silvaniteGuiHandler); } public static WorldGen worldGen = new WorldGen(); public final static Block silvaniteChest = new SilvaniteChest(1850).setBlockName("silvaniteChest"); public final static Block merciliteChest = new MerciliteChest(1851).setBlockName("merciliteChest"); public final static Block remulaChest = new RemulaChest(1852).setBlockName("remulaChest"); @Init public void load(FMLInitializationEvent event) { proxy.registerRenderThings(); proxy.init(); //Storage and Tile Entites LanguageRegistry.addName(silvaniteChest, "Silvanite Chest"); LanguageRegistry.addName(merciliteChest, "Mercilite Chest"); LanguageRegistry.addName(remulaChest, "Remula Chest"); //Storage Blocks/Tile Entites GameRegistry.registerBlock(silvaniteChest, "silvaniteChest"); GameRegistry.registerBlock(merciliteChest, "merciliteChest"); GameRegistry.registerBlock(remulaChest, "remulaChest"); //Tile Entities GameRegistry.registerTileEntity(TileEntitySilvaniteChest.class, "tileEntitySilvaniteChest"); GameRegistry.registerTileEntity(TileEntityMerciliteChest.class, "tileEntityMerciliteChest"); GameRegistry.registerTileEntity(TileEntityRemulaChest.class, "tileEntityRemulaChest"); //Other Registry Stuff LanguageRegistry.instance().addStringLocalization("itemGroup.tabRemula", "en_US", "Remula"); LanguageRegistry.instance().addStringLocalization("itemGroup.tabAkatoe", "en_US", "Akatoe"); LanguageRegistry.instance().addStringLocalization("itemGroup.tabBaloinus", "en_US", "Baloinus"); LanguageRegistry.instance().addStringLocalization("itemGroup.tabDeepSpace", "en_US", "Deep-Space"); GameRegistry.registerWorldGenerator(new WorldGen()); NetworkRegistry.instance().registerGuiHandler(this, new SilvaniteGuiHandler()); NetworkRegistry.instance().registerGuiHandler(this, new MerciliteGuiHandler()); NetworkRegistry.instance().registerGuiHandler(this, new RemulaGuiHandler()); GameRegistry.addBiome(akatoePlainsBiome); } @PostInit public void postInit(FMLPostInitializationEvent event) { // Stub Method } } Finally on a more advanced note, if you look at my GUI images, you'll see the chests have built-in tanks. How would I make these functional? Each tank should hold 9 buckets-worth of a single liquid, and once a liquid is in it wont accept any other liquid (Like the buildcraft tank). Also if possible, I want the slots above/below to only accept buckets (filled or empty) Any help is great, sorry for so much in one thread
-
That points to your BiomeAkatoePlains I know, that's why I posted the BiomeAkatoePlains class right above it...
-
My classes are all prefixed Akatoe; I'm having more than one dimension in my mod, so that's how I differentiate between them. As far as I know, the name doesn't matter? Anyways, I have AkatoeBiomeDecorator, AkatoeChunkManager, AkatoeChunkProvider (Which is the noise one), AkatoePortalBlock and AkatoeWorldProvider. Currently I also have BiomeAkatoePlains, but I'll add a few others in the future once it's working. The error I posted above, that was the entire trace, but here's the whole log: 2013-05-14 13:03:51 [iNFO] [ForgeModLoader] Forge Mod Loader version 4.7.35.556 for Minecraft 1.4.7 loading 2013-05-14 13:03:53 [iNFO] [sTDOUT] 27 achievements 2013-05-14 13:03:53 [iNFO] [sTDOUT] 210 recipes 2013-05-14 13:03:53 [iNFO] [sTDOUT] Setting user: Player128, - 2013-05-14 13:03:53 [iNFO] [sTDERR] Client asked for parameter: server 2013-05-14 13:03:53 [iNFO] [sTDOUT] LWJGL Version: 2.4.2 2013-05-14 13:03:54 [iNFO] [MinecraftForge] Attempting early MinecraftForge initialization 2013-05-14 13:03:54 [iNFO] [sTDOUT] MinecraftForge v6.6.2.534 Initialized 2013-05-14 13:03:54 [iNFO] [ForgeModLoader] MinecraftForge v6.6.2.534 Initialized 2013-05-14 13:03:54 [iNFO] [sTDOUT] Replaced 84 ore recipies 2013-05-14 13:03:54 [iNFO] [MinecraftForge] Completed early MinecraftForge initialization 2013-05-14 13:03:54 [iNFO] [ForgeModLoader] Reading custom logging properties from F:\Code\Minecraft\GitHub\Remula\forge\mcp\jars\config\logging.properties 2013-05-14 13:03:54 [OFF] [ForgeModLoader] Logging level for ForgeModLoader logging is set to ALL 2013-05-14 13:03:54 [iNFO] [ForgeModLoader] Searching F:\Code\Minecraft\GitHub\Remula\forge\mcp\jars\mods for mods 2013-05-14 13:03:55 [iNFO] [ForgeModLoader] Forge Mod Loader has identified 4 mods to load 2013-05-14 13:03:55 [iNFO] [mcp] Activating mod mcp 2013-05-14 13:03:55 [iNFO] [FML] Activating mod FML 2013-05-14 13:03:55 [iNFO] [Forge] Activating mod Forge 2013-05-14 13:03:56 [iNFO] [Remula] Activating mod Remula 2013-05-14 13:03:56 [iNFO] [sTDERR] Exception in thread "Minecraft main thread" java.lang.ExceptionInInitializerError 2013-05-14 13:03:56 [iNFO] [sTDERR] at java.lang.Class.forName0(Native Method) 2013-05-14 13:03:56 [iNFO] [sTDERR] at java.lang.Class.forName(Unknown Source) 2013-05-14 13:03:56 [iNFO] [sTDERR] at cpw.mods.fml.common.FMLModContainer.constructMod(FMLModContainer.java:418) 2013-05-14 13:03:56 [iNFO] [sTDERR] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 2013-05-14 13:03:56 [iNFO] [sTDERR] at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 2013-05-14 13:03:56 [iNFO] [sTDERR] at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 2013-05-14 13:03:56 [iNFO] [sTDERR] at java.lang.reflect.Method.invoke(Unknown Source) 2013-05-14 13:03:56 [iNFO] [sTDERR] at com.google.common.eventbus.EventHandler.handleEvent(EventHandler.java:69) 2013-05-14 13:03:56 [iNFO] [sTDERR] at com.google.common.eventbus.SynchronizedEventHandler.handleEvent(SynchronizedEventHandler.java:45) 2013-05-14 13:03:56 [iNFO] [sTDERR] at com.google.common.eventbus.EventBus.dispatch(EventBus.java:317) 2013-05-14 13:03:56 [iNFO] [sTDERR] at com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:300) 2013-05-14 13:03:56 [iNFO] [sTDERR] at com.google.common.eventbus.EventBus.post(EventBus.java:268) 2013-05-14 13:03:56 [iNFO] [sTDERR] at cpw.mods.fml.common.LoadController.propogateStateMessage(LoadController.java:153) 2013-05-14 13:03:56 [iNFO] [sTDERR] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 2013-05-14 13:03:56 [iNFO] [sTDERR] at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 2013-05-14 13:03:56 [iNFO] [sTDERR] at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 2013-05-14 13:03:56 [iNFO] [sTDERR] at java.lang.reflect.Method.invoke(Unknown Source) 2013-05-14 13:03:56 [iNFO] [sTDERR] at com.google.common.eventbus.EventHandler.handleEvent(EventHandler.java:69) 2013-05-14 13:03:56 [iNFO] [sTDERR] at com.google.common.eventbus.SynchronizedEventHandler.handleEvent(SynchronizedEventHandler.java:45) 2013-05-14 13:03:56 [iNFO] [sTDERR] at com.google.common.eventbus.EventBus.dispatch(EventBus.java:317) 2013-05-14 13:03:56 [iNFO] [sTDERR] at com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:300) 2013-05-14 13:03:56 [iNFO] [sTDERR] at com.google.common.eventbus.EventBus.post(EventBus.java:268) 2013-05-14 13:03:56 [iNFO] [sTDERR] at cpw.mods.fml.common.LoadController.distributeStateMessage(LoadController.java:86) 2013-05-14 13:03:56 [iNFO] [sTDERR] at cpw.mods.fml.common.Loader.loadMods(Loader.java:494) 2013-05-14 13:03:56 [iNFO] [sTDERR] at cpw.mods.fml.client.FMLClientHandler.beginMinecraftLoading(FMLClientHandler.java:161) 2013-05-14 13:03:56 [iNFO] [sTDERR] at net.minecraft.client.Minecraft.startGame(Minecraft.java:412) 2013-05-14 13:03:56 [iNFO] [sTDERR] at net.minecraft.client.MinecraftAppletImpl.startGame(MinecraftAppletImpl.java:44) 2013-05-14 13:03:56 [iNFO] [sTDERR] at net.minecraft.client.Minecraft.run(Minecraft.java:746) 2013-05-14 13:03:56 [iNFO] [sTDERR] at java.lang.Thread.run(Unknown Source) 2013-05-14 13:03:56 [iNFO] [sTDERR] Caused by: java.lang.NullPointerException 2013-05-14 13:03:56 [iNFO] [sTDERR] at co.uk.silvania.Remula.dimensions.akatoe.BiomeAkatoePlains.<init>(BiomeAkatoePlains.java:19) 2013-05-14 13:03:56 [iNFO] [sTDERR] at co.uk.silvania.Remula.Remula.<clinit>(Remula.java:143) 2013-05-14 13:03:56 [iNFO] [sTDERR] ... 29 more 2013-05-14 13:04:00 [iNFO] [sTDERR] Someone is closing me! If I comment out the topBlock and fillerBlock in here, the error stops: package co.uk.silvania.Remula.dimensions.akatoe; import co.uk.silvania.Remula.Remula; import co.uk.silvania.Remula.entity.akatoe.EntityAkatonian; import co.uk.silvania.Remula.entity.akatoe.EntityGlog; import net.minecraft.world.biome.BiomeGenBase; import net.minecraft.world.biome.SpawnListEntry; public class BiomeAkatoePlains extends BiomeGenBase { public BiomeAkatoePlains(int id) { super(id); this.setBiomeName("Akatonian Plain"); this.setDisableRain(); this.spawnableMonsterList.clear(); this.spawnableCreatureList.clear(); this.spawnableWaterCreatureList.clear(); this.spawnableCreatureList.add(new SpawnListEntry(EntityGlog.class, 10, 4, 4)); this.topBlock = (byte) Remula.akatoeGrass.blockID; this.fillerBlock = (byte) Remula.akatoeDirt.blockID; this.maxHeight = 0.5F; this.minHeight = 0.0F; this.waterColorMultiplier = 0X00FF21; } } I wont post my whole core mod class (Remula.java) because it's ~700 lines, but the bits of importance: public static BiomeGenBase akatoePlainsBiome = new BiomeAkatoePlains(60); //Line 143, referenced in the stacktrace public final static Block akatoeStone = new AkatoeStone(200, 0, Material.rock).setBlockName("akatoeStone"); public final static Block akatoeGrass = new AkatoeGrass(201).setBlockName("akatoeGrass"); public final static Block akatoeDirt = new AkatoeDirt(202, 2, Material.ground).setBlockName("akatoeGround");
-
The buildcraft oil code is massively complicated if you're new to liquids. Trust me, I tried to learn from it and got nowhere. Plus, isn't that against their license? Arturo, not sure how useful this will be, but here's the github from the mod I was making when I wrote the (admittedly bad) liquid tutorial. Feel free to learn from the liquid code; I got buckets working with it too which isn't on the tutorial. https://github.com/Flenix/FlenixRoads/tree/master/co/uk/silvania/roads Let me know if that helps or if you have questions from anything. Feel free to fork it and delete all but the liquid code so you can work out how it works etc without the clutter of the rest of the mod.
-
Changing rotation for block +new cannot cast error
Flenix replied to SamTebbs33's topic in Modder Support
First, add both of these to your class for the xray bug: public boolean isOpaqueCube() { return false; } public boolean renderAsNormalBlock() { return false; } Both their names make it pretty obvious what they do; the first asks if the block is see-through, and the second asks if it is a full block or not. Judging from your texture, I assume you want the block to be smaller on all sides? (so it's literally just a panel on the side of another block) If that's the case, you'll need a model file (use Techne, it's easy enough) and you'll probably need it to be a tile entity too. You should get your rotation sorted in the process of getting those. -
Sorry for all these threads :( Another help is needed
Flenix replied to AssassinHero's topic in Modder Support
Don't be sorry for the threads, these forums are for getting help. More description would be useful though. I assume you've made the mob in techne, and it's working in-game (minus textures) I'm still stuck in the dark days of 1.4.7, but with that in the EntityYourMob file, under super have: this.texture = "/path/to/your/file.png"; However, 1.5.x changed texturing, so it's probably different now. Doesn't hurt to try though! -
https://github.com/Flenix/Remula/blob/master/co/uk/silvania/Remula/dimensions/akatoe/AkatoeChunkProvider.java ^^My WorldChunkProvider, for OwnAgePau to use for testing. Most of it is vanilla anyways but I changed one or two things. Works except the error I mentioned in my last post. Edit: originally the code was here, but it was making the thread extra-wide so I swapped it for a github link.
-
Try removing the # from your hex colours? Edit: Ninja'd What are the exact errors for the other two? If you hit F2 you can focus, which lets you copy and paste (Assuming you're in Eclipse here. There's probably a similar thing in Netbeans, but I've never used that)
-
[Part-solved] Container Tile Entity doesn't like me...
Flenix replied to Flenix's topic in Modder Support
I also for the life of me can't figure out how to texture it. I've tried @Override public String getTextureFile () { return "/co/uk/silvania/Remula/resources/SilvaniteChest1.png"; } (Path is correct) And I've also tried changing it to my model in TileEntitySilvaniteChestRenderer. I have no idea if that's taken effect or not, as it's just invisibile right now. It's worth nothing I'm still on 1.4.7 as this is for my server. -
[Part-solved] Container Tile Entity doesn't like me...
Flenix replied to Flenix's topic in Modder Support
Cool, that's the storing sorted. Now just the minor bug of shift-clicking, any advice on where to look? -
Ok, I tried that, no errors in Eclipse but on launch: 2013-05-13 21:49:38 [iNFO] [sTDERR] Exception in thread "Minecraft main thread" java.lang.ExceptionInInitializerError 2013-05-13 21:49:38 [iNFO] [sTDERR] at java.lang.Class.forName0(Native Method) 2013-05-13 21:49:38 [iNFO] [sTDERR] at java.lang.Class.forName(Unknown Source) 2013-05-13 21:49:38 [iNFO] [sTDERR] at cpw.mods.fml.common.FMLModContainer.constructMod(FMLModContainer.java:418) 2013-05-13 21:49:38 [iNFO] [sTDERR] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 2013-05-13 21:49:38 [iNFO] [sTDERR] at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 2013-05-13 21:49:38 [iNFO] [sTDERR] at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 2013-05-13 21:49:38 [iNFO] [sTDERR] at java.lang.reflect.Method.invoke(Unknown Source) 2013-05-13 21:49:38 [iNFO] [sTDERR] at com.google.common.eventbus.EventHandler.handleEvent(EventHandler.java:69) 2013-05-13 21:49:38 [iNFO] [sTDERR] at com.google.common.eventbus.SynchronizedEventHandler.handleEvent(SynchronizedEventHandler.java:45) 2013-05-13 21:49:38 [iNFO] [sTDERR] at com.google.common.eventbus.EventBus.dispatch(EventBus.java:317) 2013-05-13 21:49:38 [iNFO] [sTDERR] at com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:300) 2013-05-13 21:49:38 [iNFO] [sTDERR] at com.google.common.eventbus.EventBus.post(EventBus.java:268) 2013-05-13 21:49:38 [iNFO] [sTDERR] at cpw.mods.fml.common.LoadController.propogateStateMessage(LoadController.java:153) 2013-05-13 21:49:38 [iNFO] [sTDERR] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 2013-05-13 21:49:38 [iNFO] [sTDERR] at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 2013-05-13 21:49:38 [iNFO] [sTDERR] at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 2013-05-13 21:49:38 [iNFO] [sTDERR] at java.lang.reflect.Method.invoke(Unknown Source) 2013-05-13 21:49:38 [iNFO] [sTDERR] at com.google.common.eventbus.EventHandler.handleEvent(EventHandler.java:69) 2013-05-13 21:49:38 [iNFO] [sTDERR] at com.google.common.eventbus.SynchronizedEventHandler.handleEvent(SynchronizedEventHandler.java:45) 2013-05-13 21:49:38 [iNFO] [sTDERR] at com.google.common.eventbus.EventBus.dispatch(EventBus.java:317) 2013-05-13 21:49:38 [iNFO] [sTDERR] at com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:300) 2013-05-13 21:49:38 [iNFO] [sTDERR] at com.google.common.eventbus.EventBus.post(EventBus.java:268) 2013-05-13 21:49:38 [iNFO] [sTDERR] at cpw.mods.fml.common.LoadController.distributeStateMessage(LoadController.java:86) 2013-05-13 21:49:38 [iNFO] [sTDERR] at cpw.mods.fml.common.Loader.loadMods(Loader.java:494) 2013-05-13 21:49:38 [iNFO] [sTDERR] at cpw.mods.fml.client.FMLClientHandler.beginMinecraftLoading(FMLClientHandler.java:161) 2013-05-13 21:49:38 [iNFO] [sTDERR] at net.minecraft.client.Minecraft.startGame(Minecraft.java:412) 2013-05-13 21:49:38 [iNFO] [sTDERR] at net.minecraft.client.MinecraftAppletImpl.startGame(MinecraftAppletImpl.java:44) 2013-05-13 21:49:38 [iNFO] [sTDERR] at net.minecraft.client.Minecraft.run(Minecraft.java:746) 2013-05-13 21:49:38 [iNFO] [sTDERR] at java.lang.Thread.run(Unknown Source) 2013-05-13 21:49:38 [iNFO] [sTDERR] Caused by: java.lang.NullPointerException 2013-05-13 21:49:38 [iNFO] [sTDERR] at co.uk.silvania.Remula.dimensions.akatoe.BiomeAkatoePlains.<init>(BiomeAkatoePlains.java:14) 2013-05-13 21:49:38 [iNFO] [sTDERR] at co.uk.silvania.Remula.Remula.<clinit>(Remula.java:97) 2013-05-13 21:49:38 [iNFO] [sTDERR] ... 29 more My biome class: package co.uk.silvania.Remula.dimensions.akatoe; import co.uk.silvania.Remula.Remula; import co.uk.silvania.Remula.entity.akatoe.EntityAkatonian; import co.uk.silvania.Remula.entity.akatoe.EntityGlog; import net.minecraft.world.biome.BiomeGenBase; public class BiomeAkatoePlains extends BiomeGenBase { public BiomeAkatoePlains(int id) { super(id); this.setBiomeName("Akatonian Plain"); this.setDisableRain(); this.topBlock = (byte) Remula.akatoeGrass.blockID; //This is the line referenced in the stacktrace this.fillerBlock = (byte) Remula.akatoeDirt.blockID; this.maxHeight = 0.5F; this.minHeight = 0.0F; this.waterColorMultiplier = 0X00FF21; } } I did see someone mention in a tutorial that custom blocks didn't work, but they never mentioned a solution. It's worth noting that my grass ID is 201, so under the 255 limit.
-
[Part-solved] Container Tile Entity doesn't like me...
Flenix replied to Flenix's topic in Modder Support
I feel stupid, ignore me. I just noticed at the top of my TileEntity, I had a line: private ItemStack[] chestContents = new ItemStack[36]; Which I promptly changed to 56. I then changed my Container file: addSlotToContainer(new Slot(tileEntity, j + i * 9 + 2, -1 + j * 18, -10 + i * 18)); and everything is placing nicely across all 56 slots! Unfortunately, I do still have bugs: Shift-clicking dupilicates the item (Although it's just a ghost, you don't actually get more items, but still annoying) More importantly however, the inventory isn't actually saving: 2013-05-12 12:39:30 [sEVERE] [ForgeModLoader] A TileEntity type co.uk.silvania.Remula.tileentity.TileEntitySilvaniteChest has throw an exception trying to write state. It will not persist. Report this to the mod author java.lang.RuntimeException: class co.uk.silvania.Remula.tileentity.TileEntitySilvaniteChest is missing a mapping! This is a bug! at net.minecraft.tileentity.TileEntity.writeToNBT(TileEntity.java:107) at co.uk.silvania.Remula.tileentity.TileEntitySilvaniteChest.writeToNBT(TileEntitySilvaniteChest.java:165) at net.minecraft.world.chunk.storage.AnvilChunkLoader.writeChunkToNBT(AnvilChunkLoader.java:311) at net.minecraft.world.chunk.storage.AnvilChunkLoader.saveChunk(AnvilChunkLoader.java:127) at net.minecraft.world.gen.ChunkProviderServer.safeSaveChunk(ChunkProviderServer.java:232) at net.minecraft.world.gen.ChunkProviderServer.saveChunks(ChunkProviderServer.java:284) at net.minecraft.world.WorldServer.saveAllChunks(WorldServer.java:844) at net.minecraft.server.MinecraftServer.saveAllWorlds(MinecraftServer.java:373) at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:118) at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:497) at net.minecraft.server.ThreadMinecraftServer.run(ThreadMinecraftServer.java:16) Here's an up-to-date version of my TileEntitySilvaniteChest and ContainerSilvaniteChest files. Most of the TileEntitySilvaniteChest is pretty much the same as vanilla chest, but I changed a few things trying to get it to work... [spoiler=TileEntitySilvaniteChest] package co.uk.silvania.Remula.tileentity; import java.util.Iterator; import java.util.List; import co.uk.silvania.Remula.Remula; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.AxisAlignedBB; public class TileEntitySilvaniteChest extends TileEntity implements IInventory { private ItemStack[] silvaniteChestContents = new ItemStack[56]; /** Determines if the check for adjacent chests has taken place. */ public boolean adjacentChestChecked = false; /** Contains the chest tile located adjacent to this one (if any) */ public TileEntitySilvaniteChest adjacentChestZNeg; /** Contains the chest tile located adjacent to this one (if any) */ public TileEntitySilvaniteChest adjacentChestXPos; /** Contains the chest tile located adjacent to this one (if any) */ public TileEntitySilvaniteChest adjacentChestXNeg; /** Contains the chest tile located adjacent to this one (if any) */ public TileEntitySilvaniteChest adjacentChestZPosition; /** The current angle of the lid (between 0 and 1) */ public float lidAngle; /** The angle of the lid last tick */ public float prevLidAngle; /** The number of players currently using this chest */ public int numUsingPlayers; /** Server sync counter (once per 20 ticks) */ private int ticksSinceSync; /** * Returns the number of slots in the inventory. */ public int getSizeInventory() { return 56; } /** * Returns the stack in slot i */ public ItemStack getStackInSlot(int par1) { return this.silvaniteChestContents[par1]; } /** * 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.silvaniteChestContents[par1] != null) { ItemStack var3; if (this.silvaniteChestContents[par1].stackSize <= par2) { var3 = this.silvaniteChestContents[par1]; this.silvaniteChestContents[par1] = null; this.onInventoryChanged(); return var3; } else { var3 = this.silvaniteChestContents[par1].splitStack(par2); if (this.silvaniteChestContents[par1].stackSize == 0) { this.silvaniteChestContents[par1] = null; } this.onInventoryChanged(); return var3; } } else { return null; } } /** * 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.silvaniteChestContents[par1] != null) { ItemStack var2 = this.silvaniteChestContents[par1]; this.silvaniteChestContents[par1] = null; return var2; } 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.silvaniteChestContents[par1] = par2ItemStack; if (par2ItemStack != null && par2ItemStack.stackSize > this.getInventoryStackLimit()) { par2ItemStack.stackSize = this.getInventoryStackLimit(); } this.onInventoryChanged(); } /** * Returns the name of the inventory. */ public String getInvName() { return "Silvanite Chest"; } /** * Reads a tile entity from NBT. */ public void readFromNBT(NBTTagCompound par1NBTTagCompound) { super.readFromNBT(par1NBTTagCompound); NBTTagList var2 = par1NBTTagCompound.getTagList("Items"); this.silvaniteChestContents = new ItemStack[this.getSizeInventory()]; for (int var3 = 0; var3 < var2.tagCount(); ++var3) { NBTTagCompound var4 = (NBTTagCompound)var2.tagAt(var3); int var5 = var4.getByte("Slot") & 255; if (var5 >= 0 && var5 < this.silvaniteChestContents.length) { this.silvaniteChestContents[var5] = ItemStack.loadItemStackFromNBT(var4); } } } /** * Writes a tile entity to NBT. */ public void writeToNBT(NBTTagCompound par1NBTTagCompound) { super.writeToNBT(par1NBTTagCompound); NBTTagList var2 = new NBTTagList(); for (int var3 = 0; var3 < this.silvaniteChestContents.length; ++var3) { if (this.silvaniteChestContents[var3] != null) { NBTTagCompound var4 = new NBTTagCompound(); var4.setByte("Slot", (byte)var3); this.silvaniteChestContents[var3].writeToNBT(var4); var2.appendTag(var4); } } par1NBTTagCompound.setTag("Items", var2); } /** * 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 64; } /** * Do not make give this method the name canInteractWith because it clashes with Container */ public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer) { return this.worldObj.getBlockTileEntity(this.xCoord, this.yCoord, this.zCoord) != this ? false : par1EntityPlayer.getDistanceSq((double)this.xCoord + 0.5D, (double)this.yCoord + 0.5D, (double)this.zCoord + 0.5D) <= 64.0D; } /** * Causes the TileEntity to reset all it's cached values for it's container block, blockID, metaData and in the case * of Chests, the adjcacent Chest check */ public void updateContainingBlockInfo() { super.updateContainingBlockInfo(); this.adjacentChestChecked = false; } private void func_90009_a(TileEntitySilvaniteChest par1TileEntityChest, int par2) { if (par1TileEntityChest.isInvalid()) { this.adjacentChestChecked = false; } else if (this.adjacentChestChecked) { switch (par2) { case 0: if (this.adjacentChestZPosition != par1TileEntityChest) { this.adjacentChestChecked = false; } break; case 1: if (this.adjacentChestXNeg != par1TileEntityChest) { this.adjacentChestChecked = false; } break; case 2: if (this.adjacentChestZNeg != par1TileEntityChest) { this.adjacentChestChecked = false; } break; case 3: if (this.adjacentChestXPos != par1TileEntityChest) { this.adjacentChestChecked = false; } } } } /** * Performs the check for adjacent silvaniteChests to determine if this silvaniteChest is double or not. */ public void checkForAdjacentChests() { if (!this.adjacentChestChecked) { this.adjacentChestChecked = true; this.adjacentChestZNeg = null; this.adjacentChestXPos = null; this.adjacentChestXNeg = null; this.adjacentChestZPosition = null; if (this.worldObj.getBlockId(this.xCoord - 1, this.yCoord, this.zCoord) == Remula.silvaniteChest.blockID) { this.adjacentChestXNeg = (TileEntitySilvaniteChest)this.worldObj.getBlockTileEntity(this.xCoord - 1, this.yCoord, this.zCoord); } if (this.worldObj.getBlockId(this.xCoord + 1, this.yCoord, this.zCoord) == Remula.silvaniteChest.blockID) { this.adjacentChestXPos = (TileEntitySilvaniteChest)this.worldObj.getBlockTileEntity(this.xCoord + 1, this.yCoord, this.zCoord); } if (this.worldObj.getBlockId(this.xCoord, this.yCoord, this.zCoord - 1) == Remula.silvaniteChest.blockID) { this.adjacentChestZNeg = (TileEntitySilvaniteChest)this.worldObj.getBlockTileEntity(this.xCoord, this.yCoord, this.zCoord - 1); } if (this.worldObj.getBlockId(this.xCoord, this.yCoord, this.zCoord + 1) == Remula.silvaniteChest.blockID) { this.adjacentChestZPosition = (TileEntitySilvaniteChest)this.worldObj.getBlockTileEntity(this.xCoord, this.yCoord, this.zCoord + 1); } if (this.adjacentChestZNeg != null) { this.adjacentChestZNeg.func_90009_a(this, 0); } if (this.adjacentChestZPosition != null) { this.adjacentChestZPosition.func_90009_a(this, 2); } if (this.adjacentChestXPos != null) { this.adjacentChestXPos.func_90009_a(this, 1); } if (this.adjacentChestXNeg != null) { this.adjacentChestXNeg.func_90009_a(this, 3); } } } /** * Allows the entity to update its state. Overridden in most subclasses, e.g. the mob spawner uses this to count * ticks and creates a new spawn inside its implementation. */ public void updateEntity() { super.updateEntity(); this.checkForAdjacentChests(); ++this.ticksSinceSync; float var1; if (!this.worldObj.isRemote && this.numUsingPlayers != 0 && (this.ticksSinceSync + this.xCoord + this.yCoord + this.zCoord) % 200 == 0) { this.numUsingPlayers = 0; var1 = 5.0F; List var2 = this.worldObj.getEntitiesWithinAABB(EntityPlayer.class, AxisAlignedBB.getAABBPool().addOrModifyAABBInPool((double)((float)this.xCoord - var1), (double)((float)this.yCoord - var1), (double)((float)this.zCoord - var1), (double)((float)(this.xCoord + 1) + var1), (double)((float)(this.yCoord + 1) + var1), (double)((float)(this.zCoord + 1) + var1))); Iterator var3 = var2.iterator(); while (var3.hasNext()) { EntityPlayer var4 = (EntityPlayer)var3.next(); if (var4.openContainer instanceof ContainerSilvaniteChest) { IInventory var5 = ((ContainerSilvaniteChest)var4.openContainer).getSilvaniteChestInventory(); ++this.numUsingPlayers; } } } this.prevLidAngle = this.lidAngle; var1 = 0.1F; double var11; if (this.numUsingPlayers > 0 && this.lidAngle == 0.0F && this.adjacentChestZNeg == null && this.adjacentChestXNeg == null) { double var8 = (double)this.xCoord + 0.5D; var11 = (double)this.zCoord + 0.5D; if (this.adjacentChestZPosition != null) { var11 += 0.5D; } if (this.adjacentChestXPos != null) { var8 += 0.5D; } this.worldObj.playSoundEffect(var8, (double)this.yCoord + 0.5D, var11, "random.chestopen", 0.5F, this.worldObj.rand.nextFloat() * 0.1F + 0.9F); } if (this.numUsingPlayers == 0 && this.lidAngle > 0.0F || this.numUsingPlayers > 0 && this.lidAngle < 1.0F) { float var9 = this.lidAngle; if (this.numUsingPlayers > 0) { this.lidAngle += var1; } else { this.lidAngle -= var1; } if (this.lidAngle > 1.0F) { this.lidAngle = 1.0F; } float var10 = 0.5F; if (this.lidAngle < var10 && var9 >= var10 && this.adjacentChestZNeg == null && this.adjacentChestXNeg == null) { var11 = (double)this.xCoord + 0.5D; double var6 = (double)this.zCoord + 0.5D; if (this.adjacentChestZPosition != null) { var6 += 0.5D; } if (this.adjacentChestXPos != null) { var11 += 0.5D; } this.worldObj.playSoundEffect(var11, (double)this.yCoord + 0.5D, var6, "random.chestclosed", 0.5F, this.worldObj.rand.nextFloat() * 0.1F + 0.9F); } if (this.lidAngle < 0.0F) { this.lidAngle = 0.0F; } } } /** * Called when a client event is received with the event number and argument, see World.sendClientEvent */ public void receiveClientEvent(int par1, int par2) { if (par1 == 1) { this.numUsingPlayers = par2; } } public void openChest() { ++this.numUsingPlayers; this.worldObj.addBlockEvent(this.xCoord, this.yCoord, this.zCoord, Remula.silvaniteChest.blockID, 1, this.numUsingPlayers); } public void closeChest() { --this.numUsingPlayers; this.worldObj.addBlockEvent(this.xCoord, this.yCoord, this.zCoord, Remula.silvaniteChest.blockID, 1, this.numUsingPlayers); } /** * invalidates a tile entity */ public void invalidate() { super.invalidate(); this.updateContainingBlockInfo(); this.checkForAdjacentChests(); } } [spoiler=ContainerSilvaniteChest] package co.uk.silvania.Remula.tileentity; import co.uk.silvania.Remula.Remula; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.inventory.Container; import net.minecraft.inventory.IInventory; import net.minecraft.inventory.Slot; import net.minecraft.item.ItemStack; public class ContainerSilvaniteChest extends Container { protected TileEntitySilvaniteChest tileEntity; private IInventory silvaniteChestInventory; public ContainerSilvaniteChest (InventoryPlayer inventoryPlayer, TileEntitySilvaniteChest te) { tileEntity = te; //Main Storage for (int i = 0; i < 6; i++) { for (int j = 0; j < 9; j++) { addSlotToContainer(new Slot(tileEntity, j + i * 9 + 2, -1 + j * 18, -10 + i * 18)); } } //Upper Bucket Slot for (int k = 0; k < 1; k++) { addSlotToContainer(new Slot(tileEntity, k, 163 + k * 18, -10)); } //Lower Bucket Slot for (int l = 0; l < 1; l++) { addSlotToContainer(new Slot(tileEntity, l, 163 + l * 18, 148)); } bindPlayerInventory(inventoryPlayer); } @Override public boolean canInteractWith(EntityPlayer player) { return tileEntity.isUseableByPlayer(player); } //Player Inventory protected void bindPlayerInventory(InventoryPlayer inventoryPlayer) { for (int m = 0; m < 3; m++) { for (int n = 0; n < 9; n++) { addSlotToContainer(new Slot(inventoryPlayer, n + m * 9 + 9, -1 + n * 18, 112 + m * 18)); } } //Player's hotbar for (int o = 0; o < 9; o++) { addSlotToContainer(new Slot(inventoryPlayer, o, -1 + o * 18, 170)); } } @Override public ItemStack transferStackInSlot(EntityPlayer player, int slot) { ItemStack stack = null; Slot slotObject = (Slot) inventorySlots.get(slot); if (slotObject != null && slotObject.getHasStack()) { ItemStack stackInSlot = slotObject.getStack(); stack = stackInSlot.copy(); if (slot < 9) { if (!this.mergeItemStack(stackInSlot, 9, 45, true)) { return null; } } else if (!this.mergeItemStack(stackInSlot, 0, 9, false)) { return null; } if (stackInSlot.stackSize == 10) { slotObject.putStack(null); } else { slotObject.onSlotChanged(); } if (stackInSlot.stackSize == stack.stackSize) { return null; } slotObject.onPickupFromSlot(player, stackInSlot); } return stack; } public IInventory getSilvaniteChestInventory() { return this.silvaniteChestInventory; } } Sorry for needing so much help, but I really appreciate you pointing me in the right direction like this. I'm doing this to learn Java, not make a cheap mod, so it's really helping me -
[Part-solved] Container Tile Entity doesn't like me...
Flenix replied to Flenix's topic in Modder Support
I think this may be the issue. I looked in ContainerChest, and it has the same i+j*9 that I was trying to do (albeit they were var5 and var4). I figure there must be an error somewhere, my out of bounds is saying: 2013-05-12 12:14:28 [iNFO] [sTDERR] Caused by: java.lang.ArrayIndexOutOfBoundsException: 36 2013-05-12 12:14:28 [iNFO] [sTDERR] at co.uk.silvania.Remula.tileentity.TileEntitySilvaniteChest.getStackInSlot(TileEntitySilvaniteChest.java:60) 2013-05-12 12:14:28 [iNFO] [sTDERR] at net.minecraft.inventory.Slot.getStack(Slot.java:87) 2013-05-12 12:14:28 [iNFO] [sTDERR] at net.minecraft.client.gui.inventory.GuiContainer.drawSlotInventory(GuiContainer.java:317) 2013-05-12 12:14:28 [iNFO] [sTDERR] at net.minecraft.client.gui.inventory.GuiContainer.drawScreen(GuiContainer.java:109) 2013-05-12 12:14:28 [iNFO] [sTDERR] at net.minecraft.client.renderer.EntityRenderer.updateCameraAndRender(EntityRenderer.java:1004) 2013-05-12 12:14:28 [iNFO] [sTDERR] ... 3 more I figure I should be using * 9, because that would be the same as a chest which effectively is what this is. The error references the return line here, in my TileEntity file: /** * Returns the stack in slot i */ public ItemStack getStackInSlot(int par1) { return this.chestContents[par1]; } Which I thought was just checking the contents of the chest... but then again I don't understand tile entities as much as I'd like to. I would have thought that this line would be relevant though, also in the TileEntity: /** * Returns the number of slots in the inventory. */ public int getSizeInventory() { return 56; } Because surely, my IndexOutOfBounds shouldn't trigger until I reach 56, not 36? I'm almost certain that "i + j * 9" is the right thing judging from what you've said, and the fact that it's in the Inventory code below - and if I change that to say * 4, the inventory code gets the same bug. -
public static ArrayList<BiomeGenBase> allowedBiomes = new ArrayList<BiomeGenBase>(Arrays.asList(forest, plains, taiga, taigaHills, forestHills, jungle. jungleHills)); That's checking in BiomeGenBase, which I assume means I need my own BiomeGenBase etc... I couldn't quite get my head around that just yet.
-
Hey, does the block act like a liquid at all? like does it flow? or can you literally stand on top of it. I wrote the tutorial purely because there was none, and it took me a few days to work out liquid code. I never touched on animation or anything like that, because I still don't know how that works. Also note the tutorial is for 1.4.7 If it's actually acting like a solid block post up the code, and I'll see if I see anything obvious.
-
In the worldprovider, "disallowedBiomes" seems to work just like "allowedBiomes" for the above line of code. I've not tried it yet; I can't figure out how to get it to read my biomes instead of just BiomeGenBase.
-
Got a couple more really simple dimension questions, so I didn't want to make a new topic. How do I... - Set the fog colour, - Set the gravity, - Generate a skylands/end type of place? (I tried setting the End biome as a test for the last one, but it didn't do the floating island type of thing...)
-
[Part-solved] Container Tile Entity doesn't like me...
Flenix replied to Flenix's topic in Modder Support
Alright, so to clarify: "addSlotToContainer(new Slot(tileEntity, j + i /*something here*/, -1 + j * 18, -10 + i * 18));" I need to put something in there. Looking over the tutorial again, I saw there was a * 3 in there. Experimented a little with multiplying by different amounts, and the position of the duplication did change, but I could never get rid of it. I started getting an Out of Bounds error if I went too high... Any idea what I'm missing? Thanks for helping me try and work this out myself. I do prefer this kind of help, and I think that's the issue with the tutorial I followed; it just gives the code with little to no explanation... -
My original problem is now solved, but the tile entity wont save it's state now. Code is further down the page. Original post kept below so others can learn from it. Hey guys, I've been trying to make a chest following the Containers and GUIs tutorial on the wiki. Honestly, a few things were missing, but I got it mostly working. My chest is there (textureless and invisibile for now), the GUI opens, and all the slots line up nicely. But, whenever I put something inside, it's stacked across all the diagonal slots: Shift-clicking them moves it to a different section, and duplicates the block. Also, the top-left is mirrored onto the two right-hand extra slots: I can't work out why it's doing it at all. Here's my code - I replaced the TileEntity code from the tutorial with the one from the vanilla chest; the tutorial one doesn't store the items after the game closes. [spoiler=TileEntitySilvaniteChest] package co.uk.silvania.Remula.tileentity; import java.util.Iterator; import java.util.List; import net.minecraft.block.Block; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.ContainerChest; import net.minecraft.inventory.IInventory; import net.minecraft.inventory.InventoryLargeChest; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.AxisAlignedBB; public class TileEntitySilvaniteChest extends TileEntity implements IInventory { private ItemStack[] chestContents = new ItemStack[36]; /** Determines if the check for adjacent chests has taken place. */ public boolean adjacentChestChecked = false; /** Contains the chest tile located adjacent to this one (if any) */ public TileEntitySilvaniteChest adjacentChestZNeg; /** Contains the chest tile located adjacent to this one (if any) */ public TileEntitySilvaniteChest adjacentChestXPos; /** Contains the chest tile located adjacent to this one (if any) */ public TileEntitySilvaniteChest adjacentChestXNeg; /** Contains the chest tile located adjacent to this one (if any) */ public TileEntitySilvaniteChest adjacentChestZPosition; /** The current angle of the lid (between 0 and 1) */ public float lidAngle; /** The angle of the lid last tick */ public float prevLidAngle; /** The number of players currently using this chest */ public int numUsingPlayers; /** Server sync counter (once per 20 ticks) */ private int ticksSinceSync; /** * Returns the number of slots in the inventory. */ public int getSizeInventory() { return 56; } //The above is 56; 54 for standard double-chest storage size, and 2 for the bucket slots on the right. /** * Returns the stack in slot i */ public ItemStack getStackInSlot(int par1) { return this.chestContents[par1]; } /** * 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.chestContents[par1] != null) { ItemStack var3; if (this.chestContents[par1].stackSize <= par2) { var3 = this.chestContents[par1]; this.chestContents[par1] = null; this.onInventoryChanged(); return var3; } else { var3 = this.chestContents[par1].splitStack(par2); if (this.chestContents[par1].stackSize == 0) { this.chestContents[par1] = null; } this.onInventoryChanged(); return var3; } } else { return null; } } /** * 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.chestContents[par1] != null) { ItemStack var2 = this.chestContents[par1]; this.chestContents[par1] = null; return var2; } 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.chestContents[par1] = par2ItemStack; if (par2ItemStack != null && par2ItemStack.stackSize > this.getInventoryStackLimit()) { par2ItemStack.stackSize = this.getInventoryStackLimit(); } this.onInventoryChanged(); } /** * Returns the name of the inventory. */ public String getInvName() { return "container.chest"; } /** * Reads a tile entity from NBT. */ public void readFromNBT(NBTTagCompound par1NBTTagCompound) { super.readFromNBT(par1NBTTagCompound); NBTTagList var2 = par1NBTTagCompound.getTagList("Items"); this.chestContents = new ItemStack[this.getSizeInventory()]; for (int var3 = 0; var3 < var2.tagCount(); ++var3) { NBTTagCompound var4 = (NBTTagCompound)var2.tagAt(var3); int var5 = var4.getByte("Slot") & 255; if (var5 >= 0 && var5 < this.chestContents.length) { this.chestContents[var5] = ItemStack.loadItemStackFromNBT(var4); } } } /** * Writes a tile entity to NBT. */ public void writeToNBT(NBTTagCompound par1NBTTagCompound) { super.writeToNBT(par1NBTTagCompound); NBTTagList var2 = new NBTTagList(); for (int var3 = 0; var3 < this.chestContents.length; ++var3) { if (this.chestContents[var3] != null) { NBTTagCompound var4 = new NBTTagCompound(); var4.setByte("Slot", (byte)var3); this.chestContents[var3].writeToNBT(var4); var2.appendTag(var4); } } par1NBTTagCompound.setTag("Items", var2); } /** * 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 64; } /** * Do not make give this method the name canInteractWith because it clashes with Container */ public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer) { return this.worldObj.getBlockTileEntity(this.xCoord, this.yCoord, this.zCoord) != this ? false : par1EntityPlayer.getDistanceSq((double)this.xCoord + 0.5D, (double)this.yCoord + 0.5D, (double)this.zCoord + 0.5D) <= 64.0D; } /** * Causes the TileEntity to reset all it's cached values for it's container block, blockID, metaData and in the case * of chests, the adjcacent chest check */ public void updateContainingBlockInfo() { super.updateContainingBlockInfo(); this.adjacentChestChecked = false; } private void func_90009_a(TileEntitySilvaniteChest par1TileEntityChest, int par2) { if (par1TileEntityChest.isInvalid()) { this.adjacentChestChecked = false; } else if (this.adjacentChestChecked) { switch (par2) { case 0: if (this.adjacentChestZPosition != par1TileEntityChest) { this.adjacentChestChecked = false; } break; case 1: if (this.adjacentChestXNeg != par1TileEntityChest) { this.adjacentChestChecked = false; } break; case 2: if (this.adjacentChestZNeg != par1TileEntityChest) { this.adjacentChestChecked = false; } break; case 3: if (this.adjacentChestXPos != par1TileEntityChest) { this.adjacentChestChecked = false; } } } } /** * Performs the check for adjacent chests to determine if this chest is double or not. */ public void checkForAdjacentChests() { if (!this.adjacentChestChecked) { this.adjacentChestChecked = true; this.adjacentChestZNeg = null; this.adjacentChestXPos = null; this.adjacentChestXNeg = null; this.adjacentChestZPosition = null; if (this.worldObj.getBlockId(this.xCoord - 1, this.yCoord, this.zCoord) == Block.chest.blockID) { this.adjacentChestXNeg = (TileEntitySilvaniteChest)this.worldObj.getBlockTileEntity(this.xCoord - 1, this.yCoord, this.zCoord); } if (this.worldObj.getBlockId(this.xCoord + 1, this.yCoord, this.zCoord) == Block.chest.blockID) { this.adjacentChestXPos = (TileEntitySilvaniteChest)this.worldObj.getBlockTileEntity(this.xCoord + 1, this.yCoord, this.zCoord); } if (this.worldObj.getBlockId(this.xCoord, this.yCoord, this.zCoord - 1) == Block.chest.blockID) { this.adjacentChestZNeg = (TileEntitySilvaniteChest)this.worldObj.getBlockTileEntity(this.xCoord, this.yCoord, this.zCoord - 1); } if (this.worldObj.getBlockId(this.xCoord, this.yCoord, this.zCoord + 1) == Block.chest.blockID) { this.adjacentChestZPosition = (TileEntitySilvaniteChest)this.worldObj.getBlockTileEntity(this.xCoord, this.yCoord, this.zCoord + 1); } if (this.adjacentChestZNeg != null) { this.adjacentChestZNeg.func_90009_a(this, 0); } if (this.adjacentChestZPosition != null) { this.adjacentChestZPosition.func_90009_a(this, 2); } if (this.adjacentChestXPos != null) { this.adjacentChestXPos.func_90009_a(this, 1); } if (this.adjacentChestXNeg != null) { this.adjacentChestXNeg.func_90009_a(this, 3); } } } /** * Allows the entity to update its state. Overridden in most subclasses, e.g. the mob spawner uses this to count * ticks and creates a new spawn inside its implementation. */ public void updateEntity() { super.updateEntity(); this.checkForAdjacentChests(); ++this.ticksSinceSync; float var1; if (!this.worldObj.isRemote && this.numUsingPlayers != 0 && (this.ticksSinceSync + this.xCoord + this.yCoord + this.zCoord) % 200 == 0) { this.numUsingPlayers = 0; var1 = 5.0F; List var2 = this.worldObj.getEntitiesWithinAABB(EntityPlayer.class, AxisAlignedBB.getAABBPool().addOrModifyAABBInPool((double)((float)this.xCoord - var1), (double)((float)this.yCoord - var1), (double)((float)this.zCoord - var1), (double)((float)(this.xCoord + 1) + var1), (double)((float)(this.yCoord + 1) + var1), (double)((float)(this.zCoord + 1) + var1))); Iterator var3 = var2.iterator(); while (var3.hasNext()) { EntityPlayer var4 = (EntityPlayer)var3.next(); if (var4.openContainer instanceof ContainerChest) { IInventory var5 = ((ContainerChest)var4.openContainer).getLowerChestInventory(); if (var5 == this || var5 instanceof InventoryLargeChest && ((InventoryLargeChest)var5).isPartOfLargeChest(this)) { ++this.numUsingPlayers; } } } } this.prevLidAngle = this.lidAngle; var1 = 0.1F; double var11; if (this.numUsingPlayers > 0 && this.lidAngle == 0.0F && this.adjacentChestZNeg == null && this.adjacentChestXNeg == null) { double var8 = (double)this.xCoord + 0.5D; var11 = (double)this.zCoord + 0.5D; if (this.adjacentChestZPosition != null) { var11 += 0.5D; } if (this.adjacentChestXPos != null) { var8 += 0.5D; } this.worldObj.playSoundEffect(var8, (double)this.yCoord + 0.5D, var11, "random.chestopen", 0.5F, this.worldObj.rand.nextFloat() * 0.1F + 0.9F); } if (this.numUsingPlayers == 0 && this.lidAngle > 0.0F || this.numUsingPlayers > 0 && this.lidAngle < 1.0F) { float var9 = this.lidAngle; if (this.numUsingPlayers > 0) { this.lidAngle += var1; } else { this.lidAngle -= var1; } if (this.lidAngle > 1.0F) { this.lidAngle = 1.0F; } float var10 = 0.5F; if (this.lidAngle < var10 && var9 >= var10 && this.adjacentChestZNeg == null && this.adjacentChestXNeg == null) { var11 = (double)this.xCoord + 0.5D; double var6 = (double)this.zCoord + 0.5D; if (this.adjacentChestZPosition != null) { var6 += 0.5D; } if (this.adjacentChestXPos != null) { var11 += 0.5D; } this.worldObj.playSoundEffect(var11, (double)this.yCoord + 0.5D, var6, "random.chestclosed", 0.5F, this.worldObj.rand.nextFloat() * 0.1F + 0.9F); } if (this.lidAngle < 0.0F) { this.lidAngle = 0.0F; } } } /** * Called when a client event is received with the event number and argument, see World.sendClientEvent */ public void receiveClientEvent(int par1, int par2) { if (par1 == 1) { this.numUsingPlayers = par2; } } public void openChest() { ++this.numUsingPlayers; this.worldObj.addBlockEvent(this.xCoord, this.yCoord, this.zCoord, Block.chest.blockID, 1, this.numUsingPlayers); } public void closeChest() { --this.numUsingPlayers; this.worldObj.addBlockEvent(this.xCoord, this.yCoord, this.zCoord, Block.chest.blockID, 1, this.numUsingPlayers); } /** * invalidates a tile entity */ public void invalidate() { super.invalidate(); this.updateContainingBlockInfo(); this.checkForAdjacentChests(); } } [spoiler=ContainerSilvaniteChest] package co.uk.silvania.Remula.tileentity; import co.uk.silvania.Remula.Remula; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.inventory.Container; import net.minecraft.inventory.IInventory; import net.minecraft.inventory.Slot; import net.minecraft.item.ItemStack; public class ContainerSilvaniteChest extends Container { protected TileEntitySilvaniteChest tileEntity; public ContainerSilvaniteChest (InventoryPlayer inventoryPlayer, TileEntitySilvaniteChest te) { tileEntity = te; //Main Storage for (int i = 0; i < 6; i++) { for (int j = 0; j < 9; j++) { addSlotToContainer(new Slot(tileEntity, j + i, -1 + j * 18, -10 + i * 18)); } } //Upper Bucket Slot for (int i = 0; i < 1; i++) { addSlotToContainer(new Slot(tileEntity, i, 163 + i * 18, -10)); } //Lower Bucket Slot for (int i = 0; i < 1; i++) { addSlotToContainer(new Slot(tileEntity, i, 163 + i * 18, 148)); } bindPlayerInventory(inventoryPlayer); } @Override public boolean canInteractWith(EntityPlayer player) { return tileEntity.isUseableByPlayer(player); } //Player Inventory protected void bindPlayerInventory(InventoryPlayer inventoryPlayer) { for (int i = 0; i < 3; i++) { for (int j = 0; j < 9; j++) { addSlotToContainer(new Slot(inventoryPlayer, j + i * 9 + 9, -1 + j * 18, 112 + i * 18)); } } //Player's hotbar for (int i = 0; i < 9; i++) { addSlotToContainer(new Slot(inventoryPlayer, i, -1 + i * 18, 170)); } } @Override public ItemStack transferStackInSlot(EntityPlayer player, int slot) { ItemStack stack = null; Slot slotObject = (Slot) inventorySlots.get(slot); if (slotObject != null && slotObject.getHasStack()) { ItemStack stackInSlot = slotObject.getStack(); stack = stackInSlot.copy(); if (slot < 9) { if (!this.mergeItemStack(stackInSlot, 9, 45, true)) { return null; } } else if (!this.mergeItemStack(stackInSlot, 0, 9, false)) { return null; } if (stackInSlot.stackSize == 0) { slotObject.putStack(null); } else { slotObject.onSlotChanged(); } if (stackInSlot.stackSize == stack.stackSize) { return null; } slotObject.onPickupFromSlot(player, stackInSlot); } return stack; } } [spoiler=SilvaniteChest] package co.uk.silvania.Remula.tileentity; import java.util.Random; import co.uk.silvania.Remula.CommonProxy; import co.uk.silvania.Remula.Remula; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.block.BlockContainer; import net.minecraft.block.material.Material; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.MathHelper; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; public class SilvaniteChest extends BlockContainer { public SilvaniteChest (int id) { super(id, Material.iron); setHardness(2.0F); setResistance(5.0F); setCreativeTab(Remula.tabRemula); this.setBlockBounds(0.0625F, 0.0F, 0.0625F, 0.9375F, 0.875F, 0.9375F); } @Override public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int idk, float what, float these, float are) { TileEntity tileEntity = world.getBlockTileEntity(x, y, z); if (tileEntity == null || player.isSneaking()) { return false; } player.openGui(Remula.instance, 0, world, x, y, z); return true; } @Override public void breakBlock(World world, int x, int y, int z, int par5, int par6) { dropItems(world, x, y, z); super.breakBlock(world, x, y, z, par5, par6); } public boolean isOpaqueCube() { return false; } public boolean renderAsNormalBlock() { return false; } public int getRenderType() { return 22; } public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving) { int var6 = par1World.getBlockId(par2, par3, par4 - 1); int var7 = par1World.getBlockId(par2, par3, par4 + 1); int var8 = par1World.getBlockId(par2 - 1, par3, par4); int var9 = par1World.getBlockId(par2 + 1, par3, par4); byte var10 = 0; int var11 = MathHelper.floor_double((double)(par5EntityLiving.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3; if (var11 == 0) { var10 = 2; } if (var11 == 1) { var10 = 5; } if (var11 == 2) { var10 = 3; } if (var11 == 3) { var10 = 4; } if (var6 != this.blockID && var7 != this.blockID && var8 != this.blockID && var9 != this.blockID) { par1World.setBlockMetadataWithNotify(par2, par3, par4, var10); } else { if ((var6 == this.blockID || var7 == this.blockID) && (var10 == 4 || var10 == 5)) { if (var6 == this.blockID) { par1World.setBlockMetadataWithNotify(par2, par3, par4 - 1, var10); } else { par1World.setBlockMetadataWithNotify(par2, par3, par4 + 1, var10); } par1World.setBlockMetadataWithNotify(par2, par3, par4, var10); } if ((var8 == this.blockID || var9 == this.blockID) && (var10 == 2 || var10 == 3)) { if (var8 == this.blockID) { par1World.setBlockMetadataWithNotify(par2 - 1, par3, par4, var10); } else { par1World.setBlockMetadataWithNotify(par2 + 1, par3, par4, var10); } par1World.setBlockMetadataWithNotify(par2, par3, par4, var10); } } } @Override public String getTextureFile () { return CommonProxy.BLOCK_PNG; } @SideOnly(Side.CLIENT) /** * Retrieves the block texture to use based on the display side. Args: iBlockAccess, x, y, z, side */ public int getBlockTexture(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { return 4; } /** * Returns the block texture based on the side being looked at. Args: side */ public int getBlockTextureFromSide(int par1) { return 4; } private void dropItems(World world, int x, int y, int z){ Random rand = new Random(); TileEntity tileEntity = world.getBlockTileEntity(x, y, z); if (!(tileEntity instanceof IInventory)) { return; } IInventory inventory = (IInventory) tileEntity; for (int i = 0; i < inventory.getSizeInventory(); i++) { ItemStack item = inventory.getStackInSlot(i); if (item != null && item.stackSize > 0) { float rx = rand.nextFloat() * 0.8F + 0.1F; float ry = rand.nextFloat() * 0.8F + 0.1F; float rz = rand.nextFloat() * 0.8F + 0.1F; EntityItem entityItem = new EntityItem(world, x + rx, y + ry, z + rz, new ItemStack(item.itemID, item.stackSize, item.getItemDamage())); if (item.hasTagCompound()) { entityItem.getEntityItem().setTagCompound((NBTTagCompound) item.getTagCompound().copy()); } float factor = 0.05F; entityItem.motionX = rand.nextGaussian() * factor; entityItem.motionY = rand.nextGaussian() * factor + 0.2F; entityItem.motionZ = rand.nextGaussian() * factor; world.spawnEntityInWorld(entityItem); item.stackSize = 0; } } } @Override public TileEntity createNewTileEntity(World world) { return new TileEntitySilvaniteChest(); } } [spoiler=SilvaniteGuiHandler] package co.uk.silvania.Remula.tileentity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.tileentity.TileEntity; import net.minecraft.world.World; import cpw.mods.fml.common.network.IGuiHandler; public class SilvaniteGuiHandler implements IGuiHandler { //returns an instance of the Container you made earlier @Override public Object getServerGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) { TileEntity tileEntity = world.getBlockTileEntity(x, y, z); if(tileEntity instanceof TileEntitySilvaniteChest){ return new ContainerSilvaniteChest(player.inventory, (TileEntitySilvaniteChest) tileEntity); } return null; } //returns an instance of the Gui you made earlier @Override public Object getClientGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) { TileEntity tileEntity = world.getBlockTileEntity(x, y, z); if(tileEntity instanceof TileEntitySilvaniteChest){ return new SilvaniteGuiChest(player.inventory, (TileEntitySilvaniteChest) tileEntity); } return null; } } [spoiler=SilvaniteGuiChest] package co.uk.silvania.Remula.tileentity; import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.util.StatCollector; import org.lwjgl.opengl.GL11; public class SilvaniteGuiChest extends GuiContainer { public SilvaniteGuiChest (InventoryPlayer inventoryPlayer, TileEntitySilvaniteChest tileEntity) { super(new ContainerSilvaniteChest(inventoryPlayer, tileEntity)); } /** The X size of the inventory window in pixels. */ protected int xSize = 194; /** The Y size of the inventory window in pixels. */ protected int ySize = 222; @Override protected void drawGuiContainerForegroundLayer(int param1, int param2) { fontRenderer.drawString("Silvanite Chest", 0, -22, 4210752); fontRenderer.drawString(StatCollector.translateToLocal("container.inventory"), 0, ySize - 122, 4210752); } @Override protected void drawGuiContainerBackgroundLayer(float par1, int par2, int par3) { int texture = mc.renderEngine.getTexture("/co/uk/silvania/Remula/gui/silvanitechest.png"); GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); this.mc.renderEngine.bindTexture(texture); int x = (width - xSize) / 2; int y = (height - ySize) / 2; this.drawTexturedModalRect(x, y, 0, 0, xSize, ySize); } } Any help would be really great If you need to see other classes let me know. It's probably just a noobie mistake somewhere, this is my first real attempt at tile entites.