TheRedMezek Posted May 23, 2015 Posted May 23, 2015 I have a furnace-like block which is supposed to change light level depending on whether or not it's in use. So far my attempts to make this work have succeeded in a very broken way; the light level only changes when the block is done cooking, it never goes back to how it was, and it changes for all of the blocks in the world at once. I've been changing it with this.setLightLevel(), if you know of another way to change the light level I would appreciate it. The code it below. My code trying to change the light level is currently in the particle spawning method because I couldn't figure out where to put it. public class CookingBrazier extends BlockContainer{ private String name = "cookingbrazier"; private static boolean keepInventory; public static final PropertyBool ISBURNING = PropertyBool.create("active"); public boolean isOpaqueCube(){ return false; } public boolean isFullCube() { return false; } @SideOnly(Side.CLIENT) public void randomDisplayTick(World worldIn, BlockPos pos, IBlockState state, Random rand) { boolean isBurning = ((Boolean)state.getValue(ISBURNING)).booleanValue(); if(isBurning) { if(isBurning == true) { this.setLightLevel(.96f); }else if (isBurning == false){ this.setLightLevel(0f); } double d0 = (double) pos.getX() + 0.5D; double d1 = (double) pos.getY() + 0.9D; double d2 = (double) pos.getZ() + 0.5D; worldIn.spawnParticle(EnumParticleTypes.SMOKE_NORMAL, d0, d1, d2, 0.0D, 0.0D, 0.0D, new int[0]); } } @Override public int getRenderType() { return 3; } public String getName(){ return name; } public void setBlockBoundsBasedOnState(IBlockAccess worldIn, BlockPos pos) { setBlockBounds(0.1F, 0.0F, 0.1F, 0.9F, 1F, 0.9F); } public CookingBrazier(boolean isBurning){ super(Material.circuits); this.setDefaultState(this.blockState.getBaseState().withProperty(ISBURNING, Boolean.valueOf(false))); this.setCreativeTab(CreativeTabs.tabDecorations); this.setUnlocalizedName("braziermod" + "_" + name); this.setHardness(0.8f); this.setLightLevel(0f); GameRegistry.registerBlock(this, name); } public TileEntity createNewTileEntity(World worldIn, int meta) { return new TileEntityCookingBrazier(); } @SideOnly(Side.CLIENT) public EnumWorldBlockLayer getBlockLayer() { return EnumWorldBlockLayer.CUTOUT; } public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn, EnumFacing side, float hitX, float hitY, float hitZ) { if (worldIn.isRemote) { return true; } else { TileEntity tileentity = worldIn.getTileEntity(pos); if (tileentity instanceof TileEntityCookingBrazier) { playerIn.displayGUIChest((TileEntityCookingBrazier)tileentity); } return true; } } public void breakBlock(World worldIn, BlockPos pos, IBlockState state) { if (!keepInventory) { TileEntity tileentity = worldIn.getTileEntity(pos); if (tileentity instanceof TileEntityFurnace) { InventoryHelper.dropInventoryItems(worldIn, pos, (TileEntityFurnace)tileentity); worldIn.updateComparatorOutputLevel(pos, this); } } super.breakBlock(worldIn, pos, state); } public static void setState(boolean active, World worldIn, BlockPos pos){ TileEntity tileentity = worldIn.getTileEntity(pos); worldIn.setBlockState(pos, BrazierMod.cookingbrazier.getDefaultState().withProperty(ISBURNING, active), 2); if (tileentity != null) { tileentity.validate(); worldIn.setTileEntity(pos, tileentity); } } //public IBlockState onBlockPlaced(World worldIn, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer) //{ //return this.getDefaultState().withProperty(ISBURNING, Boolean.valueOf(false)); //} public IBlockState getActualState(IBlockState state, IBlockAccess worldIn, BlockPos pos) { TileEntity tileEntity = worldIn.getTileEntity(pos); if (tileEntity instanceof TileEntityCookingBrazier) { TileEntityCookingBrazier tileInventoryFurnace = (TileEntityCookingBrazier)tileEntity; boolean burningSlots = ((Boolean)state.getValue(ISBURNING)).booleanValue(); return getDefaultState().withProperty(ISBURNING, burningSlots); } return state; } protected BlockState createBlockState() { return new BlockState(this, new IProperty[] {ISBURNING}); } //public IBlockState getStateFromMeta(int meta) //{ //return this.getDefaultState(); //return this.getDefaultState().withProperty(ISBURNING, meta == 1); //return this.getDefaultState().withProperty(ISBURNING, Boolean.valueOf(isBurning)); //} public IBlockState getStateFromMeta(int meta) { return this.getDefaultState().withProperty(ISBURNING, Boolean.valueOf(meta == 1)); } public int getMetaFromState(IBlockState state) { return ((Boolean)state.getValue(ISBURNING)).booleanValue() ? 1 : 0; } } And I thought I was done asking on here for help with this mod...ha ha... Quote
TheRedMezek Posted May 23, 2015 Author Posted May 23, 2015 Thank you. The problem now is that I don't know how to get the information of whether it's cooking (stored in the block's blockstate) from within the method, seeing as nothing helpful like it's position is passed in. EDIT: Oh derp, there's two getLightValues. I shall use the more helpful second one. Quote
TheRedMezek Posted May 23, 2015 Author Posted May 23, 2015 Now I have this, and the block just stays dark. No light change. @Override public int getLightValue(IBlockAccess world, BlockPos pos){ Block block = world.getBlockState(pos).getBlock(); if (block != this) { return block.getLightValue(world, pos); } IBlockState state = world.getBlockState(pos); boolean isBurning = ((Boolean)state.getValue(ISBURNING)).booleanValue(); if(isBurning) { return 1; } return 0; } Quote
ItsAMysteriousYT Posted May 23, 2015 Posted May 23, 2015 You'll need to call: world.markBlockForUpdate(blockXPos, blockYPos, blockZPos); //get blocks position from the BlockPos variable in method in the randomDisplayTick method, so minecraft updates the lighting from the block. Quote
TheRedMezek Posted May 23, 2015 Author Posted May 23, 2015 It says it can't resolve method markBlockForUpdate Quote
TheRedMezek Posted May 23, 2015 Author Posted May 23, 2015 Ah, thank you! I think it almost works now. The light level changes, but only for the block itself. It doesn't shine out. Quote
TheRedMezek Posted May 23, 2015 Author Posted May 23, 2015 Trying now. What is that flag for, anyways? I've tried fiddling with it before and it didn't seem to do anything. Quote
TheRedMezek Posted May 23, 2015 Author Posted May 23, 2015 It still only lights the space the block occupies. Quote
TheRedMezek Posted May 23, 2015 Author Posted May 23, 2015 public class CookingBrazier extends BlockContainer{ private String name = "cookingbrazier"; private static boolean keepInventory; public static final PropertyBool ISBURNING = PropertyBool.create("active"); public boolean isOpaqueCube(){ return false; } public boolean isFullCube() { return false; } @SideOnly(Side.CLIENT) public void randomDisplayTick(World worldIn, BlockPos pos, IBlockState state, Random rand) { boolean isBurning = ((Boolean)state.getValue(ISBURNING)).booleanValue(); if(isBurning) { double d0 = (double) pos.getX() + 0.5D; double d1 = (double) pos.getY() + 0.9D; double d2 = (double) pos.getZ() + 0.5D; worldIn.spawnParticle(EnumParticleTypes.SMOKE_NORMAL, d0, d1, d2, 0.0D, 0.0D, 0.0D, new int[0]); } } @Override public int getRenderType() { return 3; } public String getName(){ return name; } @Override public int getLightValue(IBlockAccess world, BlockPos pos){ Block block = world.getBlockState(pos).getBlock(); if (block != this) { return block.getLightValue(world, pos); } IBlockState state = world.getBlockState(pos); boolean isBurning = ((Boolean)state.getValue(ISBURNING)).booleanValue(); if(isBurning) { return 15; } return 0; } public void setBlockBoundsBasedOnState(IBlockAccess worldIn, BlockPos pos) { setBlockBounds(0.1F, 0.0F, 0.1F, 0.9F, 1F, 0.9F); } public CookingBrazier(boolean isBurning){ super(Material.circuits); this.setDefaultState(this.blockState.getBaseState().withProperty(ISBURNING, Boolean.valueOf(false))); this.setCreativeTab(CreativeTabs.tabDecorations); this.setUnlocalizedName("braziermod" + "_" + name); this.setHardness(0.8f); this.setLightLevel(0f); GameRegistry.registerBlock(this, name); } public TileEntity createNewTileEntity(World worldIn, int meta) { return new TileEntityCookingBrazier(); } @SideOnly(Side.CLIENT) public EnumWorldBlockLayer getBlockLayer() { return EnumWorldBlockLayer.CUTOUT; } public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn, EnumFacing side, float hitX, float hitY, float hitZ) { if (worldIn.isRemote) { return true; } else { TileEntity tileentity = worldIn.getTileEntity(pos); if (tileentity instanceof TileEntityCookingBrazier) { playerIn.displayGUIChest((TileEntityCookingBrazier)tileentity); } return true; } } public void breakBlock(World worldIn, BlockPos pos, IBlockState state) { if (!keepInventory) { TileEntity tileentity = worldIn.getTileEntity(pos); if (tileentity instanceof TileEntityFurnace) { InventoryHelper.dropInventoryItems(worldIn, pos, (TileEntityFurnace)tileentity); worldIn.updateComparatorOutputLevel(pos, this); } } super.breakBlock(worldIn, pos, state); } public static void setState(boolean active, World worldIn, BlockPos pos){ TileEntity tileentity = worldIn.getTileEntity(pos); worldIn.setBlockState(pos, BrazierMod.cookingbrazier.getDefaultState().withProperty(ISBURNING, active), 3); if (tileentity != null) { tileentity.validate(); worldIn.setTileEntity(pos, tileentity); } } //public IBlockState onBlockPlaced(World worldIn, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer) //{ //return this.getDefaultState().withProperty(ISBURNING, Boolean.valueOf(false)); //} public IBlockState getActualState(IBlockState state, IBlockAccess worldIn, BlockPos pos) { TileEntity tileEntity = worldIn.getTileEntity(pos); if (tileEntity instanceof TileEntityCookingBrazier) { TileEntityCookingBrazier tileInventoryFurnace = (TileEntityCookingBrazier)tileEntity; boolean burningSlots = ((Boolean)state.getValue(ISBURNING)).booleanValue(); return getDefaultState().withProperty(ISBURNING, burningSlots); } return state; } protected BlockState createBlockState() { return new BlockState(this, new IProperty[] {ISBURNING}); } //public IBlockState getStateFromMeta(int meta) //{ //return this.getDefaultState(); //return this.getDefaultState().withProperty(ISBURNING, meta == 1); //return this.getDefaultState().withProperty(ISBURNING, Boolean.valueOf(isBurning)); //} public IBlockState getStateFromMeta(int meta) { return this.getDefaultState().withProperty(ISBURNING, Boolean.valueOf(meta == 1)); } public int getMetaFromState(IBlockState state) { return ((Boolean)state.getValue(ISBURNING)).booleanValue() ? 1 : 0; } } Thank you for being patient with me. Quote
TheRedMezek Posted May 23, 2015 Author Posted May 23, 2015 It gets called in this method in the block's tile entity: public void update() { boolean flag = this.isBurning(); boolean flag1 = false; if (this.isBurning()) { --this.furnaceBurnTime; } if (!this.worldObj.isRemote) { if (!this.isBurning() && (this.furnaceItemStacks[1] == null || this.furnaceItemStacks[0] == null)) { if (!this.isBurning() && this.cookTime > 0) { this.cookTime = MathHelper.clamp_int(this.cookTime - 2, 0, this.totalCookTime); } } else { if (!this.isBurning() && this.canSmelt()) { this.currentItemBurnTime = this.furnaceBurnTime = getItemBurnTime(this.furnaceItemStacks[1]); if (this.isBurning()) { flag1 = true; if (this.furnaceItemStacks[1] != null) { --this.furnaceItemStacks[1].stackSize; if (this.furnaceItemStacks[1].stackSize == 0) { this.furnaceItemStacks[1] = furnaceItemStacks[1].getItem().getContainerItem(furnaceItemStacks[1]); } } } } if (this.isBurning() && this.canSmelt()) { ++this.cookTime; if (this.cookTime == this.totalCookTime) { this.cookTime = 0; this.totalCookTime = this.func_174904_a(this.furnaceItemStacks[0]); this.smeltItem(); flag1 = true; } } else { this.cookTime = 0; } } if (flag != this.isBurning()) { flag1 = true; //CookingBrazier.setState(this.isBurning(), this.worldObj, this.pos); //IBlockState iblockstate = this.worldObj.getBlockState(this.getPos()); //iblockstate = iblockstate.withProperty(CookingBrazier.ISBURNING, true); //this.worldObj.setBlockState(this.pos, iblockstate, 2); } CookingBrazier.setState(this.isBurning(), this.worldObj, this.pos); worldObj.markBlockForUpdate(pos); } if (flag1) { this.markDirty(); } } Quote
TheRedMezek Posted May 23, 2015 Author Posted May 23, 2015 Well, it DOES work, in that the light level changes correctly at the correct times. It just only changes the light level of the exact voxel the block occupies. Quote
TheGreyGhost Posted May 23, 2015 Posted May 23, 2015 Hi I'm guessing you might need to force a blocklight recalculation. Try putting something like this into your tileentity update method // when the number of burning slots changes, we need to force the block to re-render, otherwise the change in // state will not be visible. Likewise, we need to force a lighting recalculation. // The block update (for renderer) is only required on client side, but the lighting is required on both, since // the client needs it for rendering and the server needs it for crop growth etc int numberBurning = numberOfBurningFuelSlots(); if (cachedNumberOfBurningSlots != numberBurning) { cachedNumberOfBurningSlots = numberBurning; if (worldObj.isRemote) { worldObj.markBlockForUpdate(pos); } worldObj.checkLightFor(EnumSkyBlock.BLOCK, pos); } -TGG Quote
saxon564 Posted May 24, 2015 Posted May 24, 2015 Having done some dynamic lighting in my mod, TGG is right, but you may have to use checkLightFor on the blocks around your block if it doesnt work when you check it on your block. 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.