--- a/net/minecraft/world/level/block/NetherPortalBlock.java
+++ b/net/minecraft/world/level/block/NetherPortalBlock.java
@@ -26,8 +26,12 @@
 import net.minecraft.world.level.portal.PortalShape;
 import net.minecraft.world.phys.shapes.CollisionContext;
 import net.minecraft.world.phys.shapes.VoxelShape;
+// CraftBukkit start
+import org.bukkit.event.entity.EntityPortalEnterEvent;
+// CraftBukkit end
 
 public class NetherPortalBlock extends Block {
+
     public static final EnumProperty<Direction.Axis> AXIS = BlockStateProperties.HORIZONTAL_AXIS;
     protected static final int AABB_OFFSET = 2;
     protected static final VoxelShape X_AXIS_AABB = Block.box(0.0D, 0.0D, 6.0D, 16.0D, 16.0D, 10.0D);
@@ -35,31 +39,35 @@
 
     public NetherPortalBlock(BlockBehaviour.Properties settings) {
         super(settings);
-        this.registerDefaultState(this.stateDefinition.any().setValue(AXIS, Direction.Axis.X));
+        this.registerDefaultState((BlockState) ((BlockState) this.stateDefinition.any()).setValue(NetherPortalBlock.AXIS, Direction.Axis.X));
     }
 
     @Override
     public VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) {
-        switch ((Direction.Axis)state.getValue(AXIS)) {
+        switch ((Direction.Axis) state.getValue(NetherPortalBlock.AXIS)) {
             case Z:
-                return Z_AXIS_AABB;
+                return NetherPortalBlock.Z_AXIS_AABB;
             case X:
             default:
-                return X_AXIS_AABB;
+                return NetherPortalBlock.X_AXIS_AABB;
         }
     }
 
     @Override
     public void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) {
-        if (world.dimensionType().natural() && world.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && random.nextInt(2000) < world.getDifficulty().getId()) {
-            while(world.getBlockState(pos).is(this)) {
+        if (world.spigotConfig.enableZombiePigmenPortalSpawns && world.dimensionType().natural() && world.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && random.nextInt(2000) < world.getDifficulty().getId()) { // Spigot
+            while (world.getBlockState(pos).is((Block) this)) {
                 pos = pos.below();
             }
 
             if (world.getBlockState(pos).isValidSpawn(world, pos, EntityType.ZOMBIFIED_PIGLIN)) {
-                Entity entity = EntityType.ZOMBIFIED_PIGLIN.spawn(world, (CompoundTag)null, (Component)null, (Player)null, pos.above(), MobSpawnType.STRUCTURE, false, false);
+                // CraftBukkit - set spawn reason to NETHER_PORTAL
+                Entity entity = EntityType.ZOMBIFIED_PIGLIN.spawn(world, (CompoundTag) null, (Component) null, (Player) null, pos.above(), MobSpawnType.STRUCTURE, false, false, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NETHER_PORTAL);
+
                 if (entity != null) {
                     entity.setPortalCooldown();
+                    entity.fromNetherPortal = true; // Paper
+                    if (world.paperConfig().entities.behavior.nerfPigmenFromNetherPortals) ((net.minecraft.world.entity.Mob) entity).aware = false; // Paper
                 }
             }
         }
@@ -68,15 +76,21 @@
 
     @Override
     public BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) {
-        Direction.Axis axis = direction.getAxis();
-        Direction.Axis axis2 = state.getValue(AXIS);
-        boolean bl = axis2 != axis && axis.isHorizontal();
-        return !bl && !neighborState.is(this) && !(new PortalShape(world, pos, axis2)).isComplete() ? Blocks.AIR.defaultBlockState() : super.updateShape(state, direction, neighborState, world, pos, neighborPos);
+        Direction.Axis enumdirection_enumaxis = direction.getAxis();
+        Direction.Axis enumdirection_enumaxis1 = (Direction.Axis) state.getValue(NetherPortalBlock.AXIS);
+        boolean flag = enumdirection_enumaxis1 != enumdirection_enumaxis && enumdirection_enumaxis.isHorizontal();
+
+        return !flag && !neighborState.is((Block) this) && !(new PortalShape(world, pos, enumdirection_enumaxis1)).isComplete() ? Blocks.AIR.defaultBlockState() : super.updateShape(state, direction, neighborState, world, pos, neighborPos);
     }
 
     @Override
     public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
+        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.v1_19_R1.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
         if (!entity.isPassenger() && !entity.isVehicle() && entity.canChangeDimensions()) {
+            // CraftBukkit start - Entity in portal
+            EntityPortalEnterEvent event = new EntityPortalEnterEvent(entity.getBukkitEntity(), new org.bukkit.Location(world.getWorld(), pos.getX(), pos.getY(), pos.getZ()));
+            world.getCraftServer().getPluginManager().callEvent(event);
+            // CraftBukkit end
             entity.handleInsidePortal(pos);
         }
 
@@ -85,26 +99,27 @@
     @Override
     public void animateTick(BlockState state, Level world, BlockPos pos, RandomSource random) {
         if (random.nextInt(100) == 0) {
-            world.playLocalSound((double)pos.getX() + 0.5D, (double)pos.getY() + 0.5D, (double)pos.getZ() + 0.5D, SoundEvents.PORTAL_AMBIENT, SoundSource.BLOCKS, 0.5F, random.nextFloat() * 0.4F + 0.8F, false);
+            world.playLocalSound((double) pos.getX() + 0.5D, (double) pos.getY() + 0.5D, (double) pos.getZ() + 0.5D, SoundEvents.PORTAL_AMBIENT, SoundSource.BLOCKS, 0.5F, random.nextFloat() * 0.4F + 0.8F, false);
         }
 
-        for(int i = 0; i < 4; ++i) {
-            double d = (double)pos.getX() + random.nextDouble();
-            double e = (double)pos.getY() + random.nextDouble();
-            double f = (double)pos.getZ() + random.nextDouble();
-            double g = ((double)random.nextFloat() - 0.5D) * 0.5D;
-            double h = ((double)random.nextFloat() - 0.5D) * 0.5D;
-            double j = ((double)random.nextFloat() - 0.5D) * 0.5D;
-            int k = random.nextInt(2) * 2 - 1;
-            if (!world.getBlockState(pos.west()).is(this) && !world.getBlockState(pos.east()).is(this)) {
-                d = (double)pos.getX() + 0.5D + 0.25D * (double)k;
-                g = (double)(random.nextFloat() * 2.0F * (float)k);
+        for (int i = 0; i < 4; ++i) {
+            double d0 = (double) pos.getX() + random.nextDouble();
+            double d1 = (double) pos.getY() + random.nextDouble();
+            double d2 = (double) pos.getZ() + random.nextDouble();
+            double d3 = ((double) random.nextFloat() - 0.5D) * 0.5D;
+            double d4 = ((double) random.nextFloat() - 0.5D) * 0.5D;
+            double d5 = ((double) random.nextFloat() - 0.5D) * 0.5D;
+            int j = random.nextInt(2) * 2 - 1;
+
+            if (!world.getBlockState(pos.west()).is((Block) this) && !world.getBlockState(pos.east()).is((Block) this)) {
+                d0 = (double) pos.getX() + 0.5D + 0.25D * (double) j;
+                d3 = (double) (random.nextFloat() * 2.0F * (float) j);
             } else {
-                f = (double)pos.getZ() + 0.5D + 0.25D * (double)k;
-                j = (double)(random.nextFloat() * 2.0F * (float)k);
+                d2 = (double) pos.getZ() + 0.5D + 0.25D * (double) j;
+                d5 = (double) (random.nextFloat() * 2.0F * (float) j);
             }
 
-            world.addParticle(ParticleTypes.PORTAL, d, e, f, g, h, j);
+            world.addParticle(ParticleTypes.PORTAL, d0, d1, d2, d3, d4, d5);
         }
 
     }
@@ -119,11 +134,11 @@
         switch (rotation) {
             case COUNTERCLOCKWISE_90:
             case CLOCKWISE_90:
-                switch ((Direction.Axis)state.getValue(AXIS)) {
+                switch ((Direction.Axis) state.getValue(NetherPortalBlock.AXIS)) {
                     case Z:
-                        return state.setValue(AXIS, Direction.Axis.X);
+                        return (BlockState) state.setValue(NetherPortalBlock.AXIS, Direction.Axis.X);
                     case X:
-                        return state.setValue(AXIS, Direction.Axis.Z);
+                        return (BlockState) state.setValue(NetherPortalBlock.AXIS, Direction.Axis.Z);
                     default:
                         return state;
                 }
@@ -134,6 +149,6 @@
 
     @Override
     protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
-        builder.add(AXIS);
+        builder.add(NetherPortalBlock.AXIS);
     }
 }
