Posted November 18, 20195 yr I am making a block that looks like the ore rocks from runescape. Some of these blocks are found on runescape's surface and I was wondering if there is a way to make this block spawn on the surface or on the floors of caves. I also want the rock to be very rare, as when the block is mined it transforms into an "empty ore rock" just like in old school runescape. These rocks will eventually revert back to containing ore in them after a random amount of time has passed. So yeah how would I make these spawn? EDIT: new problem: when the block is mined it completely disapears instead of converting into its empty state: here is the code: package com.kenneths_mod.objects.blocks.respawning_ores; import java.util.Random; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.IGrowable; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.state.BooleanProperty; import net.minecraft.state.IntegerProperty; import net.minecraft.state.StateContainer.Builder; import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockReader; import net.minecraft.world.World; public class RespawningOreNode extends Block implements IGrowable { private static final IntegerProperty STAGE = BlockStateProperties.AGE_0_1; private static final BooleanProperty FILLED = BooleanProperty.create("filled"); public RespawningOreNode(Properties properties) { super(properties); this.setDefaultState(this.stateContainer.getBaseState().with(STAGE, Integer.valueOf(0)).with(FILLED, Boolean.valueOf(true))); } @Override public boolean canGrow(IBlockReader worldIn, BlockPos pos, BlockState state, boolean isClient) { return true; } @Override public boolean canUseBonemeal(World worldIn, Random rand, BlockPos pos, BlockState state) { return true; } @Override public void onBlockHarvested(World worldIn, BlockPos pos, BlockState state, PlayerEntity player) { if(state.get(FILLED) == true) { worldIn.setBlockState(pos, this.stateContainer.getBaseState().with(STAGE, Integer.valueOf(0)).with(FILLED, Boolean.valueOf(false))); } } @Override public void grow(World worldIn, Random rand, BlockPos pos, BlockState state) { if (state.get(FILLED) == false) { if(state.get(STAGE) == 0) { worldIn.setBlockState(pos, state.cycle(STAGE), 4); } else { worldIn.setBlockState(pos, state.with(STAGE, Integer.valueOf(0)).with(FILLED, Boolean.valueOf(true))); } } } @Override protected void fillStateContainer(Builder<Block, BlockState> builder) { builder.add(STAGE, FILLED); } } Edited November 18, 20195 yr by Kenneth201998
November 18, 20195 yr 1 hour ago, Kenneth201998 said: Integer.valueOf(0)).with(FILLED, Boolean.valueOf(false)) oh christ, why all this boxing? Do you want an int or a bool? Use the value you want, done. with(FILLED, false). with(STAGE, 0). Also, nothing in your code ever sets FILLED to true. Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable. If you think this is the case, JUST REPORT ME. Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice. Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked. DO NOT PM ME WITH PROBLEMS. No help will be given.
November 18, 20195 yr Author 17 minutes ago, Draco18s said: oh christ, why all this boxing? Do you want an int or a bool? Use the value you want, done. with(FILLED, false). with(STAGE, 0). Also, nothing in your code ever sets FILLED to true. I updated the code: package com.kenneths_mod.objects.blocks.respawning_ores; import java.util.Random; import com.kenneths_mod.KenmodMain; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.IGrowable; import net.minecraft.state.BooleanProperty; import net.minecraft.state.IntegerProperty; import net.minecraft.state.StateContainer.Builder; import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockReader; import net.minecraft.world.IWorld; import net.minecraft.world.World; public class RespawningOreNode extends Block implements IGrowable { private static final IntegerProperty STAGE = BlockStateProperties.AGE_0_1; private static final BooleanProperty FILLED = BooleanProperty.create("filled"); public RespawningOreNode(Properties properties) { super(properties); this.setDefaultState(this.stateContainer.getBaseState().with(STAGE, Integer.valueOf(0)).with(FILLED, Boolean.valueOf(true))); } @Override public boolean canGrow(IBlockReader worldIn, BlockPos pos, BlockState state, boolean isClient) { return true; } @Override public boolean canUseBonemeal(World worldIn, Random rand, BlockPos pos, BlockState state) { return true; } @Override public void onPlayerDestroy(IWorld worldIn, BlockPos pos, BlockState state) { KenmodMain.debugString(state.getBlock().getRegistryName().toString()); if(state.get(FILLED) == true) { KenmodMain.debugString("test0: " + worldIn.getBlockState(pos).getBlock().getRegistryName()); worldIn.setBlockState(pos, this.stateContainer.getBaseState().with(STAGE, Integer.valueOf(0)).with(FILLED, Boolean.valueOf(false)), 1); KenmodMain.debugString("test1: " + worldIn.getBlockState(pos).getBlock().getRegistryName()); } } @Override public void grow(World worldIn, Random rand, BlockPos pos, BlockState state) { if (state.get(FILLED) == false) { if(state.get(STAGE) == 0) { worldIn.setBlockState(pos, state.cycle(STAGE), 4); } else { worldIn.setBlockState(pos, state.with(STAGE, Integer.valueOf(0)).with(FILLED, Boolean.valueOf(true))); } } } @Override public boolean isSolid(BlockState state) { return false; } @Override protected void fillStateContainer(Builder<Block, BlockState> builder) { builder.add(STAGE, FILLED); } } The ore can be destroyed and set filled to false, but the ore will not respawn. Also I did the "boxing" thing because it appears that way in vanilla code. Edited November 18, 20195 yr by Kenneth201998
November 19, 20195 yr Author Ok so now the ore nodes respawn and I even figured out how to get them to spawn on the surface using these codes: Respawnable ore node: package com.kenneths_mod.objects.blocks.respawning_ores; import java.util.Random; import com.kenneths_mod.KenmodMain; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.state.BooleanProperty; import net.minecraft.state.IntegerProperty; import net.minecraft.state.StateContainer.Builder; import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.util.math.BlockPos; import net.minecraft.world.IWorld; import net.minecraft.world.World; public class RespawningOreNode extends Block { private static final IntegerProperty STAGE = BlockStateProperties.AGE_0_1; private static final BooleanProperty FILLED = BooleanProperty.create("filled"); public RespawningOreNode(Properties properties) { super(properties); this.setDefaultState(this.stateContainer.getBaseState().with(STAGE, Integer.valueOf(0)).with(FILLED, Boolean.valueOf(true))); } @Override public void onPlayerDestroy(IWorld worldIn, BlockPos pos, BlockState state) { KenmodMain.debugString(state.getBlock().getRegistryName().toString()); if(state.get(FILLED) == true) { worldIn.setBlockState(pos, this.stateContainer.getBaseState().with(STAGE, Integer.valueOf(0)).with(FILLED, Boolean.valueOf(false)), 1); } } @Override public boolean ticksRandomly(BlockState state) { return true; } @Override public void randomTick(BlockState state, World worldIn, BlockPos pos, Random random) { if (state.get(FILLED) == false) { if(state.get(STAGE) == 0) { worldIn.setBlockState(pos, state.cycle(STAGE), 4); } else { //Respawn Ore: worldIn.setBlockState(pos, state.with(STAGE, Integer.valueOf(0)).with(FILLED, Boolean.valueOf(true))); } } } @Override public boolean isSolid(BlockState state) { return false; } @Override protected void fillStateContainer(Builder<Block, BlockState> builder) { builder.add(STAGE, FILLED); } } Natural Generation: (I added it to VEGETAL_DECORATION because I want it to spawn on the surface of mountains similar to how dead bushes spawn on the surface of deserts: private void addFeatures () { Biomes.MOUNTAINS.addFeature(GenerationStage.Decoration.VEGETAL_DECORATION, Biome.createDecoratedFeature(KenmodFeatures.respawning_iron_feature, IFeatureConfig.NO_FEATURE_CONFIG, Placement.COUNT_EXTRA_HEIGHTMAP, new AtSurfaceWithExtraConfig(0, 0.2F, 1))); } And here is the feature class: package com.kenneths_mod.world_gen.respawning_ores; import java.util.Random; import java.util.function.Function; import com.kenneths_mod.objects.BlockList; import com.mojang.datafixers.Dynamic; import net.minecraft.block.Blocks; import net.minecraft.util.math.BlockPos; import net.minecraft.world.IWorld; import net.minecraft.world.gen.ChunkGenerator; import net.minecraft.world.gen.GenerationSettings; import net.minecraft.world.gen.feature.Feature; import net.minecraft.world.gen.feature.NoFeatureConfig; public class RespawningIronFeature extends Feature<NoFeatureConfig> { public RespawningIronFeature(Function<Dynamic<?>, ? extends NoFeatureConfig> configFactoryIn) { super(configFactoryIn); } @Override public boolean place(IWorld worldIn, ChunkGenerator<? extends GenerationSettings> generator, Random rand, BlockPos pos, NoFeatureConfig config) { if(worldIn.isAirBlock(pos) && worldIn.getBlockState(pos.down()).getBlock() == Blocks.STONE) { worldIn.setBlockState(pos, BlockList.iron_ore_node.getDefaultState(), 2); } return true; } } I am still trying to get them to spawn on cave floors and that should look something like this: Biomes.MOUNTAINS.addFeature(GenerationStage.Decoration.UNDERGROUND_DECORATION, Biome.createDecoratedFeature(KenmodFeatures.respawning_iron_feature, IFeatureConfig.NO_FEATURE_CONFIG, Placement.COUNT_EXTRA_HEIGHTMAP, //I dont know what to put here for cave features)); Still need help with the last bit of code above. Thanks. Edited November 19, 20195 yr by Kenneth201998
November 19, 20195 yr 18 hours ago, Kenneth201998 said: Also I did the "boxing" thing because it appears that way in vanilla code. Vanilla code looks like that because the decompiler isn't smart enough to know the difference (5 and Integer.valueOf(5) compile to the same byte code). Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable. If you think this is the case, JUST REPORT ME. Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice. Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked. DO NOT PM ME WITH PROBLEMS. No help will be given.
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.