Spacejet Posted November 29, 2018 Posted November 29, 2018 (edited) using Forge 1.12.2 So I have a couple of problems to do with PropertyBool set on a block with a TileEntity. First problem is that the PropertyBool is not setting to it's default state on block placement, set in setDefaultState() this.setDefaultState(this.blockState.getBaseState().withProperty(ACTIVATED, Boolean.valueOf(true))); ACTIVATED is always false on placement, but, after a quick re-log (I don't restart minecraft, just the world) it changes to true. Second Problem is that I don't know how to get and set the value of ACTIVATED from other classes, specifically in this case, the TileEntity class. I have tried everything, searched online, read the documentation but failed to find a mention on how to do it. Full Block class: Spoiler package com.spacejet.quantivity.blocks; import com.spacejet.quantivity.Main; import com.spacejet.quantivity.tileentity.TileEntityEnergyAccumulator; import com.spacejet.quantivity.util.handlers.GuiHandler; import com.spacejet.quantivity.util.handlers.TileEntityHandler; import net.minecraft.block.ITileEntityProvider; import net.minecraft.block.SoundType; import net.minecraft.block.material.Material; import net.minecraft.block.properties.IProperty; import net.minecraft.block.properties.PropertyBool; import net.minecraft.block.state.BlockStateContainer; 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.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 EnergyAccumulator extends BlockBase implements ITileEntityProvider { public static final PropertyBool ACTIVATED = PropertyBool.create("activated"); public EnergyAccumulator(String name, Material material) { super(name, material); setHardness(5); setHarvestLevel("pickaxe", 2); setResistance(30); setSoundType(SoundType.METAL); setLightLevel(1); this.setDefaultState(this.blockState.getBaseState().withProperty(ACTIVATED, Boolean.valueOf(true))); } @Override public int getMetaFromState(IBlockState state) { if(ACTIVATED.getAllowedValues().contains(true)) return 1; else return 0; } @Override public IBlockState getStateFromMeta(int meta) { if(meta == 1) return this.getDefaultState().withProperty(ACTIVATED, Boolean.valueOf(true)); else return this.getDefaultState().withProperty(ACTIVATED, Boolean.valueOf(false)); } @Override protected BlockStateContainer createBlockState() { return new BlockStateContainer(this, new IProperty[] {ACTIVATED}); } @Override public boolean hasTileEntity(IBlockState state) { return true; } @Override public TileEntity createNewTileEntity(World worldIn, int meta) { return TileEntityHandler.ENERGY_ACCUMULATOR; } @Override public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer playerIn, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) { if(!world.isRemote) { playerIn.openGui(Main.instance, GuiHandler.ENERGY_ACCUMULATOR, world, pos.getX(), pos.getY(), pos.getZ()); } return true; } } Full TileEntity class (note- I am using the CJCore Library in this mod) Spoiler package com.spacejet.quantivity.tileentity; import cjminecraft.core.energy.EnergyUnit; import cjminecraft.core.energy.EnergyUtils; import cjminecraft.core.energy.compat.forge.CustomForgeEnergyStorage; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Biomes; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; import net.minecraft.util.ITickable; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.TextComponentTranslation; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.ICapabilityProvider; import net.minecraftforge.energy.CapabilityEnergy; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.ItemStackHandler; public class TileEntityEnergyAccumulator extends TileEntity implements ITickable, ICapabilityProvider { private ItemStackHandler handler; private CustomForgeEnergyStorage storage; public static boolean active; public String name; private int energy; public TileEntityEnergyAccumulator(int maxInOut, int maxStore) { this.handler = new ItemStackHandler(2); this.storage = new CustomForgeEnergyStorage(maxStore, 0); this.energy = storage.getEnergyStored(); } @Override public void update() { if(this.world != null) { if(!this.world.isRemote) { if(this.world.getBiome(this.pos) == Biomes.PLAINS) { if(active) { this.storage.receiveEnergyInternal(60, false); } } this.storage.extractEnergyInternal((int) EnergyUtils.giveEnergyAllFaces(this.world, this.pos, this.storage.getEnergyStored(), EnergyUnit.REDSTONE_FLUX, false, false), false); } } } @SuppressWarnings("unchecked") @Override public <T> T getCapability(Capability<T> capability, EnumFacing facing) { if(capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return (T) this.handler; if (capability == CapabilityEnergy.ENERGY) return (T) this.storage; return super.getCapability(capability, facing); } @Override public boolean hasCapability(Capability<?> capability, EnumFacing facing) { if(capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return true; if(capability == CapabilityEnergy.ENERGY) return true; return super.hasCapability(capability, facing); } @Override public void readFromNBT(NBTTagCompound nbt) { this.storage.readFromNBT(nbt); active = nbt.getBoolean("active"); super.readFromNBT(nbt); } @Override public NBTTagCompound writeToNBT(NBTTagCompound nbt) { this.storage.writeToNBT(nbt); nbt.setBoolean("active", active); return super.writeToNBT(nbt); } @Override public ITextComponent getDisplayName() { return new TextComponentTranslation("container.energy_accumulator.name"); } public void setEnergy(int value) { this.energy = value; } public int getEnergy() { return this.energy; } public boolean isUsableByPlayer(EntityPlayer player) { return this.world.getTileEntity(this.pos) != this ? false : player.getDistanceSq(this.pos.getX() + 0.5D, this.pos.getY() + 0.5D, this.pos.getZ() + 0.5D) <= 64.0D; } } NOTE- I have not set the value of active(In TE class) as I need to set it equal to ACTIVATED(PropBool in Block class), which I cannot find a way to do Thanks for any help! EDIT - After Reading I moved on from using ITileEntityProvider to overriding hasTileEntity() and createTileEntity() Edited December 1, 2018 by Spacejet Marked as Solved Quote
V0idWa1k3r Posted November 29, 2018 Posted November 29, 2018 3 hours ago, Spacejet said: Boolean.valueOf(true) Why are you using boxed values? 3 hours ago, Spacejet said: extends BlockBase BlockBase is an antipattern. There is already a BlockBase, it's called Block. 3 hours ago, Spacejet said: @Override public int getMetaFromState(IBlockState state) { if(ACTIVATED.getAllowedValues().contains(true)) return 1; else return 0; } This will always return 1. Serialize the value of the property, not it's property. 3 hours ago, Spacejet said: implements ITickable, ICapabilityProvider TileEntity already implements ICapabilityProvider. 3 hours ago, Spacejet said: public static boolean active; Why is this static? 3 hours ago, Spacejet said: if(this.world != null) This should never happen in onUpdate, and if it does some mod severely messes up and you should crash the game. 3 hours ago, Spacejet said: active = nbt.getBoolean("active"); active is static though. Why are you (de)serializing it for instances? 3 hours ago, Spacejet said: I don't know how to get and set the value of ACTIVATED from other classes, specifically in this case, the TileEntity class. The same way you would do it in your block class. You have the world(TileEntity.world) and the position(TileEntity.pos). Get the blockstate from the world at position and change the value of the property in the same way you would for your block. Quote
Spacejet Posted November 29, 2018 Author Posted November 29, 2018 (edited) @V0idWa1k3r the answer to your questions : active is static because I was trying to set it in my block class as ACTIVATED was a part of my block class. I just forgot to change it back. Will do that. I don't really know why I used boxed values when I could have simply used 'true' or 'false' ?. 42 minutes ago, V0idWa1k3r said: 4 hours ago, Spacejet said: mplements ITickable, ICapabilityProvider TileEntity already implements ICapabilityProvider I did not know that. Nice to know! 42 minutes ago, V0idWa1k3r said: 4 hours ago, Spacejet said: I don't know how to get and set the value of ACTIVATED from other classes, specifically in this case, the TileEntity class. The same way you would do it in your block class. You have the world(TileEntity.world) and the position(TileEntity.pos). Get the blockstate from the world at position and change the value of the property in the same way you would for your block Is it with setBlockState() cause now I remember that I did not try that. Thanks a ton. 42 minutes ago, V0idWa1k3r said: 4 hours ago, Spacejet said: extends BlockBase BlockBase is an antipattern. There is already a BlockBase, it's called Block. I call my Registry Handler and register all my blocks in this class. 42 minutes ago, V0idWa1k3r said: 4 hours ago, Spacejet said: @Override public int getMetaFromState(IBlockState state) { if(ACTIVATED.getAllowedValues().contains(true)) return 1; else return 0; } This will always return 1. Serialize the value of the property, not it's property. I just got to know about an hour ago that .contains() will search every possible output, not the selected. What should I use instead of that?? How do I get the value of the property in the first place?? getBlockState()?? But that returns a BlockStateContainer. EDIT: I want to get its boolean value to set active equal to, but getBlockState() returns the state, not value! Right? 42 minutes ago, V0idWa1k3r said: 4 hours ago, Spacejet said: if(this.world != null) This should never happen in onUpdate, and if it does some mod severely messes up and you should crash the game. K. Will crash the game. Thanks a lot for all those improvement tips and answers to some of my questions. P.S: do you know why ACTIVATED returns false when block is first placed into the world? Set default state sets its default state to true! Edited November 29, 2018 by Spacejet More detail added Quote
V0idWa1k3r Posted November 29, 2018 Posted November 29, 2018 4 minutes ago, Spacejet said: I call my Registry Handler and register all my blocks in this class. That sounds bad. That sound directly accessing the registry levels of bad. And potentially IHasModel levels of bad too. 5 minutes ago, Spacejet said: How do I get the value of the property in the first place?? getBlockState()?? But that returns a BlockStateContainer. IBlockState#getValue. 6 minutes ago, Spacejet said: do you know why ACTIVATED returns false when block is first placed into the world? Set default state sets its default state to true! I am not sure but you can override Block#getStateForPlacement and return the blockstate with the correct value. 7 minutes ago, Spacejet said: Is it with setBlockState() Yes, but you will need to override TileEntity#shouldRefresh in your TE class and make sure it returns false when the value of the property changes, but true otherwise or else the game will recreate your TE when you do that. Quote
Spacejet Posted November 29, 2018 Author Posted November 29, 2018 (edited) 6 minutes ago, V0idWa1k3r said: 10 minutes ago, Spacejet said: do you know why ACTIVATED returns false when block is first placed into the world? Set default state sets its default state to true! I am not sure but you can override Block#getStateForPlacement and return the blockstate with the correct value Ok will try that.....sounds like it will work (hopefully) 6 minutes ago, V0idWa1k3r said: 10 minutes ago, Spacejet said: How do I get the value of the property in the first place?? getBlockState()?? But that returns a BlockStateContainer. IBlockState#getValue Oh. 6 minutes ago, V0idWa1k3r said: 10 minutes ago, Spacejet said: I call my Registry Handler and register all my blocks in this class. That sounds bad. That sound directly accessing the registry levels of bad. And potentially IHasModel levels of bad too I regret writing that as I am not on my computer and cannot check to make sure what I wrote was correct as that is what I thought I was doing in blockbase..... what should I do if I was doing the bad thing? Edited November 29, 2018 by Spacejet Spelling mistake Quote
V0idWa1k3r Posted November 29, 2018 Posted November 29, 2018 4 minutes ago, Spacejet said: what should I do if I was doing the bad thing? Don't directly access the registry, register your things in the appropriate RegistryEvent.Register, in this case it would be Register<Block>. In case of IHasModel - get rid of it and just register your models directly in the ModelRegistryEvent. 1 Quote
Spacejet Posted November 29, 2018 Author Posted November 29, 2018 Oh then it's fine as I am indeed using registryevents.. phew.. scared me real good. Quote
Cadiboo Posted November 29, 2018 Posted November 29, 2018 3 hours ago, Spacejet said: Oh then it's fine as I am indeed using registryevents.. phew.. scared me real good. Are you instantiating your objects in their registry events? Quote About Me Spoiler My Discord - Cadiboo#8887 My Website - Cadiboo.github.io My Mods - Cadiboo.github.io/projects My Tutorials - Cadiboo.github.io/tutorials Versions below 1.14.4 are no longer supported on this forum. Use the latest version to receive support. When asking support remember to include all relevant log files (logs are found in .minecraft/logs/), code if applicable and screenshots if possible. Only download mods from trusted sites like CurseForge (minecraft.curseforge.com). A list of bad sites can be found here, with more information available at stopmodreposts.org Edit your own signature at www.minecraftforge.net/forum/settings/signature/ (Make sure to check its compatibility with the Dark Theme)
Spacejet Posted November 29, 2018 Author Posted November 29, 2018 13 hours ago, Cadiboo said: Are you instantiating your objects in their registry events? Yes. I am just adding the blocks extend blockbase to a list and then that list is passed on to the onBlockRegister() event BlockBase: Spoiler package com.spacejet.quantivity.blocks; import com.spacejet.quantivity.Main; import com.spacejet.quantivity.init.ModBlocks; import com.spacejet.quantivity.init.ModItems; import com.spacejet.quantivity.util.IHasModel; import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.item.Item; import net.minecraft.item.ItemBlock; public class BlockBase extends Block implements IHasModel{ public BlockBase(String name, Material material) { super(material); setUnlocalizedName(name); setRegistryName(name); ModBlocks.BLOCKS.add(this); ModItems.ITEMS.add(new ItemBlock(this).setRegistryName(this.getRegistryName())); } @Override public void registerModels() { Main.proxy.registerItemRenderer(Item.getItemFromBlock(this), 0, "inventory"); } } RegistryHandler: Spoiler package com.spacejet.quantivity.util.handlers; import com.spacejet.quantivity.Main; import com.spacejet.quantivity.init.ModBiomes; import com.spacejet.quantivity.init.ModBlocks; import com.spacejet.quantivity.init.ModItems; import com.spacejet.quantivity.util.IHasModel; import net.minecraft.block.Block; import net.minecraft.item.Item; import net.minecraftforge.client.event.ModelRegistryEvent; import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.fml.common.Mod.EventBusSubscriber; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.network.NetworkRegistry; @EventBusSubscriber public class RegistryHandler { @SubscribeEvent public static void onItemRegister(RegistryEvent.Register<Item> event) { event.getRegistry().registerAll(ModItems.ITEMS.toArray(new Item[0])); } @SubscribeEvent public static void onBlockRegister(RegistryEvent.Register<Block> event) { event.getRegistry().registerAll(ModBlocks.BLOCKS.toArray(new Block[0])); } @SubscribeEvent public static void onModelRegister(ModelRegistryEvent event) { for(Item item : ModItems.ITEMS) { if(item instanceof IHasModel) { ((IHasModel)item).registerModels(); } } for(Block block : ModBlocks.BLOCKS) { if(block instanceof IHasModel) { ((IHasModel)block).registerModels(); } } } public static void preInitRegistries() { ModBiomes.registerBiomes(); TileEntityHandler.RegisterTileEntities(); } public static void initRegisteries() { NetworkRegistry.INSTANCE.registerGuiHandler(Main.instance, new GuiHandler()); } } Quote
Animefan8888 Posted November 29, 2018 Posted November 29, 2018 26 minutes ago, Spacejet said: IHasModel Did you remove this like voidwaker said? 26 minutes ago, Spacejet said: Yes. I am just adding the blocks extend blockbase to a list and then that list is passed on to the onBlockRegister() event Where are you instantiating(calling the constructor) for them? Also you shouldn't have a BlockBase class when you instantiate them add them to the list like so list.add(new Block(...).set...); Or even RegistryObject registry = event.getRegistry registry.register(new Block(...).set...); Quote VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect. Forge and vanilla BlockState generator.
Spacejet Posted November 29, 2018 Author Posted November 29, 2018 (edited) 9 minutes ago, Animefan8888 said: 39 minutes ago, Spacejet said: Yes. I am just adding the blocks extend blockbase to a list and then that list is passed on to the onBlockRegister() event Where are you instantiating(calling the constructor) for them This is my Mod Blocks class which has the list I am adding the blocks into Spoiler package com.spacejet.quantivity.init; import java.util.ArrayList; import java.util.List; import com.spacejet.quantivity.blocks.CrystalBlock; import com.spacejet.quantivity.blocks.EnergyAccumulator; import com.spacejet.quantivity.blocks.Lantern; import com.spacejet.quantivity.blocks.TitaniumBlock; import com.spacejet.quantivity.blocks.TitaniumOre; import com.spacejet.quantivity.blocks.material.ModMaterial; import net.minecraft.block.Block; import net.minecraft.block.material.Material; public class ModBlocks { public static final List<Block> BLOCKS = new ArrayList<Block>(); public static final Block TITANIUM_BLOCK = new TitaniumBlock("titanium_block", Material.IRON); public static final Block BLUE_CRYSTAL_BLOCK = new CrystalBlock("blue_crystal_block", Material.GLASS); public static final Block RED_CRYSTAL_BLOCK = new CrystalBlock("red_crystal_block", Material.GLASS); public static final Block TITANIUM_ORE = new TitaniumOre("titanium_ore", Material.ROCK); public static final Block LANTERN = new Lantern("lantern", ModMaterial.LANTERN); //Energy Blocks public static final Block ENERGY_ACCUMULATOR = new EnergyAccumulator("energy_accumulator", Material.IRON); } The constructors are called in the class above as you can see.. Edited November 29, 2018 by Spacejet grammar imperfections Quote
Animefan8888 Posted November 30, 2018 Posted November 30, 2018 1 hour ago, Spacejet said: public static final Block TITANIUM_BLOCK = new TitaniumBlock("titanium_block", Material.IRON); Dont do this, this is a static initializer you shouldn't do this with any IForgeRegistryEntry object. Ie anything that has a registry event. They should be initialized in the registryEvent where you register them. Quote VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect. Forge and vanilla BlockState generator.
Spacejet Posted November 30, 2018 Author Posted November 30, 2018 1 hour ago, Animefan8888 said: Dont do this, this is a static initializer you shouldn't do this with any IForgeRegistryEntry object. Ie anything that has a registry event. They should be initialized in the registryEvent where you register them. How would you do that? Quote
Cadiboo Posted November 30, 2018 Posted November 30, 2018 Take a look at https://github.com/Cadiboo/Example-Mod/blob/master/src/main/java/cadiboo/examplemod/EventSubscriber.java You should also check out the README of that repo. Quote About Me Spoiler My Discord - Cadiboo#8887 My Website - Cadiboo.github.io My Mods - Cadiboo.github.io/projects My Tutorials - Cadiboo.github.io/tutorials Versions below 1.14.4 are no longer supported on this forum. Use the latest version to receive support. When asking support remember to include all relevant log files (logs are found in .minecraft/logs/), code if applicable and screenshots if possible. Only download mods from trusted sites like CurseForge (minecraft.curseforge.com). A list of bad sites can be found here, with more information available at stopmodreposts.org Edit your own signature at www.minecraftforge.net/forum/settings/signature/ (Make sure to check its compatibility with the Dark Theme)
Spacejet Posted November 30, 2018 Author Posted November 30, 2018 5 minutes ago, Cadiboo said: Take a look at https://github.com/Cadiboo/Example-Mod/blob/master/src/main/java/cadiboo/examplemod/EventSubscriber.java You should also check out the README of that repo. I'll surely look at it. Thanks a lot to everybody who has helped me Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.