Jump to content

rushingseas8

Members
  • Posts

    4
  • Joined

  • Last visited

Everything posted by rushingseas8

  1. That works a lot better for my needs. The solution I previously had also messed with FOV (which might be useful for some other applications). Updated code: // BlockSapling.java @Override public void onEntityCollision(IBlockState state, World worldIn, BlockPos pos, Entity entityIn) { entityIn.motionX *= 0.8f; entityIn.motionY *= 0.8f; entityIn.motionZ *= 0.8f; } Thanks a bunch!
  2. Okay, that seems to work. Shame there's not a more efficient way to do it. For reference, here's the working code: private static final UUID saplingSlowUUID = UUID.fromString("83BD3C05-50EB-460B-8961-615633A6D813"); // -0.2D with operation 1 corresponds to a 0.8x speed multiplier. private static final AttributeModifier saplingSlow = new AttributeModifier(saplingSlowUUID, "SAPLING_SLOW", -0.2D, 1); @SubscribeEvent public static void onPlayerTick(TickEvent.PlayerTickEvent playerTickEvent) { if (playerTickEvent.side == LogicalSide.SERVER) { EntityPlayer player = playerTickEvent.player; World world = player.getEntityWorld(); // Get all blocks that any part of the player model is colliding with. Iterable<BlockPos.MutableBlockPos> playerColliding = BlockPos.getAllInBoxMutable( (int) Math.floor(player.posX - (player.width / 2)), (int) Math.floor(player.posY - (player.height / 2)), (int) Math.floor(player.posZ - (player.width / 2)), (int) Math.floor(player.posX + (player.width / 2)), (int) Math.floor(player.posY + (player.height / 2)), (int) Math.floor(player.posZ + (player.width / 2)) ); boolean shouldSlow = false; for (BlockPos bp : playerColliding) { shouldSlow |= world.getBlockState(bp).getBlock() instanceof BlockSapling; } IAttributeInstance movement = playerTickEvent.player.getAttribute(SharedMonsterAttributes.MOVEMENT_SPEED); if (shouldSlow) { // Add modifier, if it's not already applied if (!movement.hasModifier(saplingSlow)) { movement.applyModifier(saplingSlow); } } else { // Remove modifier, if it exists if (movement.hasModifier(saplingSlow)) { movement.removeModifier(saplingSlow); } } } } // [Elsewhere, in some register event] MinecraftForge.EVENT_BUS.register(BlockSapling.class); Thanks for the help. If anyone has a better way to do this, please let me know.
  3. I should also add that I don't want to have the hardcoded 0.25x multiplier on horizontal speed/0.05x on vertical. Ideally I'd want to have a 0.8x speed multipler across the board, which Entity#setInWeb wouldn't do.
  4. I'm trying to make a custom block that slows down mobs (definitely the player, possibly enemies, but not items). I first looked at the behavior of BlockWeb, but it hardcodes a field "isInWeb" in Entity, so I can't directly copy that block's behavior without modifying the vanilla code directly. After that, I looked into AttributeModifiers to see if I could modify "SharedMonsterAttributes.MOVEMENT_SPEED" inside of EntityLivingBase. My plan was to apply a custom slowness effect when inside the block, and try to remove it from the player every tick. Here's my current code: // Apply slowness when an EntityLivingBase is within the bounds of the sapling block. @Override public void onEntityCollision(IBlockState state, World worldIn, BlockPos pos, Entity entityIn) { if (entityIn instanceof EntityLivingBase) { IAttributeInstance movement = ((EntityLivingBase) entityIn).getAttribute(SharedMonsterAttributes.MOVEMENT_SPEED); if (movement.hasModifier(saplingSlow)) { movement.removeModifier(saplingSlow); } movement.applyModifier(saplingSlow); System.out.println("Applied slowness"); } } // Attempt to remove the effect when outside the bounds of the block using a PlayerTick event. // This is registered in a registration event elsewhere. @SubscribeEvent public static void onPlayerTick(TickEvent.PlayerTickEvent playerTickEvent) { if (playerTickEvent.side == LogicalSide.SERVER) { IAttributeInstance movement = playerTickEvent.player.getAttribute(SharedMonsterAttributes.MOVEMENT_SPEED); if (movement.getModifier(saplingSlowUUID) != null) { if (movement.hasModifier(saplingSlow)) { movement.removeModifier(saplingSlow); } } } } The "onEntityCollision" code works fine, but the "onPlayerTick" seems incorrect. When I walk into the block, the slowness is repeatedly applied and removed, rather than being smoothly active when inside the block and inactive when not. I could add logic to check if the Player is within the bounds of my custom block within the "onPlayerTick" method, but that doesn't seem like an efficient way of doing it. Is there an easier way to achieve what I'm trying to do? Or am I on the right track, but missing something in my current code?
×
×
  • Create New...

Important Information

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