2010-12-29 00:52:29 +01:00
|
|
|
package net.minecraft.server;
|
|
|
|
|
2011-01-29 22:50:29 +01:00
|
|
|
import java.util.ArrayList;
|
2012-07-29 09:33:13 +02:00
|
|
|
import java.util.Collection;
|
|
|
|
import java.util.HashSet;
|
|
|
|
import java.util.Iterator;
|
2011-01-29 22:50:29 +01:00
|
|
|
import java.util.List;
|
2012-07-29 09:33:13 +02:00
|
|
|
import java.util.Random;
|
|
|
|
import java.util.Set;
|
|
|
|
import java.util.TreeSet;
|
2011-01-01 09:12:39 +01:00
|
|
|
|
2011-01-11 09:25:13 +01:00
|
|
|
// CraftBukkit start
|
2012-12-20 22:51:27 +01:00
|
|
|
import org.bukkit.WeatherType;
|
2012-07-29 09:33:13 +02:00
|
|
|
import org.bukkit.block.BlockState;
|
|
|
|
import org.bukkit.craftbukkit.util.LongHash;
|
|
|
|
|
|
|
|
import org.bukkit.event.block.BlockFormEvent;
|
2011-04-26 01:47:25 +02:00
|
|
|
import org.bukkit.event.weather.LightningStrikeEvent;
|
2012-07-29 09:33:13 +02:00
|
|
|
import org.bukkit.event.weather.ThunderChangeEvent;
|
|
|
|
import org.bukkit.event.weather.WeatherChangeEvent;
|
2010-12-29 00:52:29 +01:00
|
|
|
|
2012-07-22 08:18:00 +02:00
|
|
|
public class WorldServer extends World implements org.bukkit.BlockChangeDelegate {
|
2011-06-12 00:02:58 +02:00
|
|
|
// CraftBukkit end
|
2010-12-29 00:52:29 +01:00
|
|
|
|
2012-07-29 09:33:13 +02:00
|
|
|
private final MinecraftServer server;
|
|
|
|
public EntityTracker tracker; // CraftBukkit - private final -> public
|
2012-12-20 05:03:52 +01:00
|
|
|
private final PlayerChunkMap manager;
|
|
|
|
private Set L;
|
|
|
|
private TreeSet M;
|
2011-04-20 19:05:14 +02:00
|
|
|
public ChunkProviderServer chunkProviderServer;
|
2011-09-24 23:03:31 +02:00
|
|
|
public boolean savingDisabled;
|
2012-12-20 05:03:52 +01:00
|
|
|
private boolean N;
|
2012-08-25 02:51:51 +02:00
|
|
|
private int emptyTime = 0;
|
2012-12-20 05:03:52 +01:00
|
|
|
private final PortalTravelAgent P;
|
|
|
|
private NoteDataList[] Q = new NoteDataList[] { new NoteDataList((EmptyClass2) null), new NoteDataList((EmptyClass2) null)};
|
|
|
|
private int R = 0;
|
|
|
|
private static final StructurePieceTreasure[] S = new StructurePieceTreasure[] { new StructurePieceTreasure(Item.STICK.id, 0, 1, 3, 10), new StructurePieceTreasure(Block.WOOD.id, 0, 1, 3, 10), new StructurePieceTreasure(Block.LOG.id, 0, 1, 3, 10), new StructurePieceTreasure(Item.STONE_AXE.id, 0, 1, 1, 3), new StructurePieceTreasure(Item.WOOD_AXE.id, 0, 1, 1, 5), new StructurePieceTreasure(Item.STONE_PICKAXE.id, 0, 1, 1, 3), new StructurePieceTreasure(Item.WOOD_PICKAXE.id, 0, 1, 1, 5), new StructurePieceTreasure(Item.APPLE.id, 0, 2, 3, 5), new StructurePieceTreasure(Item.BREAD.id, 0, 2, 3, 3)};
|
2013-03-13 23:33:27 +01:00
|
|
|
private ArrayList T = new ArrayList();
|
2012-01-14 21:03:48 +01:00
|
|
|
private IntHashMap entitiesById;
|
2010-12-29 00:52:29 +01:00
|
|
|
|
2012-07-29 09:33:13 +02:00
|
|
|
// CraftBukkit start
|
|
|
|
public final int dimension;
|
|
|
|
|
2013-03-13 23:33:27 +01:00
|
|
|
public WorldServer(MinecraftServer minecraftserver, IDataManager idatamanager, String s, int i, WorldSettings worldsettings, MethodProfiler methodprofiler, IConsoleLogManager iconsolelogmanager, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) {
|
|
|
|
super(idatamanager, s, worldsettings, WorldProvider.byDimension(env.getId()), methodprofiler, iconsolelogmanager, gen, env);
|
2012-07-29 09:33:13 +02:00
|
|
|
this.dimension = i;
|
|
|
|
this.pvpMode = minecraftserver.getPvP();
|
|
|
|
// CraftBukkit end
|
2011-04-20 19:05:14 +02:00
|
|
|
this.server = minecraftserver;
|
2012-07-29 09:33:13 +02:00
|
|
|
this.tracker = new EntityTracker(this);
|
2012-12-20 05:03:52 +01:00
|
|
|
this.manager = new PlayerChunkMap(this, minecraftserver.getPlayerList().o());
|
2012-01-14 21:03:48 +01:00
|
|
|
if (this.entitiesById == null) {
|
|
|
|
this.entitiesById = new IntHashMap();
|
2011-12-01 22:43:54 +01:00
|
|
|
}
|
2011-01-29 22:50:29 +01:00
|
|
|
|
2012-12-20 05:03:52 +01:00
|
|
|
if (this.L == null) {
|
|
|
|
this.L = new HashSet();
|
2012-07-29 09:33:13 +02:00
|
|
|
}
|
|
|
|
|
2012-12-20 05:03:52 +01:00
|
|
|
if (this.M == null) {
|
|
|
|
this.M = new TreeSet();
|
2012-07-29 09:33:13 +02:00
|
|
|
}
|
2012-11-06 13:05:28 +01:00
|
|
|
|
2012-12-22 19:46:24 +01:00
|
|
|
this.P = new org.bukkit.craftbukkit.CraftTravelAgent(this); // CraftBukkit
|
2013-03-13 23:33:27 +01:00
|
|
|
this.scoreboard = new ScoreboardServer(minecraftserver);
|
|
|
|
ScoreboardSaveData scoreboardsavedata = (ScoreboardSaveData) this.worldMaps.get(ScoreboardSaveData.class, "scoreboard");
|
|
|
|
|
|
|
|
if (scoreboardsavedata == null) {
|
|
|
|
scoreboardsavedata = new ScoreboardSaveData();
|
|
|
|
this.worldMaps.a("scoreboard", scoreboardsavedata);
|
|
|
|
}
|
|
|
|
|
|
|
|
scoreboardsavedata.a(this.scoreboard);
|
|
|
|
((ScoreboardServer) this.scoreboard).a(scoreboardsavedata);
|
2011-01-29 22:50:29 +01:00
|
|
|
}
|
|
|
|
|
2012-07-29 09:33:13 +02:00
|
|
|
// CraftBukkit start
|
2011-10-02 05:25:21 +02:00
|
|
|
@Override
|
|
|
|
public TileEntity getTileEntity(int i, int j, int k) {
|
|
|
|
TileEntity result = super.getTileEntity(i, j, k);
|
|
|
|
int type = getTypeId(i, j, k);
|
|
|
|
|
|
|
|
if (type == Block.CHEST.id) {
|
|
|
|
if (!(result instanceof TileEntityChest)) {
|
|
|
|
result = fixTileEntity(i, j, k, type, result);
|
|
|
|
}
|
|
|
|
} else if (type == Block.FURNACE.id) {
|
|
|
|
if (!(result instanceof TileEntityFurnace)) {
|
|
|
|
result = fixTileEntity(i, j, k, type, result);
|
|
|
|
}
|
2013-04-01 02:38:25 +02:00
|
|
|
} else if (type == Block.DROPPER.id) {
|
|
|
|
if (!(result instanceof TileEntityDropper)) {
|
|
|
|
result = fixTileEntity(i, j, k, type, result);
|
|
|
|
}
|
2011-10-02 05:25:21 +02:00
|
|
|
} else if (type == Block.DISPENSER.id) {
|
|
|
|
if (!(result instanceof TileEntityDispenser)) {
|
|
|
|
result = fixTileEntity(i, j, k, type, result);
|
|
|
|
}
|
|
|
|
} else if (type == Block.JUKEBOX.id) {
|
|
|
|
if (!(result instanceof TileEntityRecordPlayer)) {
|
|
|
|
result = fixTileEntity(i, j, k, type, result);
|
|
|
|
}
|
|
|
|
} else if (type == Block.NOTE_BLOCK.id) {
|
|
|
|
if (!(result instanceof TileEntityNote)) {
|
|
|
|
result = fixTileEntity(i, j, k, type, result);
|
|
|
|
}
|
|
|
|
} else if (type == Block.MOB_SPAWNER.id) {
|
|
|
|
if (!(result instanceof TileEntityMobSpawner)) {
|
|
|
|
result = fixTileEntity(i, j, k, type, result);
|
|
|
|
}
|
|
|
|
} else if ((type == Block.SIGN_POST.id) || (type == Block.WALL_SIGN.id)) {
|
|
|
|
if (!(result instanceof TileEntitySign)) {
|
|
|
|
result = fixTileEntity(i, j, k, type, result);
|
|
|
|
}
|
2012-07-29 09:33:13 +02:00
|
|
|
} else if (type == Block.ENDER_CHEST.id) {
|
|
|
|
if (!(result instanceof TileEntityEnderChest)) {
|
|
|
|
result = fixTileEntity(i, j, k, type, result);
|
|
|
|
}
|
2013-04-01 02:38:25 +02:00
|
|
|
} else if (type == Block.BREWING_STAND.id) {
|
|
|
|
if (!(result instanceof TileEntityBrewingStand)) {
|
|
|
|
result = fixTileEntity(i, j, k, type, result);
|
|
|
|
}
|
|
|
|
} else if (type == Block.BEACON.id) {
|
|
|
|
if (!(result instanceof TileEntityBeacon)) {
|
|
|
|
result = fixTileEntity(i, j, k, type, result);
|
|
|
|
}
|
|
|
|
} else if (type == Block.HOPPER.id) {
|
|
|
|
if (!(result instanceof TileEntityHopper)) {
|
|
|
|
result = fixTileEntity(i, j, k, type, result);
|
|
|
|
}
|
2011-10-02 05:25:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
private TileEntity fixTileEntity(int x, int y, int z, int type, TileEntity found) {
|
2013-03-13 23:33:27 +01:00
|
|
|
this.getServer().getLogger().severe("Block at " + x + "," + y + "," + z + " is " + org.bukkit.Material.getMaterial(type).toString() + " but has " + found + ". "
|
2011-10-02 05:25:21 +02:00
|
|
|
+ "Bukkit will attempt to fix this, but there may be additional damage that we cannot recover.");
|
|
|
|
|
|
|
|
if (Block.byId[type] instanceof BlockContainer) {
|
2013-03-13 23:33:27 +01:00
|
|
|
TileEntity replacement = ((BlockContainer) Block.byId[type]).b(this);
|
2013-04-01 07:06:09 +02:00
|
|
|
replacement.world = this;
|
2013-03-13 23:33:27 +01:00
|
|
|
this.setTileEntity(x, y, z, replacement);
|
2011-10-02 05:25:21 +02:00
|
|
|
return replacement;
|
|
|
|
} else {
|
2013-03-13 23:33:27 +01:00
|
|
|
this.getServer().getLogger().severe("Don't know how to fix for this type... Can't do anything! :(");
|
2011-10-02 05:25:21 +02:00
|
|
|
return found;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-07-29 09:33:13 +02:00
|
|
|
private boolean canSpawn(int x, int z) {
|
|
|
|
if (this.generator != null) {
|
|
|
|
return this.generator.canSpawn(this.getWorld(), x, z);
|
|
|
|
} else {
|
|
|
|
return this.worldProvider.canSpawn(x, z);
|
|
|
|
}
|
|
|
|
}
|
2011-01-29 22:50:29 +01:00
|
|
|
// CraftBukkit end
|
|
|
|
|
2012-07-29 09:33:13 +02:00
|
|
|
public void doTick() {
|
|
|
|
super.doTick();
|
|
|
|
if (this.getWorldData().isHardcore() && this.difficulty < 3) {
|
|
|
|
this.difficulty = 3;
|
|
|
|
}
|
|
|
|
|
2012-10-25 05:53:23 +02:00
|
|
|
this.worldProvider.d.b();
|
2012-07-29 09:33:13 +02:00
|
|
|
if (this.everyoneDeeplySleeping()) {
|
|
|
|
boolean flag = false;
|
|
|
|
|
|
|
|
if (this.allowMonsters && this.difficulty >= 1) {
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!flag) {
|
2012-11-06 13:05:28 +01:00
|
|
|
long i = this.worldData.getDayTime() + 24000L;
|
2012-07-29 09:33:13 +02:00
|
|
|
|
2012-11-06 13:05:28 +01:00
|
|
|
this.worldData.setDayTime(i - i % 24000L);
|
2012-07-29 09:33:13 +02:00
|
|
|
this.d();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-09-10 06:19:28 +02:00
|
|
|
this.methodProfiler.a("mobSpawner");
|
2012-07-29 09:33:13 +02:00
|
|
|
// CraftBukkit start - Only call spawner if we have players online and the world allows for mobs or animals
|
|
|
|
long time = this.worldData.getTime();
|
2012-10-25 05:53:23 +02:00
|
|
|
if (this.getGameRules().getBoolean("doMobSpawning") && (this.allowMonsters || this.allowAnimals) && (this instanceof WorldServer && this.players.size() > 0)) {
|
|
|
|
SpawnerCreature.spawnEntities(this, this.allowMonsters && (this.ticksPerMonsterSpawns != 0 && time % this.ticksPerMonsterSpawns == 0L), this.allowAnimals && (this.ticksPerAnimalSpawns != 0 && time % this.ticksPerAnimalSpawns == 0L), this.worldData.getTime() % 400L == 0L);
|
2012-07-29 09:33:13 +02:00
|
|
|
}
|
|
|
|
// CraftBukkit end
|
2012-09-10 06:19:28 +02:00
|
|
|
this.methodProfiler.c("chunkSource");
|
2012-07-29 09:33:13 +02:00
|
|
|
this.chunkProvider.unloadChunks();
|
|
|
|
int j = this.a(1.0F);
|
|
|
|
|
2012-10-25 05:53:23 +02:00
|
|
|
if (j != this.j) {
|
|
|
|
this.j = j;
|
2012-07-29 09:33:13 +02:00
|
|
|
}
|
|
|
|
|
2012-11-06 13:05:28 +01:00
|
|
|
this.worldData.setTime(this.worldData.getTime() + 1L);
|
|
|
|
this.worldData.setDayTime(this.worldData.getDayTime() + 1L);
|
2012-09-10 06:19:28 +02:00
|
|
|
this.methodProfiler.c("tickPending");
|
2012-07-29 09:33:13 +02:00
|
|
|
this.a(false);
|
2012-09-10 06:19:28 +02:00
|
|
|
this.methodProfiler.c("tickTiles");
|
2012-07-29 09:33:13 +02:00
|
|
|
this.g();
|
2012-09-10 06:19:28 +02:00
|
|
|
this.methodProfiler.c("chunkMap");
|
2012-07-29 09:33:13 +02:00
|
|
|
this.manager.flush();
|
2012-09-10 06:19:28 +02:00
|
|
|
this.methodProfiler.c("village");
|
2012-07-29 09:33:13 +02:00
|
|
|
this.villages.tick();
|
|
|
|
this.siegeManager.a();
|
2012-11-06 13:05:28 +01:00
|
|
|
this.methodProfiler.c("portalForcer");
|
2012-12-20 05:03:52 +01:00
|
|
|
this.P.a(this.getTime());
|
2012-09-10 06:19:28 +02:00
|
|
|
this.methodProfiler.b();
|
2013-03-13 23:33:27 +01:00
|
|
|
this.Y();
|
[Bleeding] Implement periodic chunk garbage collector
This adds two settings to bukkit.yml, allowing activation and control of
two chunk garbage collection triggering conditions:
chunk-gc/period-in-ticks controls a periodic GC, run once every N ticks
(default is 600); chunk-gc/load-threshold causes the GC to run once
after every N calls to loadChunk() on a given world (this call is an API
call used by plugins, and is distinct from the path taken for routine
player movement-based loading). In both cases, setting to zero will
disable the given GC scheduling strategy.
In either case, the act of doing the GC is simply one of scanning the
loaded chunks, seeing which are NOT being used by one or more players
(due to view-distance) and which are not already queued for unload, and
queueing them for a normal unload. Ultimately, the unload is then
processed the same as if the chunk were unloaded due to leaving the
view-distance range of all players, so the impact on plugins should be
no different (and strategies such as handling the ChunkUnloadEvent in
order to prevent unload will still work).
The initial interval for the periodic GC is randomized on a per-world
basis, in order to avoid all world being GCed at the same time -
minimizing potential lag spikes.
2012-12-10 16:38:26 +01:00
|
|
|
|
|
|
|
this.getWorld().processChunkGC(); // CraftBukkit
|
2012-07-29 09:33:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public BiomeMeta a(EnumCreatureType enumcreaturetype, int i, int j, int k) {
|
2013-03-13 23:33:27 +01:00
|
|
|
List list = this.J().getMobsFor(enumcreaturetype, i, j, k);
|
2012-07-29 09:33:13 +02:00
|
|
|
|
|
|
|
return list != null && !list.isEmpty() ? (BiomeMeta) WeightedRandom.a(this.random, (Collection) list) : null;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void everyoneSleeping() {
|
2012-12-20 05:03:52 +01:00
|
|
|
this.N = !this.players.isEmpty();
|
2012-07-29 09:33:13 +02:00
|
|
|
Iterator iterator = this.players.iterator();
|
|
|
|
|
|
|
|
while (iterator.hasNext()) {
|
|
|
|
EntityHuman entityhuman = (EntityHuman) iterator.next();
|
|
|
|
|
|
|
|
if (!entityhuman.isSleeping() && !entityhuman.fauxSleeping) { // CraftBukkit
|
2012-12-20 05:03:52 +01:00
|
|
|
this.N = false;
|
2012-07-29 09:33:13 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void d() {
|
2012-12-20 05:03:52 +01:00
|
|
|
this.N = false;
|
2012-07-29 09:33:13 +02:00
|
|
|
Iterator iterator = this.players.iterator();
|
|
|
|
|
|
|
|
while (iterator.hasNext()) {
|
|
|
|
EntityHuman entityhuman = (EntityHuman) iterator.next();
|
|
|
|
|
|
|
|
if (entityhuman.isSleeping()) {
|
|
|
|
entityhuman.a(false, false, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-03-13 23:33:27 +01:00
|
|
|
this.X();
|
2012-07-29 09:33:13 +02:00
|
|
|
}
|
|
|
|
|
2013-03-13 23:33:27 +01:00
|
|
|
private void X() {
|
2012-07-29 09:33:13 +02:00
|
|
|
// CraftBukkit start
|
|
|
|
WeatherChangeEvent weather = new WeatherChangeEvent(this.getWorld(), false);
|
|
|
|
this.getServer().getPluginManager().callEvent(weather);
|
|
|
|
|
|
|
|
ThunderChangeEvent thunder = new ThunderChangeEvent(this.getWorld(), false);
|
|
|
|
this.getServer().getPluginManager().callEvent(thunder);
|
|
|
|
if (!weather.isCancelled()) {
|
|
|
|
this.worldData.setWeatherDuration(0);
|
|
|
|
this.worldData.setStorm(false);
|
|
|
|
}
|
|
|
|
if (!thunder.isCancelled()) {
|
|
|
|
this.worldData.setThunderDuration(0);
|
|
|
|
this.worldData.setThundering(false);
|
|
|
|
}
|
|
|
|
// CraftBukkit end
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean everyoneDeeplySleeping() {
|
2012-12-20 05:03:52 +01:00
|
|
|
if (this.N && !this.isStatic) {
|
2012-07-29 09:33:13 +02:00
|
|
|
Iterator iterator = this.players.iterator();
|
|
|
|
|
|
|
|
// CraftBukkit - This allows us to assume that some people are in bed but not really, allowing time to pass in spite of AFKers
|
|
|
|
boolean foundActualSleepers = false;
|
|
|
|
|
|
|
|
EntityHuman entityhuman;
|
|
|
|
|
|
|
|
do {
|
|
|
|
if (!iterator.hasNext()) {
|
|
|
|
return foundActualSleepers; // CraftBukkit
|
|
|
|
}
|
|
|
|
|
|
|
|
entityhuman = (EntityHuman) iterator.next();
|
|
|
|
// CraftBukkit start
|
|
|
|
if (entityhuman.isDeeplySleeping()) {
|
|
|
|
foundActualSleepers = true;
|
|
|
|
}
|
|
|
|
} while (entityhuman.isDeeplySleeping() || entityhuman.fauxSleeping);
|
|
|
|
// CraftBukkit end
|
|
|
|
|
|
|
|
return false;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void g() {
|
|
|
|
super.g();
|
|
|
|
int i = 0;
|
|
|
|
int j = 0;
|
|
|
|
// CraftBukkit start
|
2012-10-25 05:53:23 +02:00
|
|
|
// Iterator iterator = this.chunkTickList.iterator();
|
|
|
|
|
2012-07-29 09:33:13 +02:00
|
|
|
for (long chunkCoord : this.chunkTickList.popAll()) {
|
|
|
|
int chunkX = LongHash.msw(chunkCoord);
|
|
|
|
int chunkZ = LongHash.lsw(chunkCoord);
|
|
|
|
// ChunkCoordIntPair chunkcoordintpair = (ChunkCoordIntPair) iterator.next();
|
|
|
|
int k = chunkX * 16;
|
|
|
|
int l = chunkZ * 16;
|
|
|
|
|
2012-09-10 06:19:28 +02:00
|
|
|
this.methodProfiler.a("getChunk");
|
2012-07-29 09:33:13 +02:00
|
|
|
Chunk chunk = this.getChunkAt(chunkX, chunkZ);
|
|
|
|
// CraftBukkit end
|
|
|
|
|
|
|
|
this.a(k, l, chunk);
|
2012-09-10 06:19:28 +02:00
|
|
|
this.methodProfiler.c("tickChunk");
|
2012-07-29 09:33:13 +02:00
|
|
|
chunk.k();
|
2012-09-10 06:19:28 +02:00
|
|
|
this.methodProfiler.c("thunder");
|
2012-07-29 09:33:13 +02:00
|
|
|
int i1;
|
|
|
|
int j1;
|
|
|
|
int k1;
|
|
|
|
int l1;
|
|
|
|
|
2013-03-13 23:33:27 +01:00
|
|
|
if (this.random.nextInt(100000) == 0 && this.O() && this.N()) {
|
2012-10-25 05:53:23 +02:00
|
|
|
this.k = this.k * 3 + 1013904223;
|
|
|
|
i1 = this.k >> 2;
|
2012-07-29 09:33:13 +02:00
|
|
|
j1 = k + (i1 & 15);
|
|
|
|
k1 = l + (i1 >> 8 & 15);
|
2012-10-25 05:53:23 +02:00
|
|
|
l1 = this.h(j1, k1);
|
2013-03-13 23:33:27 +01:00
|
|
|
if (this.F(j1, l1, k1)) {
|
2012-07-29 09:33:13 +02:00
|
|
|
this.strikeLightning(new EntityLightning(this, (double) j1, (double) l1, (double) k1));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-09-10 06:19:28 +02:00
|
|
|
this.methodProfiler.c("iceandsnow");
|
2012-07-29 09:33:13 +02:00
|
|
|
int i2;
|
|
|
|
|
|
|
|
if (this.random.nextInt(16) == 0) {
|
2012-10-25 05:53:23 +02:00
|
|
|
this.k = this.k * 3 + 1013904223;
|
|
|
|
i1 = this.k >> 2;
|
2012-07-29 09:33:13 +02:00
|
|
|
j1 = i1 & 15;
|
|
|
|
k1 = i1 >> 8 & 15;
|
2012-10-25 05:53:23 +02:00
|
|
|
l1 = this.h(j1 + k, k1 + l);
|
2013-03-13 23:33:27 +01:00
|
|
|
if (this.y(j1 + k, l1 - 1, k1 + l)) {
|
2012-07-29 09:33:13 +02:00
|
|
|
// CraftBukkit start
|
|
|
|
BlockState blockState = this.getWorld().getBlockAt(j1 + k, l1 - 1, k1 + l).getState();
|
|
|
|
blockState.setTypeId(Block.ICE.id);
|
|
|
|
|
|
|
|
BlockFormEvent iceBlockForm = new BlockFormEvent(blockState.getBlock(), blockState);
|
|
|
|
this.getServer().getPluginManager().callEvent(iceBlockForm);
|
|
|
|
if (!iceBlockForm.isCancelled()) {
|
|
|
|
blockState.update(true);
|
|
|
|
}
|
|
|
|
// CraftBukkit end
|
|
|
|
}
|
|
|
|
|
2013-03-13 23:33:27 +01:00
|
|
|
if (this.O() && this.z(j1 + k, l1, k1 + l)) {
|
2012-07-29 09:33:13 +02:00
|
|
|
// CraftBukkit start
|
|
|
|
BlockState blockState = this.getWorld().getBlockAt(j1 + k, l1, k1 + l).getState();
|
|
|
|
blockState.setTypeId(Block.SNOW.id);
|
|
|
|
|
|
|
|
BlockFormEvent snow = new BlockFormEvent(blockState.getBlock(), blockState);
|
|
|
|
this.getServer().getPluginManager().callEvent(snow);
|
|
|
|
if (!snow.isCancelled()) {
|
|
|
|
blockState.update(true);
|
|
|
|
}
|
|
|
|
// CraftBukkit end
|
|
|
|
}
|
|
|
|
|
2013-03-13 23:33:27 +01:00
|
|
|
if (this.O()) {
|
2012-07-29 09:33:13 +02:00
|
|
|
BiomeBase biomebase = this.getBiome(j1 + k, k1 + l);
|
|
|
|
|
|
|
|
if (biomebase.d()) {
|
|
|
|
i2 = this.getTypeId(j1 + k, l1 - 1, k1 + l);
|
|
|
|
if (i2 != 0) {
|
2013-03-13 23:33:27 +01:00
|
|
|
Block.byId[i2].g(this, j1 + k, l1 - 1, k1 + l);
|
2012-07-29 09:33:13 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-09-10 06:19:28 +02:00
|
|
|
this.methodProfiler.c("tickTiles");
|
2012-07-29 09:33:13 +02:00
|
|
|
ChunkSection[] achunksection = chunk.i();
|
|
|
|
|
|
|
|
j1 = achunksection.length;
|
|
|
|
|
|
|
|
for (k1 = 0; k1 < j1; ++k1) {
|
|
|
|
ChunkSection chunksection = achunksection[k1];
|
|
|
|
|
|
|
|
if (chunksection != null && chunksection.b()) {
|
|
|
|
for (int j2 = 0; j2 < 3; ++j2) {
|
2012-10-25 05:53:23 +02:00
|
|
|
this.k = this.k * 3 + 1013904223;
|
|
|
|
i2 = this.k >> 2;
|
2012-07-29 09:33:13 +02:00
|
|
|
int k2 = i2 & 15;
|
|
|
|
int l2 = i2 >> 8 & 15;
|
|
|
|
int i3 = i2 >> 16 & 15;
|
|
|
|
int j3 = chunksection.a(k2, i3, l2);
|
|
|
|
|
|
|
|
++j;
|
|
|
|
Block block = Block.byId[j3];
|
|
|
|
|
2012-10-25 05:53:23 +02:00
|
|
|
if (block != null && block.isTicking()) {
|
2012-07-29 09:33:13 +02:00
|
|
|
++i;
|
2013-03-13 23:33:27 +01:00
|
|
|
block.a(this, k2 + k, i3 + chunksection.d(), l2 + l, this.random);
|
2012-07-29 09:33:13 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-09-10 06:19:28 +02:00
|
|
|
this.methodProfiler.b();
|
2012-07-29 09:33:13 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-03-13 23:33:27 +01:00
|
|
|
public boolean a(int i, int j, int k, int l) {
|
|
|
|
NextTickListEntry nextticklistentry = new NextTickListEntry(i, j, k, l);
|
|
|
|
|
|
|
|
return this.T.contains(nextticklistentry);
|
|
|
|
}
|
|
|
|
|
2012-07-29 09:33:13 +02:00
|
|
|
public void a(int i, int j, int k, int l, int i1) {
|
2012-10-25 05:53:23 +02:00
|
|
|
this.a(i, j, k, l, i1, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void a(int i, int j, int k, int l, int i1, int j1) {
|
2012-07-29 09:33:13 +02:00
|
|
|
NextTickListEntry nextticklistentry = new NextTickListEntry(i, j, k, l);
|
2013-03-13 23:33:27 +01:00
|
|
|
byte b0 = 0;
|
2012-07-29 09:33:13 +02:00
|
|
|
|
2012-10-25 05:53:23 +02:00
|
|
|
if (this.d && l > 0) {
|
|
|
|
if (Block.byId[l].l()) {
|
2013-03-13 23:33:27 +01:00
|
|
|
if (this.e(nextticklistentry.a - b0, nextticklistentry.b - b0, nextticklistentry.c - b0, nextticklistentry.a + b0, nextticklistentry.b + b0, nextticklistentry.c + b0)) {
|
2012-10-25 05:53:23 +02:00
|
|
|
int k1 = this.getTypeId(nextticklistentry.a, nextticklistentry.b, nextticklistentry.c);
|
2012-07-29 09:33:13 +02:00
|
|
|
|
2012-10-25 05:53:23 +02:00
|
|
|
if (k1 == nextticklistentry.d && k1 > 0) {
|
2013-03-13 23:33:27 +01:00
|
|
|
Block.byId[k1].a(this, nextticklistentry.a, nextticklistentry.b, nextticklistentry.c, this.random);
|
2012-10-25 05:53:23 +02:00
|
|
|
}
|
2012-07-29 09:33:13 +02:00
|
|
|
}
|
2012-10-25 05:53:23 +02:00
|
|
|
|
|
|
|
return;
|
2012-07-29 09:33:13 +02:00
|
|
|
}
|
|
|
|
|
2012-10-25 05:53:23 +02:00
|
|
|
i1 = 1;
|
|
|
|
}
|
|
|
|
|
2013-03-13 23:33:27 +01:00
|
|
|
if (this.e(i - b0, j - b0, k - b0, i + b0, j + b0, k + b0)) {
|
2012-10-25 05:53:23 +02:00
|
|
|
if (l > 0) {
|
|
|
|
nextticklistentry.a((long) i1 + this.worldData.getTime());
|
|
|
|
nextticklistentry.a(j1);
|
|
|
|
}
|
|
|
|
|
2012-12-20 05:03:52 +01:00
|
|
|
if (!this.L.contains(nextticklistentry)) {
|
|
|
|
this.L.add(nextticklistentry);
|
2012-10-25 05:53:23 +02:00
|
|
|
this.M.add(nextticklistentry);
|
2012-07-29 09:33:13 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-03-13 23:33:27 +01:00
|
|
|
public void b(int i, int j, int k, int l, int i1, int j1) {
|
2012-07-29 09:33:13 +02:00
|
|
|
NextTickListEntry nextticklistentry = new NextTickListEntry(i, j, k, l);
|
|
|
|
|
2013-03-13 23:33:27 +01:00
|
|
|
nextticklistentry.a(j1);
|
2012-07-29 09:33:13 +02:00
|
|
|
if (l > 0) {
|
|
|
|
nextticklistentry.a((long) i1 + this.worldData.getTime());
|
|
|
|
}
|
|
|
|
|
2012-12-20 05:03:52 +01:00
|
|
|
if (!this.L.contains(nextticklistentry)) {
|
|
|
|
this.L.add(nextticklistentry);
|
2012-10-25 05:53:23 +02:00
|
|
|
this.M.add(nextticklistentry);
|
2012-07-29 09:33:13 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-08-25 02:51:51 +02:00
|
|
|
public void tickEntities() {
|
|
|
|
if (false && this.players.isEmpty()) { // CraftBukkit - this prevents entity cleanup, other issues on servers with no players
|
2012-10-25 05:53:23 +02:00
|
|
|
if (this.emptyTime++ >= 1200) {
|
2012-08-25 02:51:51 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
} else {
|
2012-10-25 05:53:23 +02:00
|
|
|
this.i();
|
2012-08-25 02:51:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
super.tickEntities();
|
|
|
|
}
|
|
|
|
|
2012-10-25 05:53:23 +02:00
|
|
|
public void i() {
|
|
|
|
this.emptyTime = 0;
|
|
|
|
}
|
|
|
|
|
2012-07-29 09:33:13 +02:00
|
|
|
public boolean a(boolean flag) {
|
2012-12-20 05:03:52 +01:00
|
|
|
int i = this.M.size();
|
2012-07-29 09:33:13 +02:00
|
|
|
|
2012-12-20 05:03:52 +01:00
|
|
|
if (i != this.L.size()) {
|
2012-07-29 09:33:13 +02:00
|
|
|
throw new IllegalStateException("TickNextTick list out of synch");
|
|
|
|
} else {
|
|
|
|
if (i > 1000) {
|
2013-03-25 05:22:32 +01:00
|
|
|
// CraftBukkit start - If the server has too much to process over time, try to alleviate that
|
2012-07-29 09:33:13 +02:00
|
|
|
if (i > 20 * 1000) {
|
|
|
|
i = i / 20;
|
|
|
|
} else {
|
|
|
|
i = 1000;
|
|
|
|
}
|
|
|
|
// CraftBukkit end
|
|
|
|
}
|
|
|
|
|
2013-03-13 23:33:27 +01:00
|
|
|
this.methodProfiler.a("cleaning");
|
|
|
|
|
|
|
|
NextTickListEntry nextticklistentry;
|
2012-07-29 09:33:13 +02:00
|
|
|
|
2013-03-13 23:33:27 +01:00
|
|
|
for (int j = 0; j < i; ++j) {
|
|
|
|
nextticklistentry = (NextTickListEntry) this.M.first();
|
2012-07-29 09:33:13 +02:00
|
|
|
if (!flag && nextticklistentry.e > this.worldData.getTime()) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2012-10-25 05:53:23 +02:00
|
|
|
this.M.remove(nextticklistentry);
|
2012-12-20 05:03:52 +01:00
|
|
|
this.L.remove(nextticklistentry);
|
2013-03-13 23:33:27 +01:00
|
|
|
this.T.add(nextticklistentry);
|
|
|
|
}
|
2012-07-29 09:33:13 +02:00
|
|
|
|
2013-03-13 23:33:27 +01:00
|
|
|
this.methodProfiler.b();
|
|
|
|
this.methodProfiler.a("ticking");
|
|
|
|
Iterator iterator = this.T.iterator();
|
|
|
|
|
|
|
|
while (iterator.hasNext()) {
|
|
|
|
nextticklistentry = (NextTickListEntry) iterator.next();
|
|
|
|
iterator.remove();
|
|
|
|
byte b0 = 0;
|
|
|
|
|
|
|
|
if (this.e(nextticklistentry.a - b0, nextticklistentry.b - b0, nextticklistentry.c - b0, nextticklistentry.a + b0, nextticklistentry.b + b0, nextticklistentry.c + b0)) {
|
2012-07-29 09:33:13 +02:00
|
|
|
int k = this.getTypeId(nextticklistentry.a, nextticklistentry.b, nextticklistentry.c);
|
|
|
|
|
2013-03-13 23:33:27 +01:00
|
|
|
if (k > 0 && Block.b(k, nextticklistentry.d)) {
|
2012-11-06 13:05:28 +01:00
|
|
|
try {
|
2013-03-13 23:33:27 +01:00
|
|
|
Block.byId[k].a(this, nextticklistentry.a, nextticklistentry.b, nextticklistentry.c, this.random);
|
2012-11-06 13:05:28 +01:00
|
|
|
} catch (Throwable throwable) {
|
|
|
|
CrashReport crashreport = CrashReport.a(throwable, "Exception while ticking a block");
|
|
|
|
CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Block being ticked");
|
|
|
|
|
|
|
|
int l;
|
|
|
|
|
|
|
|
try {
|
|
|
|
l = this.getData(nextticklistentry.a, nextticklistentry.b, nextticklistentry.c);
|
|
|
|
} catch (Throwable throwable1) {
|
|
|
|
l = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
CrashReportSystemDetails.a(crashreportsystemdetails, nextticklistentry.a, nextticklistentry.b, nextticklistentry.c, k, l);
|
|
|
|
throw new ReportedException(crashreport);
|
2012-12-20 05:03:52 +01:00
|
|
|
}
|
|
|
|
}
|
2013-03-13 23:33:27 +01:00
|
|
|
} else {
|
|
|
|
this.a(nextticklistentry.a, nextticklistentry.b, nextticklistentry.c, nextticklistentry.d, 0);
|
2012-07-29 09:33:13 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-03-13 23:33:27 +01:00
|
|
|
this.methodProfiler.b();
|
|
|
|
this.T.clear();
|
2012-12-20 05:03:52 +01:00
|
|
|
return !this.M.isEmpty();
|
2012-07-29 09:33:13 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public List a(Chunk chunk, boolean flag) {
|
|
|
|
ArrayList arraylist = null;
|
|
|
|
ChunkCoordIntPair chunkcoordintpair = chunk.l();
|
2013-03-13 23:33:27 +01:00
|
|
|
int i = (chunkcoordintpair.x << 4) - 2;
|
|
|
|
int j = i + 16 + 2;
|
|
|
|
int k = (chunkcoordintpair.z << 4) - 2;
|
|
|
|
int l = k + 16 + 2;
|
2012-07-29 09:33:13 +02:00
|
|
|
|
2013-03-13 23:33:27 +01:00
|
|
|
for (int i1 = 0; i1 < 2; ++i1) {
|
|
|
|
Iterator iterator;
|
2012-07-29 09:33:13 +02:00
|
|
|
|
2013-03-13 23:33:27 +01:00
|
|
|
if (i1 == 0) {
|
|
|
|
iterator = this.M.iterator();
|
|
|
|
} else {
|
|
|
|
iterator = this.T.iterator();
|
2013-03-25 05:22:32 +01:00
|
|
|
/* CraftBukkit start - Comment out debug spam
|
2013-03-13 23:33:27 +01:00
|
|
|
if (!this.T.isEmpty()) {
|
|
|
|
System.out.println(this.T.size());
|
2012-07-29 09:33:13 +02:00
|
|
|
}
|
2013-03-16 19:45:42 +01:00
|
|
|
// CraftBukkit end */
|
2013-03-13 23:33:27 +01:00
|
|
|
}
|
2012-07-29 09:33:13 +02:00
|
|
|
|
2013-03-13 23:33:27 +01:00
|
|
|
while (iterator.hasNext()) {
|
|
|
|
NextTickListEntry nextticklistentry = (NextTickListEntry) iterator.next();
|
2012-07-29 09:33:13 +02:00
|
|
|
|
2013-03-13 23:33:27 +01:00
|
|
|
if (nextticklistentry.a >= i && nextticklistentry.a < j && nextticklistentry.c >= k && nextticklistentry.c < l) {
|
|
|
|
if (flag) {
|
|
|
|
this.L.remove(nextticklistentry);
|
|
|
|
iterator.remove();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (arraylist == null) {
|
|
|
|
arraylist = new ArrayList();
|
|
|
|
}
|
|
|
|
|
|
|
|
arraylist.add(nextticklistentry);
|
|
|
|
}
|
2012-07-29 09:33:13 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return arraylist;
|
|
|
|
}
|
|
|
|
|
2011-04-20 19:05:14 +02:00
|
|
|
public void entityJoinedWorld(Entity entity, boolean flag) {
|
2011-05-14 16:29:42 +02:00
|
|
|
/* CraftBukkit start - We prevent spawning in general, so this butchering is not needed
|
2012-07-29 09:33:13 +02:00
|
|
|
if (!this.server.getSpawnAnimals() && (entity instanceof EntityAnimal || entity instanceof EntityWaterAnimal)) {
|
2011-05-14 16:29:42 +02:00
|
|
|
entity.die();
|
|
|
|
}
|
|
|
|
// CraftBukkit end */
|
2012-07-29 09:33:13 +02:00
|
|
|
if (!this.server.getSpawnNPCs() && entity instanceof NPC) {
|
2012-01-12 23:10:13 +01:00
|
|
|
entity.die();
|
|
|
|
}
|
2011-01-29 22:50:29 +01:00
|
|
|
|
2012-07-29 09:33:13 +02:00
|
|
|
if (!(entity.passenger instanceof EntityHuman)) {
|
2011-04-20 19:05:14 +02:00
|
|
|
super.entityJoinedWorld(entity, flag);
|
2011-01-11 09:25:13 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-04-20 19:05:14 +02:00
|
|
|
public void vehicleEnteredWorld(Entity entity, boolean flag) {
|
|
|
|
super.entityJoinedWorld(entity, flag);
|
2011-01-11 09:25:13 +01:00
|
|
|
}
|
|
|
|
|
2012-10-25 05:53:23 +02:00
|
|
|
protected IChunkProvider j() {
|
2011-11-30 00:17:43 +01:00
|
|
|
IChunkLoader ichunkloader = this.dataManager.createChunkLoader(this.worldProvider);
|
2011-02-23 03:37:56 +01:00
|
|
|
|
2011-06-12 00:02:58 +02:00
|
|
|
// CraftBukkit start
|
2012-07-22 08:18:00 +02:00
|
|
|
org.bukkit.craftbukkit.generator.InternalChunkGenerator gen;
|
2011-06-06 15:52:02 +02:00
|
|
|
|
|
|
|
if (this.generator != null) {
|
2012-07-22 08:18:00 +02:00
|
|
|
gen = new org.bukkit.craftbukkit.generator.CustomChunkGenerator(this, this.getSeed(), this.generator);
|
2011-06-06 15:52:02 +02:00
|
|
|
} else if (this.worldProvider instanceof WorldProviderHell) {
|
2012-07-22 08:18:00 +02:00
|
|
|
gen = new org.bukkit.craftbukkit.generator.NetherChunkGenerator(this, this.getSeed());
|
2011-11-30 00:17:43 +01:00
|
|
|
} else if (this.worldProvider instanceof WorldProviderTheEnd) {
|
2012-07-22 08:18:00 +02:00
|
|
|
gen = new org.bukkit.craftbukkit.generator.SkyLandsChunkGenerator(this, this.getSeed());
|
2011-06-06 15:52:02 +02:00
|
|
|
} else {
|
2012-07-22 08:18:00 +02:00
|
|
|
gen = new org.bukkit.craftbukkit.generator.NormalChunkGenerator(this, this.getSeed());
|
2011-06-06 15:52:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
this.chunkProviderServer = new ChunkProviderServer(this, ichunkloader, gen);
|
2011-06-12 00:02:58 +02:00
|
|
|
// CraftBukkit end
|
2011-06-06 15:52:02 +02:00
|
|
|
|
2011-04-20 19:05:14 +02:00
|
|
|
return this.chunkProviderServer;
|
2011-01-11 09:25:13 +01:00
|
|
|
}
|
|
|
|
|
2011-04-20 19:05:14 +02:00
|
|
|
public List getTileEntities(int i, int j, int k, int l, int i1, int j1) {
|
2011-01-11 09:25:13 +01:00
|
|
|
ArrayList arraylist = new ArrayList();
|
2013-03-25 05:22:32 +01:00
|
|
|
// CraftBukkit start - Use iterator
|
2012-07-29 09:33:13 +02:00
|
|
|
Iterator iterator = this.tileEntityList.iterator();
|
2011-01-11 09:25:13 +01:00
|
|
|
|
2012-07-29 09:33:13 +02:00
|
|
|
while (iterator.hasNext()) {
|
|
|
|
TileEntity tileentity = (TileEntity) iterator.next();
|
2012-11-06 13:05:28 +01:00
|
|
|
// CraftBukkit end
|
2011-01-11 09:25:13 +01:00
|
|
|
|
2011-06-27 00:25:01 +02:00
|
|
|
if (tileentity.x >= i && tileentity.y >= j && tileentity.z >= k && tileentity.x < l && tileentity.y < i1 && tileentity.z < j1) {
|
2011-01-29 22:50:29 +01:00
|
|
|
arraylist.add(tileentity);
|
2011-01-11 09:25:13 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-01-29 22:50:29 +01:00
|
|
|
return arraylist;
|
2011-01-11 09:25:13 +01:00
|
|
|
}
|
|
|
|
|
2011-01-29 22:50:29 +01:00
|
|
|
public boolean a(EntityHuman entityhuman, int i, int j, int k) {
|
2013-03-13 23:33:27 +01:00
|
|
|
return !this.server.a(this, i, j, k, entityhuman);
|
2011-01-11 09:25:13 +01:00
|
|
|
}
|
|
|
|
|
2012-07-29 09:33:13 +02:00
|
|
|
protected void a(WorldSettings worldsettings) {
|
2012-01-14 21:03:48 +01:00
|
|
|
if (this.entitiesById == null) {
|
|
|
|
this.entitiesById = new IntHashMap();
|
2011-12-01 22:43:54 +01:00
|
|
|
}
|
|
|
|
|
2012-12-20 05:03:52 +01:00
|
|
|
if (this.L == null) {
|
|
|
|
this.L = new HashSet();
|
2012-07-29 09:33:13 +02:00
|
|
|
}
|
|
|
|
|
2012-12-20 05:03:52 +01:00
|
|
|
if (this.M == null) {
|
|
|
|
this.M = new TreeSet();
|
2012-07-29 09:33:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
this.b(worldsettings);
|
|
|
|
super.a(worldsettings);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void b(WorldSettings worldsettings) {
|
|
|
|
if (!this.worldProvider.e()) {
|
|
|
|
this.worldData.setSpawn(0, this.worldProvider.getSeaLevel(), 0);
|
|
|
|
} else {
|
|
|
|
this.isLoading = true;
|
2012-10-25 05:53:23 +02:00
|
|
|
WorldChunkManager worldchunkmanager = this.worldProvider.d;
|
2012-07-29 09:33:13 +02:00
|
|
|
List list = worldchunkmanager.a();
|
|
|
|
Random random = new Random(this.getSeed());
|
|
|
|
ChunkPosition chunkposition = worldchunkmanager.a(0, 0, 256, list, random);
|
|
|
|
int i = 0;
|
|
|
|
int j = this.worldProvider.getSeaLevel();
|
|
|
|
int k = 0;
|
|
|
|
|
|
|
|
// CraftBukkit start
|
|
|
|
if (this.generator != null) {
|
|
|
|
Random rand = new Random(this.getSeed());
|
|
|
|
org.bukkit.Location spawn = this.generator.getFixedSpawnLocation(((WorldServer) this).getWorld(), rand);
|
|
|
|
|
|
|
|
if (spawn != null) {
|
|
|
|
if (spawn.getWorld() != ((WorldServer) this).getWorld()) {
|
|
|
|
throw new IllegalStateException("Cannot set spawn point for " + this.worldData.getName() + " to be in another world (" + spawn.getWorld().getName() + ")");
|
|
|
|
} else {
|
|
|
|
this.worldData.setSpawn(spawn.getBlockX(), spawn.getBlockY(), spawn.getBlockZ());
|
|
|
|
this.isLoading = false;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// CraftBukkit end
|
|
|
|
|
|
|
|
if (chunkposition != null) {
|
|
|
|
i = chunkposition.x;
|
|
|
|
k = chunkposition.z;
|
|
|
|
} else {
|
2013-03-13 23:33:27 +01:00
|
|
|
this.getLogger().warning("Unable to find spawn biome");
|
2012-07-29 09:33:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int l = 0;
|
|
|
|
|
2012-10-25 05:53:23 +02:00
|
|
|
while (!this.canSpawn(i, k)) { // CraftBukkit - use our own canSpawn
|
2012-07-29 09:33:13 +02:00
|
|
|
i += random.nextInt(64) - random.nextInt(64);
|
|
|
|
k += random.nextInt(64) - random.nextInt(64);
|
|
|
|
++l;
|
|
|
|
if (l == 1000) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
this.worldData.setSpawn(i, j, k);
|
|
|
|
this.isLoading = false;
|
|
|
|
if (worldsettings.c()) {
|
2012-10-25 05:53:23 +02:00
|
|
|
this.k();
|
2012-07-29 09:33:13 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-10-25 05:53:23 +02:00
|
|
|
protected void k() {
|
2012-12-20 05:03:52 +01:00
|
|
|
WorldGenBonusChest worldgenbonuschest = new WorldGenBonusChest(S, 10);
|
2012-07-29 09:33:13 +02:00
|
|
|
|
|
|
|
for (int i = 0; i < 10; ++i) {
|
|
|
|
int j = this.worldData.c() + this.random.nextInt(6) - this.random.nextInt(6);
|
|
|
|
int k = this.worldData.e() + this.random.nextInt(6) - this.random.nextInt(6);
|
2012-10-25 05:53:23 +02:00
|
|
|
int l = this.i(j, k) + 1;
|
2012-07-29 09:33:13 +02:00
|
|
|
|
|
|
|
if (worldgenbonuschest.a(this, this.random, j, l, k)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2011-12-01 22:43:54 +01:00
|
|
|
}
|
|
|
|
|
2012-07-29 09:33:13 +02:00
|
|
|
public ChunkCoordinates getDimensionSpawn() {
|
|
|
|
return this.worldProvider.h();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void save(boolean flag, IProgressUpdate iprogressupdate) throws ExceptionWorldConflict { // CraftBukkit - added throws
|
|
|
|
if (this.chunkProvider.canSave()) {
|
|
|
|
if (iprogressupdate != null) {
|
|
|
|
iprogressupdate.a("Saving level");
|
|
|
|
}
|
|
|
|
|
|
|
|
this.a();
|
|
|
|
if (iprogressupdate != null) {
|
|
|
|
iprogressupdate.c("Saving chunks");
|
|
|
|
}
|
|
|
|
|
|
|
|
this.chunkProvider.saveChunks(flag, iprogressupdate);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void a() throws ExceptionWorldConflict { // CraftBukkit - added throws
|
2013-03-13 23:33:27 +01:00
|
|
|
this.E();
|
2012-12-20 05:03:52 +01:00
|
|
|
this.dataManager.saveWorldData(this.worldData, this.server.getPlayerList().q());
|
2012-07-29 09:33:13 +02:00
|
|
|
this.worldMaps.a();
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void a(Entity entity) {
|
|
|
|
super.a(entity);
|
2012-01-14 21:03:48 +01:00
|
|
|
this.entitiesById.a(entity.id, entity);
|
2013-03-13 23:33:27 +01:00
|
|
|
Entity[] aentity = entity.an();
|
2011-11-20 09:01:14 +01:00
|
|
|
|
|
|
|
if (aentity != null) {
|
2012-11-06 13:05:28 +01:00
|
|
|
for (int i = 0; i < aentity.length; ++i) {
|
|
|
|
this.entitiesById.a(aentity[i].id, aentity[i]);
|
2011-11-20 09:01:14 +01:00
|
|
|
}
|
|
|
|
}
|
2011-04-20 22:47:26 +02:00
|
|
|
}
|
|
|
|
|
2012-07-29 09:33:13 +02:00
|
|
|
protected void b(Entity entity) {
|
|
|
|
super.b(entity);
|
2012-01-14 21:03:48 +01:00
|
|
|
this.entitiesById.d(entity.id);
|
2013-03-13 23:33:27 +01:00
|
|
|
Entity[] aentity = entity.an();
|
2011-11-20 09:01:14 +01:00
|
|
|
|
|
|
|
if (aentity != null) {
|
2012-11-06 13:05:28 +01:00
|
|
|
for (int i = 0; i < aentity.length; ++i) {
|
|
|
|
this.entitiesById.d(aentity[i].id);
|
2011-11-20 09:01:14 +01:00
|
|
|
}
|
|
|
|
}
|
2011-01-11 09:25:13 +01:00
|
|
|
}
|
|
|
|
|
2011-04-20 19:05:14 +02:00
|
|
|
public Entity getEntity(int i) {
|
2012-02-29 22:31:04 +01:00
|
|
|
return (Entity) this.entitiesById.get(i);
|
2011-04-20 22:47:26 +02:00
|
|
|
}
|
|
|
|
|
2011-06-27 00:25:01 +02:00
|
|
|
public boolean strikeLightning(Entity entity) {
|
2011-06-11 02:37:33 +02:00
|
|
|
// CraftBukkit start
|
2011-06-27 00:25:01 +02:00
|
|
|
LightningStrikeEvent lightning = new LightningStrikeEvent(this.getWorld(), (org.bukkit.entity.LightningStrike) entity.getBukkitEntity());
|
|
|
|
this.getServer().getPluginManager().callEvent(lightning);
|
2011-05-14 16:29:42 +02:00
|
|
|
|
2011-06-11 02:37:33 +02:00
|
|
|
if (lightning.isCancelled()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-06-27 00:25:01 +02:00
|
|
|
if (super.strikeLightning(entity)) {
|
2012-12-20 05:03:52 +01:00
|
|
|
this.server.getPlayerList().sendPacketNearby(entity.locX, entity.locY, entity.locZ, 512.0D, this.dimension, new Packet71Weather(entity));
|
2011-05-14 16:29:42 +02:00
|
|
|
// CraftBukkit end
|
|
|
|
return true;
|
2011-04-20 22:47:26 +02:00
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
2011-01-11 09:25:13 +01:00
|
|
|
}
|
|
|
|
|
2012-02-29 22:31:04 +01:00
|
|
|
public void broadcastEntityEffect(Entity entity, byte b0) {
|
2011-01-29 22:50:29 +01:00
|
|
|
Packet38EntityStatus packet38entitystatus = new Packet38EntityStatus(entity.id, b0);
|
2011-01-11 09:25:13 +01:00
|
|
|
|
2012-07-29 09:33:13 +02:00
|
|
|
this.getTracker().sendPacketToEntity(entity, packet38entitystatus);
|
2011-01-11 09:25:13 +01:00
|
|
|
}
|
|
|
|
|
2012-10-25 05:53:23 +02:00
|
|
|
public Explosion createExplosion(Entity entity, double d0, double d1, double d2, float f, boolean flag, boolean flag1) {
|
2011-05-14 16:29:42 +02:00
|
|
|
// CraftBukkit start
|
2012-10-25 05:53:23 +02:00
|
|
|
Explosion explosion = super.createExplosion(entity, d0, d1, d2, f, flag, flag1);
|
2011-01-11 09:25:13 +01:00
|
|
|
|
2011-02-23 13:56:36 +01:00
|
|
|
if (explosion.wasCanceled) {
|
2011-02-07 19:37:08 +01:00
|
|
|
return explosion;
|
|
|
|
}
|
|
|
|
|
2011-06-27 00:25:01 +02:00
|
|
|
/* Remove
|
2011-06-12 00:02:58 +02:00
|
|
|
explosion.a = flag;
|
2012-10-25 05:53:23 +02:00
|
|
|
explosion.b = flag1;
|
2011-06-12 00:02:58 +02:00
|
|
|
explosion.a();
|
|
|
|
explosion.a(false);
|
2012-10-31 03:24:48 +01:00
|
|
|
*/
|
|
|
|
// CraftBukkit end - TODO: Check if explosions are still properly implemented
|
|
|
|
|
2012-10-25 05:53:23 +02:00
|
|
|
if (!flag1) {
|
|
|
|
explosion.blocks.clear();
|
|
|
|
}
|
|
|
|
|
2012-07-29 09:33:13 +02:00
|
|
|
Iterator iterator = this.players.iterator();
|
|
|
|
|
|
|
|
while (iterator.hasNext()) {
|
|
|
|
EntityHuman entityhuman = (EntityHuman) iterator.next();
|
|
|
|
|
|
|
|
if (entityhuman.e(d0, d1, d2) < 4096.0D) {
|
2012-12-20 05:03:52 +01:00
|
|
|
((EntityPlayer) entityhuman).playerConnection.sendPacket(new Packet60Explosion(d0, d1, d2, f, explosion.blocks, (Vec3D) explosion.b().get(entityhuman)));
|
2012-07-29 09:33:13 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-01-11 09:25:13 +01:00
|
|
|
return explosion;
|
|
|
|
}
|
|
|
|
|
2012-07-29 09:33:13 +02:00
|
|
|
public void playNote(int i, int j, int k, int l, int i1, int j1) {
|
|
|
|
NoteBlockData noteblockdata = new NoteBlockData(i, j, k, l, i1, j1);
|
2012-12-20 05:03:52 +01:00
|
|
|
Iterator iterator = this.Q[this.R].iterator();
|
2012-07-29 09:33:13 +02:00
|
|
|
|
|
|
|
NoteBlockData noteblockdata1;
|
|
|
|
|
|
|
|
do {
|
|
|
|
if (!iterator.hasNext()) {
|
2012-12-20 05:03:52 +01:00
|
|
|
this.Q[this.R].add(noteblockdata);
|
2012-07-29 09:33:13 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
noteblockdata1 = (NoteBlockData) iterator.next();
|
|
|
|
} while (!noteblockdata1.equals(noteblockdata));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2013-03-13 23:33:27 +01:00
|
|
|
private void Y() {
|
2012-12-20 05:03:52 +01:00
|
|
|
while (!this.Q[this.R].isEmpty()) {
|
|
|
|
int i = this.R;
|
2012-07-29 09:33:13 +02:00
|
|
|
|
2012-12-20 05:03:52 +01:00
|
|
|
this.R ^= 1;
|
|
|
|
Iterator iterator = this.Q[i].iterator();
|
2012-07-29 09:33:13 +02:00
|
|
|
|
|
|
|
while (iterator.hasNext()) {
|
|
|
|
NoteBlockData noteblockdata = (NoteBlockData) iterator.next();
|
|
|
|
|
|
|
|
if (this.a(noteblockdata)) {
|
2012-08-09 11:28:04 +02:00
|
|
|
// CraftBukkit - this.worldProvider.dimension -> this.dimension
|
2012-12-20 05:03:52 +01:00
|
|
|
this.server.getPlayerList().sendPacketNearby((double) noteblockdata.a(), (double) noteblockdata.b(), (double) noteblockdata.c(), 64.0D, this.dimension, new Packet54PlayNoteBlock(noteblockdata.a(), noteblockdata.b(), noteblockdata.c(), noteblockdata.f(), noteblockdata.d(), noteblockdata.e()));
|
2012-07-29 09:33:13 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-12-20 05:03:52 +01:00
|
|
|
this.Q[i].clear();
|
2012-07-29 09:33:13 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private boolean a(NoteBlockData noteblockdata) {
|
|
|
|
int i = this.getTypeId(noteblockdata.a(), noteblockdata.b(), noteblockdata.c());
|
|
|
|
|
2013-03-13 23:33:27 +01:00
|
|
|
return i == noteblockdata.f() ? Block.byId[i].b(this, noteblockdata.a(), noteblockdata.b(), noteblockdata.c(), noteblockdata.d(), noteblockdata.e()) : false;
|
2011-02-23 03:37:56 +01:00
|
|
|
}
|
|
|
|
|
2011-04-20 19:05:14 +02:00
|
|
|
public void saveLevel() {
|
2012-07-29 09:33:13 +02:00
|
|
|
this.dataManager.a();
|
2011-04-20 22:47:26 +02:00
|
|
|
}
|
|
|
|
|
2012-10-25 05:53:23 +02:00
|
|
|
protected void n() {
|
2013-03-13 23:33:27 +01:00
|
|
|
boolean flag = this.O();
|
2011-04-20 22:47:26 +02:00
|
|
|
|
2012-10-25 05:53:23 +02:00
|
|
|
super.n();
|
2013-03-13 23:33:27 +01:00
|
|
|
if (flag != this.O()) {
|
2013-03-25 05:22:32 +01:00
|
|
|
// CraftBukkit start - Only send weather packets to those affected
|
2011-06-09 08:33:16 +02:00
|
|
|
for (int i = 0; i < this.players.size(); ++i) {
|
2011-06-27 00:25:01 +02:00
|
|
|
if (((EntityPlayer) this.players.get(i)).world == this) {
|
2012-12-20 22:51:27 +01:00
|
|
|
((EntityPlayer) this.players.get(i)).setPlayerWeather((!flag ? WeatherType.DOWNFALL : WeatherType.CLEAR), false);
|
2011-06-09 08:33:16 +02:00
|
|
|
}
|
2011-04-20 22:47:26 +02:00
|
|
|
}
|
2011-06-09 08:33:16 +02:00
|
|
|
// CraftBukkit end
|
2011-04-20 22:47:26 +02:00
|
|
|
}
|
2011-01-14 22:22:14 +01:00
|
|
|
}
|
2012-07-29 09:33:13 +02:00
|
|
|
|
|
|
|
public MinecraftServer getMinecraftServer() {
|
|
|
|
return this.server;
|
|
|
|
}
|
|
|
|
|
|
|
|
public EntityTracker getTracker() {
|
|
|
|
return this.tracker;
|
|
|
|
}
|
|
|
|
|
2012-12-20 05:03:52 +01:00
|
|
|
public PlayerChunkMap getPlayerChunkMap() {
|
2012-07-29 09:33:13 +02:00
|
|
|
return this.manager;
|
|
|
|
}
|
2012-11-06 13:05:28 +01:00
|
|
|
|
|
|
|
public PortalTravelAgent s() {
|
2012-12-20 05:03:52 +01:00
|
|
|
return this.P;
|
2012-11-06 13:05:28 +01:00
|
|
|
}
|
2013-03-13 23:33:27 +01:00
|
|
|
|
|
|
|
// CraftBukkit start - Compatibility methods for BlockChangeDelegate
|
|
|
|
public boolean setRawTypeId(int x, int y, int z, int typeId) {
|
|
|
|
return this.setTypeIdAndData(x, y, z, typeId, 0, 4);
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean setRawTypeIdAndData(int x, int y, int z, int typeId, int data) {
|
|
|
|
return this.setTypeIdAndData(x, y, z, typeId, data, 4);
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean setTypeId(int x, int y, int z, int typeId) {
|
|
|
|
return this.setTypeIdAndData(x, y, z, typeId, 0, 3);
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean setTypeIdAndData(int x, int y, int z, int typeId, int data) {
|
|
|
|
return this.setTypeIdAndData(x, y, z, typeId, data, 3);
|
|
|
|
}
|
|
|
|
// CraftBukkit end
|
2010-12-29 00:52:29 +01:00
|
|
|
}
|