diff --git a/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch index cc68813c83..afd444004c 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch @@ -61,7 +61,7 @@ +// CraftBukkit end public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess, ScoreHolder { -+ + + // CraftBukkit start + private static final int CURRENT_LEVEL = 2; + static boolean isLevelAtLeast(CompoundTag tag, int level) { @@ -143,7 +143,7 @@ + public org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason; // Paper - Entity#getEntitySpawnReason + + private CraftEntity bukkitEntity; - ++ + public CraftEntity getBukkitEntity() { + if (this.bukkitEntity == null) { + this.bukkitEntity = CraftEntity.getEntity(this.level.getCraftServer(), this); @@ -169,7 +169,7 @@ private static final EntityDataAccessor DATA_TICKS_FROZEN = SynchedEntityData.defineId(Entity.class, EntityDataSerializers.INT); private EntityInLevelCallback levelCallback; private final VecDeltaCodec packetPositionCodec; -@@ -253,7 +385,64 @@ +@@ -253,7 +385,65 @@ private final List movementThisTick; private final Set blocksInside; private final LongSet visitedBlocks; @@ -195,13 +195,14 @@ + public void inactiveTick() { } + // Spigot end + protected int numCollisions = 0; // Paper - Cap entity collisions ++ public boolean fromNetherPortal; // Paper - Add option to nerf pigmen from nether portals + public boolean spawnedViaMobSpawner; // Paper - Yes this name is similar to above, upstream took the better one + // Paper start - Entity origin API + @javax.annotation.Nullable + private org.bukkit.util.Vector origin; + @javax.annotation.Nullable + private UUID originWorld; -+ + + public void setOrigin(@javax.annotation.Nonnull Location location) { + this.origin = location.toVector(); + this.originWorld = location.getWorld().getUID(); @@ -220,7 +221,7 @@ + public float getBukkitYaw() { + return this.yRot; + } - ++ + public boolean isChunkLoaded() { + return this.level.hasChunk((int) Math.floor(this.getX()) >> 4, (int) Math.floor(this.getZ()) >> 4); + } @@ -234,7 +235,7 @@ public Entity(EntityType type, Level world) { this.id = Entity.ENTITY_COUNTER.incrementAndGet(); this.passengers = ImmutableList.of(); -@@ -261,7 +450,7 @@ +@@ -261,7 +451,7 @@ this.bb = Entity.INITIAL_AABB; this.stuckSpeedMultiplier = Vec3.ZERO; this.nextStep = 1.0F; @@ -243,7 +244,7 @@ this.remainingFireTicks = -this.getFireImmuneTicks(); this.fluidHeight = new Object2DoubleArrayMap(2); this.fluidOnEyes = new HashSet(); -@@ -284,6 +473,13 @@ +@@ -284,6 +474,13 @@ this.position = Vec3.ZERO; this.blockPosition = BlockPos.ZERO; this.chunkPosition = ChunkPos.ZERO; @@ -257,7 +258,7 @@ SynchedEntityData.Builder datawatcher_a = new SynchedEntityData.Builder(this); datawatcher_a.define(Entity.DATA_SHARED_FLAGS_ID, (byte) 0); -@@ -292,7 +488,7 @@ +@@ -292,7 +489,7 @@ datawatcher_a.define(Entity.DATA_CUSTOM_NAME, Optional.empty()); datawatcher_a.define(Entity.DATA_SILENT, false); datawatcher_a.define(Entity.DATA_NO_GRAVITY, false); @@ -266,7 +267,7 @@ datawatcher_a.define(Entity.DATA_TICKS_FROZEN, 0); this.defineSynchedData(datawatcher_a); this.entityData = datawatcher_a.build(); -@@ -362,20 +558,36 @@ +@@ -362,20 +559,36 @@ } public void kill(ServerLevel world) { @@ -305,7 +306,7 @@ public boolean equals(Object object) { return object instanceof Entity ? ((Entity) object).id == this.id : false; } -@@ -385,22 +597,34 @@ +@@ -385,22 +598,34 @@ } public void remove(Entity.RemovalReason reason) { @@ -345,7 +346,7 @@ return this.getPose() == pose; } -@@ -417,6 +641,33 @@ +@@ -417,6 +642,33 @@ } public void setRot(float yaw, float pitch) { @@ -379,7 +380,7 @@ this.setYRot(yaw % 360.0F); this.setXRot(pitch % 360.0F); } -@@ -462,6 +713,15 @@ +@@ -462,6 +714,15 @@ this.baseTick(); } @@ -395,7 +396,7 @@ public void baseTick() { ProfilerFiller gameprofilerfiller = Profiler.get(); -@@ -475,7 +735,7 @@ +@@ -475,7 +736,7 @@ --this.boardingCooldown; } @@ -404,7 +405,7 @@ if (this.canSpawnSprintParticle()) { this.spawnSprintParticle(); } -@@ -514,6 +774,10 @@ +@@ -514,6 +775,10 @@ if (this.isInLava()) { this.lavaHurt(); this.fallDistance *= 0.5F; @@ -415,7 +416,7 @@ } this.checkBelowWorld(); -@@ -525,7 +789,7 @@ +@@ -525,7 +790,7 @@ world = this.level(); if (world instanceof ServerLevel worldserver) { if (this instanceof Leashable) { @@ -424,7 +425,7 @@ } } -@@ -537,7 +801,11 @@ +@@ -537,7 +802,11 @@ } public void checkBelowWorld() { @@ -437,7 +438,7 @@ this.onBelowWorld(); } -@@ -568,15 +836,32 @@ +@@ -568,15 +837,32 @@ public void lavaHurt() { if (!this.fireImmune()) { @@ -472,15 +473,15 @@ } } -@@ -587,9 +872,25 @@ +@@ -587,7 +873,23 @@ } public final void igniteForSeconds(float seconds) { - this.igniteForTicks(Mth.floor(seconds * 20.0F)); + // CraftBukkit start + this.igniteForSeconds(seconds, true); - } - ++ } ++ + public final void igniteForSeconds(float f, boolean callEvent) { + if (callEvent) { + EntityCombustEvent event = new EntityCombustEvent(this.getBukkitEntity(), f); @@ -494,12 +495,10 @@ + } + // CraftBukkit end + this.igniteForTicks(Mth.floor(f * 20.0F)); -+ } -+ + } + public void igniteForTicks(int ticks) { - if (this.remainingFireTicks < ticks) { - this.setRemainingFireTicks(ticks); -@@ -610,7 +911,7 @@ +@@ -610,7 +912,7 @@ } protected void onBelowWorld() { @@ -508,7 +507,7 @@ } public boolean isFree(double offsetX, double offsetY, double offsetZ) { -@@ -750,6 +1051,28 @@ +@@ -750,6 +1052,28 @@ } } @@ -537,7 +536,7 @@ if (!this.level().isClientSide() || this.isControlledByLocalInstance()) { Entity.MovementEmission entity_movementemission = this.getMovementEmission(); -@@ -1133,6 +1456,20 @@ +@@ -1133,6 +1457,20 @@ return SoundEvents.GENERIC_SPLASH; } @@ -558,7 +557,7 @@ public void recordMovementThroughBlocks(Vec3 oldPos, Vec3 newPos) { this.movementThisTick.add(new Entity.Movement(oldPos, newPos)); } -@@ -1609,6 +1946,7 @@ +@@ -1609,6 +1947,7 @@ this.yo = y; this.zo = d4; this.setPos(d3, y, d4); @@ -566,7 +565,7 @@ } public void moveTo(Vec3 pos) { -@@ -1737,7 +2075,21 @@ +@@ -1737,7 +2076,21 @@ } public void push(double deltaX, double deltaY, double deltaZ) { @@ -589,7 +588,7 @@ this.hasImpulse = true; } -@@ -1861,6 +2213,12 @@ +@@ -1861,6 +2214,12 @@ return false; } @@ -602,7 +601,7 @@ public void awardKillScore(Entity entityKilled, DamageSource damageSource) { if (entityKilled instanceof ServerPlayer) { CriteriaTriggers.ENTITY_KILLED_PLAYER.trigger((ServerPlayer) entityKilled, this, damageSource); -@@ -1889,16 +2247,22 @@ +@@ -1889,16 +2248,22 @@ } public boolean saveAsPassenger(CompoundTag nbt) { @@ -628,22 +627,21 @@ return true; } } -@@ -1909,54 +2273,98 @@ +@@ -1909,54 +2274,98 @@ } public CompoundTag saveWithoutId(CompoundTag nbt) { -- try { -- if (this.vehicle != null) { -- nbt.put("Pos", this.newDoubleList(this.vehicle.getX(), this.getY(), this.vehicle.getZ())); -- } else { -- nbt.put("Pos", this.newDoubleList(this.getX(), this.getY(), this.getZ())); + // CraftBukkit start - allow excluding certain data when saving + return this.saveWithoutId(nbt, true); + } + + public CompoundTag saveWithoutId(CompoundTag nbttagcompound, boolean includeAll) { + // CraftBukkit end -+ try { + try { +- if (this.vehicle != null) { +- nbt.put("Pos", this.newDoubleList(this.vehicle.getX(), this.getY(), this.vehicle.getZ())); +- } else { +- nbt.put("Pos", this.newDoubleList(this.getX(), this.getY(), this.getZ())); + // CraftBukkit start - selectively save position + if (includeAll) { + if (this.vehicle != null) { @@ -748,7 +746,7 @@ } ListTag nbttaglist; -@@ -1972,10 +2380,10 @@ +@@ -1972,10 +2381,10 @@ nbttaglist.add(StringTag.valueOf(s)); } @@ -761,7 +759,7 @@ if (this.isVehicle()) { nbttaglist = new ListTag(); iterator = this.getPassengers().iterator(); -@@ -1984,17 +2392,38 @@ +@@ -1984,17 +2393,41 @@ Entity entity = (Entity) iterator.next(); CompoundTag nbttagcompound1 = new CompoundTag(); @@ -798,16 +796,18 @@ + if (spawnedViaMobSpawner) { + nbttagcompound.putBoolean("Paper.FromMobSpawner", true); + } ++ if (fromNetherPortal) { ++ nbttagcompound.putBoolean("Paper.FromNetherPortal", true); ++ } + // Paper end + return nbttagcompound; } catch (Throwable throwable) { CrashReport crashreport = CrashReport.forThrowable(throwable, "Saving entity NBT"); CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Entity being saved"); -@@ -2079,7 +2508,87 @@ - } +@@ -2080,6 +2513,87 @@ } else { throw new IllegalStateException("Entity has invalid position"); -+ } + } + + // CraftBukkit start + // Spigot start @@ -866,6 +866,7 @@ + } + + spawnedViaMobSpawner = nbt.getBoolean("Paper.FromMobSpawner"); // Restore entity's from mob spawner status ++ fromNetherPortal = nbt.getBoolean("Paper.FromNetherPortal"); + if (nbt.contains("Paper.SpawnReason")) { + String spawnReasonName = nbt.getString("Paper.SpawnReason"); + try { @@ -882,7 +883,7 @@ + spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL; + } + } - } ++ } + if (spawnReason == null) { + spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT; + } @@ -891,7 +892,7 @@ } catch (Throwable throwable) { CrashReport crashreport = CrashReport.forThrowable(throwable, "Loading entity NBT"); CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Entity being loaded"); -@@ -2101,6 +2610,12 @@ +@@ -2101,6 +2615,12 @@ return entitytypes.canSerialize() && minecraftkey != null ? minecraftkey.toString() : null; } @@ -904,7 +905,7 @@ protected abstract void readAdditionalSaveData(CompoundTag nbt); protected abstract void addAdditionalSaveData(CompoundTag nbt); -@@ -2153,9 +2668,22 @@ +@@ -2153,9 +2673,22 @@ if (stack.isEmpty()) { return null; } else { @@ -927,7 +928,7 @@ world.addFreshEntity(entityitem); return entityitem; } -@@ -2184,6 +2712,12 @@ +@@ -2184,6 +2717,12 @@ if (this.isAlive() && this instanceof Leashable leashable) { if (leashable.getLeashHolder() == player) { if (!this.level().isClientSide()) { @@ -940,7 +941,7 @@ if (player.hasInfiniteMaterials()) { leashable.removeLeash(); } else { -@@ -2200,6 +2734,13 @@ +@@ -2200,6 +2739,13 @@ if (itemstack.is(Items.LEAD) && leashable.canHaveALeashAttachedToIt()) { if (!this.level().isClientSide()) { @@ -954,7 +955,7 @@ leashable.setLeashedTo(player, true); } -@@ -2265,7 +2806,7 @@ +@@ -2265,7 +2811,7 @@ } public boolean showVehicleHealth() { @@ -963,7 +964,7 @@ } public boolean startRiding(Entity entity, boolean force) { -@@ -2273,7 +2814,7 @@ +@@ -2273,7 +2819,7 @@ return false; } else if (!entity.couldAcceptPassenger()) { return false; @@ -972,7 +973,7 @@ return false; } else { for (Entity entity1 = entity; entity1.vehicle != null; entity1 = entity1.vehicle) { -@@ -2285,11 +2826,32 @@ +@@ -2285,11 +2831,32 @@ if (!force && (!this.canRide(entity) || !entity.canAddPassenger(this))) { return false; } else { @@ -1006,7 +1007,7 @@ this.vehicle = entity; this.vehicle.addPassenger(this); entity.getIndirectPassengersStream().filter((entity2) -> { -@@ -2314,19 +2876,30 @@ +@@ -2314,19 +2881,30 @@ } public void removeVehicle() { @@ -1039,7 +1040,7 @@ protected void addPassenger(Entity passenger) { if (passenger.getVehicle() != this) { throw new IllegalStateException("Use x.startRiding(y), not y.addPassenger(x)"); -@@ -2349,21 +2922,53 @@ +@@ -2349,21 +2927,53 @@ } } @@ -1099,7 +1100,7 @@ } protected boolean canAddPassenger(Entity passenger) { -@@ -2464,7 +3069,7 @@ +@@ -2464,7 +3074,7 @@ if (teleporttransition != null) { ServerLevel worldserver1 = teleporttransition.newLevel(); @@ -1108,7 +1109,7 @@ this.teleport(teleporttransition); } } -@@ -2547,7 +3152,7 @@ +@@ -2547,7 +3157,7 @@ } public boolean isCrouching() { @@ -1117,7 +1118,7 @@ } public boolean isSprinting() { -@@ -2563,7 +3168,7 @@ +@@ -2563,7 +3173,7 @@ } public boolean isVisuallySwimming() { @@ -1126,7 +1127,7 @@ } public boolean isVisuallyCrawling() { -@@ -2571,6 +3176,13 @@ +@@ -2571,6 +3181,13 @@ } public void setSwimming(boolean swimming) { @@ -1140,7 +1141,7 @@ this.setSharedFlag(4, swimming); } -@@ -2609,6 +3221,7 @@ +@@ -2609,6 +3226,7 @@ @Nullable public PlayerTeam getTeam() { @@ -1148,7 +1149,7 @@ return this.level().getScoreboard().getPlayersTeam(this.getScoreboardName()); } -@@ -2624,8 +3237,12 @@ +@@ -2624,8 +3242,12 @@ return this.getTeam() != null ? this.getTeam().isAlliedTo(team) : false; } @@ -1162,7 +1163,7 @@ } public boolean getSharedFlag(int index) { -@@ -2644,7 +3261,7 @@ +@@ -2644,7 +3266,7 @@ } public int getMaxAirSupply() { @@ -1171,7 +1172,7 @@ } public int getAirSupply() { -@@ -2652,7 +3269,18 @@ +@@ -2652,7 +3274,18 @@ } public void setAirSupply(int air) { @@ -1191,7 +1192,7 @@ } public int getTicksFrozen() { -@@ -2679,11 +3307,40 @@ +@@ -2679,11 +3312,40 @@ public void thunderHit(ServerLevel world, LightningBolt lightning) { this.setRemainingFireTicks(this.remainingFireTicks + 1); @@ -1234,7 +1235,7 @@ } public void onAboveBubbleCol(boolean drag) { -@@ -2713,7 +3370,7 @@ +@@ -2713,7 +3375,7 @@ this.resetFallDistance(); } @@ -1243,7 +1244,7 @@ return true; } -@@ -2818,7 +3475,7 @@ +@@ -2818,7 +3480,7 @@ public String toString() { String s = this.level() == null ? "~NULL~" : this.level().toString(); @@ -1252,7 +1253,7 @@ } public final boolean isInvulnerableToBase(DamageSource damageSource) { -@@ -2852,6 +3509,26 @@ +@@ -2852,6 +3514,26 @@ if (world instanceof ServerLevel worldserver) { if (!this.isRemoved()) { @@ -1279,7 +1280,7 @@ ServerLevel worldserver1 = teleportTarget.newLevel(); boolean flag = worldserver1.dimension() != worldserver.dimension(); -@@ -2920,8 +3597,12 @@ +@@ -2920,8 +3602,12 @@ } else { entity.restoreFrom(this); this.removeAfterChangingDimensions(); @@ -1293,7 +1294,7 @@ Iterator iterator1 = list1.iterator(); while (iterator1.hasNext()) { -@@ -2947,7 +3628,7 @@ +@@ -2947,7 +3633,7 @@ } private void sendTeleportTransitionToRidingPlayers(TeleportTransition teleportTarget) { @@ -1302,7 +1303,7 @@ Iterator iterator = this.getIndirectPassengers().iterator(); while (iterator.hasNext()) { -@@ -2995,8 +3676,9 @@ +@@ -2995,8 +3681,9 @@ } protected void removeAfterChangingDimensions() { @@ -1313,12 +1314,10 @@ leashable.removeLeash(); } -@@ -3004,7 +3686,21 @@ - - public Vec3 getRelativePortalPosition(Direction.Axis portalAxis, BlockUtil.FoundRectangle portalRect) { +@@ -3006,6 +3693,20 @@ return PortalShape.getRelativePosition(portalRect, portalAxis, this.position(), this.getDimensions(this.getPose())); -+ } -+ + } + + // CraftBukkit start + public CraftPortalEvent callPortalEvent(Entity entity, Location exit, PlayerTeleportEvent.TeleportCause cause, int searchRadius, int creationRadius) { + org.bukkit.entity.Entity bukkitEntity = entity.getBukkitEntity(); @@ -1330,12 +1329,13 @@ + return null; + } + return new CraftPortalEvent(event); - } ++ } + // CraftBukkit end - ++ public boolean canUsePortal(boolean allowVehicles) { return (allowVehicles || !this.isPassenger()) && this.isAlive(); -@@ -3134,10 +3830,16 @@ + } +@@ -3134,10 +3835,16 @@ return (Boolean) this.entityData.get(Entity.DATA_CUSTOM_NAME_VISIBLE); } @@ -1355,7 +1355,7 @@ return entity != null; } -@@ -3187,7 +3889,7 @@ +@@ -3187,7 +3894,7 @@ /** @deprecated */ @Deprecated protected void fixupDimensions() { @@ -1364,7 +1364,7 @@ EntityDimensions entitysize = this.getDimensions(entitypose); this.dimensions = entitysize; -@@ -3196,7 +3898,7 @@ +@@ -3196,7 +3903,7 @@ public void refreshDimensions() { EntityDimensions entitysize = this.dimensions; @@ -1373,7 +1373,7 @@ EntityDimensions entitysize1 = this.getDimensions(entitypose); this.dimensions = entitysize1; -@@ -3258,10 +3960,29 @@ +@@ -3258,10 +3965,29 @@ } public final void setBoundingBox(AABB boundingBox) { @@ -1405,7 +1405,7 @@ return this.getDimensions(pose).eyeHeight(); } -@@ -3335,7 +4056,7 @@ +@@ -3335,7 +4061,7 @@ } @Nullable @@ -1414,7 +1414,7 @@ return null; } -@@ -3435,7 +4156,7 @@ +@@ -3435,7 +4161,7 @@ } public boolean isControlledByLocalInstance() { @@ -1423,7 +1423,7 @@ if (entityliving instanceof Player entityhuman) { return entityhuman.isLocalPlayer(); -@@ -3445,7 +4166,7 @@ +@@ -3445,7 +4171,7 @@ } public boolean isControlledByClient() { @@ -1432,7 +1432,7 @@ return entityliving != null && entityliving.isControlledByClient(); } -@@ -3463,7 +4184,7 @@ +@@ -3463,7 +4189,7 @@ return new Vec3((double) f1 * d2 / (double) f3, 0.0D, (double) f2 * d2 / (double) f3); } @@ -1441,7 +1441,7 @@ return new Vec3(this.getX(), this.getBoundingBox().maxY, this.getZ()); } -@@ -3488,9 +4209,38 @@ +@@ -3488,9 +4214,38 @@ public int getFireImmuneTicks() { return 1; } @@ -1481,7 +1481,7 @@ } public void lookAt(EntityAnchorArgument.Anchor anchorPoint, Vec3 target) { -@@ -3551,6 +4301,11 @@ +@@ -3551,6 +4306,11 @@ vec3d = vec3d.add(vec3d1); ++k1; } @@ -1493,7 +1493,7 @@ } } } -@@ -3613,7 +4368,7 @@ +@@ -3613,7 +4373,7 @@ return new ClientboundAddEntityPacket(this, entityTrackerEntry); } @@ -1502,7 +1502,7 @@ return this.type.getDimensions(); } -@@ -3818,8 +4573,16 @@ +@@ -3818,8 +4578,16 @@ @Override public final void setRemoved(Entity.RemovalReason reason) { @@ -1520,7 +1520,7 @@ } if (this.removalReason.shouldDestroy()) { -@@ -3827,8 +4590,8 @@ +@@ -3827,8 +4595,8 @@ } this.getPassengers().forEach(Entity::stopRiding); @@ -1531,7 +1531,7 @@ } public void unsetRemoved() { -@@ -3887,7 +4650,7 @@ +@@ -3887,7 +4655,7 @@ } public Vec3 getKnownMovement() { diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/NetherPortalBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/NetherPortalBlock.java.patch index f99dd80b03..ead3c90aa1 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/NetherPortalBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/NetherPortalBlock.java.patch @@ -20,7 +20,7 @@ public class NetherPortalBlock extends Block implements Portal { -@@ -71,13 +78,14 @@ +@@ -71,16 +78,21 @@ @Override protected void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { @@ -37,7 +37,14 @@ if (entity != null) { entity.setPortalCooldown(); -@@ -104,6 +112,10 @@ ++ // Paper start - Add option to nerf pigmen from nether portals ++ entity.fromNetherPortal = true; ++ if (world.paperConfig().entities.behavior.nerfPigmenFromNetherPortals) ((net.minecraft.world.entity.Mob) entity).aware = false; ++ // Paper end - Add option to nerf pigmen from nether portals + Entity entity1 = entity.getVehicle(); + + if (entity1 != null) { +@@ -104,6 +116,10 @@ @Override protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { if (entity.canUsePortal(false)) { @@ -48,7 +55,7 @@ entity.setAsInsidePortal(this, pos); } -@@ -121,51 +133,72 @@ +@@ -121,51 +137,72 @@ @Nullable @Override public TeleportTransition getPortalDestination(ServerLevel world, Entity entity, BlockPos pos) { @@ -134,7 +141,7 @@ } private static TeleportTransition getDimensionTransitionFromExit(Entity entity, BlockPos pos, BlockUtil.FoundRectangle exitPortalRectangle, ServerLevel world, TeleportTransition.PostTeleportTransition postDimensionTransition) { -@@ -203,7 +236,7 @@ +@@ -203,7 +240,7 @@ Vec3 vec3d1 = new Vec3((double) blockposition.getX() + (flag ? d2 : d4), (double) blockposition.getY() + d3, (double) blockposition.getZ() + (flag ? d4 : d2)); Vec3 vec3d2 = PortalShape.findCollisionFreePosition(vec3d1, world, entity, entitysize);