Jump to content

andGarrett

Members
  • Posts

    101
  • Joined

  • Last visited

  • Days Won

    1

Everything posted by andGarrett

  1. I stored the container in an instance field because I couldn't figure out how to get access to it any other way. for your second question, I don't know how to interact with IItemHandler. I don't know if this is relevant, but the container is a different class. I figured working with the container associated with the block was the best way to effect the inventory.
  2. I figured it out. read solution at top in interested.
  3. The class is incomplete. I'm in the process of setting up the mineBlock method. currently it only really does something if the AutoMiner block is facing up and has a block above it. the important part is on line 123 in the mineBlock method. package com.Garrett.backtobasics.blocks; import net.minecraft.block.Block; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.inventory.container.Container; import net.minecraft.inventory.container.INamedContainerProvider; import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundNBT; import net.minecraft.tileentity.ITickableTileEntity; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.Direction; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.StringTextComponent; import net.minecraft.world.server.ServerWorld; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.util.INBTSerializable; import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.ItemStackHandler; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import static net.minecraft.util.Direction.*; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.util.List; import static com.Garrett.backtobasics.blocks.ModBlocks.AUTO_MINER_TILE_ENTITY; public class AutoMinerTileEntity extends TileEntity implements ITickableTileEntity, INamedContainerProvider { private static final Logger LOGGER = LogManager.getLogger(); private LazyOptional<IItemHandler> handler = LazyOptional.of(this::createHandler); private int tickCounter = 0; private AutoMinerContainer container; public AutoMinerTileEntity() { super(AUTO_MINER_TILE_ENTITY); } // 20 ticks per second @Override public void tick() { tickCounter++; if (tickCounter >= 60) { tickCounter = 0; mineBlock(); } } // the lazy handler postpones execution of code until it is needed for the first time and cashes it // so it won't be recreated every time it is used. private ItemStackHandler createHandler () { return new ItemStackHandler(1); } // reads inventory from world file on load @Override public void read(CompoundNBT tag) { CompoundNBT invTag = tag.getCompound("inv"); handler.ifPresent(h -> ((INBTSerializable<CompoundNBT>) h).deserializeNBT(invTag)); createHandler().deserializeNBT(invTag); super.read(tag); } // writes inventory to world file whenever world is saved @Override public CompoundNBT write(CompoundNBT tag) { handler.ifPresent(h -> { CompoundNBT compound = ((INBTSerializable<CompoundNBT>) h).serializeNBT(); tag.put("inv", compound); }); return super.write(tag); } // Capabilities add funcionality to blocks and items. @Nonnull @Override public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) { if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) { return handler.cast(); } return super.getCapability(cap, side); } @Override public ITextComponent getDisplayName() { return new StringTextComponent(getType().getRegistryName().getPath()); } @Nullable @Override public Container createMenu(int i, PlayerInventory playerInventory, PlayerEntity playerEntity) { this.container = new AutoMinerContainer(i, world, pos, playerInventory, playerEntity); return container; } private void mineBlock() { if (getBlockState().getValues().containsValue(UP) && !world.getBlockState(getPos().up()).getMaterial().isToolNotRequired() && world.getServer() != null && this.container != null) { if (this.container.getInventory().get(0).getCount() < this.container.getInventory().get(0).getItem().getMaxStackSize()) { Block block = world.getBlockState(getPos().up()).getBlock(); ServerWorld serverWorld = world.getServer().getWorld(world.dimension.getType()); List<ItemStack> drops = Block.getDrops(block.getDefaultState(), serverWorld, getPos().up(), super.getTileEntity()); for (ItemStack item: drops) { if (item.getItem() == this.container.getInventory().get(0).getItem()) { this.container.getInventory().get(0).grow(1); } else if (this.container.getInventory().get(0).isEmpty()) { LOGGER.info(item); this.container.getInventory().set(0, item).setCount(1); // Here's where I want to add items to the inventory } //LOGGER.info(drops.get(0).getItem().getRegistryName()); //LOGGER.info(drops.get(0).getCount()); } } } else if (getBlockState().getValues().containsValue(DOWN)) { if (!world.getBlockState(getPos().down()).getMaterial().isToolNotRequired()) { LOGGER.info(world.getBlockState(getPos().down()).getBlock().getLootTable().toString()); } } else if (getBlockState().getValues().containsValue(NORTH)) { if (!world.getBlockState(getPos().north()).getMaterial().isToolNotRequired()) { LOGGER.info(world.getBlockState(getPos().north()).getBlock().getLootTable().toString()); } } else if (getBlockState().getValues().containsValue(SOUTH)) { if (!world.getBlockState(getPos().south()).getMaterial().isToolNotRequired()) { LOGGER.info(world.getBlockState(getPos().south()).getBlock().getLootTable().toString()); } } else if (getBlockState().getValues().containsValue(EAST)) { if (!world.getBlockState(getPos().east()).getMaterial().isToolNotRequired()) { LOGGER.info(world.getBlockState(getPos().east()).getBlock().getLootTable().toString()); } } else if (getBlockState().getValues().containsValue(WEST)) { if (!world.getBlockState(getPos().west()).getMaterial().isToolNotRequired()) { LOGGER.info(world.getBlockState(getPos().west()).getBlock().getLootTable().toString()); } } } }
  4. I'm trying to add an item to an empty inventory, but what I've tried hasn't worked. I tried: this.container.getInventory().set(0, item); and this.container.getInventory().set(0, item).setCount(1); "item" in this context is an item stack containing 1 coal. I'm able to change the count if there is already an item in the container, so I know I'm accessing the correct container. [SOLUTION] use your handler's "insertItem" method.
  5. I think I got it now. Thanks for all the help y'all! @Nullable @Override public BlockState getStateForPlacement(BlockItemUseContext context) { BlockState blockstate = super.getStateForPlacement(context); if (blockstate != null) { blockstate = blockstate.with(BlockStateProperties.FACING, context.getNearestLookingDirection()); } return blockstate; }
  6. I'm not sure what you mean. use the context in the "onBlockPlacedBy" method or the "getStateForPlacement" method? I don't know how to get the context any other way.
  7. I couldn't figure out how to get the BlockItemUseContext without overriding the getStateForPlacement method and storing the context in an instance field. is that the correct way to do it? something about storing the data in an instance field feels wrong, but it works. here's the relevant code: @Override public void onBlockPlacedBy(World world, BlockPos pos, BlockState state, @Nullable LivingEntity entity, ItemStack stack) { if (entity != null) { world.setBlockState(pos, state.with(BlockStateProperties.FACING, context.getNearestLookingDirection()), 2); LOGGER.info(getFacingFromEntity(pos, entity).getOpposite().toString()); } } @Nullable @Override public BlockState getStateForPlacement(BlockItemUseContext context) { this.context = context; return super.getStateForPlacement(context); }
  8. for some reason getFacingFromEntity always gives me the opposite facing. when looking down it gives up, when looking north it gives south etc. I'm using it when placing certain blocks. @Override public void onBlockPlacedBy(World world, BlockPos pos, BlockState state, @Nullable LivingEntity entity, ItemStack stack) { if (entity != null) { world.setBlockState(pos, state.with(BlockStateProperties.FACING, getFacingFromEntity(pos, entity)), 2); LOGGER.info(getFacingFromEntity(pos, entity).toString()); } } [EDIT] changed title from "[1.14.4] getFacingFromEntity gives opposite facing" to "[1.14.4] set block facing direction based on player" to make it more relevant to the actual topic discussed. [SOLUTION]-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- getFacingFromEntity was a method copied from this tutorial. instead of overriding onBlockPlacedBy, you should override getStateForPlacement. @Nullable @Override public BlockState getStateForPlacement(BlockItemUseContext context) { BlockState blockstate = super.getStateForPlacement(context); if (blockstate != null) { blockstate = blockstate.with(BlockStateProperties.FACING, context.getNearestLookingDirection()); } return blockstate; }
  9. ever since I updated intellij, every time I use "runClient" it opens up one of my classes. it's always the same class. has this been happening to anyone else?
  10. Thanks! I don't know why I missed it
  11. I'm trying to create a block that mines the block next to one of its faces. I've run into two problems I can't seem to figure out on my own: 1. how do I get facing information for my mining block 2. how do I communicate the facing information to my mining blocks tile entity so I can use it to do the mining every 20-60 ticks [SOLUTION] 1 and 2: first, in your blocks tile entity class import static net.minecraft.util.Direction.*; then you can use: getBlockState().getValues().containsValue(UP), getBlockState().getValues().containsValue(DOWN), getBlockState().getValues().containsValue(NORTH), getBlockState().getValues().containsValue(SOUTH), getBlockState().getValues().containsValue(EAST), getBlockState().getValues().containsValue(WEST).
  12. Yeah, that's what I was planning on doing if I couldn't do a find and replace method. I fiddled around with this for an hour or two, but I couldn't figure out how to make it work. the final if statement condition is never true.
  13. in [1.14.4][SOLVED] remove vanilla ore generation in I figured out how to remove ALL ores with: for (Biome biome : ForgeRegistries.BIOMES) { biome.getFeatures(GenerationStage.Decoration.UNDERGROUND_ORES).clear(); } The problem with that is that it includes things I don't want to remove. I'm trying to create a find and replace method to just find all the iron_ore features in all the biomes but I don't know how to identify what each feature actually is. I get things like: "net.minecraft.world.gen.feature.ConfiguredFeature@41aa9e27" when I try to get the feature information using: "biome.getFeatures(GenerationStage.Decoration.UNDERGROUND_ORES).get(0).toString()". how might I identify a given feature? [SOLUTION](sort of...) Create this class: package com.YourName.YourMod.world; import com.google.common.collect.Lists; import net.minecraft.block.Blocks; import net.minecraft.world.biome.Biome; import net.minecraft.world.gen.GenerationStage; import net.minecraft.world.gen.GenerationStage.Decoration; import net.minecraft.world.gen.feature.*; import net.minecraft.world.gen.placement.*; import net.minecraftforge.registries.ForgeRegistries; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; public class OreGeneration { public static void setupOreGeneration() { for (Biome biome: ForgeRegistries.BIOMES) { if (biome.getFeatures(GenerationStage.Decoration.UNDERGROUND_ORES).size() == 15) { biome.getFeatures(GenerationStage.Decoration.UNDERGROUND_ORES).clear(); addStoneVariants(biome); addOres(biome); addSedimentDisks(biome); addExtraEmeraldOre(biome); addInfestedStone(biome); } else if (biome.getFeatures(GenerationStage.Decoration.UNDERGROUND_ORES).size() == 14) { biome.getFeatures(GenerationStage.Decoration.UNDERGROUND_ORES).clear(); addStoneVariants(biome); addOres(biome); addSedimentDisks(biome); } else if (biome.getFeatures(GenerationStage.Decoration.UNDERGROUND_ORES).size() == 12) { biome.getFeatures(GenerationStage.Decoration.UNDERGROUND_ORES).clear(); addStoneVariants(biome); addOres(biome); addSwampClayDisks(biome); } } } public static void addStoneVariants(Biome biomeIn) { biomeIn.addFeature(GenerationStage.Decoration.UNDERGROUND_ORES, Biome.createDecoratedFeature(Feature.ORE, new OreFeatureConfig(OreFeatureConfig.FillerBlockType.NATURAL_STONE, Blocks.DIRT.getDefaultState(), 33), Placement.COUNT_RANGE, new CountRangeConfig(10, 0, 0, 256))); biomeIn.addFeature(GenerationStage.Decoration.UNDERGROUND_ORES, Biome.createDecoratedFeature(Feature.ORE, new OreFeatureConfig(OreFeatureConfig.FillerBlockType.NATURAL_STONE, Blocks.GRAVEL.getDefaultState(), 33), Placement.COUNT_RANGE, new CountRangeConfig(8, 0, 0, 256))); biomeIn.addFeature(GenerationStage.Decoration.UNDERGROUND_ORES, Biome.createDecoratedFeature(Feature.ORE, new OreFeatureConfig(OreFeatureConfig.FillerBlockType.NATURAL_STONE, Blocks.GRANITE.getDefaultState(), 33), Placement.COUNT_RANGE, new CountRangeConfig(10, 0, 0, 80))); biomeIn.addFeature(GenerationStage.Decoration.UNDERGROUND_ORES, Biome.createDecoratedFeature(Feature.ORE, new OreFeatureConfig(OreFeatureConfig.FillerBlockType.NATURAL_STONE, Blocks.DIORITE.getDefaultState(), 33), Placement.COUNT_RANGE, new CountRangeConfig(10, 0, 0, 80))); biomeIn.addFeature(GenerationStage.Decoration.UNDERGROUND_ORES, Biome.createDecoratedFeature(Feature.ORE, new OreFeatureConfig(OreFeatureConfig.FillerBlockType.NATURAL_STONE, Blocks.ANDESITE.getDefaultState(), 33), Placement.COUNT_RANGE, new CountRangeConfig(10, 0, 0, 80))); } public static void addOres(Biome biomeIn) { biomeIn.addFeature(GenerationStage.Decoration.UNDERGROUND_ORES, Biome.createDecoratedFeature(Feature.ORE, new OreFeatureConfig(OreFeatureConfig.FillerBlockType.NATURAL_STONE, Blocks.COAL_ORE.getDefaultState(), 17), Placement.COUNT_RANGE, new CountRangeConfig(20, 0, 0, 128))); biomeIn.addFeature(GenerationStage.Decoration.UNDERGROUND_ORES, Biome.createDecoratedFeature(Feature.ORE, new OreFeatureConfig(OreFeatureConfig.FillerBlockType.NATURAL_STONE, Blocks.IRON_ORE.getDefaultState(), 9), Placement.COUNT_RANGE, new CountRangeConfig(20, 0, 0, 64))); biomeIn.addFeature(GenerationStage.Decoration.UNDERGROUND_ORES, Biome.createDecoratedFeature(Feature.ORE, new OreFeatureConfig(OreFeatureConfig.FillerBlockType.NATURAL_STONE, Blocks.GOLD_ORE.getDefaultState(), 9), Placement.COUNT_RANGE, new CountRangeConfig(2, 0, 0, 32))); biomeIn.addFeature(GenerationStage.Decoration.UNDERGROUND_ORES, Biome.createDecoratedFeature(Feature.ORE, new OreFeatureConfig(OreFeatureConfig.FillerBlockType.NATURAL_STONE, Blocks.REDSTONE_ORE.getDefaultState(), 8), Placement.COUNT_RANGE, new CountRangeConfig(8, 0, 0, 16))); biomeIn.addFeature(GenerationStage.Decoration.UNDERGROUND_ORES, Biome.createDecoratedFeature(Feature.ORE, new OreFeatureConfig(OreFeatureConfig.FillerBlockType.NATURAL_STONE, Blocks.DIAMOND_ORE.getDefaultState(), 8), Placement.COUNT_RANGE, new CountRangeConfig(1, 0, 0, 16))); biomeIn.addFeature(GenerationStage.Decoration.UNDERGROUND_ORES, Biome.createDecoratedFeature(Feature.ORE, new OreFeatureConfig(OreFeatureConfig.FillerBlockType.NATURAL_STONE, Blocks.LAPIS_ORE.getDefaultState(), 7), Placement.COUNT_DEPTH_AVERAGE, new DepthAverageConfig(1, 16, 16))); } public static void addExtraEmeraldOre(Biome biomeIn) { biomeIn.addFeature(GenerationStage.Decoration.UNDERGROUND_ORES, Biome.createDecoratedFeature(Feature.EMERALD_ORE, new ReplaceBlockConfig(Blocks.STONE.getDefaultState(), Blocks.EMERALD_ORE.getDefaultState()), Placement.EMERALD_ORE, IPlacementConfig.NO_PLACEMENT_CONFIG)); } public static void addInfestedStone(Biome biomeIn) { biomeIn.addFeature(GenerationStage.Decoration.UNDERGROUND_DECORATION, Biome.createDecoratedFeature(Feature.ORE, new OreFeatureConfig(OreFeatureConfig.FillerBlockType.NATURAL_STONE, Blocks.INFESTED_STONE.getDefaultState(), 9), Placement.COUNT_RANGE, new CountRangeConfig(7, 0, 0, 64))); } public static void addSedimentDisks(Biome biomeIn) { biomeIn.addFeature(GenerationStage.Decoration.UNDERGROUND_ORES, Biome.createDecoratedFeature(Feature.DISK, new SphereReplaceConfig(Blocks.SAND.getDefaultState(), 7, 2, Lists.newArrayList(Blocks.DIRT.getDefaultState(), Blocks.GRASS_BLOCK.getDefaultState())), Placement.COUNT_TOP_SOLID, new FrequencyConfig(3))); biomeIn.addFeature(GenerationStage.Decoration.UNDERGROUND_ORES, Biome.createDecoratedFeature(Feature.DISK, new SphereReplaceConfig(Blocks.CLAY.getDefaultState(), 4, 1, Lists.newArrayList(Blocks.DIRT.getDefaultState(), Blocks.CLAY.getDefaultState())), Placement.COUNT_TOP_SOLID, new FrequencyConfig(1))); biomeIn.addFeature(GenerationStage.Decoration.UNDERGROUND_ORES, Biome.createDecoratedFeature(Feature.DISK, new SphereReplaceConfig(Blocks.GRAVEL.getDefaultState(), 6, 2, Lists.newArrayList(Blocks.DIRT.getDefaultState(), Blocks.GRASS_BLOCK.getDefaultState())), Placement.COUNT_TOP_SOLID, new FrequencyConfig(1))); } public static void addSwampClayDisks(Biome biomeIn) { biomeIn.addFeature(GenerationStage.Decoration.UNDERGROUND_ORES, Biome.createDecoratedFeature(Feature.DISK, new SphereReplaceConfig(Blocks.CLAY.getDefaultState(), 4, 1, Lists.newArrayList(Blocks.DIRT.getDefaultState(), Blocks.CLAY.getDefaultState())), Placement.COUNT_TOP_SOLID, new FrequencyConfig(1))); } } look for the ore you want to replace in one of the "add*" methods and put yours in its place add the class to your main mod class setup event: private void setup(final FMLCommonSetupEvent event) { // some preinit code setup.init(); LOGGER.info("HELLO FROM PREINIT"); LOGGER.info("DIRT BLOCK >> {}", Blocks.DIRT.getRegistryName()); OreGeneration.setupOreGeneration(); }
  14. Thanks! it was surprisingly simple once I knew where to look.
  15. I can't seem to find any documentation on removing vanilla ore generation in 1.14.x. does anyone know of a guide or a good place to start? [SOLUTION] Create this class: package com.yourname.yourmod.world; import net.minecraft.world.biome.Biome; import net.minecraft.world.gen.GenerationStage; import net.minecraft.world.gen.feature.Feature; import net.minecraft.world.gen.feature.OreFeatureConfig; import net.minecraft.world.gen.placement.CountRangeConfig; import net.minecraft.world.gen.placement.Placement; import net.minecraftforge.registries.ForgeRegistries; public class OreGeneration { public static void removeVanillaOre() { for (Biome biome : ForgeRegistries.BIOMES) { biome.getFeatures(GenerationStage.Decoration.UNDERGROUND_ORES).clear(); } } } add the class to your main mod class setup event: private void setup(final FMLCommonSetupEvent event) { // some preinit code setup.init(); LOGGER.info("HELLO FROM PREINIT"); LOGGER.info("DIRT BLOCK >> {}", Blocks.DIRT.getRegistryName()); OreGeneration.removeVanillaOre(); }
  16. Thanks! I don't know why I was unable to override "removedByPlayer" before, but pasting in Draco18s code allowed me to do what was needed. I have the "harvestBlock" method spawn the drops at the players location. @Override public void harvestBlock(World worldIn, PlayerEntity player, BlockPos pos, BlockState state, @Nullable TileEntity te, ItemStack stack) { player.addStat(Stats.BLOCK_MINED.get(this)); player.addExhaustion(0.005F); BlockPos pPos = player.getPosition(); spawnDrops(state, worldIn, pPos, te, player, stack); } @Override public boolean removedByPlayer(BlockState state, World world, BlockPos pos, PlayerEntity player, boolean willHarvest, IFluidState fluid) { return true; }
  17. I think I got it. I just added this to my blocks class: @Override public void onPlayerDestroy(IWorld worldIn, BlockPos pos, BlockState state) { worldIn.setBlockState(pos, state, 0); } let me know if there is a simpler way or if this would cause problems.
  18. I'm trying to create an ore block that is infinitely harvestable. When the player goes to harvest the block they will get a smeltable item, but the ore block will remain. I figure it has something to do with "removedByPlayer", but I don't know how to proceed. I tried overriding removedByPlayer in my blocks class, but that seems impossible and/or incorrect. [SOLUTION] override the "removedByPlayer" method. also override the "harvestBlock" method so you can set the spawnDrops location to the players position. @Override public void harvestBlock(World worldIn, PlayerEntity player, BlockPos pos, BlockState state, @Nullable TileEntity te, ItemStack stack) { player.addStat(Stats.BLOCK_MINED.get(this)); player.addExhaustion(0.005F); BlockPos pPos = player.getPosition(); spawnDrops(state, worldIn, pPos, te, player, stack); } @Override public boolean removedByPlayer(BlockState state, World world, BlockPos pos, PlayerEntity player, boolean willHarvest, IFluidState fluid) { return true; }
  19. I want to replace all metal ore blocks with my own. Does it make more sense to: a. override said blocks or b. create my own and switch them in in the world gen. For example I am replacing iron ore blocks with "iron vein" blocks that will be similar yet have a few key differences.
  20. I often do figure things out on my own, but I'm new to java and this is the first time I've done anything with forge. I find it difficult to understand how to work with new code, especially when there is so much of it. I've never worked with anything more complex than a simple swing program.
  21. that did it! thanks again my dude! ♥♥♥♥♥♥♥
  22. I was able to replace/override the vanilla coal ore block, but I can't seem to change its loot table. I've tried copying the default coal ore loot table. I've tried adding "name": "pool1" and when that didn't work, I tried "name": "main" any ideas?
  23. Thank you, that worked!
  24. how do I supply the other half or otherwise do what needs to be done?
  25. I tried setting the registry name in a block class via setRegistryName("coal_ore");. that didn't do it. I tried setting all kinds of things to the same name as "coal_ore".
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.