Jump to content

kwpugh

Members
  • Posts

    85
  • Joined

  • Last visited

Everything posted by kwpugh

  1. IForgeRegistry<IRecipeSerializer<?>>. This one?
  2. Yes, that would be bad. Ok, back to original suggestion. - I do not understand getSubItem, so I will need to research that. - How does one disable recipes within a mod, programmatically? I have only worked with adding or removing json file manually.
  3. Ok. So that seems like a lot of work just to remove an item. What exactly is the downside of my old method of conditional registration based on config values. Looking at other mods source code, this seems to be a fairly common practice. I am not clear on the negative implications.
  4. Ok. I assume disabling the recipes and removing from ItemGroup would still leave already created versions of the item in the game? Is that correct? My desire is that disabling the item in the config would also remove any of the items in the world as well.
  5. Ok. So I clearly did it the wrong way in my 1.12.2 version, since I used conditional statements to either register or not based on config values. Can you provide some guidance on how I should accomplish this? I am not aware of how I would "hide" an item or block from the game after it is already registered. Thank you.
  6. Hi All, I'm looking for some guidance on how to test if ForgeConfigSpec.BooleanValue equals true in my item register class. I have setup an item value in my general mod config builder (e.g. SNIPER_SWORD): package com.kwpugh.gobber2.world; import net.minecraftforge.common.ForgeConfigSpec; public class GeneralModConfig { public static ForgeConfigSpec.BooleanValue GOBBER2_ORE_GENERATION; public static ForgeConfigSpec.IntValue GOBBER2_ORE_CHANCE; public static ForgeConfigSpec.IntValue GOBBER2_ORE_SIZE; public static ForgeConfigSpec.IntValue GOBBER2_ORE_MIN_HEIGHT; public static ForgeConfigSpec.IntValue GOBBER2_ORE_MAX_HEIGHT; public static ForgeConfigSpec.BooleanValue GOBBER2_LUCKY_BLOCK_GENERATION; public static ForgeConfigSpec.IntValue GOBBER2_LUCKY_BLOCK_CHANCE; public static ForgeConfigSpec.IntValue GOBBER2_LUCKY_BLOCK_SIZE; public static ForgeConfigSpec.IntValue GOBBER2_LUCKY_BLOCK_MIN_HEIGHT; public static ForgeConfigSpec.IntValue GOBBER2_LUCKY_BLOCK_MAX_HEIGHT; public static ForgeConfigSpec.BooleanValue GOBBER2_ORE_NETHER_GENERATION; public static ForgeConfigSpec.IntValue GOBBER2_ORE_NETHER_CHANCE; public static ForgeConfigSpec.IntValue GOBBER2_ORE_NETHER_SIZE; public static ForgeConfigSpec.IntValue GOBBER2_ORE_NETHER_MIN_HEIGHT; public static ForgeConfigSpec.IntValue GOBBER2_ORE_NETHER_MAX_HEIGHT; public static ForgeConfigSpec.BooleanValue GOBBER2_ORE_END_GENERATION; public static ForgeConfigSpec.IntValue GOBBER2_ORE_END_CHANCE; public static ForgeConfigSpec.IntValue GOBBER2_ORE_END_SIZE; public static ForgeConfigSpec.IntValue GOBBER2_ORE_END_MIN_HEIGHT; public static ForgeConfigSpec.IntValue GOBBER2_ORE_END_MAX_HEIGHT; public static ForgeConfigSpec.BooleanValue SNIPER_SWORD; public static void init(ForgeConfigSpec.Builder SERVER_BUILDER) { SERVER_BUILDER.comment("Gobber Ore Generation").push("gobber2_ore"); GOBBER2_ORE_GENERATION = SERVER_BUILDER.comment("Generate Gobber Ore in the world [true / false]").define("gobberOreGeneration", true); GOBBER2_ORE_SIZE = SERVER_BUILDER.comment("Size of Gobber Ore pockets [0-100, default: 3]").defineInRange("gobberOreSize", 3, 0, 100); GOBBER2_ORE_CHANCE = SERVER_BUILDER.comment("Chances of Gobber Ore pocket being generated [0-100, default: 10]").defineInRange("gobberOreChance", 10, 0, 100); GOBBER2_ORE_MIN_HEIGHT = SERVER_BUILDER.comment("Minimal height for Gobber Ore pocket generation, [0-255, default: 20]").defineInRange("gobberOReMinHeight", 20, 0, 255); GOBBER2_ORE_MAX_HEIGHT = SERVER_BUILDER.comment("Maximal height for Gobber Ore pocket generation [0-255, default: 30]").defineInRange("gobberOreMaxHeight", 30, 0, 255); SERVER_BUILDER.pop(); SERVER_BUILDER.comment("Gobber Lucky Block Generation").push("gobber2_lucky_block"); GOBBER2_LUCKY_BLOCK_GENERATION = SERVER_BUILDER.comment("Generate Gobber Lucky Block in the world [true / false]").define("gobberLuckyBlockGeneration", true); GOBBER2_LUCKY_BLOCK_SIZE = SERVER_BUILDER.comment("Size of Gobber Lucky Block pockets [0-100, default: 3]").defineInRange("gobberLuckyBlockSize", 3, 0, 100); GOBBER2_LUCKY_BLOCK_CHANCE = SERVER_BUILDER.comment("Chances of Gobber Lucky Block pocket being generated [0-100, default: 20]").defineInRange("gobberLuckyBlockChance", 20, 0, 100); GOBBER2_LUCKY_BLOCK_MIN_HEIGHT = SERVER_BUILDER.comment("Minimal height for Gobber Lucky Block pocket generation, [0-255, default: 1]").defineInRange("gobberLuckyBlockMinHeight", 1, 0, 255); GOBBER2_LUCKY_BLOCK_MAX_HEIGHT = SERVER_BUILDER.comment("Maximal height for Gobber Lucky Block pocket generation [0-255, default: 255]").defineInRange("gobberLuckyBlockMaxHeight", 255, 0, 255); SERVER_BUILDER.pop(); SERVER_BUILDER.comment("Gobber Nether Ore Generation").push("gobber2_ore_nether"); GOBBER2_ORE_NETHER_GENERATION = SERVER_BUILDER.comment("Generate Gobber Nether Ore in the world [true / false]").define("gobberOreNetherGeneration", true); GOBBER2_ORE_NETHER_SIZE = SERVER_BUILDER.comment("Size of Gobber Nether Ore pockets [0-100, default: 1]").defineInRange("gobberOreNetherSize", 3, 0, 100); GOBBER2_ORE_NETHER_CHANCE = SERVER_BUILDER.comment("Chances of Gobber Nether Ore pocket being generated [0-100, default: 10]").defineInRange("gobberOreNetherChance", 80, 0, 100); GOBBER2_ORE_NETHER_MIN_HEIGHT = SERVER_BUILDER.comment("Minimal height for Gobber Nether Ore pocket generation, [0-255, default: 5]").defineInRange("gobberOreNetherMinHeight", 20, 0, 255); GOBBER2_ORE_NETHER_MAX_HEIGHT = SERVER_BUILDER.comment("Maximal height for Gobber Nether Ore pocket generation [0-255, default: 50]").defineInRange("gobberOreNetherMaxHeight", 255, 0, 255); SERVER_BUILDER.pop(); SERVER_BUILDER.comment("Gobber End Ore Generation").push("gobber2_ore_end"); GOBBER2_ORE_END_GENERATION = SERVER_BUILDER.comment("Generate Gobber End Ore in the world [true / false]").define("gobberOreEndGeneration", true); GOBBER2_ORE_END_SIZE = SERVER_BUILDER.comment("Size of Gobber End Ore pockets [0-100, default: 5]").defineInRange("gobberOreEndSize", 5, 0, 100); GOBBER2_ORE_END_CHANCE = SERVER_BUILDER.comment("Chances of Gobber End Ore pocket being generated [0-100, default: 10]").defineInRange("gobberOreEndChance", 80, 0, 100); GOBBER2_ORE_END_MIN_HEIGHT = SERVER_BUILDER.comment("Minimal height for Gobber End Ore pocket generation, [0-255, default: 5]").defineInRange("gobberOreEndMinHeight", 0, 0, 255); GOBBER2_ORE_END_MAX_HEIGHT = SERVER_BUILDER.comment("Maximal height for Gobber End Ore pocket generation [0-255, default: 50]").defineInRange("gobberOreEndMaxHeight", 255, 0, 255); SERVER_BUILDER.pop(); SERVER_BUILDER.comment("Sniper Sword Enablement").push("gobber2_sniper_sword"); SNIPER_SWORD = SERVER_BUILDER.comment("Enable crafting of Sniper Sword [true / false]").define("sniperSwordEnablement", true); SERVER_BUILDER.pop(); } } The value correctly writes to my config file. In my item register class, doing a simple: if(GeneralModConfig.SNIPER_SWORD == true) yields an error: "Incompatible operand types ForgeConfigSpec.BooleanValue and boolean" Looking through ForgeConfigSpec class, it is clear that this is a much more complex structure than just a boolean. In reading the ForgeConfigSpec class code, I am not able to figure out how to navigate this structure to test the ForgeConfigSpec.BooleanValue I set. Any guidance would be helpful. Regards.
  7. Ok, you confused me. You said the event handler methods must be static before.
  8. Ok, I see. I mis-read. The doc explains BOTH static and non-static methods and indicates that "An event handler may also be static", I didn't understand that it is required. I got it working, thank you.
  9. I had put System.out.println statements in the onPlayerTick and repair methods and nothing prints in the log, telling me that my code is never hit.
  10. Hi, I'm looking for some guidance on how to effectively interate through the player inventory, test for a condition, and take an action. The following code is something I am attempting to migrate from 1.12.2, but having little luck. package com.kwpugh.gobber2.util; import com.kwpugh.gobber2.Gobber2; import com.kwpugh.gobber2.lists.ItemList; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.inventory.EquipmentSlotType; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraftforge.eventbus.api.EventPriority; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod.EventBusSubscriber; import net.minecraftforge.fml.common.gameevent.TickEvent; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; @EventBusSubscriber(modid = Gobber2.modid, bus = EventBusSubscriber.Bus.FORGE ) public class RepairTickHandler { int DELAY; Item repairGring; int time; public RepairTickHandler(Item item, int delay) { repairGring = item; DELAY = delay; time = DELAY; } @SubscribeEvent(receiveCanceled = true, priority= EventPriority.HIGHEST) public void onPlayerTick(TickEvent.PlayerTickEvent event) { PlayerEntity player = (PlayerEntity) event.player; IItemHandler inv = (IItemHandler) player.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null); for (int i = 0; i < inv.getSlots(); i++) { ItemStack target = inv.getStackInSlot(i); if (target.getItem() == ItemList.gobber2_ring_repair) { time--; if (time <= 0) { time = DELAY; repair(player); } } } } private void repair(PlayerEntity player) { IItemHandler inv = (IItemHandler) player.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null); for (int i = 0; i < ((IItemHandler) inv).getSlots(); i++) { ItemStack target = inv.getStackInSlot(i); if (!target.isEmpty() && target.getItem().isRepairable(target)) { if (!(player.isSwingInProgress && target == player.getItemStackFromSlot(EquipmentSlotType.MAINHAND))) { if (target.isDamaged()) { target.setDamage(target.getDamage() - 1); return; } } } } } } It is not working as expected and I am not sure why. Any guidance would be helpful. Regards, Thank you.
  11. Hi All, I am wondering what the best practices is for adding new ores to the game. Should the custom ore extend Block or OreBlock? As I work on my own mining item, I notice that different modders follow different methods (e.g. some Block, some OreBlock). Is there a preferred way to either include or exclude all custom ore blocks that are added by different mods? Thank you for the guidance. Regards.
  12. Ok, so I stopped looking at the screen and took a nap. Looking at it again with fresh eyes, I was able to (hopefully) simplify it a bit. I also noticed the .connection.setLocationAndUpdate in the ServerPlayNetHandler. I was thinking my problem was I was moving the player around and not sending notice to the server of that fact (I think). I was hoping the ".connection" was sufficient to let the server know. I spent some time playing SP and on the local server, no crashes, no excess ticking. Here is the current class: package com.kwpugh.gobber2.items.rings; import java.util.List; import com.kwpugh.gobber2.util.RayTraceUtil; import net.minecraft.client.util.ITooltipFlag; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.ServerPlayerEntity; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.util.ActionResult; import net.minecraft.util.ActionResultType; import net.minecraft.util.Hand; import net.minecraft.util.SoundCategory; import net.minecraft.util.SoundEvents; import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.StringTextComponent; import net.minecraft.util.text.TextFormatting; import net.minecraft.world.World; public class ItemCustomRingBlink extends Item { public ItemCustomRingBlink(Properties properties) { super(properties); } public ActionResult<ItemStack> onItemRightClick(World world, PlayerEntity player, Hand hand) { ItemStack stack = player.getHeldItem(hand); ItemStack equippedMain = player.getHeldItemMainhand(); if(equippedMain == stack) //Only works in the main hand { if (!world.isRemote) { RayTraceResult pos = RayTraceUtil.getNearestPositionWithAir(world, player, 100); if(pos != null && (pos.getType() == RayTraceResult.Type.BLOCK || player.rotationPitch >= -5)) { int side = pos.getType().ordinal(); if(side != -1) { double x = pos.getHitVec().x-(side == 4 ? 0.5 : 0)+(side == 5 ? 0.5 : 0); double y = pos.getHitVec().y-(side == 0 ? 2.0 : 0)+(side == 1 ? 0.5 : 0); double z = pos.getHitVec().z-(side == 2 ? 0.5 : 0)+(side == 3 ? 0.5 : 0); player.stopRiding(); ((ServerPlayerEntity)player).connection.setPlayerLocation(x, y, z, player.rotationYaw, player.rotationPitch); world.playSound(null, player.posX, player.posY, player.posZ, SoundEvents.ENTITY_ENDERMAN_TELEPORT, SoundCategory.PLAYERS, 1.0F, 1.0F); return ActionResult.newResult(ActionResultType.SUCCESS, stack); } } } } return new ActionResult<ItemStack>(ActionResultType.SUCCESS, stack); } @Override public void addInformation(ItemStack stack, World world, List<ITextComponent> list, ITooltipFlag flag) { super.addInformation(stack, world, list, flag); list.add(new StringTextComponent(TextFormatting.BLUE + "Teleports player to the location looking at")); list.add(new StringTextComponent(TextFormatting.GREEN + "Right-click to use")); list.add(new StringTextComponent(TextFormatting.YELLOW + "Range limit: 100 blocks")); } } I did not make any changes to the RayTraceUtil that I had previously posted. Is there anything glaringly wrong I'm doing or is this ok? Regards.
  13. Hi All, Looking for some guidance/expert advice on my code. I created an item that appears to do what I want it to (e.g. teleport the player to the location they are looking on right-click). I used the source for EndermanEnity and EnderPearlEntity as a reference point. I have an uneasy feeling that they way I am doing this is dangerous (or flat out wrong) and I'm looking for expert advice. While testing the mod on a local server, I get an occasional crash. # # A fatal error has been detected by the Java Runtime Environment: # # SIGSEGV (0xb) at pc=0x0000000110ec8aa1, pid=34978, tid=0x0000000000005003 # # JRE version: Java(TM) SE Runtime Environment (8.0_151-b12) (build 1.8.0_151-b12) # Java VM: Java HotSpot(TM) 64-Bit Server VM (25.151-b12 mixed mode bsd-amd64 compressed oops) # Problematic frame: # V [libjvm.dylib+0x4c8aa1] # # Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again # # An error report file with more information is saved as: # /Users/kwpugh/eclipse-workspace/gobber2-1.14/run/hs_err_pid34978.log # # If you would like to submit a bug report, please visit: # http://bugreport.java.com/bugreport/crash.jsp # Link to the client crash report: https://gist.github.com/kwpugh/36d24c7a315e260a0417c1ebcee09bce Link to server crash report: https://gist.github.com/kwpugh/6dc5976977ea55c510c4db09275d3410 Here are my classes: package com.kwpugh.gobber2.items.rings; import java.util.List; import com.kwpugh.gobber2.util.RayTraceUtil; import net.minecraft.client.util.ITooltipFlag; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.ServerPlayerEntity; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.util.ActionResult; import net.minecraft.util.ActionResultType; import net.minecraft.util.Hand; import net.minecraft.util.SoundCategory; import net.minecraft.util.SoundEvents; import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.StringTextComponent; import net.minecraft.util.text.TextFormatting; import net.minecraft.world.World; public class ItemCustomRingBlink extends Item { public ItemCustomRingBlink(Properties properties) { super(properties); } public ActionResult<ItemStack> onItemRightClick(World world, PlayerEntity player, Hand hand) { ItemStack stack = player.getHeldItem(hand); ItemStack equippedMain = player.getHeldItemMainhand(); if(equippedMain == stack) //Only works in the main hand { if (!world.isRemote) { if(player instanceof LivingEntity) { LivingEntity livingentity = player; if(livingentity instanceof ServerPlayerEntity) { ServerPlayerEntity serverplayerentity = (ServerPlayerEntity)livingentity; RayTraceResult pos = RayTraceUtil.getNearestPositionWithAir(world, player, 100); if(pos != null && (pos.getType() == RayTraceResult.Type.BLOCK || player.rotationPitch >= -5)) { int side = pos.getType().ordinal(); if(side != -1) { double x = pos.getHitVec().x-(side == 4 ? 0.5 : 0)+(side == 5 ? 0.5 : 0); double y = pos.getHitVec().y-(side == 0 ? 2.0 : 0)+(side == 1 ? 0.5 : 0); double z = pos.getHitVec().z-(side == 2 ? 0.5 : 0)+(side == 3 ? 0.5 : 0); //Use the existing event for ender pearl teleport for our own purposes net.minecraftforge.event.entity.living.EnderTeleportEvent event = new net.minecraftforge.event.entity.living.EnderTeleportEvent(serverplayerentity, player.posX, player.posY, player.posZ, 5.0F); if (livingentity.isPassenger()) { livingentity.stopRiding(); } //Set the target values for the event to the location the player is looking event.setTargetX(x); event.setTargetY(y); event.setTargetZ(z); livingentity.setPositionAndUpdate(event.getTargetX(), event.getTargetY(), event.getTargetZ()); world.playSound(null, player.posX, player.posY, player.posZ, SoundEvents.ENTITY_ENDERMAN_TELEPORT, SoundCategory.PLAYERS, 1.0F, 1.0F); return ActionResult.newResult(ActionResultType.SUCCESS, stack); } } } } } } return new ActionResult<ItemStack>(ActionResultType.SUCCESS, stack); } @Override public void addInformation(ItemStack stack, World world, List<ITextComponent> list, ITooltipFlag flag) { super.addInformation(stack, world, list, flag); list.add(new StringTextComponent(TextFormatting.BLUE + "Teleports player to the location looking at")); list.add(new StringTextComponent(TextFormatting.GREEN + "Right-click to use")); list.add(new StringTextComponent(TextFormatting.YELLOW + "Range limit: 100 blocks")); } } The RayTraceUtil is outside the item because I use it elsewhere in my mod. package com.kwpugh.gobber2.util; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.RayTraceContext; import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; public class RayTraceUtil { public static RayTraceResult getNearestPositionWithAir(World world, PlayerEntity player, int reach) { return getMovingObjectPosWithReachDistance(world, player, reach, false, false, true); } private static RayTraceResult getMovingObjectPosWithReachDistance(World world, PlayerEntity player, double distance, boolean p1, boolean p2, boolean p3) { float f = player.rotationPitch; float f1 = player.rotationYaw; double d0 = player.posX; double d1 = player.posY + (double) player.getEyeHeight(); double d2 = player.posZ; Vec3d vec3 = new Vec3d(d0, d1, d2); float f2 = MathHelper.cos(-f1 * 0.017453292F - (float) Math.PI); float f3 = MathHelper.sin(-f1 * 0.017453292F - (float) Math.PI); float f4 = -MathHelper.cos(-f * 0.017453292F); float f5 = MathHelper.sin(-f * 0.017453292F); float f6 = f3 * f4; float f7 = f2 * f4; Vec3d vec31 = vec3.add((double) f6 * distance, (double) f5 * distance, (double) f7 * distance); return world.rayTraceBlocks(new RayTraceContext(vec3, vec31, RayTraceContext.BlockMode.COLLIDER, RayTraceContext.FluidMode.ANY, player)); } } Thank you in advance for any helpful advice. Regards.
  14. Ok, so I actually got it working as I wanted, but it seems like a very contrived way to accomplished it. Feedback to simplify are welcome. package com.kwpugh.gobber2.blocks; import java.util.List; import javax.annotation.Nullable; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.GlassBlock; import net.minecraft.client.util.ITooltipFlag; import net.minecraft.entity.Entity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.shapes.ISelectionContext; import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.StringTextComponent; import net.minecraft.util.text.TextFormatting; import net.minecraft.world.IBlockReader; import net.minecraft.world.World; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; public class BlockGobberGlass extends GlassBlock { public BlockGobberGlass(Properties properties) { super(properties); } public static final VoxelShape GLASS_NOT_SOLID_AABB = Block.makeCuboidShape(0.0D, 0.0D, 0.00D, 0.0D, 0.0D, 0.0D); public static final VoxelShape GLASS_SOLID_AABB = Block.makeCuboidShape(0.0D, 0.0D, 0.0D, 16.0D, 16.0D, 16.0D); public VoxelShape getCollisionShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) { if( (context.getEntity() instanceof PlayerEntity) && (context.getEntity().isSneaking()) ) { return GLASS_SOLID_AABB; } if(context.getEntity() instanceof PlayerEntity) { return GLASS_NOT_SOLID_AABB; } else { return GLASS_SOLID_AABB; } } public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) { if( (context.getEntity() instanceof PlayerEntity) && (context.getEntity().isSneaking()) ) { return GLASS_SOLID_AABB; } if(context.getEntity() instanceof PlayerEntity) { return GLASS_NOT_SOLID_AABB; } else { return GLASS_SOLID_AABB; } } public void onEntityCollision(BlockState state, World worldIn, BlockPos pos, Entity entityIn) { //entityIn.attackEntityFrom(DamageSource.CACTUS, 1.0F); } @OnlyIn(Dist.CLIENT) public void addInformation(ItemStack stack, @Nullable IBlockReader world, List<ITextComponent> tooltip, ITooltipFlag flag) { super.addInformation(stack, world, tooltip, flag); tooltip.add(new StringTextComponent(TextFormatting.BLUE + "A very sturdy glass block")); tooltip.add(new StringTextComponent(TextFormatting.GREEN + "Drops the block when broken")); } } My question now is how to conditionally change block properties (ex. if entity is a spider then setBesideClimbableBlock to false).
  15. Hello Again, I am still trying work through this. I found that the LilyPadBlock class still uses the onEntityCollison, so I started to pattern my custom glass block on that. It is not working. I suspect that I am not fully understanding exactly how VoxelShapes work. Here is my current class for a custom glass block. package com.kwpugh.gobber2.blocks; import java.util.List; import javax.annotation.Nullable; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.GlassBlock; import net.minecraft.client.util.ITooltipFlag; import net.minecraft.entity.Entity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.shapes.ISelectionContext; import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.util.math.shapes.VoxelShapes; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.StringTextComponent; import net.minecraft.util.text.TextFormatting; import net.minecraft.world.IBlockReader; import net.minecraft.world.World; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; public class BlockGobberGlass extends GlassBlock { public BlockGobberGlass(Properties properties) { super(properties); } @SuppressWarnings("deprecation") public void onEntityCollision(BlockState state, World worldIn, BlockPos pos, Entity entityIn) { ISelectionContext context = (ISelectionContext) entityIn; super.onEntityCollision(state, worldIn, pos, entityIn); entityIn.sendMessage(new StringTextComponent("Collision occured")); getShape(state, worldIn, pos, context); } public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) { if(context instanceof PlayerEntity) { return VoxelShapes.empty(); } else { return VoxelShapes.fullCube(); } } @OnlyIn(Dist.CLIENT) public void addInformation(ItemStack stack, @Nullable IBlockReader world, List<ITextComponent> tooltip, ITooltipFlag flag) { super.addInformation(stack, world, tooltip, flag); tooltip.add(new StringTextComponent(TextFormatting.BLUE + "A very sturdy glass block")); tooltip.add(new StringTextComponent(TextFormatting.GREEN + "Drops the block when broken")); } } Please keep in mind that I am pretty new to Java and continue to work my way through a large Udemy course (77+ hours). Big question: I am not quite clear about the relationship between AxisAlignedBB and VoxelShapes. - Which one actually controls the properties of a given block's bounding box. - What is the difference between a block's bounding box and collision box? Is there a difference? - is a return of VoxelShapes.empty() and VoxelShapes.fullCube() intended to have an empty BB and a full BB respectively? - Am I using the selectionContext interface correctly? Thank you in advance for any guidance. Regards. [EDIT] I am also confused by when to use VoxelShape and VoxelShapes.
  16. Hi, Thanks. I'm trying your suggestions. Question: does getCollisionShape replace the deprecated onEntityCollision?
  17. Well, that did the trick. Thank you so much. I have been struggling with this quite a lot. I am halfway thru a 77 hour Java course on Udemy at the moment, so I am learning and doing at the same time. Thanks for your help. Regards.
  18. That compiles without error. As to my OreGeneration.class, there are some many parameters on the biome line, that I am confused about how to pass in an instance of my CustomOreFeature. public static void setupEndOregen() { if(WorldgenConfig.GOBBER2_ORE_END_GENERATION.get()) Biomes.END_HIGHLANDS.addFeature(GenerationStage.Decoration.UNDERGROUND_DECORATION, Biome.createDecoratedFeature(Feature.ORE, new OreFeatureConfig(OreFeatureConfig.FillerBlockType.NATURAL_STONE, BlockList.gobber2_ore_end.getDefaultState(), WorldgenConfig.GOBBER2_ORE_END_SIZE.get().intValue()), COUNT_RANGE, new CountRangeConfig(WorldgenConfig.GOBBER2_ORE_END_CHANCE.get(), WorldgenConfig.GOBBER2_ORE_END_MIN_HEIGHT.get(), WorldgenConfig.GOBBER2_ORE_END_MIN_HEIGHT.get(), WorldgenConfig.GOBBER2_ORE_END_MAX_HEIGHT.get()))); if(WorldgenConfig.GOBBER2_ORE_END_GENERATION.get()) Biomes.END_MIDLANDS.addFeature(GenerationStage.Decoration.UNDERGROUND_DECORATION, Biome.createDecoratedFeature(Feature.ORE, new OreFeatureConfig(OreFeatureConfig.FillerBlockType.NATURAL_STONE, BlockList.gobber2_ore_end.getDefaultState(), WorldgenConfig.GOBBER2_ORE_END_SIZE.get().intValue()), COUNT_RANGE, new CountRangeConfig(WorldgenConfig.GOBBER2_ORE_END_CHANCE.get(), WorldgenConfig.GOBBER2_ORE_END_MIN_HEIGHT.get(), WorldgenConfig.GOBBER2_ORE_END_MIN_HEIGHT.get(), WorldgenConfig.GOBBER2_ORE_END_MAX_HEIGHT.get()))); if(WorldgenConfig.GOBBER2_ORE_END_GENERATION.get()) Biomes.THE_END.addFeature(GenerationStage.Decoration.UNDERGROUND_DECORATION, Biome.createDecoratedFeature(Feature.ORE, new OreFeatureConfig(OreFeatureConfig.FillerBlockType.NATURAL_STONE, BlockList.gobber2_ore_end.getDefaultState(), WorldgenConfig.GOBBER2_ORE_END_SIZE.get().intValue()), COUNT_RANGE, new CountRangeConfig(WorldgenConfig.GOBBER2_ORE_END_CHANCE.get(), WorldgenConfig.GOBBER2_ORE_END_MIN_HEIGHT.get(), WorldgenConfig.GOBBER2_ORE_END_MIN_HEIGHT.get(), WorldgenConfig.GOBBER2_ORE_END_MAX_HEIGHT.get()))); }
  19. Hi m00nl1ght, I tried coding this up and perhaps some of the mappings changed with the latest update. You said to look for: if (p_207803_3_.target.func_214738_b().test(p_207803_1_.getBlockState(blockpos$mutableblockpos))) { ... I presume in OreFeature.java, but there isn't one. I did find: if (config.target.func_214738_b().test(worldIn.getBlockState(blockpos$mutableblockpos))) { inside of the protected boolean func_207803_a method I created my own CustomOreFeature class and @Override on functionalists_207803. I then replaced the following: if (config.target.func_214738_b().test(worldIn.getBlockState(blockpos$mutableblockpos))) replaced with: if (config.target.func_214738_b().test(worldIn.getBlockState(blockpos$mutableblockpos).getBlock() == Blocks.END_STONE) ) { I get the following error on test: The method test(BlockState) in the type Predicate<BlockState> is not applicable for the arguments (boolean) Doing this directly: if (p_207803_1_.getBlockState(blockpos$mutableblockpos).getBlock() == Blocks.END_STONE) Generates unresolved variable on p_207803_1 and blockpos$mutableblockpos cannot be resolved to a variable errors. Any thoughts? Regards.
  20. Thanks for the guidance. How would it my custom version of OreFeature get used here? if(WorldgenConfig.GOBBER2_ORE_END_GENERATION.get()) Biomes.THE_END.addFeature(GenerationStage.Decoration.UNDERGROUND_DECORATION, Biome.createDecoratedFeature(Feature.ORE, new OreFeatureConfig(OreFeatureConfig.FillerBlockType.NATURAL_STONE, BlockList.gobber2_ore_end.getDefaultState(), WorldgenConfig.GOBBER2_ORE_END_SIZE.get().intValue()), COUNT_RANGE, new CountRangeConfig(WorldgenConfig.GOBBER2_ORE_END_CHANCE.get(), WorldgenConfig.GOBBER2_ORE_END_MIN_HEIGHT.get(), WorldgenConfig.GOBBER2_ORE_END_MIN_HEIGHT.get(), WorldgenConfig.GOBBER2_ORE_END_MAX_HEIGHT.get())));
  21. So, through a little "trial-n-error" I was able to get a delay working. if (igrowable.canGrow(world, tagetPos, blockstate, world.isRemote)) { { if (!world.isRemote) { if (player.ticksExisted % 60 == 0) { igrowable.grow(world, world.rand, tagetPos, blockstate); } } } } A value of 60 goes much slower, smaller numbers make it faster. Since I do not know what the value is stored in ticksExisted, it could just be luck. I still would like to understand what that variable contains and how it works. Regards.
  22. Thank you for the clarification. I found these examples in the reference code, that seem to control the rate that natural regeneration occurs: if (this.getHealth() < this.getMaxHealth() && this.ticksExisted % 20 == 0) { this.heal(1.0F); } if (this.foodStats.needFood() && this.ticksExisted % 10 == 0) { this.foodStats.setFoodLevel(this.foodStats.getFoodLevel() + 1); } What I do not understand from looking at this is "what is ticksExisted" containing? Is this a continuing count of the # of ticks the player entity has existed or something else? I see the ticksExisted is an int variable declared in Entiy.java, but I do not understand what it is storing. Regards.
  23. Thank you for the suggestion, but frankly, I have no idea what that means. I'll do some research to see if I can figure it out. Questions for clarification: - by modulo, I presume you are talking about the remainder of the division of two numbers? - the ticksExisted of the entity, where the "entity" is the plant or crop?
×
×
  • Create New...

Important Information

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