Posted February 20, 20241 yr I made a lasso item in forge 1.20.1 that can be used as grappling hook and to move entities towards it. When I test it on singleplayer it works flawlessly, but if I use it on servers it has a deflection. Also if I have used it once, all projectiles receive a deflection until I leave. My Item class: package com.kuikenpower.falidsmp.init.item; import java.util.List; import com.kuikenpower.falidsmp.entities.HookEntity; import net.minecraft.core.BlockPos; import net.minecraft.network.protocol.game.ClientboundLevelParticlesPacket; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResultHolder; import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.effect.MobEffects; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity.RemovalReason; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.ambient.Bat; import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.level.Level; import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.Vec3; public class MesaLasso extends Item { public HookEntity entity; public Vec3 startPoint; public Vec3 controlPoint; public Vec3 endPoint; public double lastDistance; public long startTime; public Bat leashHolder; private static final long MOVEMENT_DURATION = 1000; public AABB leashArea; public MesaLasso(Properties p_41383_) { super(p_41383_); // TODO Auto-generated constructor stub } public static Vec3 lerpBetweenPoints(Vec3 start, Vec3 end, float percentage) { double x = start.x + (end.x - start.x) * percentage; double y = start.y + (end.y - start.y) * percentage; double z = start.z + (end.z - start.z) * percentage; return new Vec3(x, y, z); } public Vec3 getCurvePosition(float percentage) { // Calculate the position between the start and end points along the y-axis double y = startPoint.y + (endPoint.y - startPoint.y) * percentage; double curveFactor = 2.0; y += curveFactor * Math.sin(percentage * Math.PI * ((2 * Math.PI) / 8)); // Use the original x and z coordinates from the start point double x = startPoint.x + (endPoint.x - startPoint.x) * percentage; double z = startPoint.z + (endPoint.z - startPoint.z) * percentage; return new Vec3(x, y, z); } @Override public InteractionResultHolder<ItemStack> use(Level level, Player player, InteractionHand p_41434_) { if(entity != null) { if(leashHolder != null) { entity.blockColliding = false; entity.kill(); leashArea = new AABB(leashHolder.position().x + 2, leashHolder.position().y + 2, leashHolder.position().z + 2, leashHolder.position().x - 2, leashHolder.position().y - 2, leashHolder.position().z - 2); leashHolder.remove(RemovalReason.DISCARDED); killLead(level); } } entity = new HookEntity(level, player); level.addFreshEntity(entity); if(entity != null) { leashHolder = new Bat(EntityType.BAT, level); leashHolder.setPos(entity.position()); leashHolder.addTag("leashHolder"); leashHolder.setInvulnerable(true); leashHolder.addEffect(new MobEffectInstance(MobEffects.INVISIBILITY, 10, 10, false, false)); level.addFreshEntity(leashHolder); } return super.use(level, player, p_41434_); } @Override public void inventoryTick(ItemStack p_41404_, Level p_41405_, Entity player, int p_41407_, boolean p_41408_) { if(entity != null) { if(leashHolder != null) { if(entity.entityColliding == false) { leashHolder.setPos(entity.position()); leashHolder.addEffect(new MobEffectInstance(MobEffects.INVISIBILITY, 10, 10, false, false)); } } double deltaX = entity.position().x - player.position().x; double deltaY = entity.position().y - player.position().y; double deltaZ = entity.position().z - player.position().z; Vec3 midPoint = new Vec3((entity.position().x + player.position().x) * 0.5f, (entity.position().y + player.position().y) * 0.5f, (entity.position().z + player.position().z) * 0.5f); double Yangle = Math.atan2(deltaZ, deltaX) * (180 / Math.PI) + 90f; double dX = (Math.sin(Yangle)) * 0.25; double dZ = (Math.cos(Yangle)) * 0.25; if(deltaZ < 0) { deltaZ *= -1; } double Xangle = Math.atan(deltaY / deltaZ) * (180 / Math.PI); double dY = (Math.sin(Xangle)) * 0.25; float hLength = (float)Math.sqrt((deltaX * deltaX) + (deltaZ * deltaZ)); float length = (float)Math.sqrt((hLength * hLength) + (deltaY * deltaY)); float tCrease = 0.25f / length; for (float t = 0; t <= 1; t += tCrease) { double x = player.position().x + (entity.position().x - player.position().x) * t; double y = (player.position().y + 1f) + (entity.position().y - (player.position().y + 1)) * t; double z = player.position().z + (entity.position().z - player.position().z) * t; } if(entity.blockCollidingOnce) { startPoint = player.position(); endPoint = new Vec3(entity.position().x, entity.position().y + 2.5, entity.position().z); startTime = System.currentTimeMillis(); entity.blockCollidingOnce = false; } if(entity.blockColliding) { double dx = endPoint.x - player.position().x; double dy = endPoint.y - player.position().y; double dz = endPoint.z - player.position().z; double distanceToTarget = Math.sqrt(dx * dx + dy * dy + dz * dz); if (distanceToTarget > 0.5) { dx /= distanceToTarget; dy /= distanceToTarget; dz /= distanceToTarget; player.setDeltaMovement(dx * 1, dy * 1 , dz * 1); } else { entity.blockColliding = false; entity.kill(); leashArea = new AABB(leashHolder.position().x + 2, leashHolder.position().y + 2, leashHolder.position().z + 2, leashHolder.position().x - 2, leashHolder.position().y - 2, leashHolder.position().z - 2); leashHolder.remove(RemovalReason.DISCARDED); killLead(p_41405_); } } if(entity.entityCollidingOnce) { startPoint = player.position(); endPoint = new Vec3(entity.position().x, entity.position().y + 2.5, entity.position().z); startTime = System.currentTimeMillis(); entity.entityCollidingOnce = false; } if(entity.entityColliding) { leashHolder.setPos(entity.hitEntity.position()); leashHolder.addEffect(new MobEffectInstance(MobEffects.INVISIBILITY, 10, 10, false, false)); double dx = player.position().x - entity.hitEntity.position().x; double dy = player.position().y - entity.hitEntity.position().y; double dz = player.position().z - entity.hitEntity.position().z; double distanceToTarget = Math.sqrt(dx * dx + dy * dy + dz * dz); if (distanceToTarget > 0.5) { dx /= distanceToTarget; dy /= distanceToTarget; dz /= distanceToTarget; entity.hitEntity.setDeltaMovement(dx * 1, dy * 1 , dz * 1); } else { entity.entityColliding = false; entity.kill(); leashArea = new AABB(leashHolder.position().x + 2, leashHolder.position().y + 2, leashHolder.position().z + 2, leashHolder.position().x - 2, leashHolder.position().y - 2, leashHolder.position().z - 2); leashHolder.remove(RemovalReason.DISCARDED); killLead(p_41405_); } } } super.inventoryTick(p_41404_, p_41405_, player, p_41407_, p_41408_); } private boolean isPlayerCollidingWithBlock(Entity player) { AABB playerBoundingBox = player.getBoundingBox(); int playerX = (int) player.getX(); int playerY = (int) player.getX(); int playerZ = (int) player.getZ(); for (int x = playerX - 1; x <= playerX + 1; x++) { for (int y = playerY - 1; y <= playerY + 1; y++) { for (int z = playerZ - 1; z <= playerZ + 1; z++) { if (player.level().getBlockState(new BlockPos(x, y, z)).getCollisionShape(player.level(), new BlockPos(x, y, z)).isEmpty()) { continue; } if (playerBoundingBox.intersects(new AABB(x, y, z, x + 1, y + 1, z + 1))) { return true; } } } } return false; // Player is not colliding with any block. } private void sendPacketToAllPlayers(ClientboundLevelParticlesPacket packet, Player sourcePlayer) { if(sourcePlayer.getServer() != null) { for (ServerPlayer player : sourcePlayer.getServer().getPlayerList().getPlayers()) { player.connection.send(packet); } } } public void killLead(Level level) { if(leashArea != null) { List<ItemEntity> list = level.getEntitiesOfClass(ItemEntity.class, leashArea); for(ItemEntity item : list) { if(item.getItem().getItem() == Items.SHIELD); { item.kill(); } } } } }
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.