--- a/net/minecraft/world/spawner/WorldEntitySpawner.java
+++ b/net/minecraft/world/spawner/WorldEntitySpawner.java
@@ -83,7 +83,7 @@
          }
 
          final Entity entity_f = entity;
-         EntityClassification entityclassification = entity.func_200600_R().func_220339_d();
+         EntityClassification entityclassification = entity.getClassification(true);
          if (entityclassification != EntityClassification.MISC) {
             BlockPos blockpos = entity.func_233580_cy_();
             long i = ChunkPos.func_77272_a(blockpos.func_177958_n() >> 4, blockpos.func_177952_p() >> 4);
@@ -171,13 +171,15 @@
                         }
 
                         mobentity.func_70012_b(d0, (double)i, d1, p_234966_1_.field_73012_v.nextFloat() * 360.0F, 0.0F);
-                        if (func_234974_a_(p_234966_1_, mobentity, d2)) {
+                        int canSpawn = net.minecraftforge.common.ForgeHooks.canEntitySpawn(mobentity, p_234966_1_, d0, i, d1, null, SpawnReason.NATURAL);
+                        if (canSpawn != -1 && (canSpawn == 1 || func_234974_a_(p_234966_1_, mobentity, d2))) {
+                           if (!net.minecraftforge.event.ForgeEventFactory.doSpecialSpawn(mobentity, p_234966_1_, (float)d0, (float)i, (float)d1, null, SpawnReason.NATURAL))
                            ilivingentitydata = mobentity.func_213386_a(p_234966_1_, p_234966_1_.func_175649_E(mobentity.func_233580_cy_()), SpawnReason.NATURAL, ilivingentitydata, (CompoundNBT)null);
                            ++j;
                            ++l1;
                            p_234966_1_.func_217376_c(mobentity);
                            p_234966_5_.run(mobentity, p_234966_2_);
-                           if (j >= mobentity.func_70641_bl()) {
+                           if (j >= net.minecraftforge.event.ForgeEventFactory.getMaxSpawnPackSize(mobentity)) {
                               return;
                            }
 
@@ -255,6 +257,7 @@
          return null;
       } else {
          List<Biome.SpawnListEntry> list = func_241463_a_(p_234977_0_, p_234977_1_, p_234977_2_, p_234977_3_, p_234977_5_, biome);
+         list = net.minecraftforge.event.ForgeEventFactory.getPotentialSpawns(p_234977_0_, p_234977_3_, p_234977_5_, list);
          return list.isEmpty() ? null : WeightedRandom.func_76271_a(p_234977_4_, list);
       }
    }
@@ -294,6 +297,13 @@
       if (p_209382_0_ == EntitySpawnPlacementRegistry.PlacementType.NO_RESTRICTIONS) {
          return true;
       } else if (p_209382_3_ != null && p_209382_1_.func_175723_af().func_177746_a(p_209382_2_)) {
+         return p_209382_0_.canSpawnAt(p_209382_1_, p_209382_2_, p_209382_3_);
+      }
+      return false;
+   }
+
+   public static boolean canSpawnAtBody(EntitySpawnPlacementRegistry.PlacementType p_209382_0_, IWorldReader p_209382_1_, BlockPos p_209382_2_, @Nullable EntityType<?> p_209382_3_) {
+      {
          BlockState blockstate = p_209382_1_.func_180495_p(p_209382_2_);
          FluidState fluidstate = p_209382_1_.func_204610_c(p_209382_2_);
          BlockPos blockpos = p_209382_2_.func_177984_a();
@@ -306,14 +316,12 @@
          case ON_GROUND:
          default:
             BlockState blockstate1 = p_209382_1_.func_180495_p(blockpos1);
-            if (!blockstate1.func_215688_a(p_209382_1_, blockpos1, p_209382_3_)) {
+            if (!blockstate1.canCreatureSpawn(p_209382_1_, blockpos1, p_209382_0_, p_209382_3_)) {
                return false;
             } else {
                return func_234968_a_(p_209382_1_, p_209382_2_, blockstate, fluidstate, p_209382_3_) && func_234968_a_(p_209382_1_, blockpos, p_209382_1_.func_180495_p(blockpos), p_209382_1_.func_204610_c(blockpos), p_209382_3_);
             }
          }
-      } else {
-         return false;
       }
    }
 
@@ -356,6 +364,7 @@
                      entity.func_70012_b(d0, (double)blockpos.func_177956_o(), d1, p_77191_4_.nextFloat() * 360.0F, 0.0F);
                      if (entity instanceof MobEntity) {
                         MobEntity mobentity = (MobEntity)entity;
+                        if (net.minecraftforge.common.ForgeHooks.canEntitySpawn(mobentity, p_77191_0_, d0, blockpos.func_177956_o(), d1, null, SpawnReason.CHUNK_GENERATION) == -1) continue;
                         if (mobentity.func_213380_a(p_77191_0_, SpawnReason.CHUNK_GENERATION) && mobentity.func_205019_a(p_77191_0_)) {
                            ilivingentitydata = mobentity.func_213386_a(p_77191_0_, p_77191_0_.func_175649_E(mobentity.func_233580_cy_()), SpawnReason.CHUNK_GENERATION, ilivingentitydata, (CompoundNBT)null);
                            p_77191_0_.func_217376_c(mobentity);
