jonaskohl
-
Posts
9 -
Joined
-
Last visited
Posts posted by jonaskohl
-
-
I'm sorry if this is a stupid question, but how would I do that? Because right now, the PlayerEntity is never an instance of ServerPlayerEntity (my check never returns true)
-
I am trying to implement a right-click interaction between a vanilla tool and a vanilla block (so I can't use onBlockActivated or onItemUse). Everything is working fine except my call to ItemStack#attemptDamageItem, because the PlayerEntity I get from PlayerInteractEvent.RightClickBlock#getPlayer() is an instance of ClientPlayerEntity, not a ServerPlayerEntity. However, ItemStack#attemptDamageItem expects a ServerPlayerEntity only. I tried passing in null as the damager parameter, and this almost works, but the item doesn't break when reaching 0 durability. This may be, because the ITEM_DURABILITY_CHANGED trigger never fires when damager is null. Now my question: How can I get access to a ServerPlayerEntity instance, or alternatively, how can I make sure the item breaks when reaching 0 durability?
My code looks as follows:
Spoiler@SubscribeEvent public void onInteract(PlayerInteractEvent.RightClickBlock event) { World world = event.getWorld(); ItemStack stack = event.getItemStack(); BlockPos pos = event.getPos(); BlockState state = world.getBlockState(pos); Direction face = event.getFace(); PlayerEntity player = event.getPlayer(); if (stack.getItem() instanceof ShearsItem && state.getBlock().equals(Blocks.GRASS_BLOCK) && Objects.equals(face, Direction.UP)) { if (!player.isCreative()) { if (player instanceof ServerPlayerEntity) stack.attemptDamageItem(1, world.rand, (ServerPlayerEntity) player); else stack.attemptDamageItem(1, world.rand, null); } BlockState above = world.getBlockState(pos.up()); world.setBlockState( pos, ModBlocks.LAWN_BLOCK .get() .getDefaultState() .with(LawnBlock.SNOWY, above.matchesBlock(Blocks.SNOW_BLOCK) || above.matchesBlock(Blocks.SNOW)) .with(LawnBlock.FACING, player.getHorizontalFacing().getOpposite()) ); world.playSound(player, pos, SoundEvents.BLOCK_GRASS_PLACE, SoundCategory.BLOCKS, 1.0F, 1.0F); player.swing(event.getHand(), true); } }
-
*bump* Anyone?
-
I'm trying to add a custom tree to my mod. I'm using the following method to register the tree:
//// == ElderTree.java == //// public class ElderTree extends Tree { @Nullable @Override protected ConfiguredFeature<BaseTreeFeatureConfig, ?> getTreeFeature(Random randomIn, boolean largeHive) { return (ConfiguredFeature<BaseTreeFeatureConfig, ?>) ModFeatures.ELDER_TREE.get(); } } //// == ModFeatures.java == //// // [...] public static final Lazy<ConfiguredFeature<? extends IFeatureConfig, ?>> ELDER_TREE = register("elder_tree", () -> Feature.TREE.withConfiguration(Configs.ELDER_TREE_CONFIG) .withPlacement(Features.Placements.HEIGHTMAP_PLACEMENT) .withPlacement(Placements.ELDER_TREE_PLACEMENT) ); // [...] public static final class Configs { public static final BaseTreeFeatureConfig ELDER_TREE_CONFIG; // [...] static { ELDER_TREE_CONFIG = new BaseTreeFeatureConfig.Builder( new SimpleBlockStateProvider(ModBlocks.ELDER_LOG.get().getDefaultState()), new SimpleBlockStateProvider(ModBlocks.ELDER_LEAVES.get().getDefaultState()), // Radius | Offset | Height new BlobFoliagePlacer(FeatureSpread.create(2), FeatureSpread.create(0), 3), // Base height | Height Rand A | Height Rand B new StraightTrunkPlacer(4, 2, 0), new TwoLayerFeature(1, 0, 1) ) .setIgnoreVines() .build(); } // [...] }
But whenever I try to grow a sapling or generate a new world, Minecraft crashes with the following exception:
[13:25:21] [Server thread/FATAL] [minecraft/ThreadTaskExecutor]: Error executing task on Server java.lang.ClassCastException: net.minecraft.world.gen.feature.DecoratedFeatureConfig cannot be cast to net.minecraft.world.gen.feature.BaseTreeFeatureConfig at net.minecraft.block.trees.Tree.attemptGrowTree(Tree.java:28) ~[forge:?] {re:classloading} at team.mixxit.allotment.blocks.ModSapling.placeTree(ModSapling.java:50) ~[?:?] {re:classloading} at team.mixxit.allotment.blocks.ModSapling.grow(ModSapling.java:71) ~[?:?] {re:classloading} at net.minecraft.item.BoneMealItem.applyBonemeal(BoneMealItem.java:73) ~[forge:?] {re:classloading} at net.minecraft.item.BoneMealItem.onItemUse(BoneMealItem.java:36) ~[forge:?] {re:classloading} at net.minecraftforge.common.ForgeHooks.onPlaceItemIntoWorld(ForgeHooks.java:613) ~[forge:?] {re:classloading} at net.minecraft.item.ItemStack.onItemUse(ItemStack.java:191) ~[forge:?] {re:classloading} at net.minecraft.server.management.PlayerInteractionManager.func_219441_a(PlayerInteractionManager.java:359) ~[forge:?] {re:classloading} at net.minecraft.network.play.ServerPlayNetHandler.processTryUseItemOnBlock(ServerPlayNetHandler.java:986) ~[forge:?] {re:classloading} at net.minecraft.network.play.client.CPlayerTryUseItemOnBlockPacket.processPacket(CPlayerTryUseItemOnBlockPacket.java:45) ~[forge:?] {re:classloading} at net.minecraft.network.play.client.CPlayerTryUseItemOnBlockPacket.processPacket(CPlayerTryUseItemOnBlockPacket.java:12) ~[forge:?] {re:classloading} at net.minecraft.network.PacketThreadUtil.lambda$checkThreadAndEnqueue$0(PacketThreadUtil.java:19) ~[forge:?] {re:classloading} at net.minecraft.util.concurrent.TickDelayedTask.run(TickDelayedTask.java:20) ~[forge:?] {re:classloading} at net.minecraft.util.concurrent.ThreadTaskExecutor.run(ThreadTaskExecutor.java:139) ~[forge:?] {re:classloading,pl:accesstransformer:B} at net.minecraft.util.concurrent.RecursiveEventLoop.run(RecursiveEventLoop.java:22) ~[forge:?] {re:classloading} at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:758) ~[forge:?] {re:classloading,pl:accesstransformer:B} at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:159) ~[forge:?] {re:classloading,pl:accesstransformer:B} at net.minecraft.util.concurrent.ThreadTaskExecutor.driveOne(ThreadTaskExecutor.java:109) ~[forge:?] {re:classloading,pl:accesstransformer:B} at net.minecraft.server.MinecraftServer.driveOneInternal(MinecraftServer.java:741) ~[forge:?] {re:classloading,pl:accesstransformer:B} at net.minecraft.server.MinecraftServer.driveOne(MinecraftServer.java:735) ~[forge:?] {re:classloading,pl:accesstransformer:B} at net.minecraft.util.concurrent.ThreadTaskExecutor.driveUntil(ThreadTaskExecutor.java:122) ~[forge:?] {re:classloading,pl:accesstransformer:B} at net.minecraft.server.MinecraftServer.runScheduledTasks(MinecraftServer.java:721) ~[forge:?] {re:classloading,pl:accesstransformer:B} at net.minecraft.server.MinecraftServer.func_240802_v_(MinecraftServer.java:667) ~[forge:?] {re:classloading,pl:accesstransformer:B} at net.minecraft.server.MinecraftServer.lambda$startServer$0(MinecraftServer.java:233) ~[forge:?] {re:classloading,pl:accesstransformer:B} at java.lang.Thread.run(Thread.java:748) [?:1.8.0_241] {}
It seems that ConfiguredFeature#withPlacement(ConfiguredPlacement<?>) is the culprit, as it adds a DecoratedFeatureConfig to the feature. What is the proper way to add a placement rule to a tree?
-
I want to add a recipe to my mod that has a block (let's say wooden planks) and a vanilla tool (let's say an axe) and I want the axe to loose durability when used in crafting. This is what I got so far (inside of ModRecipeProvider#registerRecipes):
Ingredient axeIngredients = Ingredient.fromItems( () -> Items.WOODEN_AXE, () -> Items.STONE_AXE, () -> Items.GOLDEN_AXE, () -> Items.IRON_AXE, () -> Items.DIAMOND_AXE, () -> Items.NETHERITE_AXE ); ShapelessRecipeBuilder.shapelessRecipe(ModBlocks.CHIPPED_OAK_PLANK.get()) .addIngredient(Blocks.OAK_PLANKS) .addIngredient(axeIngredients) .addCriterion("has_plank", hasItem(Blocks.OAK_PLANKS)) .build(consumer);
However, this will consume the axe completely when crafted. How can I make the axe stay inside of the crafting grid and lose one point of durability?
(Forge 1.16)
-
I am using the following snippet inside of an onBlockClicked event listener to strip a custom log.
Spoiler@SubscribeEvent public static void onBlockClicked(PlayerInteractEvent.RightClickBlock event) { final int FLAG_BLOCK_UPDATE = 1; final int FLAG_SEND_TO_CLIENTS = 2; final int FLAG_FORCE_RERENDER_MAIN_THREAD = 8; if (event.getItemStack().getItem() instanceof AxeItem) { World world = event.getWorld(); BlockPos blockpos = event.getPos(); BlockState blockstate = world.getBlockState(blockpos); Block block = BLOCK_STRIPPING_MAP.get(blockstate.getBlock()); if (block != null) { PlayerEntity playerentity = event.getPlayer(); world.playSound(playerentity, blockpos, SoundEvents.ITEM_AXE_STRIP, SoundCategory.BLOCKS, 1.0F, 1.0F); if (!world.isRemote) { world.setBlockState(blockpos, block.getDefaultState() .with(RotatedPillarBlock.AXIS, blockstate.get(RotatedPillarBlock.AXIS)), FLAG_BLOCK_UPDATE | FLAG_SEND_TO_CLIENTS | FLAG_FORCE_RERENDER_MAIN_THREAD); if (playerentity != null) { playerentity.swingArm(event.getHand()); event.getItemStack().damageItem(1, playerentity, (entityIn) -> { entityIn.sendBreakAnimation(event.getHand()); }); } } } } }
Everything works as expected, except the axe doesn't "swing" as it does with vanilla blocks. It just does nothing. I tried using
playerentity.swingArm(event.getHand());
but that does absolutely nothing. How can I achieve a swinging tool?
-
That did the trick! Thank you so much!
-
In my mod I have several custom flower types (instances of FlowerBlock), which I register using the DeferredRegister. Now I want to add them to the composter's registry of compostable items. I know I need to add them to ComposterBlock.CHANCES, but I don't know when exactly I need to do this. When I call ComposterBlock.CHANCES.put() in my mod's main class's constructor, I get a NullPointerException with the message 'Registry Object not present: my_mod:my_flower', even though I created the flower objects before I tried to register them. I suspect I need to call this at a later time, but I couldn't find any information about this anywhere.
Item not breaking in PlayerInteractEvent.RightClickBlock event
in Modder Support
Posted
I realized that I'm still on 1.16.4 with MCP mappings, so I probably can't expect any support...
(I tried upgrading the mod to 1.18.2, but that went, uhm, let's say horrible, as so much has changed between 1.16.4 and 1.18.2 and I couldn't find a migration guide, so the mod would require a major rewrite, but that's an entierly different topic...)