mirror of
https://github.com/barkeser2002/CatServer.git
synced 2026-09-25 08:00:02 +03:00
280 lines
18 KiB
Diff
280 lines
18 KiB
Diff
--- ../src-base/minecraft/net/minecraft/world/WorldEntitySpawner.java
|
|
+++ ../src-work/minecraft/net/minecraft/world/WorldEntitySpawner.java
|
|
@@ -1,9 +1,9 @@
|
|
package net.minecraft.world;
|
|
|
|
import com.google.common.collect.Sets;
|
|
-import java.util.List;
|
|
-import java.util.Random;
|
|
-import java.util.Set;
|
|
+
|
|
+import java.util.*;
|
|
+
|
|
import net.minecraft.block.Block;
|
|
import net.minecraft.block.BlockRailBase;
|
|
import net.minecraft.block.state.IBlockState;
|
|
@@ -20,12 +20,35 @@
|
|
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.craftbukkit.util.LongHash;
|
|
+import org.bukkit.craftbukkit.util.LongHashSet;
|
|
|
|
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();
|
|
+ //private final LongHashSet longHashChunksForSpawning = new LongHashSet(1024);
|
|
|
|
+ // 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.chunkXPos;
|
|
+ int z = coord.chunkZPos;
|
|
+ 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)
|
|
@@ -44,21 +67,26 @@
|
|
int j = MathHelper.floor_double(entityplayer.posX / 16.0D);
|
|
int k = MathHelper.floor_double(entityplayer.posZ / 16.0D);
|
|
int l = 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 = -8; i1 <= 8; ++i1)
|
|
+ for (int i1 = -b0; i1 <= b0; ++i1)
|
|
{
|
|
- for (int j1 = -8; j1 <= 8; ++j1)
|
|
+ for (int j1 = -b0; j1 <= b0; ++j1)
|
|
{
|
|
- boolean flag = i1 == -8 || i1 == 8 || j1 == -8 || j1 == 8;
|
|
+ boolean flag = i1 == -b0 || i1 == b0 || j1 == -b0 || j1 == b0;
|
|
ChunkPos chunkpos = new ChunkPos(i1 + j, j1 + k);
|
|
+ //final long chunkCoords = LongHash.toLong(i1 + j, j1 + k);
|
|
|
|
if (!this.eligibleChunksForSpawning.contains(chunkpos))
|
|
{
|
|
++i;
|
|
|
|
- if (!flag && worldServerIn.getWorldBorder().contains(chunkpos))
|
|
+ if (!flag && worldServerIn.getWorldBorder().isInBounds(i1+j, j1+k))
|
|
{
|
|
- PlayerChunkMapEntry playerchunkmapentry = worldServerIn.getPlayerChunkMap().getEntry(chunkpos.chunkXPos, chunkpos.chunkZPos);
|
|
+ PlayerChunkMapEntry playerchunkmapentry = worldServerIn.getPlayerChunkMap().getEntry(i1 + j, j1 + k);
|
|
|
|
if (playerchunkmapentry != null && playerchunkmapentry.isSentToPlayers())
|
|
{
|
|
@@ -70,106 +98,126 @@
|
|
}
|
|
}
|
|
}
|
|
-
|
|
int j4 = 0;
|
|
BlockPos blockpos1 = worldServerIn.getSpawnPoint();
|
|
|
|
for (EnumCreatureType enumcreaturetype : EnumCreatureType.values())
|
|
{
|
|
- if ((!enumcreaturetype.getPeacefulCreature() || spawnPeacefulMobs) && (enumcreaturetype.getPeacefulCreature() || spawnHostileMobs) && (!enumcreaturetype.getAnimal() || spawnOnSetTickRate))
|
|
- {
|
|
- int k4 = worldServerIn.countEntities(enumcreaturetype, true);
|
|
- int l4 = enumcreaturetype.getMaxNumberOfCreature() * i / MOB_COUNT_DIV;
|
|
-
|
|
- if (k4 <= l4)
|
|
+ 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) {
|
|
+ int mobcnt = 0;
|
|
+ if ((!enumcreaturetype.getPeacefulCreature() || spawnPeacefulMobs) && (enumcreaturetype.getPeacefulCreature() || spawnHostileMobs) && (!enumcreaturetype.getAnimal() || spawnOnSetTickRate))
|
|
{
|
|
- java.util.ArrayList<ChunkPos> shuffled = com.google.common.collect.Lists.newArrayList(this.eligibleChunksForSpawning);
|
|
- java.util.Collections.shuffle(shuffled);
|
|
- BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos();
|
|
- label411:
|
|
+ int k4 = worldServerIn.countEntities(enumcreaturetype, true);
|
|
+ int l4 = limit * i / MOB_COUNT_DIV;
|
|
|
|
- for (ChunkPos chunkpos1 : shuffled)
|
|
+ if (( mobcnt = getEntityCount(worldServerIn,enumcreaturetype.getCreatureClass())) <= limit * i/256)
|
|
{
|
|
- BlockPos blockpos = getRandomChunkPosition(worldServerIn, chunkpos1.chunkXPos, chunkpos1.chunkZPos);
|
|
- int k1 = blockpos.getX();
|
|
- int l1 = blockpos.getY();
|
|
- int i2 = blockpos.getZ();
|
|
- IBlockState iblockstate = worldServerIn.getBlockState(blockpos);
|
|
-
|
|
- if (!iblockstate.isNormalCube())
|
|
+ Iterator<ChunkPos> iterator = this.eligibleChunksForSpawning.iterator();
|
|
+ BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos();
|
|
+ int moblimit = limit * i / 256 - mobcnt + 1; // Spigot - up to 1 more than limit
|
|
+ label411:
|
|
+ while(iterator.hasNext() && (moblimit >0))
|
|
{
|
|
- int j2 = 0;
|
|
+ ChunkPos key = iterator.next();
|
|
+ //BlockPos blockpos = getRandomChunkPosition(worldServerIn, LongHash.msw(key), LongHash.lsw(key)); //TODO
|
|
+ BlockPos blockpos = getRandomChunkPosition(worldServerIn, key.chunkXPos, key.chunkZPos);
|
|
+ int k1 = blockpos.getX();
|
|
+ int l1 = blockpos.getY();
|
|
+ int i2 = blockpos.getZ();
|
|
+ IBlockState iblockstate = worldServerIn.getBlockState(blockpos);
|
|
|
|
- for (int k2 = 0; k2 < 3; ++k2)
|
|
+ if (!iblockstate.isNormalCube())
|
|
{
|
|
- int l2 = k1;
|
|
- int i3 = l1;
|
|
- int j3 = i2;
|
|
- int k3 = 6;
|
|
- Biome.SpawnListEntry biome$spawnlistentry = null;
|
|
- IEntityLivingData ientitylivingdata = null;
|
|
- int l3 = MathHelper.ceiling_double_int(Math.random() * 4.0D);
|
|
+ int j2 = 0;
|
|
|
|
- for (int i4 = 0; i4 < l3; ++i4)
|
|
+ for (int k2 = 0; k2 < 3; ++k2)
|
|
{
|
|
- l2 += worldServerIn.rand.nextInt(6) - worldServerIn.rand.nextInt(6);
|
|
- i3 += worldServerIn.rand.nextInt(1) - worldServerIn.rand.nextInt(1);
|
|
- j3 += worldServerIn.rand.nextInt(6) - worldServerIn.rand.nextInt(6);
|
|
- blockpos$mutableblockpos.setPos(l2, i3, j3);
|
|
- float f = (float)l2 + 0.5F;
|
|
- float f1 = (float)j3 + 0.5F;
|
|
+ int l2 = k1;
|
|
+ int i3 = l1;
|
|
+ int j3 = i2;
|
|
+ int k3 = 6;
|
|
+ Biome.SpawnListEntry biome$spawnlistentry = null;
|
|
+ IEntityLivingData ientitylivingdata = null;
|
|
+ int l3 = MathHelper.ceiling_double_int(Math.random() * 4.0D);
|
|
|
|
- if (!worldServerIn.isAnyPlayerWithinRangeAt((double)f, (double)i3, (double)f1, 24.0D) && blockpos1.distanceSq((double)f, (double)i3, (double)f1) >= 576.0D)
|
|
+ for (int i4 = 0; i4 < l3; ++i4)
|
|
{
|
|
- if (biome$spawnlistentry == null)
|
|
- {
|
|
- biome$spawnlistentry = worldServerIn.getSpawnListEntryForTypeAt(enumcreaturetype, blockpos$mutableblockpos);
|
|
+ l2 += worldServerIn.rand.nextInt(6) - worldServerIn.rand.nextInt(6);
|
|
+ i3 += worldServerIn.rand.nextInt(1) - worldServerIn.rand.nextInt(1);
|
|
+ j3 += worldServerIn.rand.nextInt(6) - worldServerIn.rand.nextInt(6);
|
|
+ blockpos$mutableblockpos.setPos(l2, i3, j3);
|
|
+ float f = (float)l2 + 0.5F;
|
|
+ float f1 = (float)j3 + 0.5F;
|
|
|
|
+ if (!worldServerIn.isAnyPlayerWithinRangeAt((double)f, (double)i3, (double)f1, 24.0D) && blockpos1.distanceSq((double)f, (double)i3, (double)f1) >= 576.0D)
|
|
+ {
|
|
if (biome$spawnlistentry == null)
|
|
{
|
|
- break;
|
|
- }
|
|
- }
|
|
+ biome$spawnlistentry = worldServerIn.getSpawnListEntryForTypeAt(enumcreaturetype, blockpos$mutableblockpos);
|
|
|
|
- if (worldServerIn.canCreatureTypeSpawnHere(enumcreaturetype, biome$spawnlistentry, blockpos$mutableblockpos) && canCreatureTypeSpawnAtLocation(EntitySpawnPlacementRegistry.getPlacementForEntity(biome$spawnlistentry.entityClass), worldServerIn, blockpos$mutableblockpos))
|
|
- {
|
|
- EntityLiving entityliving;
|
|
-
|
|
- try
|
|
- {
|
|
- entityliving = (EntityLiving)biome$spawnlistentry.newInstance(worldServerIn);
|
|
+ if (biome$spawnlistentry == null)
|
|
+ {
|
|
+ break;
|
|
+ }
|
|
}
|
|
- catch (Exception exception)
|
|
- {
|
|
- exception.printStackTrace();
|
|
- return j4;
|
|
- }
|
|
|
|
- entityliving.setLocationAndAngles((double)f, (double)i3, (double)f1, worldServerIn.rand.nextFloat() * 360.0F, 0.0F);
|
|
-
|
|
- net.minecraftforge.fml.common.eventhandler.Event.Result canSpawn = net.minecraftforge.event.ForgeEventFactory.canEntitySpawn(entityliving, worldServerIn, f, i3, f1);
|
|
- if (canSpawn == net.minecraftforge.fml.common.eventhandler.Event.Result.ALLOW || (canSpawn == net.minecraftforge.fml.common.eventhandler.Event.Result.DEFAULT && (entityliving.getCanSpawnHere() && entityliving.isNotColliding())))
|
|
+ if (worldServerIn.canCreatureTypeSpawnHere(enumcreaturetype, biome$spawnlistentry, blockpos$mutableblockpos) && canCreatureTypeSpawnAtLocation(EntitySpawnPlacementRegistry.getPlacementForEntity(biome$spawnlistentry.entityClass), worldServerIn, blockpos$mutableblockpos))
|
|
{
|
|
- if (!net.minecraftforge.event.ForgeEventFactory.doSpecialSpawn(entityliving, worldServerIn, f, i3, f1))
|
|
- ientitylivingdata = entityliving.onInitialSpawn(worldServerIn.getDifficultyForLocation(new BlockPos(entityliving)), ientitylivingdata);
|
|
+ EntityLiving entityliving;
|
|
|
|
- if (entityliving.isNotColliding())
|
|
+ try
|
|
{
|
|
- ++j2;
|
|
- worldServerIn.spawnEntityInWorld(entityliving);
|
|
+ entityliving = (EntityLiving)biome$spawnlistentry.newInstance(worldServerIn);
|
|
}
|
|
- else
|
|
+ catch (Exception exception)
|
|
{
|
|
- entityliving.setDead();
|
|
+ exception.printStackTrace();
|
|
+ return j4;
|
|
}
|
|
|
|
- if (j2 >= net.minecraftforge.event.ForgeEventFactory.getMaxSpawnPackSize(entityliving))
|
|
+ entityliving.setLocationAndAngles((double)f, (double)i3, (double)f1, worldServerIn.rand.nextFloat() * 360.0F, 0.0F);
|
|
+
|
|
+ net.minecraftforge.fml.common.eventhandler.Event.Result canSpawn = net.minecraftforge.event.ForgeEventFactory.canEntitySpawn(entityliving, worldServerIn, f, i3, f1);
|
|
+ if (canSpawn == net.minecraftforge.fml.common.eventhandler.Event.Result.ALLOW || (canSpawn == net.minecraftforge.fml.common.eventhandler.Event.Result.DEFAULT && (entityliving.getCanSpawnHere() && entityliving.isNotColliding())))
|
|
{
|
|
- continue label411;
|
|
+ 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.spawnEntityInWorld(entityliving);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ entityliving.setDead();
|
|
+ }
|
|
+ if( --moblimit <= 0){
|
|
+ if (j2 >= net.minecraftforge.event.ForgeEventFactory.getMaxSpawnPackSize(entityliving))
|
|
+ {
|
|
+ continue label411;
|
|
+ }
|
|
+ }
|
|
+
|
|
}
|
|
- }
|
|
|
|
- j4 += j2;
|
|
+ j4 += j2;
|
|
+ }
|
|
}
|
|
}
|
|
}
|