mirror of
https://github.com/barkeser2002/CatServer.git
synced 2026-09-25 01:39:52 +03:00
206 lines
11 KiB
Diff
206 lines
11 KiB
Diff
--- ../src-base/minecraft/net/minecraft/world/WorldEntitySpawner.java
|
|
+++ ../src-work/minecraft/net/minecraft/world/WorldEntitySpawner.java
|
|
@@ -1,7 +1,10 @@
|
|
package net.minecraft.world;
|
|
|
|
import com.google.common.collect.Sets;
|
|
+
|
|
+import java.util.Iterator;
|
|
import java.util.List;
|
|
+import java.util.Objects;
|
|
import java.util.Random;
|
|
import java.util.Set;
|
|
import net.minecraft.block.Block;
|
|
@@ -21,12 +24,34 @@
|
|
import net.minecraft.util.math.MathHelper;
|
|
import net.minecraft.world.biome.Biome;
|
|
import net.minecraft.world.chunk.Chunk;
|
|
+import net.minecraft.world.gen.ChunkProviderServer;
|
|
|
|
+import org.bukkit.event.entity.CreatureSpawnEvent;
|
|
+
|
|
public final class WorldEntitySpawner
|
|
{
|
|
private static final int MOB_COUNT_DIV = (int)Math.pow(17.0D, 2.0D);
|
|
private final Set<ChunkPos> eligibleChunksForSpawning = Sets.<ChunkPos>newHashSet();
|
|
|
|
+ // Spigot start - get entity count only from chunks being processed in b
|
|
+ private int getEntityCount(WorldServer server, Class oClass)
|
|
+ {
|
|
+ int i = 0;
|
|
+ Iterator<ChunkPos> it = this.eligibleChunksForSpawning.iterator();
|
|
+ while ( it.hasNext() )
|
|
+ {
|
|
+ ChunkPos coord = it.next();
|
|
+ int x = coord.x;
|
|
+ int z = coord.z;
|
|
+ if ( !((ChunkProviderServer)server.chunkProvider).droppedChunksSet.contains( coord ) && server.isChunkLoaded( x, z, true ) )
|
|
+ {
|
|
+ i += Objects.requireNonNull(server.getChunkProvider().getLoadedChunk(x, z)).entityCount.get( oClass );
|
|
+ }
|
|
+ }
|
|
+ return i;
|
|
+ }
|
|
+ // Spigot end
|
|
+
|
|
public int findChunksForSpawning(WorldServer worldServerIn, boolean spawnHostileMobs, boolean spawnPeacefulMobs, boolean spawnOnSetTickRate)
|
|
{
|
|
if (!spawnHostileMobs && !spawnPeacefulMobs)
|
|
@@ -46,11 +71,15 @@
|
|
int k = MathHelper.floor(entityplayer.posZ / 16.0D);
|
|
int l = 8;
|
|
|
|
- for (int i1 = -8; i1 <= 8; ++i1)
|
|
- {
|
|
- for (int j1 = -8; j1 <= 8; ++j1)
|
|
- {
|
|
- boolean flag = i1 == -8 || i1 == 8 || j1 == -8 || j1 == 8;
|
|
+ // Spigot Start
|
|
+ byte b0 = worldServerIn.spigotConfig.mobSpawnRange;
|
|
+ b0 = ( b0 > worldServerIn.spigotConfig.viewDistance ) ? (byte) worldServerIn.spigotConfig.viewDistance : b0;
|
|
+ b0 = ( b0 > 8 ) ? 8 : b0;
|
|
+
|
|
+ for (int i1 = -b0; i1 <= b0; ++i1) {
|
|
+ for (int j1 = -b0; j1 <= b0; ++j1) {
|
|
+ boolean flag = i1 == -b0 || i1 == b0 || j1 == -b0 || j1 == b0;
|
|
+ // Spigot End
|
|
ChunkPos chunkpos = new ChunkPos(i1 + j, j1 + k);
|
|
|
|
if (!this.eligibleChunksForSpawning.contains(chunkpos))
|
|
@@ -77,18 +106,43 @@
|
|
|
|
for (EnumCreatureType enumcreaturetype : EnumCreatureType.values())
|
|
{
|
|
+ // CraftBukkit start - Use per-world spawn limits
|
|
+ int limit = enumcreaturetype.getMaxNumberOfCreature();
|
|
+ switch (enumcreaturetype) {
|
|
+ case MONSTER:
|
|
+ limit = worldServerIn.getWorld().getMonsterSpawnLimit();
|
|
+ break;
|
|
+ case CREATURE:
|
|
+ limit = worldServerIn.getWorld().getAnimalSpawnLimit();
|
|
+ break;
|
|
+ case WATER_CREATURE:
|
|
+ limit = worldServerIn.getWorld().getWaterAnimalSpawnLimit();
|
|
+ break;
|
|
+ case AMBIENT:
|
|
+ limit = worldServerIn.getWorld().getAmbientSpawnLimit();
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ if (limit == 0) {
|
|
+ continue;
|
|
+ }
|
|
+ int mobcnt = 0; // Spigot
|
|
+ // CraftBukkit end
|
|
if ((!enumcreaturetype.getPeacefulCreature() || spawnPeacefulMobs) && (enumcreaturetype.getPeacefulCreature() || spawnHostileMobs) && (!enumcreaturetype.getAnimal() || spawnOnSetTickRate))
|
|
{
|
|
int k4 = worldServerIn.countEntities(enumcreaturetype.getCreatureClass());
|
|
- int l4 = enumcreaturetype.getMaxNumberOfCreature() * i / MOB_COUNT_DIV;
|
|
+ int l4 = limit * i / MOB_COUNT_DIV; // CraftBukkit - use per-world limits
|
|
|
|
- if (k4 <= l4)
|
|
+ if ((mobcnt = getEntityCount(worldServerIn, enumcreaturetype.getCreatureClass())) <= limit * i / 256)
|
|
{
|
|
BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos();
|
|
+ Iterator<ChunkPos> iterator = this.eligibleChunksForSpawning.iterator();
|
|
+ int moblimit = (limit * i / 256) - mobcnt + 1; // Spigot - up to 1 more than limit
|
|
label134:
|
|
|
|
- for (ChunkPos chunkpos1 : this.eligibleChunksForSpawning)
|
|
+ while(iterator.hasNext() && (moblimit >0)) // Spigot - while more allowed
|
|
{
|
|
+ ChunkPos chunkpos1 = iterator.next();
|
|
BlockPos blockpos = getRandomChunkPosition(worldServerIn, chunkpos1.x, chunkpos1.z);
|
|
int k1 = blockpos.getX();
|
|
int l1 = blockpos.getY();
|
|
@@ -136,7 +190,7 @@
|
|
|
|
try
|
|
{
|
|
- entityliving = biome$spawnlistentry.entityClass.getConstructor(World.class).newInstance(worldServerIn);
|
|
+ entityliving = biome$spawnlistentry.newInstance(worldServerIn);
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
@@ -146,21 +200,25 @@
|
|
|
|
entityliving.setLocationAndAngles((double)f, (double)i3, (double)f1, worldServerIn.rand.nextFloat() * 360.0F, 0.0F);
|
|
|
|
- if (entityliving.getCanSpawnHere() && entityliving.isNotColliding())
|
|
+ net.minecraftforge.fml.common.eventhandler.Event.Result canSpawn = net.minecraftforge.event.ForgeEventFactory.canEntitySpawn(entityliving, worldServerIn, f, i3, f1, false);
|
|
+ if (canSpawn == net.minecraftforge.fml.common.eventhandler.Event.Result.ALLOW || (canSpawn == net.minecraftforge.fml.common.eventhandler.Event.Result.DEFAULT && (entityliving.getCanSpawnHere() && entityliving.isNotColliding())))
|
|
{
|
|
+ if (!net.minecraftforge.event.ForgeEventFactory.doSpecialSpawn(entityliving, worldServerIn, f, i3, f1))
|
|
ientitylivingdata = entityliving.onInitialSpawn(worldServerIn.getDifficultyForLocation(new BlockPos(entityliving)), ientitylivingdata);
|
|
|
|
if (entityliving.isNotColliding())
|
|
{
|
|
- ++j2;
|
|
- worldServerIn.spawnEntity(entityliving);
|
|
+ if (worldServerIn.addEntity(entityliving, CreatureSpawnEvent.SpawnReason.NATURAL)) {
|
|
+ ++j2;
|
|
+ moblimit--; // Spigot
|
|
+ }
|
|
}
|
|
else
|
|
{
|
|
entityliving.setDead();
|
|
}
|
|
|
|
- if (j2 >= entityliving.getMaxSpawnedInChunk())
|
|
+ if (moblimit <= 0 || j2 >= net.minecraftforge.event.ForgeEventFactory.getMaxSpawnPackSize(entityliving)) // If we're past limit, stop spawn
|
|
{
|
|
continue label134;
|
|
}
|
|
@@ -219,6 +277,14 @@
|
|
}
|
|
else
|
|
{
|
|
+ return spawnPlacementTypeIn.canSpawnAt(worldIn, pos);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public static boolean canCreatureTypeSpawnBody(EntityLiving.SpawnPlacementType spawnPlacementTypeIn, World worldIn, BlockPos pos)
|
|
+ {
|
|
+ {
|
|
+
|
|
IBlockState iblockstate = worldIn.getBlockState(pos);
|
|
|
|
if (spawnPlacementTypeIn == EntityLiving.SpawnPlacementType.IN_WATER)
|
|
@@ -228,8 +294,9 @@
|
|
else
|
|
{
|
|
BlockPos blockpos = pos.down();
|
|
+ IBlockState state = worldIn.getBlockState(blockpos);
|
|
|
|
- if (!worldIn.getBlockState(blockpos).isTopSolid())
|
|
+ if (!state.getBlock().canCreatureSpawn(state, worldIn, blockpos, spawnPlacementTypeIn))
|
|
{
|
|
return false;
|
|
}
|
|
@@ -273,7 +340,7 @@
|
|
|
|
try
|
|
{
|
|
- entityliving = biome$spawnlistentry.entityClass.getConstructor(World.class).newInstance(worldIn);
|
|
+ entityliving = biome$spawnlistentry.newInstance(worldIn);
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
@@ -281,9 +348,13 @@
|
|
continue;
|
|
}
|
|
|
|
+ if (net.minecraftforge.event.ForgeEventFactory.canEntitySpawn(entityliving, worldIn, j + 0.5f, (float) blockpos.getY(), k +0.5f, false) == net.minecraftforge.fml.common.eventhandler.Event.Result.DENY) continue;
|
|
entityliving.setLocationAndAngles((double)((float)j + 0.5F), (double)blockpos.getY(), (double)((float)k + 0.5F), randomIn.nextFloat() * 360.0F, 0.0F);
|
|
- worldIn.spawnEntity(entityliving);
|
|
+ // CraftBukkit start - Added a reason for spawning this creature, moved entityliving.onInitialSpawn(ientitylivingdata) up
|
|
+ // worldIn.spawnEntity(entityliving);
|
|
ientitylivingdata = entityliving.onInitialSpawn(worldIn.getDifficultyForLocation(new BlockPos(entityliving)), ientitylivingdata);
|
|
+ worldIn.addEntity(entityliving, CreatureSpawnEvent.SpawnReason.CHUNK_GEN);
|
|
+ // CraftBukkit end
|
|
flag = true;
|
|
}
|
|
|