Jump to content
  • Home
  • Files
  • Docs
  • Merch
Status Updates
  • All Content

  • Advanced Search
  • Existing user? Sign In  

    Sign In



    • Not recommended on shared computers


    • Forgot your password?

  • Sign Up
  • All Activity
  • Home
  • IceMetalPunk

IceMetalPunk

Members
 View Profile  See their activity
  • Content Count

    374
  • Joined

    December 4, 2015
  • Last visited

    February 25

 Content Type 

  • All Activity

Profiles

  • Status Updates
  • Status Replies

Forums

  • Topics
  • Posts

Calendar

  • Events
  • Event Comments

Posts posted by IceMetalPunk

  • Prev
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • Next
  • Page 9 of 15  
  1. [SOLVED] [1.12] Registered SoundEvent not playing without error

    in Modder Support

    Posted July 1, 2017


    11 minutes ago, Choonster said:

    Minecraft automatically uses your mod ID as the domain for the top-level sound event names in sounds.json, don't specify it yourself.

     

    Change redplusplus:item.redstone_sandwich.eat to item.redstone_sandwich.eat in your sounds.json file.

    As I said, that's what I tried originally, and not only did the sound not play, but I got an error logged when trying to play the sound that it was an "empty sound". That's why I added the domain, and the error disappeared...

  2. What do you use a ServerProxy for?

    in Modder Support

    Posted July 1, 2017


    The only thing I can think of is code that references the world folder. Because the world folder is on the dedicated server when there is one, any code that references it should probably be in the server proxy. But honestly, I'm just speculating and haven't tried any such code, so it might work in the common proxy as well.

  3. How to check if material can be replaced.

    in Modder Support

    Posted July 1, 2017


    11 minutes ago, funsize888 said:

    So I could do something like: 

     

    Black block = world.getBlock();

    if(block = Blocks.TALLGRASS){

    block.isReplaceable();

     

    I know this isn't exact but I don't have my computer in front of me right now

    No. isReplaceable() is not a setter, it's a getter. Meaning when you call it, it is returning true or false, meaning whether or not the block is replaceable. It does not set that. You should be checking the value of isReplaceable() to determine if the block is, in fact, replaceable, and if so, using other methods (such as World#setBlockState or something) to replace it.

  4. [SOLVED] [1.12] Registered SoundEvent not playing without error

    in Modder Support

    Posted July 1, 2017 · Edited July 1, 2017 by IceMetalPunk
    Added Solved Tag


    I'm just trying to get a sound to play, but it's not. It's not playing anything, but there are no errors or warnings logged. For the filenames below, my mod ID is redplusplus.

    I have a sounds.json file in my assets/redplusplus folder with this in it:

     

    {
    	"redplusplus:item.redstone_sandwich.eat": {
    		"sounds": [
    			"redplusplus:item/redstone_sandwich/eat"
    		]
    	}
    }

     

    I've also tried leaving out the redplusplus domain from the sound location, but it didn't help. (And of course, if I leave the redplusplus domain out of the sound name itself, I get an "unable to play empty sound" error, so I think it's necessary, yes?)

    I have a class which extends SoundEvent for easier registration, which just sets the registry name upon initialization:

     

    package com.icemetalpunk.redplusplus.sounds;
    
    import com.icemetalpunk.redplusplus.RedPlusPlus;
    
    import net.minecraft.util.ResourceLocation;
    import net.minecraft.util.SoundEvent;
    import net.minecraftforge.fml.common.registry.GameRegistry;
    
    public abstract class RedPlusPlusSound extends SoundEvent {
    	public RedPlusPlusSound(String name) {
    		super(new ResourceLocation(RedPlusPlus.MODID, name));
    		this.setRegistryName(new ResourceLocation(RedPlusPlus.MODID, name));
    	}
    
    	public void register() {
    		GameRegistry.findRegistry(SoundEvent.class).register(this);
    	}
    }

     

    And then my sound group classes extend RedPlusPlusSound, taking in a specific name within the group; for instance, I have this class for the sounds related to eating "redstone sandwiches" (an item in my mod):

     

    package com.icemetalpunk.redplusplus.sounds;
    
    public class SoundRedstoneSandwich extends RedPlusPlusSound {
    
    	public SoundRedstoneSandwich(String subset) {
    		super("item.redstone_sandwich." + subset);
    	}
    
    }

    So I can have item.redstone_sandwich.eat, and in the future (when this is working), item.redstone_sandwich.super, etc. all be instances of the same class.

    And then I actually just call these instances' register() methods (defined in the parent RedPlusPlusSound class above) in a handler for the RegistryEvent<SoundEvent> event type.

    I do have the file assets/redplusplus/sounds/item/redstone_sandwich/eat.ogg which is a non-empty sound. And when I use the /playsound command, that full resource location for my sound does properly auto-complete, so it's definitely registering something with that name.

     

    So what would cause the sound not to play if there's no indication of any errors?

  5. [1.12] Add crafting recipes

    in Modder Support

    Posted July 1, 2017 · Edited July 1, 2017 by IceMetalPunk
    Added quote


    2 minutes ago, Draco18s said:

    Yes. Json files is the 1.12 way.

     

    I wonder if this is the cause of my previous crashing problem I asked about in another topic that was never answered. If I were to have a recipe in its .json form and also register it through addShapedRecipe / addShapelessRecipe, would that cause a conflict and crash? (The error message received is a generic JVM one, so I didn't know where the problem was other than it only happened when I added the advancement and recipe .json files.)

  6. [1.12] Add crafting recipes

    in Modder Support

    Posted July 1, 2017


    Can you actually register recipes from the JSON files? I've been using GameRegistry.addShapedRecipe / GameRegistry.addShapelessRecipe in 1.12, and it works just fine...

  7. [1.12] Fatal error when trying to make unlockable recipes?

    in Modder Support

    Posted June 29, 2017 · Edited June 29, 2017 by IceMetalPunk
    Typo fixing


    Since 1.12 is encouraging recipes to be unlocked, I figured I'd make my mod's recipes unlockable in the same way. So as a quick test, I started with just one. I created the assets/redplusplus/advancements/recipes folder and basically copied/pasted one of the vanilla recipe advancements in. Then I changed it to trigger when getting a comparator in your inventory instead of the iron ingot that was there, and to unlock my redplusplus:block_redstone_counter recipe instead of the one it was unlocking. (I also made a copy of the vanilla recipes/root.json advancement, which is just an impossible trigger and nothing else, and parented my advancement to that one just in case.)

    Then I created the assets/redplusplus/recipes/block_redstone_counter.json file, where I copied the recipe file for an anvil and changed the recipe ingredients and output. The ingredients are all vanilla items, the output is my custom item.

     

    I made sure to use the proper domains for all resource locations in these files, whether they're minecraft: or redplusplus: alike.

    The game loads fine, but when I open a crafting table, it crashes completely. The weird thing is the stacktrace doesn't include any of my code, only vanilla code; can someone help me pinpoint what I've done to cause a fatal error here?

    Stacktrace:

    [main/FATAL]: Error executing task
    java.util.concurrent.ExecutionException: java.lang.IndexOutOfBoundsException: bitIndex < 0: -1
    	at java.util.concurrent.FutureTask.report(Unknown Source) ~[?:1.8.0_111]
    	at java.util.concurrent.FutureTask.get(Unknown Source) ~[?:1.8.0_111]
    	at net.minecraft.util.Util.runTask(Util.java:54) [Util.class:?]
    	at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1161) [Minecraft.class:?]
    	at net.minecraft.client.Minecraft.run(Minecraft.java:436) [Minecraft.class:?]
    	at net.minecraft.client.main.Main.main(Main.java:118) [Main.class:?]
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_111]
    	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_111]
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_111]
    	at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_111]
    	at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) [launchwrapper-1.12.jar:?]
    	at net.minecraft.launchwrapper.Launch.main(Launch.java:28) [launchwrapper-1.12.jar:?]
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_111]
    	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_111]
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_111]
    	at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_111]
    	at net.minecraftforge.gradle.GradleStartCommon.launch(GradleStartCommon.java:97) [start/:?]
    	at GradleStart.main(GradleStart.java:26) [start/:?]
    Caused by: java.lang.IndexOutOfBoundsException: bitIndex < 0: -1
    	at java.util.BitSet.get(Unknown Source) ~[?:1.8.0_111]
    	at net.minecraft.stats.RecipeBook.containsRecipe(RecipeBook.java:35) ~[RecipeBook.class:?]
    	at net.minecraft.client.gui.recipebook.RecipeList.func_194214_a(RecipeList.java:35) ~[RecipeList.class:?]
    	at net.minecraft.client.network.NetHandlerPlayClient.lambda$handleRecipeBook$2(NetHandlerPlayClient.java:1636) ~[NetHandlerPlayClient.class:?]
    	at java.util.ArrayList.forEach(Unknown Source) ~[?:1.8.0_111]
    	at net.minecraft.client.network.NetHandlerPlayClient.handleRecipeBook(NetHandlerPlayClient.java:1634) ~[NetHandlerPlayClient.class:?]
    	at net.minecraft.network.play.server.SPacketRecipeBook.processPacket(SPacketRecipeBook.java:40) ~[SPacketRecipeBook.class:?]
    	at net.minecraft.network.play.server.SPacketRecipeBook.processPacket(SPacketRecipeBook.java:14) ~[SPacketRecipeBook.class:?]
    	at net.minecraft.network.PacketThreadUtil$1.run(PacketThreadUtil.java:21) ~[PacketThreadUtil$1.class:?]
    	at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) ~[?:1.8.0_111]
    	at java.util.concurrent.FutureTask.run(Unknown Source) ~[?:1.8.0_111]
    	at net.minecraft.util.Util.runTask(Util.java:53) ~[Util.class:?]
    	... 15 more

     

  8. [1.12] Smelting recipe for only certain fuel?

    in Modder Support

    Posted June 29, 2017


    Ah, I didn't even look at the date! >_< I may switch over to the newest release, then, at some point. For now, I'll make sure the rest of my mod is functional and then transition after.

     

    Thanks for the help!

  9. [1.12] Smelting recipe for only certain fuel?

    in Modder Support

    Posted June 29, 2017


    Ah. I could swear I tried registering a block with the same name as a Minecraft block (and domain), and got an error for trying to register duplicate entries. Then again, I haven't been using the registry events, and have been registering things in the preInit, so I'll try to switch over to the events and see if I can get it working after all.

    Thank you!

  10. [1.12] Smelting recipe for only certain fuel?

    in Modder Support

    Posted June 29, 2017 · Edited June 29, 2017 by IceMetalPunk
    Added question.


    Hm. That's annoying. I'm trying to make my mod as vanilla-feeling as possible, and having a special machine for just one recipe (or a small handful) puts it in the mod-feel realm.

    Thanks for the info; I'll see if there's some hacky workaround I can come up with, or else just scrap the feature I was planning.

     

    *EDIT* Speaking of workarounds, it seems substitution aliases no longer exist. What would be the proper way to replace the vanilla furnace block with a custom one that implements my custom recipes? Because that may work, if it can be done.

  11. [1.12] Smelting recipe for only certain fuel?

    in Modder Support

    Posted June 29, 2017


    Is there a way to register a smelting recipe that requires a certain fuel item? For instance, a recipe that only works if you smelt the item with coal, but not if you smelt it with wood or lava? Since the GameRegistry.addSmelting methods don't have options for that, I thought I'd need to use event handling, but while there are events for pre-and-post brewing, I can't find any for smelting.

    So how would I do this?

  12. [SOLVED] [1.12] Set block light based on redstone input

    in Modder Support

    Posted June 26, 2017 · Edited June 27, 2017 by IceMetalPunk
    Solved it myself


    I'm trying to make a simple analog lamp, where the light output equals the max redstone input. I thought this would be simple, but it's not working. This is the relevant code, inside the block class:

     

    	@Override
    	public int getLightValue(IBlockState state, IBlockAccess world, BlockPos pos) {
    		if (world instanceof World) {
    			World theWorld = (World) world;
    			return theWorld.isBlockIndirectlyGettingPowered(pos);
    		}
    		return 0;
    	}
    
    	@Override
    	public void observedNeighborChange(IBlockState thisState, World world, BlockPos thisPos, Block changedBlock,
    			BlockPos changedBlockPos) {
    		world.setLightFor(EnumSkyBlock.BLOCK, thisPos, world.isBlockIndirectlyGettingPowered(thisPos));
    		world.checkLight(thisPos);
    	}

     

    Some debug output shows that the observedNeighborChange() method is being called correctly, when there's a block state change next to the lamp, and that isBlockIndirectlyGettingPowered() is returning the appropriate redstone signal strength.

    Yet the block never lights up. Why not?

     

    *Update* After more testing, it seems like the block light *is* getting set properly, but only after I exit the world and reload it. I thought checkLight() was supposed to update the light levels; if it's not, what do I need to call to update the light levels without relogging?

    *UPDATE 2* I fixed it! As it turns out, you need to change the block state for Minecraft to actually update the lighting. Even calling setBlockState with the current state won't work; it needs to be a new block state. So I added a "power" property and set power equal to the redstone input, then I change the blockstate whenever the neighbor changes and it all works fine.

  13. [1.12] Register ItemBlock model/texture [Solved]

    in Modder Support

    Posted June 26, 2017


    2 minutes ago, Draco18s said:

    ModelLoader needs to be called during PreInit, not Init.

    Ah! And now it works! :D So what's the main benefit to using ModelLoader rather than ItemModelMesher? They seem to work equally well, just with registration occurring at different times. Is there a benefit under the hood I'm not aware of?

  14. [1.12] Register ItemBlock model/texture [Solved]

    in Modder Support

    Posted June 26, 2017


    2 minutes ago, Draco18s said:

    Why are you using the ModelMesher?

    If you're going to do it this way (and not the Registry events) then you should be using ModelLoader.setCustomModelResourceLocation

    Dylem's solution seems to work just fine; when I tried switching the code to ModelLoader.setCustomModelResourceLocation(this.itemBlock, 0, model) [this.itemBlock is of course the ItemBlock instance], it doesn't work, it just shows the purple-and-black undefined model instead again...

  15. [1.12] Register ItemBlock model/texture [Solved]

    in Modder Support

    Posted June 26, 2017


    Yeah, about 4 minutes after posting, I found it myself :) Thank you, it seems to work now!

  16. [1.12] Register ItemBlock model/texture [Solved]

    in Modder Support

    Posted June 26, 2017


    That helps, but what is the ItemModelMesher instance passed as an argument? I assume I can't just create a new instance of it and use that; where does it come from?

  17. [1.12] Register ItemBlock model/texture [Solved]

    in Modder Support

    Posted June 26, 2017 · Edited June 26, 2017 by IceMetalPunk
    Solved


    I've added a new block to the game, which is fully functional. It has its own block model and textures, which also works fine. But now, I'm trying to give its ItemBlock a model, and it's just not working.

    I've noticed that quite a few things about item and block registration have changed in Forge for 1.12; how would I properly register an item model?

    Currently, I'm simply creating an ItemBlock from my block class and registering it with the GameRegistry.findRegistry(Item.class) registry. Then I have a JSON file in my assets/<mod>/models/item folder (using the actual mod ID, not literally "<mod>") which simply defines the model parent to be the block model that already works.

    But the item isn't showing up; it's just the standard purple-and-black "not found" texture instead. So then I tried adding a call, after registering the item with FML, to ModelBakery.registerItemVariants passing only one registry name to it, in hopes that would work out; it didn't change anything. No errors, just also no item model.

    I'm probably missing a step or two; what am I missing?

  18. [1.11.2] Lang file not loading properly?

    in Modder Support

    Posted June 6, 2017


    10 minutes ago, Choonster said:

     

    It's best to include the pack.mcmeta file so you're using the current resource pack format with lowercase names.

     

    LegacyV2Adapter is only meant for loading resource packs designed for previous versions of Minecraft and could be removed at some point in the future, so it's best not to rely on it.

    That's what I figured. Thanks for all your help! :)

  19. [1.11.2] Lang file not loading properly?

    in Modder Support

    Posted June 6, 2017


    13 minutes ago, Choonster said:

    Do you have a pack.mcmeta file in src/main/resources with pack_format set to 3?

     

    If you don't, Forge will load your mod's resources using the LegacyV2Adapter IResourcePack wrapper. This means that your lang files will be loaded with the old mixed-case names (e.g. en_US.lang) rather than the new lower-case names (e.g. en_us.lang).

     

    If you do, your lang files should be loaded with lower-case names. Try refreshing your IDE project (i.e. click the "Refresh all Gradle projects" button in IDEA's Gradle window or re-run the eclipse Gradle task) and/or rebuilding it.

    Well. I had no idea that a pack.mcmeta file was required for mod resources to prevent it from loading legacy filenames. I added that, and lo and behold, it works now :)

    Thank you! I learn something new everyday. A question about convention, though: is it better to include the pack.mcmeta file, or to leave it out and use the old mixed-case filenames instead? I'd assume using the new lower-case names with the pack file is preferred, but I'd like to be sure.

  20. [1.11.2] Lang file not loading properly?

    in Modder Support

    Posted June 6, 2017


    It's been awhile since the last time I've worked on any mods, so I'm probably overlooking something stupid here, but I can't seem to figure out the problem; so here I am.

    The issue is simple: my language file isn't loading properly. None of the strings (or at least, the creative tab name and the item name for the one block I've added) are translating.

    Here's a screenshot to show you:

    lang_file_screenie.png?dl=1

     

    I create the tab like this, for reference of the tab name:

    public static CreativeTabs tab = new CreativeTabs("warpstone") {
    
    		@Override
    		public ItemStack getTabIconItem() {
    			return new ItemStack(Item.getItemFromBlock(Warpstone.blocks.get("warpstone_ore")));
    		}
    
    	};

     

    I set the unlocalized name of the block *and* ItemBlock to "warpstone_ore".

    And in my mod's src folder, I have the file

    main\resources\assets\warpstone\lang\en_us.lang

     

    With these basic contents:

    tile.warpstone_ore.name=Warpstone Ore
    itemGroup.warpstone=Warpstone

     

    And yet, as you can see from the screenshot, it's definitely not translating the names at all. What am I doing wrong?

  21. [1.10.2] Make block drop itself with all Tile Entity data?

    in Modder Support

    Posted December 21, 2016


    When you save the

    NBTTagCompound

    inside the

    ItemStack

    , you also save the coordinates of the

    Block

    at the location it was broken at. Then, when you place it down, you read from the

    ItemStack

    's

    NBTTagCompound

    , thus also setting the position of the

    TileEntity

    to the coordinates of the previous location. This may be why it's not getting ticked.

     

    Setting the correct position after reading from NBT should fix this issue, if this is what caused it.

     

    That worked! And it makes sense, too! Thank you! :D (Also, an interesting note: if the position tags are wrong, and I run the /blockdata command on the block's position, it seems to automatically fix the position in the tile entity tags [showing a successful change to the tags even if I supply an empty tag to the command] and the updates start ticking again. Weird, but interesting.)

     

    You don't need to read the data into the TE manually. Minecraft already does that for the BlockEntityTag tag on ItemBlocks.

     

    And yet if I don't load it myself in that onBlockPlacedBy override, when I re-place a broken block, all the tile entity data is lost completely (I just tested it)...

  22. [1.10.2] Make block drop itself with all Tile Entity data?

    in Modder Support

    Posted December 21, 2016


    The TileEntity cannot be accessed in

    getDrops

    , it is called after the Block has already been removed from the World. See the patches forge makes to

    BlockFlowerPot

    (between FORGE START and FORGE END).

     

    Thank you! It's a bit silly to check what the block should drop after its associated data is already removed, isn't it? But anyway, overriding the removedByPlayer and harvestBlock methods appropriately did the trick, and now it's dropping! It's almost working, except... when I place the block back down, it correctly retains the tile entity data, but it seems as though the tile entity stops ticking/updating. No errors, it just never runs the update code (and yet, the constructor is being called, so the TE is created, just not ticking).

     

    Here's the entire TE class, block base class, and specific block class I'm testing with:

     

    Tile Entity:

    package com.icemetalpunk.chaotica.tileentities;
    
    import java.util.Iterator;
    import java.util.Map;
    
    import javax.annotation.Nullable;
    
    import com.icemetalpunk.chaotica.Chaotica;
    import com.icemetalpunk.chaotica.ChaoticaUtils;
    import com.icemetalpunk.chaotica.fluids.FluidTankChaos;
    import com.icemetalpunk.chaotica.handlers.ChaoticaMessage;
    import com.icemetalpunk.chaotica.handlers.ChaoticaPacketHandler;
    import com.icemetalpunk.chaotica.sounds.ChaoticaSoundRegistry;
    
    import net.minecraft.block.Block;
    import net.minecraft.block.state.IBlockState;
    import net.minecraft.item.Item;
    import net.minecraft.item.ItemStack;
    import net.minecraft.nbt.NBTTagCompound;
    import net.minecraft.util.EnumFacing;
    import net.minecraft.util.ITickable;
    import net.minecraft.util.SoundCategory;
    import net.minecraftforge.common.capabilities.Capability;
    import net.minecraftforge.common.capabilities.ICapabilityProvider;
    import net.minecraftforge.fluids.Fluid;
    import net.minecraftforge.fluids.FluidStack;
    import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
    
    public class TileEntityChaoticCondenser extends ChaoticaTEBase implements ICapabilityProvider, ITickable {
    
    protected Fluid fluid = Chaotica.fluids.CORROSIVE_CHAOS;
    protected int capacity = 5 * Fluid.BUCKET_VOLUME;
    protected FluidTankChaos tank = new FluidTankChaos(this.capacity);
    protected int countdown = 40;
    protected int maxCountdown = 60; // Max amount it resets to
    
    public TileEntityChaoticCondenser() {
    	this.tank.setTileEntity(this);
    	System.out.println("Created TE");
    }
    
    @Override
    public boolean hasCapability(Capability<?> capability, @Nullable EnumFacing facing) {
    	if (capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) {
    		return true;
    	}
    	return super.hasCapability(capability, facing);
    }
    
    @Override
    public <T> T getCapability(Capability<T> capability, @Nullable EnumFacing facing) {
    	if (capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) {
    		return CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY.cast(this.tank);
    	}
    	return super.getCapability(capability, facing);
    }
    
    // Ticks until the next check for blocks to convert to chaos
    public int getCountdown() {
    	return this.countdown;
    }
    
    public int getMaxCountdown() {
    	return this.maxCountdown;
    }
    
    public Fluid getFluid() {
    	if (tank.getFluid() == null) {
    		return null;
    	}
    	return this.tank.getFluid().getFluid();
    }
    
    public void setFluidAmount(int amount) {
    	if (tank.getFluid() == null) {
    		tank.setFluid(new FluidStack(this.fluid, 0));
    	}
    	tank.getFluid().amount = amount;
    }
    
    @Override
    public void readFromNBT(NBTTagCompound tag) {
    	super.readFromNBT(tag);
    	NBTTagCompound tankTag = tag.getCompoundTag("Tank");
    	this.tank.readFromNBT(tankTag);
    	this.countdown = tag.getInteger("Countdown");
    }
    
    @Override
    public NBTTagCompound writeToNBT(NBTTagCompound tag) {
    	super.writeToNBT(tag);
    	NBTTagCompound tankTag = new NBTTagCompound();
    	tank.writeToNBT(tankTag);
    	tag.setTag("Tank", tankTag);
    	tag.setInteger("Countdown", this.countdown);
    	return tag;
    }
    
    public int fill(int amount, boolean doFill) {
    	return this.tank.fill(new FluidStack(this.fluid, amount), doFill);
    }
    
    @Override
    public void update() {
    	System.out.println("Updating TE");
    	if (--this.countdown == 0) {
    		this.countdown = this.maxCountdown;
    		if (!this.worldObj.isRemote) {
    			IBlockState east = this.getWorld().getBlockState(this.pos.east());
    			IBlockState west = this.getWorld().getBlockState(this.pos.west());
    			IBlockState north = this.getWorld().getBlockState(this.pos.north());
    			IBlockState south = this.getWorld().getBlockState(this.pos.south());
    			IBlockState up = this.getWorld().getBlockState(this.pos.up());
    			IBlockState down = this.getWorld().getBlockState(this.pos.down());
    
    			// Iterate over the amounts map and add the appropriate amount
    			// of fluid if applicable
    			boolean playSound = false;
    			Iterator<Map.Entry<ChaoticaUtils.BlockPair, Integer>> it = ChaoticaUtils.pairAmounts.entrySet().iterator();
    			while (it.hasNext()) {
    				Map.Entry<ChaoticaUtils.BlockPair, Integer> entry = it.next();
    				ChaoticaUtils.BlockPair pair = entry.getKey();
    				int amount = entry.getValue().intValue();
    
    				if (pair.isPair(east.getBlock(), west.getBlock())) {
    					if (this.fill(amount, true) > 0) {
    						playSound = true;
    						this.getWorld().destroyBlock(this.pos.east(), false);
    						this.getWorld().destroyBlock(this.pos.west(), false);
    					}
    				}
    				if (pair.isPair(north.getBlock(), south.getBlock())) {
    					if (this.fill(amount, true) > 0) {
    						playSound = true;
    						this.getWorld().destroyBlock(this.pos.north(), false);
    						this.getWorld().destroyBlock(this.pos.south(), false);
    					}
    				}
    				if (pair.isPair(up.getBlock(), down.getBlock())) {
    					if (this.fill(amount, true) > 0) {
    						playSound = true;
    						this.getWorld().destroyBlock(this.pos.up(), false);
    						this.getWorld().destroyBlock(this.pos.down(), false);
    					}
    				}
    			}
    			if (playSound) {
    				this.worldObj.playSound(null, this.getPos(), ChaoticaSoundRegistry.CONDENSE_CHAOS, SoundCategory.BLOCKS, 1.0f, 1.0f);
    				ChaoticaPacketHandler.INSTANCE.sendToAll(new ChaoticaMessage(ChaoticaMessage.MessageTypes.CONDENSER_LEVEL, this.pos.getX(), this.pos.getY(), this.pos.getZ(), this.tank.getFluidAmount()));
    			}
    		}
    	}
    }
    
    // If shouldHarvest() returns true, this will drop a fully tagged item
    // instead of an empty one.
    @Override
    public boolean shouldHarvest() {
    	return true;
    }
    
    @Override
    public ItemStack getHarvest() {
    	Block block = this.worldObj.getBlockState(this.pos).getBlock();
    	Item item = Item.getItemFromBlock(block);
    	ItemStack stack = new ItemStack(item, 1);
    	NBTTagCompound nbt = new NBTTagCompound();
    	this.writeToNBT(nbt);
    	stack.setTagCompound(nbt);
    	return stack;
    }
    
    }

     

    TE Provider Block Base Class:

    package com.icemetalpunk.chaotica.blocks;
    
    import java.util.ArrayList;
    
    import com.google.common.collect.Lists;
    
    import net.minecraft.block.material.Material;
    import net.minecraft.block.state.IBlockState;
    import net.minecraft.entity.EntityLivingBase;
    import net.minecraft.entity.player.EntityPlayer;
    import net.minecraft.item.ItemStack;
    import net.minecraft.nbt.NBTTagCompound;
    import net.minecraft.tileentity.TileEntity;
    import net.minecraft.util.math.BlockPos;
    import net.minecraft.world.IBlockAccess;
    import net.minecraft.world.World;
    
    public abstract class ChaoticaTEBlock extends ChaoticaBlockBase {
    
    public ChaoticaTEBlock(String name, Material materialIn) {
    	super(name, materialIn);
    }
    
    // Make sure when the block is dropped, the item retains the TE's data tags
    
    @Override
    public final ArrayList<ItemStack> getDrops(IBlockAccess world, BlockPos pos, IBlockState state, int fortune) {
    	int meta = state.getBlock().getMetaFromState(state);
    	ItemStack ret = new ItemStack(this, 1, meta);
    	NBTTagCompound nbt = new NBTTagCompound();
    	TileEntity te = world.getTileEntity(pos);
    	NBTTagCompound teTag = new NBTTagCompound();
    	te.writeToNBT(teTag);
    	nbt.setTag("BlockEntityTag", teTag);
    	ret.setTagCompound(nbt);
    	return Lists.newArrayList(ret);
    }
    
    @Override
    public boolean removedByPlayer(IBlockState state, World world, BlockPos pos, EntityPlayer player,
    		boolean willHarvest) {
    	if (willHarvest) return true; // If it will harvest, delay deletion of
    									// the block until after getDrops
    	return super.removedByPlayer(state, world, pos, player, willHarvest);
    }
    
    @Override
    public void harvestBlock(World world, EntityPlayer player, BlockPos pos, IBlockState state, TileEntity te,
    		ItemStack tool) {
    	super.harvestBlock(world, player, pos, state, te, tool);
    	world.setBlockToAir(pos);
    }
    
    @Override
    public boolean canHarvestBlock(IBlockAccess world, BlockPos pos, EntityPlayer player) {
    	return true;
    }
    
    // When placed, if the item has a tag, set the tile entity's tag
    /*
     * FIXME: When placed like this, tags are properly set, but tile entity
     * fails to update ever after.
     */
    @Override
    public void onBlockPlacedBy(World worldIn, BlockPos pos, IBlockState state, EntityLivingBase placer,
    		ItemStack stack) {
    	super.onBlockPlacedBy(worldIn, pos, state, placer, stack);
    	if (stack.hasTagCompound() && stack.getTagCompound().hasKey("BlockEntityTag")) {
    		NBTTagCompound tag = stack.getTagCompound().getCompoundTag("BlockEntityTag");
    		worldIn.getTileEntity(pos).readFromNBT(tag);
    	}
    }
    
    // Tile entity providers should provide the class and name of their tile
    // entity here for registration.
    public abstract Class<? extends TileEntity> getTileEntityClass();
    
    public abstract String getTileEntityName();
    
    @Override
    public boolean hasTileEntity(IBlockState state) {
    	return true;
    }
    
    // Generic createNewTileEntity so only the getTileEntityClass needs to be
    // specified.
    @Override
    public TileEntity createTileEntity(World world, IBlockState state) {
    	try {
    		return this.getTileEntityClass().newInstance();
    	}
    	catch (InstantiationException e) {
    		e.printStackTrace();
    		return null;
    	}
    	catch (IllegalAccessException e) {
    		e.printStackTrace();
    		return null;
    	}
    }
    }
    

     

    Block Base Class:

    package com.icemetalpunk.chaotica.blocks;
    
    import com.icemetalpunk.chaotica.Chaotica;
    
    import net.minecraft.block.Block;
    import net.minecraft.block.material.Material;
    import net.minecraft.util.ResourceLocation;
    import net.minecraftforge.fml.common.registry.GameRegistry;
    import net.minecraftforge.oredict.OreDictionary;
    
    public class ChaoticaBlockBase extends Block {
    
    public ChaoticaBlockBase(String name, Material materialIn) {
    	super(materialIn);
    	this.setUnlocalizedName(name).setRegistryName(new ResourceLocation(Chaotica.MODID, name)).setCreativeTab(Chaotica.tab);
    }
    
    protected void register() {
    	GameRegistry.register(this);
    	if (this instanceof ChaoticaTEBlock) {
    		GameRegistry.registerTileEntity(((ChaoticaTEBlock) this).getTileEntityClass(), ((ChaoticaTEBlock) this).getTileEntityName());
    	}
    
    	String[] oreDict = this.getOreDict();
    	if (oreDict != null) {
    		for (String entry : oreDict) {
    			OreDictionary.registerOre(entry, this);
    		}
    	}
    }
    
    // Override this if this block has an oredict entry.
    public String[] getOreDict() {
    	return null;
    }
    
    }
    

     

    Specific Block Class:

    package com.icemetalpunk.chaotica.blocks;
    
    import javax.annotation.Nullable;
    
    import com.icemetalpunk.chaotica.Chaotica;
    import com.icemetalpunk.chaotica.gui.ChaoticaGuiHandler;
    import com.icemetalpunk.chaotica.tileentities.TileEntityChaoticCondenser;
    
    import net.minecraft.block.SoundType;
    import net.minecraft.block.material.Material;
    import net.minecraft.block.state.IBlockState;
    import net.minecraft.entity.player.EntityPlayer;
    import net.minecraft.item.ItemStack;
    import net.minecraft.tileentity.TileEntity;
    import net.minecraft.util.EnumFacing;
    import net.minecraft.util.EnumHand;
    import net.minecraft.util.math.BlockPos;
    import net.minecraft.world.World;
    
    public class BlockChaoticCondenser extends ChaoticaTEBlock {
    
    public BlockChaoticCondenser() {
    	super("chaotic_condenser", Material.ROCK);
    	this.setHardness(3.5F);
    	this.setSoundType(SoundType.STONE);
    	this.register();
    }
    
    @Override
    public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand,
    		@Nullable ItemStack item, EnumFacing side, float hitX, float hitY, float hitZ) {
    	if (!world.isRemote) {
    		player.openGui(Chaotica.instance, ChaoticaGuiHandler.Guis.CONDENSER.ordinal(), world, pos.getX(), pos.getY(), pos.getZ());
    	}
    	return true;
    }
    
    @Override
    public Class<? extends TileEntity> getTileEntityClass() {
    	return TileEntityChaoticCondenser.class;
    }
    
    @Override
    public String getTileEntityName() {
    	return "ChaoticCondenser";
    }
    
    }
    

     

    How could the tile entity be created (it is!), its data be accessible (it is! It's displaying properly!), but the update method fail to be called, even though it works fine if I place down a fresh, "clean" block, just not when I place one down which already has tags?

     

    Just because it's final in the Block class, so I kept it that way in my override. Probably not necessary, but it also doesn't hurt, right?
    How could it be final in the Block class? Then you would not be able to override it. You do know what final means, right? But yes, it does not hurt. Finality is good actually.

     

    Yes, I did think it was strange that I was able to override it, but being relatively new to Java, I thought there was some quirk of the language that allowed me to do it...turns out I'm just an idiot and confused the example code I was learning from (which declared it as final) with the base Block class itself xD Sorry for the confusion!

  23. [1.10.2] Make block drop itself with all Tile Entity data?

    in Modder Support

    Posted December 20, 2016


    You're not returning the item stack with the NBT which you set up (and that part looks ok).  Instead you're returning an arraylist with a brand new ItemStack which has no NBT data at all:

    return Lists.newArrayList(new ItemStack(this, 1, meta));

    D'oh! This is what I get for trying to code at 5AM; how did I not see that? >_<

     

    Unfortunately, fixing it to return Lists.newArrayList(ret) doesn't seem to fix the problem. It still drops nothing at all no matter how I harvest it.

     

    Also, why are you making getItemDropped() return null?  Looks unnecessary, especially as you've overridden getDrops(), which is what primarily calls getItemDropped() in the default Block#getDrops() implementation.

     

    I wasn't sure if there were certain cases where getItemDropped() was called instead of getDrops(), and if so, I didn't want it to drop anything different. Since I can't return an ItemStack with getItemDropped(), I just had it return null for safe measure.

     

    But removing that override doesn't help; it still drops nothing.

     

    (and any particular reason you've made getDrops() final?)

     

    Just because it's final in the Block class, so I kept it that way in my override. Probably not necessary, but it also doesn't hurt, right?

  24. [1.10.2] Make block drop itself with all Tile Entity data?

    in Modder Support

    Posted December 20, 2016


    Solve one problem, another shows up.

     

    I'm trying to simply make a block, which provides a tile entity, drop a tagged item stack when harvested. In other words, the item stack should have a BlockEntityTag with all the tile entity's data, ready to resume when placed down again.

     

    Instead...I'm getting no drops at all. Whether I'm in Creative mode or Survival, using a tool or not, the block doesn't drop anything when broken.

     

    Here's the relevant code:

     

    	@Override
    public Item getItemDropped(IBlockState state, Random rand, int fortune) {
    	return null;
    }
    
    @Override
    public final ArrayList<ItemStack> getDrops(IBlockAccess world, BlockPos pos, IBlockState state, int fortune) {
    	int meta = state.getBlock().getMetaFromState(state);
    	ItemStack ret = new ItemStack(this, 1, meta);
    	NBTTagCompound nbt = new NBTTagCompound();
    	TileEntity te = world.getTileEntity(pos);
    	te.writeToNBT(nbt);
    	ret.setTagCompound(nbt);
    	return Lists.newArrayList(new ItemStack(this, 1, meta));
    }
    
    @Override
    public boolean canHarvestBlock(IBlockAccess world, BlockPos pos, EntityPlayer player) {
    	return true;
    }

     

    I'm returning an array containing the item stack from getDrops(), and I've ensured the block is harvestable at all times, so why isn't it dropping anything at all?

  25. [1.10.2] Rendering texture showing up pink? [FileNotFoundException]

    in Modder Support

    Posted December 20, 2016


    The ResourceLocation is wrong. You use

    "chaotica:fluids/corrosive_chaos_still.png"
    which points to
    assets/chaotica/fluids/corrosive_chaos_still.png
    The texture is located at
    assets/textures/chaotica/fluids/corrosive_chaos_still.png

    The correct ResourceLocation would be

    "chaotica:textures/fluids/corrosive_chaos_still.png"

     

    *Facepalm* I added "textures", but forgot the extension, then I added the extension and removed "textures"... Thank you! I don't know why I had it in my head that Minecraft would assume parts of the path, such as "textures" and ".png", for ResourceLocations being bound to textures.

     

    Thanks again!

  • Prev
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • Next
  • Page 9 of 15  
  • All Activity
  • Home
  • IceMetalPunk
  • Theme
  • Contact Us
  • Discord

Copyright © 2019 ForgeDevelopment LLC · Ads by Curse Powered by Invision Community