geforkt von Mirrors/Paper
0aa187f151
Suppressing physics updates during Chunk population prevents infinite recursion due to custom Block Populators editing border blocks on chunks.
2783 Zeilen
91 KiB
Java
2783 Zeilen
91 KiB
Java
package net.minecraft.server;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Calendar;
|
|
import java.util.Collection;
|
|
import java.util.HashSet;
|
|
import java.util.Iterator;
|
|
import java.util.List;
|
|
import java.util.Random;
|
|
import java.util.Set;
|
|
import java.util.concurrent.Callable;
|
|
|
|
// CraftBukkit start
|
|
import org.bukkit.Bukkit;
|
|
import org.bukkit.craftbukkit.util.CraftMagicNumbers;
|
|
import org.bukkit.craftbukkit.util.LongHashSet;
|
|
import org.bukkit.craftbukkit.util.UnsafeList;
|
|
import org.bukkit.generator.ChunkGenerator;
|
|
import org.bukkit.craftbukkit.CraftServer;
|
|
import org.bukkit.craftbukkit.CraftWorld;
|
|
import org.bukkit.craftbukkit.event.CraftEventFactory;
|
|
import org.bukkit.event.block.BlockCanBuildEvent;
|
|
import org.bukkit.event.block.BlockPhysicsEvent;
|
|
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
|
|
import org.bukkit.event.weather.WeatherChangeEvent;
|
|
import org.bukkit.event.weather.ThunderChangeEvent;
|
|
// CraftBukkit end
|
|
|
|
public abstract class World implements IBlockAccess {
|
|
|
|
public boolean d;
|
|
public List entityList = new ArrayList();
|
|
protected List f = new ArrayList();
|
|
public Set tileEntityList = new HashSet(); // CraftBukkit - ArrayList -> HashSet
|
|
private List a = new ArrayList();
|
|
private List b = new ArrayList();
|
|
public List players = new ArrayList();
|
|
public List i = new ArrayList();
|
|
private long c = 16777215L;
|
|
public int j;
|
|
protected int k = (new Random()).nextInt();
|
|
protected final int l = 1013904223;
|
|
protected float m;
|
|
protected float n;
|
|
protected float o;
|
|
protected float p;
|
|
public int q;
|
|
public EnumDifficulty difficulty;
|
|
public Random random = new Random();
|
|
public WorldProvider worldProvider; // CraftBukkit - remove final
|
|
protected List u = new ArrayList();
|
|
public IChunkProvider chunkProvider; // CraftBukkit - public
|
|
protected final IDataManager dataManager;
|
|
public WorldData worldData; // CraftBukkit - public
|
|
public boolean isLoading;
|
|
public PersistentCollection worldMaps;
|
|
public final PersistentVillage villages;
|
|
protected final VillageSiege siegeManager = new VillageSiege(this);
|
|
public final MethodProfiler methodProfiler;
|
|
private final Vec3DPool J = new Vec3DPool(300, 2000);
|
|
private final Calendar K = Calendar.getInstance();
|
|
public Scoreboard scoreboard = new Scoreboard(); // CraftBukkit - protected -> public
|
|
public boolean isStatic;
|
|
// CraftBukkit start - public, longhashset
|
|
protected LongHashSet chunkTickList = new LongHashSet();
|
|
private int L;
|
|
public boolean allowMonsters;
|
|
public boolean allowAnimals;
|
|
// Added the following
|
|
public boolean callingPlaceEvent = false;
|
|
public long ticksPerAnimalSpawns;
|
|
public long ticksPerMonsterSpawns;
|
|
public boolean populating;
|
|
// CraftBukkit end
|
|
private ArrayList M;
|
|
private boolean N;
|
|
int[] I;
|
|
|
|
public BiomeBase getBiome(int i, int j) {
|
|
if (this.isLoaded(i, 0, j)) {
|
|
Chunk chunk = this.getChunkAtWorldCoords(i, j);
|
|
|
|
try {
|
|
return chunk.a(i & 15, j & 15, this.worldProvider.e);
|
|
} catch (Throwable throwable) {
|
|
CrashReport crashreport = CrashReport.a(throwable, "Getting biome");
|
|
CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Coordinates of biome request");
|
|
|
|
crashreportsystemdetails.a("Location", (Callable) (new CrashReportWorldLocation(this, i, j)));
|
|
throw new ReportedException(crashreport);
|
|
}
|
|
} else {
|
|
return this.worldProvider.e.getBiome(i, j);
|
|
}
|
|
}
|
|
|
|
public WorldChunkManager getWorldChunkManager() {
|
|
return this.worldProvider.e;
|
|
}
|
|
|
|
// CraftBukkit start
|
|
private final CraftWorld world;
|
|
public boolean pvpMode;
|
|
public boolean keepSpawnInMemory = true;
|
|
public ChunkGenerator generator;
|
|
Chunk lastChunkAccessed;
|
|
int lastXAccessed = Integer.MIN_VALUE;
|
|
int lastZAccessed = Integer.MIN_VALUE;
|
|
final Object chunkLock = new Object();
|
|
|
|
public CraftWorld getWorld() {
|
|
return this.world;
|
|
}
|
|
|
|
public CraftServer getServer() {
|
|
return (CraftServer) Bukkit.getServer();
|
|
}
|
|
|
|
// Changed signature - added gen and env
|
|
public World(IDataManager idatamanager, String s, WorldSettings worldsettings, WorldProvider worldprovider, MethodProfiler methodprofiler, ChunkGenerator gen, org.bukkit.World.Environment env) {
|
|
this.generator = gen;
|
|
this.world = new CraftWorld((WorldServer) this, gen, env);
|
|
this.ticksPerAnimalSpawns = this.getServer().getTicksPerAnimalSpawns(); // CraftBukkit
|
|
this.ticksPerMonsterSpawns = this.getServer().getTicksPerMonsterSpawns(); // CraftBukkit
|
|
// CraftBukkit end
|
|
|
|
this.L = this.random.nextInt(12000);
|
|
this.allowMonsters = true;
|
|
this.allowAnimals = true;
|
|
this.M = new ArrayList();
|
|
this.I = new int['\u8000'];
|
|
this.dataManager = idatamanager;
|
|
this.methodProfiler = methodprofiler;
|
|
this.worldMaps = new PersistentCollection(idatamanager);
|
|
this.worldData = idatamanager.getWorldData();
|
|
if (worldprovider != null) {
|
|
this.worldProvider = worldprovider;
|
|
} else if (this.worldData != null && this.worldData.j() != 0) {
|
|
this.worldProvider = WorldProvider.byDimension(this.worldData.j());
|
|
} else {
|
|
this.worldProvider = WorldProvider.byDimension(0);
|
|
}
|
|
|
|
if (this.worldData == null) {
|
|
this.worldData = new WorldData(worldsettings, s);
|
|
} else {
|
|
this.worldData.setName(s);
|
|
}
|
|
|
|
this.worldProvider.a(this);
|
|
this.chunkProvider = this.j();
|
|
if (!this.worldData.isInitialized()) {
|
|
try {
|
|
this.a(worldsettings);
|
|
} catch (Throwable throwable) {
|
|
CrashReport crashreport = CrashReport.a(throwable, "Exception initializing level");
|
|
|
|
try {
|
|
this.a(crashreport);
|
|
} catch (Throwable throwable1) {
|
|
;
|
|
}
|
|
|
|
throw new ReportedException(crashreport);
|
|
}
|
|
|
|
this.worldData.d(true);
|
|
}
|
|
|
|
PersistentVillage persistentvillage = (PersistentVillage) this.worldMaps.get(PersistentVillage.class, "villages");
|
|
|
|
if (persistentvillage == null) {
|
|
this.villages = new PersistentVillage(this);
|
|
this.worldMaps.a("villages", this.villages);
|
|
} else {
|
|
this.villages = persistentvillage;
|
|
this.villages.a(this);
|
|
}
|
|
|
|
this.A();
|
|
this.a();
|
|
|
|
this.getServer().addWorld(this.world); // CraftBukkit
|
|
}
|
|
|
|
protected abstract IChunkProvider j();
|
|
|
|
protected void a(WorldSettings worldsettings) {
|
|
this.worldData.d(true);
|
|
}
|
|
|
|
public Block b(int i, int j) {
|
|
int k;
|
|
|
|
for (k = 63; !this.isEmpty(i, k + 1, j); ++k) {
|
|
;
|
|
}
|
|
|
|
return this.getType(i, k, j);
|
|
}
|
|
|
|
public Block getType(int i, int j, int k) {
|
|
if (i >= -30000000 && k >= -30000000 && i < 30000000 && k < 30000000 && j >= 0 && j < 256) {
|
|
Chunk chunk = null;
|
|
|
|
try {
|
|
chunk = this.getChunkAt(i >> 4, k >> 4);
|
|
return chunk.getType(i & 15, j, k & 15);
|
|
} catch (Throwable throwable) {
|
|
CrashReport crashreport = CrashReport.a(throwable, "Exception getting block type in world");
|
|
CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Requested block coordinates");
|
|
|
|
crashreportsystemdetails.a("Found chunk", Boolean.valueOf(chunk == null));
|
|
crashreportsystemdetails.a("Location", CrashReportSystemDetails.a(i, j, k));
|
|
throw new ReportedException(crashreport);
|
|
}
|
|
} else {
|
|
return Blocks.AIR;
|
|
}
|
|
}
|
|
|
|
public boolean isEmpty(int i, int j, int k) {
|
|
return this.getType(i, j, k).getMaterial() == Material.AIR;
|
|
}
|
|
|
|
public boolean isLoaded(int i, int j, int k) {
|
|
return j >= 0 && j < 256 ? this.isChunkLoaded(i >> 4, k >> 4) : false;
|
|
}
|
|
|
|
public boolean areChunksLoaded(int i, int j, int k, int l) {
|
|
return this.b(i - l, j - l, k - l, i + l, j + l, k + l);
|
|
}
|
|
|
|
public boolean b(int i, int j, int k, int l, int i1, int j1) {
|
|
if (i1 >= 0 && j < 256) {
|
|
i >>= 4;
|
|
k >>= 4;
|
|
l >>= 4;
|
|
j1 >>= 4;
|
|
|
|
for (int k1 = i; k1 <= l; ++k1) {
|
|
for (int l1 = k; l1 <= j1; ++l1) {
|
|
// CraftBukkit - check unload queue too so we don't leak a chunk
|
|
if (!this.isChunkLoaded(k1, l1) || ((WorldServer) this).chunkProviderServer.unloadQueue.contains(k1, l1)) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
protected boolean isChunkLoaded(int i, int j) {
|
|
return this.chunkProvider.isChunkLoaded(i, j);
|
|
}
|
|
|
|
public Chunk getChunkAtWorldCoords(int i, int j) {
|
|
return this.getChunkAt(i >> 4, j >> 4);
|
|
}
|
|
|
|
public Chunk getChunkAt(int i, int j) {
|
|
// CraftBukkit start
|
|
Chunk result = null;
|
|
synchronized (this.chunkLock) {
|
|
if (this.lastChunkAccessed == null || this.lastXAccessed != i || this.lastZAccessed != j) {
|
|
this.lastChunkAccessed = this.chunkProvider.getOrCreateChunk(i, j);
|
|
this.lastXAccessed = i;
|
|
this.lastZAccessed = j;
|
|
}
|
|
result = this.lastChunkAccessed;
|
|
}
|
|
return result;
|
|
// CraftBukkit end
|
|
}
|
|
|
|
public boolean setTypeAndData(int i, int j, int k, Block block, int l, int i1) {
|
|
if (i >= -30000000 && k >= -30000000 && i < 30000000 && k < 30000000) {
|
|
if (j < 0) {
|
|
return false;
|
|
} else if (j >= 256) {
|
|
return false;
|
|
} else {
|
|
Chunk chunk = this.getChunkAt(i >> 4, k >> 4);
|
|
Block block1 = null;
|
|
|
|
if ((i1 & 1) != 0) {
|
|
block1 = chunk.getType(i & 15, j, k & 15);
|
|
}
|
|
|
|
boolean flag = chunk.a(i & 15, j, k & 15, block, l);
|
|
|
|
this.methodProfiler.a("checkLight");
|
|
this.t(i, j, k);
|
|
this.methodProfiler.b();
|
|
if (flag) {
|
|
if ((i1 & 2) != 0 && (!this.isStatic || (i1 & 4) == 0) && chunk.k()) {
|
|
this.notify(i, j, k);
|
|
}
|
|
|
|
if (!this.isStatic && (i1 & 1) != 0) {
|
|
this.update(i, j, k, block1);
|
|
if (block.M()) {
|
|
this.f(i, j, k, block);
|
|
}
|
|
}
|
|
}
|
|
|
|
return flag;
|
|
}
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public int getData(int i, int j, int k) {
|
|
if (i >= -30000000 && k >= -30000000 && i < 30000000 && k < 30000000) {
|
|
if (j < 0) {
|
|
return 0;
|
|
} else if (j >= 256) {
|
|
return 0;
|
|
} else {
|
|
Chunk chunk = this.getChunkAt(i >> 4, k >> 4);
|
|
|
|
i &= 15;
|
|
k &= 15;
|
|
return chunk.getData(i, j, k);
|
|
}
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
public boolean setData(int i, int j, int k, int l, int i1) {
|
|
if (i >= -30000000 && k >= -30000000 && i < 30000000 && k < 30000000) {
|
|
if (j < 0) {
|
|
return false;
|
|
} else if (j >= 256) {
|
|
return false;
|
|
} else {
|
|
Chunk chunk = this.getChunkAt(i >> 4, k >> 4);
|
|
int j1 = i & 15;
|
|
int k1 = k & 15;
|
|
boolean flag = chunk.a(j1, j, k1, l);
|
|
|
|
if (flag) {
|
|
Block block = chunk.getType(j1, j, k1);
|
|
|
|
if ((i1 & 2) != 0 && (!this.isStatic || (i1 & 4) == 0) && chunk.k()) {
|
|
this.notify(i, j, k);
|
|
}
|
|
|
|
if (!this.isStatic && (i1 & 1) != 0) {
|
|
this.update(i, j, k, block);
|
|
if (block.M()) {
|
|
this.f(i, j, k, block);
|
|
}
|
|
}
|
|
}
|
|
|
|
return flag;
|
|
}
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public boolean setAir(int i, int j, int k) {
|
|
return this.setTypeAndData(i, j, k, Blocks.AIR, 0, 3);
|
|
}
|
|
|
|
public boolean setAir(int i, int j, int k, boolean flag) {
|
|
Block block = this.getType(i, j, k);
|
|
|
|
if (block.getMaterial() == Material.AIR) {
|
|
return false;
|
|
} else {
|
|
int l = this.getData(i, j, k);
|
|
|
|
this.triggerEffect(2001, i, j, k, Block.b(block) + (l << 12));
|
|
if (flag) {
|
|
block.b(this, i, j, k, l, 0);
|
|
}
|
|
|
|
return this.setTypeAndData(i, j, k, Blocks.AIR, 0, 3);
|
|
}
|
|
}
|
|
|
|
public boolean setTypeUpdate(int i, int j, int k, Block block) {
|
|
return this.setTypeAndData(i, j, k, block, 0, 3);
|
|
}
|
|
|
|
public void notify(int i, int j, int k) {
|
|
for (int l = 0; l < this.u.size(); ++l) {
|
|
((IWorldAccess) this.u.get(l)).a(i, j, k);
|
|
}
|
|
}
|
|
|
|
public void update(int i, int j, int k, Block block) {
|
|
// CraftBukkit start
|
|
if (this.populating) {
|
|
return;
|
|
}
|
|
// CraftBukkit end
|
|
this.applyPhysics(i, j, k, block);
|
|
}
|
|
|
|
public void b(int i, int j, int k, int l) {
|
|
int i1;
|
|
|
|
if (k > l) {
|
|
i1 = l;
|
|
l = k;
|
|
k = i1;
|
|
}
|
|
|
|
if (!this.worldProvider.g) {
|
|
for (i1 = k; i1 <= l; ++i1) {
|
|
this.c(EnumSkyBlock.SKY, i, i1, j);
|
|
}
|
|
}
|
|
|
|
this.c(i, k, j, i, l, j);
|
|
}
|
|
|
|
public void c(int i, int j, int k, int l, int i1, int j1) {
|
|
for (int k1 = 0; k1 < this.u.size(); ++k1) {
|
|
((IWorldAccess) this.u.get(k1)).a(i, j, k, l, i1, j1);
|
|
}
|
|
}
|
|
|
|
public void applyPhysics(int i, int j, int k, Block block) {
|
|
this.e(i - 1, j, k, block);
|
|
this.e(i + 1, j, k, block);
|
|
this.e(i, j - 1, k, block);
|
|
this.e(i, j + 1, k, block);
|
|
this.e(i, j, k - 1, block);
|
|
this.e(i, j, k + 1, block);
|
|
}
|
|
|
|
public void b(int i, int j, int k, Block block, int l) {
|
|
if (l != 4) {
|
|
this.e(i - 1, j, k, block);
|
|
}
|
|
|
|
if (l != 5) {
|
|
this.e(i + 1, j, k, block);
|
|
}
|
|
|
|
if (l != 0) {
|
|
this.e(i, j - 1, k, block);
|
|
}
|
|
|
|
if (l != 1) {
|
|
this.e(i, j + 1, k, block);
|
|
}
|
|
|
|
if (l != 2) {
|
|
this.e(i, j, k - 1, block);
|
|
}
|
|
|
|
if (l != 3) {
|
|
this.e(i, j, k + 1, block);
|
|
}
|
|
}
|
|
|
|
public void e(int i, int j, int k, Block block) {
|
|
if (!this.isStatic) {
|
|
Block block1 = this.getType(i, j, k);
|
|
|
|
try {
|
|
// CraftBukkit start
|
|
CraftWorld world = ((WorldServer) this).getWorld();
|
|
if (world != null) {
|
|
BlockPhysicsEvent event = new BlockPhysicsEvent(world.getBlockAt(i, j, k), CraftMagicNumbers.getId(block));
|
|
this.getServer().getPluginManager().callEvent(event);
|
|
|
|
if (event.isCancelled()) {
|
|
return;
|
|
}
|
|
}
|
|
// CraftBukkit end
|
|
|
|
block1.doPhysics(this, i, j, k, block);
|
|
} catch (Throwable throwable) {
|
|
CrashReport crashreport = CrashReport.a(throwable, "Exception while updating neighbours");
|
|
CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Block being updated");
|
|
|
|
int l;
|
|
|
|
try {
|
|
l = this.getData(i, j, k);
|
|
} catch (Throwable throwable1) {
|
|
l = -1;
|
|
}
|
|
|
|
crashreportsystemdetails.a("Source block type", (Callable) (new CrashReportSourceBlockType(this, block)));
|
|
CrashReportSystemDetails.a(crashreportsystemdetails, i, j, k, block1, l);
|
|
throw new ReportedException(crashreport);
|
|
}
|
|
}
|
|
}
|
|
|
|
public boolean a(int i, int j, int k, Block block) {
|
|
return false;
|
|
}
|
|
|
|
public boolean i(int i, int j, int k) {
|
|
return this.getChunkAt(i >> 4, k >> 4).d(i & 15, j, k & 15);
|
|
}
|
|
|
|
public int j(int i, int j, int k) {
|
|
if (j < 0) {
|
|
return 0;
|
|
} else {
|
|
if (j >= 256) {
|
|
j = 255;
|
|
}
|
|
|
|
return this.getChunkAt(i >> 4, k >> 4).b(i & 15, j, k & 15, 0);
|
|
}
|
|
}
|
|
|
|
public int getLightLevel(int i, int j, int k) {
|
|
return this.b(i, j, k, true);
|
|
}
|
|
|
|
public int b(int i, int j, int k, boolean flag) {
|
|
if (i >= -30000000 && k >= -30000000 && i < 30000000 && k < 30000000) {
|
|
if (flag && this.getType(i, j, k).n()) {
|
|
int l = this.b(i, j + 1, k, false);
|
|
int i1 = this.b(i + 1, j, k, false);
|
|
int j1 = this.b(i - 1, j, k, false);
|
|
int k1 = this.b(i, j, k + 1, false);
|
|
int l1 = this.b(i, j, k - 1, false);
|
|
|
|
if (i1 > l) {
|
|
l = i1;
|
|
}
|
|
|
|
if (j1 > l) {
|
|
l = j1;
|
|
}
|
|
|
|
if (k1 > l) {
|
|
l = k1;
|
|
}
|
|
|
|
if (l1 > l) {
|
|
l = l1;
|
|
}
|
|
|
|
return l;
|
|
} else if (j < 0) {
|
|
return 0;
|
|
} else {
|
|
if (j >= 256) {
|
|
j = 255;
|
|
}
|
|
|
|
Chunk chunk = this.getChunkAt(i >> 4, k >> 4);
|
|
|
|
i &= 15;
|
|
k &= 15;
|
|
return chunk.b(i, j, k, this.j);
|
|
}
|
|
} else {
|
|
return 15;
|
|
}
|
|
}
|
|
|
|
public int getHighestBlockYAt(int i, int j) {
|
|
if (i >= -30000000 && j >= -30000000 && i < 30000000 && j < 30000000) {
|
|
if (!this.isChunkLoaded(i >> 4, j >> 4)) {
|
|
return 0;
|
|
} else {
|
|
Chunk chunk = this.getChunkAt(i >> 4, j >> 4);
|
|
|
|
return chunk.b(i & 15, j & 15);
|
|
}
|
|
} else {
|
|
return 64;
|
|
}
|
|
}
|
|
|
|
public int g(int i, int j) {
|
|
if (i >= -30000000 && j >= -30000000 && i < 30000000 && j < 30000000) {
|
|
if (!this.isChunkLoaded(i >> 4, j >> 4)) {
|
|
return 0;
|
|
} else {
|
|
Chunk chunk = this.getChunkAt(i >> 4, j >> 4);
|
|
|
|
return chunk.r;
|
|
}
|
|
} else {
|
|
return 64;
|
|
}
|
|
}
|
|
|
|
public int b(EnumSkyBlock enumskyblock, int i, int j, int k) {
|
|
if (j < 0) {
|
|
j = 0;
|
|
}
|
|
|
|
if (j >= 256) {
|
|
j = 255;
|
|
}
|
|
|
|
if (i >= -30000000 && k >= -30000000 && i < 30000000 && k < 30000000) {
|
|
int l = i >> 4;
|
|
int i1 = k >> 4;
|
|
|
|
if (!this.isChunkLoaded(l, i1)) {
|
|
return enumskyblock.c;
|
|
} else {
|
|
Chunk chunk = this.getChunkAt(l, i1);
|
|
|
|
return chunk.getBrightness(enumskyblock, i & 15, j, k & 15);
|
|
}
|
|
} else {
|
|
return enumskyblock.c;
|
|
}
|
|
}
|
|
|
|
public void b(EnumSkyBlock enumskyblock, int i, int j, int k, int l) {
|
|
if (i >= -30000000 && k >= -30000000 && i < 30000000 && k < 30000000) {
|
|
if (j >= 0) {
|
|
if (j < 256) {
|
|
if (this.isChunkLoaded(i >> 4, k >> 4)) {
|
|
Chunk chunk = this.getChunkAt(i >> 4, k >> 4);
|
|
|
|
chunk.a(enumskyblock, i & 15, j, k & 15, l);
|
|
|
|
for (int i1 = 0; i1 < this.u.size(); ++i1) {
|
|
((IWorldAccess) this.u.get(i1)).b(i, j, k);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void m(int i, int j, int k) {
|
|
for (int l = 0; l < this.u.size(); ++l) {
|
|
((IWorldAccess) this.u.get(l)).b(i, j, k);
|
|
}
|
|
}
|
|
|
|
public float n(int i, int j, int k) {
|
|
return this.worldProvider.h[this.getLightLevel(i, j, k)];
|
|
}
|
|
|
|
public boolean v() {
|
|
return this.j < 4;
|
|
}
|
|
|
|
public MovingObjectPosition a(Vec3D vec3d, Vec3D vec3d1) {
|
|
return this.rayTrace(vec3d, vec3d1, false, false, false);
|
|
}
|
|
|
|
public MovingObjectPosition rayTrace(Vec3D vec3d, Vec3D vec3d1, boolean flag) {
|
|
return this.rayTrace(vec3d, vec3d1, flag, false, false);
|
|
}
|
|
|
|
public MovingObjectPosition rayTrace(Vec3D vec3d, Vec3D vec3d1, boolean flag, boolean flag1, boolean flag2) {
|
|
if (!Double.isNaN(vec3d.c) && !Double.isNaN(vec3d.d) && !Double.isNaN(vec3d.e)) {
|
|
if (!Double.isNaN(vec3d1.c) && !Double.isNaN(vec3d1.d) && !Double.isNaN(vec3d1.e)) {
|
|
int i = MathHelper.floor(vec3d1.c);
|
|
int j = MathHelper.floor(vec3d1.d);
|
|
int k = MathHelper.floor(vec3d1.e);
|
|
int l = MathHelper.floor(vec3d.c);
|
|
int i1 = MathHelper.floor(vec3d.d);
|
|
int j1 = MathHelper.floor(vec3d.e);
|
|
Block block = this.getType(l, i1, j1);
|
|
int k1 = this.getData(l, i1, j1);
|
|
|
|
if ((!flag1 || block.a(this, l, i1, j1) != null) && block.a(k1, flag)) {
|
|
MovingObjectPosition movingobjectposition = block.a(this, l, i1, j1, vec3d, vec3d1);
|
|
|
|
if (movingobjectposition != null) {
|
|
return movingobjectposition;
|
|
}
|
|
}
|
|
|
|
MovingObjectPosition movingobjectposition1 = null;
|
|
|
|
k1 = 200;
|
|
|
|
while (k1-- >= 0) {
|
|
if (Double.isNaN(vec3d.c) || Double.isNaN(vec3d.d) || Double.isNaN(vec3d.e)) {
|
|
return null;
|
|
}
|
|
|
|
if (l == i && i1 == j && j1 == k) {
|
|
return flag2 ? movingobjectposition1 : null;
|
|
}
|
|
|
|
boolean flag3 = true;
|
|
boolean flag4 = true;
|
|
boolean flag5 = true;
|
|
double d0 = 999.0D;
|
|
double d1 = 999.0D;
|
|
double d2 = 999.0D;
|
|
|
|
if (i > l) {
|
|
d0 = (double) l + 1.0D;
|
|
} else if (i < l) {
|
|
d0 = (double) l + 0.0D;
|
|
} else {
|
|
flag3 = false;
|
|
}
|
|
|
|
if (j > i1) {
|
|
d1 = (double) i1 + 1.0D;
|
|
} else if (j < i1) {
|
|
d1 = (double) i1 + 0.0D;
|
|
} else {
|
|
flag4 = false;
|
|
}
|
|
|
|
if (k > j1) {
|
|
d2 = (double) j1 + 1.0D;
|
|
} else if (k < j1) {
|
|
d2 = (double) j1 + 0.0D;
|
|
} else {
|
|
flag5 = false;
|
|
}
|
|
|
|
double d3 = 999.0D;
|
|
double d4 = 999.0D;
|
|
double d5 = 999.0D;
|
|
double d6 = vec3d1.c - vec3d.c;
|
|
double d7 = vec3d1.d - vec3d.d;
|
|
double d8 = vec3d1.e - vec3d.e;
|
|
|
|
if (flag3) {
|
|
d3 = (d0 - vec3d.c) / d6;
|
|
}
|
|
|
|
if (flag4) {
|
|
d4 = (d1 - vec3d.d) / d7;
|
|
}
|
|
|
|
if (flag5) {
|
|
d5 = (d2 - vec3d.e) / d8;
|
|
}
|
|
|
|
boolean flag6 = false;
|
|
byte b0;
|
|
|
|
if (d3 < d4 && d3 < d5) {
|
|
if (i > l) {
|
|
b0 = 4;
|
|
} else {
|
|
b0 = 5;
|
|
}
|
|
|
|
vec3d.c = d0;
|
|
vec3d.d += d7 * d3;
|
|
vec3d.e += d8 * d3;
|
|
} else if (d4 < d5) {
|
|
if (j > i1) {
|
|
b0 = 0;
|
|
} else {
|
|
b0 = 1;
|
|
}
|
|
|
|
vec3d.c += d6 * d4;
|
|
vec3d.d = d1;
|
|
vec3d.e += d8 * d4;
|
|
} else {
|
|
if (k > j1) {
|
|
b0 = 2;
|
|
} else {
|
|
b0 = 3;
|
|
}
|
|
|
|
vec3d.c += d6 * d5;
|
|
vec3d.d += d7 * d5;
|
|
vec3d.e = d2;
|
|
}
|
|
|
|
Vec3D vec3d2 = this.getVec3DPool().create(vec3d.c, vec3d.d, vec3d.e);
|
|
|
|
l = (int) (vec3d2.c = (double) MathHelper.floor(vec3d.c));
|
|
if (b0 == 5) {
|
|
--l;
|
|
++vec3d2.c;
|
|
}
|
|
|
|
i1 = (int) (vec3d2.d = (double) MathHelper.floor(vec3d.d));
|
|
if (b0 == 1) {
|
|
--i1;
|
|
++vec3d2.d;
|
|
}
|
|
|
|
j1 = (int) (vec3d2.e = (double) MathHelper.floor(vec3d.e));
|
|
if (b0 == 3) {
|
|
--j1;
|
|
++vec3d2.e;
|
|
}
|
|
|
|
Block block1 = this.getType(l, i1, j1);
|
|
int l1 = this.getData(l, i1, j1);
|
|
|
|
if (!flag1 || block1.a(this, l, i1, j1) != null) {
|
|
if (block1.a(l1, flag)) {
|
|
MovingObjectPosition movingobjectposition2 = block1.a(this, l, i1, j1, vec3d, vec3d1);
|
|
|
|
if (movingobjectposition2 != null) {
|
|
vec3d2.b.release(vec3d2); // CraftBukkit
|
|
return movingobjectposition2;
|
|
}
|
|
} else {
|
|
movingobjectposition1 = new MovingObjectPosition(l, i1, j1, b0, vec3d, false);
|
|
}
|
|
}
|
|
vec3d2.b.release(vec3d2); // CraftBukkit
|
|
}
|
|
|
|
return flag2 ? movingobjectposition1 : null;
|
|
} else {
|
|
return null;
|
|
}
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public void makeSound(Entity entity, String s, float f, float f1) {
|
|
for (int i = 0; i < this.u.size(); ++i) {
|
|
((IWorldAccess) this.u.get(i)).a(s, entity.locX, entity.locY - (double) entity.height, entity.locZ, f, f1);
|
|
}
|
|
}
|
|
|
|
public void a(EntityHuman entityhuman, String s, float f, float f1) {
|
|
for (int i = 0; i < this.u.size(); ++i) {
|
|
((IWorldAccess) this.u.get(i)).a(entityhuman, s, entityhuman.locX, entityhuman.locY - (double) entityhuman.height, entityhuman.locZ, f, f1);
|
|
}
|
|
}
|
|
|
|
public void makeSound(double d0, double d1, double d2, String s, float f, float f1) {
|
|
for (int i = 0; i < this.u.size(); ++i) {
|
|
((IWorldAccess) this.u.get(i)).a(s, d0, d1, d2, f, f1);
|
|
}
|
|
}
|
|
|
|
public void a(double d0, double d1, double d2, String s, float f, float f1, boolean flag) {}
|
|
|
|
public void a(String s, int i, int j, int k) {
|
|
for (int l = 0; l < this.u.size(); ++l) {
|
|
((IWorldAccess) this.u.get(l)).a(s, i, j, k);
|
|
}
|
|
}
|
|
|
|
public void addParticle(String s, double d0, double d1, double d2, double d3, double d4, double d5) {
|
|
for (int i = 0; i < this.u.size(); ++i) {
|
|
((IWorldAccess) this.u.get(i)).a(s, d0, d1, d2, d3, d4, d5);
|
|
}
|
|
}
|
|
|
|
public boolean strikeLightning(Entity entity) {
|
|
this.i.add(entity);
|
|
return true;
|
|
}
|
|
|
|
public boolean addEntity(Entity entity) {
|
|
// CraftBukkit start - Used for entities other than creatures
|
|
return this.addEntity(entity, SpawnReason.DEFAULT); // Set reason as DEFAULT
|
|
}
|
|
|
|
public boolean addEntity(Entity entity, SpawnReason spawnReason) { // Changed signature, added SpawnReason
|
|
if (entity == null) return false;
|
|
// CraftBukkit end
|
|
|
|
int i = MathHelper.floor(entity.locX / 16.0D);
|
|
int j = MathHelper.floor(entity.locZ / 16.0D);
|
|
boolean flag = entity.o;
|
|
|
|
if (entity instanceof EntityHuman) {
|
|
flag = true;
|
|
}
|
|
|
|
// CraftBukkit start
|
|
org.bukkit.event.Cancellable event = null;
|
|
if (entity instanceof EntityLiving && !(entity instanceof EntityPlayer)) {
|
|
boolean isAnimal = entity instanceof EntityAnimal || entity instanceof EntityWaterAnimal || entity instanceof EntityGolem;
|
|
boolean isMonster = entity instanceof EntityMonster || entity instanceof EntityGhast || entity instanceof EntitySlime;
|
|
|
|
if (spawnReason != SpawnReason.CUSTOM) {
|
|
if (isAnimal && !allowAnimals || isMonster && !allowMonsters) {
|
|
entity.dead = true;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
event = CraftEventFactory.callCreatureSpawnEvent((EntityLiving) entity, spawnReason);
|
|
} else if (entity instanceof EntityItem) {
|
|
event = CraftEventFactory.callItemSpawnEvent((EntityItem) entity);
|
|
} else if (entity.getBukkitEntity() instanceof org.bukkit.entity.Projectile) {
|
|
// Not all projectiles extend EntityProjectile, so check for Bukkit interface instead
|
|
event = CraftEventFactory.callProjectileLaunchEvent(entity);
|
|
}
|
|
|
|
if (event != null && (event.isCancelled() || entity.dead)) {
|
|
entity.dead = true;
|
|
return false;
|
|
}
|
|
// CraftBukkit end
|
|
|
|
if (!flag && !this.isChunkLoaded(i, j)) {
|
|
entity.dead = true; // CraftBukkit
|
|
return false;
|
|
} else {
|
|
if (entity instanceof EntityHuman) {
|
|
EntityHuman entityhuman = (EntityHuman) entity;
|
|
|
|
this.players.add(entityhuman);
|
|
this.everyoneSleeping();
|
|
}
|
|
|
|
this.getChunkAt(i, j).a(entity);
|
|
this.entityList.add(entity);
|
|
this.a(entity);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
protected void a(Entity entity) {
|
|
for (int i = 0; i < this.u.size(); ++i) {
|
|
((IWorldAccess) this.u.get(i)).a(entity);
|
|
}
|
|
|
|
entity.valid = true; // CraftBukkit
|
|
}
|
|
|
|
protected void b(Entity entity) {
|
|
for (int i = 0; i < this.u.size(); ++i) {
|
|
((IWorldAccess) this.u.get(i)).b(entity);
|
|
}
|
|
|
|
entity.valid = false; // CraftBukkit
|
|
}
|
|
|
|
public void kill(Entity entity) {
|
|
if (entity.passenger != null) {
|
|
entity.passenger.mount((Entity) null);
|
|
}
|
|
|
|
if (entity.vehicle != null) {
|
|
entity.mount((Entity) null);
|
|
}
|
|
|
|
entity.die();
|
|
if (entity instanceof EntityHuman) {
|
|
this.players.remove(entity);
|
|
this.everyoneSleeping();
|
|
}
|
|
}
|
|
|
|
public void removeEntity(Entity entity) {
|
|
entity.die();
|
|
if (entity instanceof EntityHuman) {
|
|
this.players.remove(entity);
|
|
this.everyoneSleeping();
|
|
}
|
|
|
|
int i = entity.ai;
|
|
int j = entity.ak;
|
|
|
|
if (entity.ah && this.isChunkLoaded(i, j)) {
|
|
this.getChunkAt(i, j).b(entity);
|
|
}
|
|
|
|
this.entityList.remove(entity);
|
|
this.b(entity);
|
|
}
|
|
|
|
public void addIWorldAccess(IWorldAccess iworldaccess) {
|
|
this.u.add(iworldaccess);
|
|
}
|
|
|
|
public List getCubes(Entity entity, AxisAlignedBB axisalignedbb) {
|
|
this.M.clear();
|
|
int i = MathHelper.floor(axisalignedbb.a);
|
|
int j = MathHelper.floor(axisalignedbb.d + 1.0D);
|
|
int k = MathHelper.floor(axisalignedbb.b);
|
|
int l = MathHelper.floor(axisalignedbb.e + 1.0D);
|
|
int i1 = MathHelper.floor(axisalignedbb.c);
|
|
int j1 = MathHelper.floor(axisalignedbb.f + 1.0D);
|
|
|
|
for (int k1 = i; k1 < j; ++k1) {
|
|
for (int l1 = i1; l1 < j1; ++l1) {
|
|
if (this.isLoaded(k1, 64, l1)) {
|
|
for (int i2 = k - 1; i2 < l; ++i2) {
|
|
Block block;
|
|
|
|
if (k1 >= -30000000 && k1 < 30000000 && l1 >= -30000000 && l1 < 30000000) {
|
|
block = this.getType(k1, i2, l1);
|
|
} else {
|
|
block = Blocks.STONE;
|
|
}
|
|
|
|
block.a(this, k1, i2, l1, axisalignedbb, this.M, entity);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
double d0 = 0.25D;
|
|
List list = this.getEntities(entity, axisalignedbb.grow(d0, d0, d0));
|
|
|
|
for (int j2 = 0; j2 < list.size(); ++j2) {
|
|
AxisAlignedBB axisalignedbb1 = ((Entity) list.get(j2)).J();
|
|
|
|
if (axisalignedbb1 != null && axisalignedbb1.b(axisalignedbb)) {
|
|
this.M.add(axisalignedbb1);
|
|
}
|
|
|
|
axisalignedbb1 = entity.g((Entity) list.get(j2));
|
|
if (axisalignedbb1 != null && axisalignedbb1.b(axisalignedbb)) {
|
|
this.M.add(axisalignedbb1);
|
|
}
|
|
}
|
|
|
|
return this.M;
|
|
}
|
|
|
|
public List a(AxisAlignedBB axisalignedbb) {
|
|
this.M.clear();
|
|
int i = MathHelper.floor(axisalignedbb.a);
|
|
int j = MathHelper.floor(axisalignedbb.d + 1.0D);
|
|
int k = MathHelper.floor(axisalignedbb.b);
|
|
int l = MathHelper.floor(axisalignedbb.e + 1.0D);
|
|
int i1 = MathHelper.floor(axisalignedbb.c);
|
|
int j1 = MathHelper.floor(axisalignedbb.f + 1.0D);
|
|
|
|
for (int k1 = i; k1 < j; ++k1) {
|
|
for (int l1 = i1; l1 < j1; ++l1) {
|
|
if (this.isLoaded(k1, 64, l1)) {
|
|
for (int i2 = k - 1; i2 < l; ++i2) {
|
|
Block block;
|
|
|
|
if (k1 >= -30000000 && k1 < 30000000 && l1 >= -30000000 && l1 < 30000000) {
|
|
block = this.getType(k1, i2, l1);
|
|
} else {
|
|
block = Blocks.BEDROCK;
|
|
}
|
|
|
|
block.a(this, k1, i2, l1, axisalignedbb, this.M, (Entity) null);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return this.M;
|
|
}
|
|
|
|
public int a(float f) {
|
|
float f1 = this.c(f);
|
|
float f2 = 1.0F - (MathHelper.cos(f1 * 3.1415927F * 2.0F) * 2.0F + 0.5F);
|
|
|
|
if (f2 < 0.0F) {
|
|
f2 = 0.0F;
|
|
}
|
|
|
|
if (f2 > 1.0F) {
|
|
f2 = 1.0F;
|
|
}
|
|
|
|
f2 = 1.0F - f2;
|
|
f2 = (float) ((double) f2 * (1.0D - (double) (this.j(f) * 5.0F) / 16.0D));
|
|
f2 = (float) ((double) f2 * (1.0D - (double) (this.h(f) * 5.0F) / 16.0D));
|
|
f2 = 1.0F - f2;
|
|
return (int) (f2 * 11.0F);
|
|
}
|
|
|
|
public float c(float f) {
|
|
return this.worldProvider.a(this.worldData.getDayTime(), f);
|
|
}
|
|
|
|
public float x() {
|
|
return WorldProvider.a[this.worldProvider.a(this.worldData.getDayTime())];
|
|
}
|
|
|
|
public float d(float f) {
|
|
float f1 = this.c(f);
|
|
|
|
return f1 * 3.1415927F * 2.0F;
|
|
}
|
|
|
|
public int h(int i, int j) {
|
|
return this.getChunkAtWorldCoords(i, j).d(i & 15, j & 15);
|
|
}
|
|
|
|
public int i(int i, int j) {
|
|
Chunk chunk = this.getChunkAtWorldCoords(i, j);
|
|
int k = chunk.h() + 15;
|
|
|
|
i &= 15;
|
|
|
|
for (j &= 15; k > 0; --k) {
|
|
Block block = chunk.getType(i, k, j);
|
|
|
|
if (block.getMaterial().isSolid() && block.getMaterial() != Material.LEAVES) {
|
|
return k + 1;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
public void a(int i, int j, int k, Block block, int l) {}
|
|
|
|
public void a(int i, int j, int k, Block block, int l, int i1) {}
|
|
|
|
public void b(int i, int j, int k, Block block, int l, int i1) {}
|
|
|
|
public void tickEntities() {
|
|
this.methodProfiler.a("entities");
|
|
this.methodProfiler.a("global");
|
|
|
|
int i;
|
|
Entity entity;
|
|
CrashReport crashreport;
|
|
CrashReportSystemDetails crashreportsystemdetails;
|
|
|
|
for (i = 0; i < this.i.size(); ++i) {
|
|
entity = (Entity) this.i.get(i);
|
|
// CraftBukkit start - Fixed an NPE, don't process entities in chunks queued for unload
|
|
if (entity == null) {
|
|
continue;
|
|
}
|
|
|
|
ChunkProviderServer chunkProviderServer = ((WorldServer) this).chunkProviderServer;
|
|
if (chunkProviderServer.unloadQueue.contains(MathHelper.floor(entity.locX) >> 4, MathHelper.floor(entity.locZ) >> 4)) {
|
|
continue;
|
|
}
|
|
// CraftBukkit end
|
|
|
|
try {
|
|
++entity.ticksLived;
|
|
entity.h();
|
|
} catch (Throwable throwable) {
|
|
crashreport = CrashReport.a(throwable, "Ticking entity");
|
|
crashreportsystemdetails = crashreport.a("Entity being ticked");
|
|
if (entity == null) {
|
|
crashreportsystemdetails.a("Entity", "~~NULL~~");
|
|
} else {
|
|
entity.a(crashreportsystemdetails);
|
|
}
|
|
|
|
throw new ReportedException(crashreport);
|
|
}
|
|
|
|
if (entity.dead) {
|
|
this.i.remove(i--);
|
|
}
|
|
}
|
|
|
|
this.methodProfiler.c("remove");
|
|
this.entityList.removeAll(this.f);
|
|
|
|
int j;
|
|
int k;
|
|
|
|
for (i = 0; i < this.f.size(); ++i) {
|
|
entity = (Entity) this.f.get(i);
|
|
j = entity.ai;
|
|
k = entity.ak;
|
|
if (entity.ah && this.isChunkLoaded(j, k)) {
|
|
this.getChunkAt(j, k).b(entity);
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < this.f.size(); ++i) {
|
|
this.b((Entity) this.f.get(i));
|
|
}
|
|
|
|
this.f.clear();
|
|
this.methodProfiler.c("regular");
|
|
|
|
for (i = 0; i < this.entityList.size(); ++i) {
|
|
entity = (Entity) this.entityList.get(i);
|
|
|
|
// CraftBukkit start - Don't tick entities in chunks queued for unload
|
|
ChunkProviderServer chunkProviderServer = ((WorldServer) this).chunkProviderServer;
|
|
if (chunkProviderServer.unloadQueue.contains(MathHelper.floor(entity.locX) >> 4, MathHelper.floor(entity.locZ) >> 4)) {
|
|
continue;
|
|
}
|
|
// CraftBukkit end
|
|
|
|
if (entity.vehicle != null) {
|
|
if (!entity.vehicle.dead && entity.vehicle.passenger == entity) {
|
|
continue;
|
|
}
|
|
|
|
entity.vehicle.passenger = null;
|
|
entity.vehicle = null;
|
|
}
|
|
|
|
this.methodProfiler.a("tick");
|
|
if (!entity.dead) {
|
|
try {
|
|
this.playerJoinedWorld(entity);
|
|
} catch (Throwable throwable1) {
|
|
crashreport = CrashReport.a(throwable1, "Ticking entity");
|
|
crashreportsystemdetails = crashreport.a("Entity being ticked");
|
|
entity.a(crashreportsystemdetails);
|
|
throw new ReportedException(crashreport);
|
|
}
|
|
}
|
|
|
|
this.methodProfiler.b();
|
|
this.methodProfiler.a("remove");
|
|
if (entity.dead) {
|
|
j = entity.ai;
|
|
k = entity.ak;
|
|
if (entity.ah && this.isChunkLoaded(j, k)) {
|
|
this.getChunkAt(j, k).b(entity);
|
|
}
|
|
|
|
this.entityList.remove(i--);
|
|
this.b(entity);
|
|
}
|
|
|
|
this.methodProfiler.b();
|
|
}
|
|
|
|
this.methodProfiler.c("blockEntities");
|
|
this.N = true;
|
|
Iterator iterator = this.tileEntityList.iterator();
|
|
|
|
while (iterator.hasNext()) {
|
|
TileEntity tileentity = (TileEntity) iterator.next();
|
|
// CraftBukkit start - Don't tick entities in chunks queued for unload
|
|
ChunkProviderServer chunkProviderServer = ((WorldServer) this).chunkProviderServer;
|
|
if (chunkProviderServer.unloadQueue.contains(tileentity.x >> 4, tileentity.z >> 4)) {
|
|
continue;
|
|
}
|
|
// CraftBukkit end
|
|
|
|
if (!tileentity.r() && tileentity.o() && this.isLoaded(tileentity.x, tileentity.y, tileentity.z)) {
|
|
try {
|
|
tileentity.h();
|
|
} catch (Throwable throwable2) {
|
|
crashreport = CrashReport.a(throwable2, "Ticking block entity");
|
|
crashreportsystemdetails = crashreport.a("Block entity being ticked");
|
|
tileentity.a(crashreportsystemdetails);
|
|
throw new ReportedException(crashreport);
|
|
}
|
|
}
|
|
|
|
if (tileentity.r()) {
|
|
iterator.remove();
|
|
if (this.isChunkLoaded(tileentity.x >> 4, tileentity.z >> 4)) {
|
|
Chunk chunk = this.getChunkAt(tileentity.x >> 4, tileentity.z >> 4);
|
|
|
|
if (chunk != null) {
|
|
chunk.f(tileentity.x & 15, tileentity.y, tileentity.z & 15);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
this.N = false;
|
|
if (!this.b.isEmpty()) {
|
|
this.tileEntityList.removeAll(this.b);
|
|
this.b.clear();
|
|
}
|
|
|
|
this.methodProfiler.c("pendingBlockEntities");
|
|
if (!this.a.isEmpty()) {
|
|
for (int l = 0; l < this.a.size(); ++l) {
|
|
TileEntity tileentity1 = (TileEntity) this.a.get(l);
|
|
|
|
if (!tileentity1.r()) {
|
|
/* CraftBukkit start - Order matters, moved down
|
|
if (!this.tileEntityList.contains(tileentity1)) {
|
|
this.tileEntityList.add(tileentity1);
|
|
}
|
|
// CraftBukkit end */
|
|
|
|
if (this.isChunkLoaded(tileentity1.x >> 4, tileentity1.z >> 4)) {
|
|
Chunk chunk1 = this.getChunkAt(tileentity1.x >> 4, tileentity1.z >> 4);
|
|
|
|
if (chunk1 != null) {
|
|
chunk1.a(tileentity1.x & 15, tileentity1.y, tileentity1.z & 15, tileentity1);
|
|
// CraftBukkit start - Moved down from above
|
|
if (!this.tileEntityList.contains(tileentity1)) {
|
|
this.tileEntityList.add(tileentity1);
|
|
}
|
|
// CraftBukkit end
|
|
}
|
|
}
|
|
|
|
this.notify(tileentity1.x, tileentity1.y, tileentity1.z);
|
|
}
|
|
}
|
|
|
|
this.a.clear();
|
|
}
|
|
|
|
this.methodProfiler.b();
|
|
this.methodProfiler.b();
|
|
}
|
|
|
|
public void a(Collection collection) {
|
|
if (this.N) {
|
|
this.a.addAll(collection);
|
|
} else {
|
|
this.tileEntityList.addAll(collection);
|
|
}
|
|
}
|
|
|
|
public void playerJoinedWorld(Entity entity) {
|
|
this.entityJoinedWorld(entity, true);
|
|
}
|
|
|
|
public void entityJoinedWorld(Entity entity, boolean flag) {
|
|
int i = MathHelper.floor(entity.locX);
|
|
int j = MathHelper.floor(entity.locZ);
|
|
byte b0 = 32;
|
|
|
|
if (!flag || this.b(i - b0, 0, j - b0, i + b0, 0, j + b0)) {
|
|
entity.T = entity.locX;
|
|
entity.U = entity.locY;
|
|
entity.V = entity.locZ;
|
|
entity.lastYaw = entity.yaw;
|
|
entity.lastPitch = entity.pitch;
|
|
if (flag && entity.ah) {
|
|
++entity.ticksLived;
|
|
if (entity.vehicle != null) {
|
|
entity.ab();
|
|
} else {
|
|
entity.h();
|
|
}
|
|
}
|
|
|
|
this.methodProfiler.a("chunkCheck");
|
|
if (Double.isNaN(entity.locX) || Double.isInfinite(entity.locX)) {
|
|
entity.locX = entity.T;
|
|
}
|
|
|
|
if (Double.isNaN(entity.locY) || Double.isInfinite(entity.locY)) {
|
|
entity.locY = entity.U;
|
|
}
|
|
|
|
if (Double.isNaN(entity.locZ) || Double.isInfinite(entity.locZ)) {
|
|
entity.locZ = entity.V;
|
|
}
|
|
|
|
if (Double.isNaN((double) entity.pitch) || Double.isInfinite((double) entity.pitch)) {
|
|
entity.pitch = entity.lastPitch;
|
|
}
|
|
|
|
if (Double.isNaN((double) entity.yaw) || Double.isInfinite((double) entity.yaw)) {
|
|
entity.yaw = entity.lastYaw;
|
|
}
|
|
|
|
int k = MathHelper.floor(entity.locX / 16.0D);
|
|
int l = MathHelper.floor(entity.locY / 16.0D);
|
|
int i1 = MathHelper.floor(entity.locZ / 16.0D);
|
|
|
|
if (!entity.ah || entity.ai != k || entity.aj != l || entity.ak != i1) {
|
|
if (entity.ah && this.isChunkLoaded(entity.ai, entity.ak)) {
|
|
this.getChunkAt(entity.ai, entity.ak).a(entity, entity.aj);
|
|
}
|
|
|
|
if (this.isChunkLoaded(k, i1)) {
|
|
entity.ah = true;
|
|
this.getChunkAt(k, i1).a(entity);
|
|
} else {
|
|
entity.ah = false;
|
|
}
|
|
}
|
|
|
|
this.methodProfiler.b();
|
|
if (flag && entity.ah && entity.passenger != null) {
|
|
if (!entity.passenger.dead && entity.passenger.vehicle == entity) {
|
|
this.playerJoinedWorld(entity.passenger);
|
|
} else {
|
|
entity.passenger.vehicle = null;
|
|
entity.passenger = null;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public boolean b(AxisAlignedBB axisalignedbb) {
|
|
return this.a(axisalignedbb, (Entity) null);
|
|
}
|
|
|
|
public boolean a(AxisAlignedBB axisalignedbb, Entity entity) {
|
|
List list = this.getEntities((Entity) null, axisalignedbb);
|
|
|
|
for (int i = 0; i < list.size(); ++i) {
|
|
Entity entity1 = (Entity) list.get(i);
|
|
|
|
if (!entity1.dead && entity1.l && entity1 != entity) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public boolean c(AxisAlignedBB axisalignedbb) {
|
|
int i = MathHelper.floor(axisalignedbb.a);
|
|
int j = MathHelper.floor(axisalignedbb.d + 1.0D);
|
|
int k = MathHelper.floor(axisalignedbb.b);
|
|
int l = MathHelper.floor(axisalignedbb.e + 1.0D);
|
|
int i1 = MathHelper.floor(axisalignedbb.c);
|
|
int j1 = MathHelper.floor(axisalignedbb.f + 1.0D);
|
|
|
|
if (axisalignedbb.a < 0.0D) {
|
|
--i;
|
|
}
|
|
|
|
if (axisalignedbb.b < 0.0D) {
|
|
--k;
|
|
}
|
|
|
|
if (axisalignedbb.c < 0.0D) {
|
|
--i1;
|
|
}
|
|
|
|
for (int k1 = i; k1 < j; ++k1) {
|
|
for (int l1 = k; l1 < l; ++l1) {
|
|
for (int i2 = i1; i2 < j1; ++i2) {
|
|
Block block = this.getType(k1, l1, i2);
|
|
|
|
if (block.getMaterial() != Material.AIR) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public boolean containsLiquid(AxisAlignedBB axisalignedbb) {
|
|
int i = MathHelper.floor(axisalignedbb.a);
|
|
int j = MathHelper.floor(axisalignedbb.d + 1.0D);
|
|
int k = MathHelper.floor(axisalignedbb.b);
|
|
int l = MathHelper.floor(axisalignedbb.e + 1.0D);
|
|
int i1 = MathHelper.floor(axisalignedbb.c);
|
|
int j1 = MathHelper.floor(axisalignedbb.f + 1.0D);
|
|
|
|
if (axisalignedbb.a < 0.0D) {
|
|
--i;
|
|
}
|
|
|
|
if (axisalignedbb.b < 0.0D) {
|
|
--k;
|
|
}
|
|
|
|
if (axisalignedbb.c < 0.0D) {
|
|
--i1;
|
|
}
|
|
|
|
for (int k1 = i; k1 < j; ++k1) {
|
|
for (int l1 = k; l1 < l; ++l1) {
|
|
for (int i2 = i1; i2 < j1; ++i2) {
|
|
Block block = this.getType(k1, l1, i2);
|
|
|
|
if (block.getMaterial().isLiquid()) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public boolean e(AxisAlignedBB axisalignedbb) {
|
|
int i = MathHelper.floor(axisalignedbb.a);
|
|
int j = MathHelper.floor(axisalignedbb.d + 1.0D);
|
|
int k = MathHelper.floor(axisalignedbb.b);
|
|
int l = MathHelper.floor(axisalignedbb.e + 1.0D);
|
|
int i1 = MathHelper.floor(axisalignedbb.c);
|
|
int j1 = MathHelper.floor(axisalignedbb.f + 1.0D);
|
|
|
|
if (this.b(i, k, i1, j, l, j1)) {
|
|
for (int k1 = i; k1 < j; ++k1) {
|
|
for (int l1 = k; l1 < l; ++l1) {
|
|
for (int i2 = i1; i2 < j1; ++i2) {
|
|
Block block = this.getType(k1, l1, i2);
|
|
|
|
if (block == Blocks.FIRE || block == Blocks.LAVA || block == Blocks.STATIONARY_LAVA) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public boolean a(AxisAlignedBB axisalignedbb, Material material, Entity entity) {
|
|
int i = MathHelper.floor(axisalignedbb.a);
|
|
int j = MathHelper.floor(axisalignedbb.d + 1.0D);
|
|
int k = MathHelper.floor(axisalignedbb.b);
|
|
int l = MathHelper.floor(axisalignedbb.e + 1.0D);
|
|
int i1 = MathHelper.floor(axisalignedbb.c);
|
|
int j1 = MathHelper.floor(axisalignedbb.f + 1.0D);
|
|
|
|
if (!this.b(i, k, i1, j, l, j1)) {
|
|
return false;
|
|
} else {
|
|
boolean flag = false;
|
|
Vec3D vec3d = this.getVec3DPool().create(0.0D, 0.0D, 0.0D);
|
|
|
|
for (int k1 = i; k1 < j; ++k1) {
|
|
for (int l1 = k; l1 < l; ++l1) {
|
|
for (int i2 = i1; i2 < j1; ++i2) {
|
|
Block block = this.getType(k1, l1, i2);
|
|
|
|
if (block.getMaterial() == material) {
|
|
double d0 = (double) ((float) (l1 + 1) - BlockFluids.b(this.getData(k1, l1, i2)));
|
|
|
|
if ((double) l >= d0) {
|
|
flag = true;
|
|
block.a(this, k1, l1, i2, entity, vec3d);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (vec3d.b() > 0.0D && entity.aC()) {
|
|
vec3d = vec3d.a();
|
|
double d1 = 0.014D;
|
|
|
|
entity.motX += vec3d.c * d1;
|
|
entity.motY += vec3d.d * d1;
|
|
entity.motZ += vec3d.e * d1;
|
|
}
|
|
vec3d.b.release(vec3d); // CraftBukkit - pop it - we're done
|
|
|
|
return flag;
|
|
}
|
|
}
|
|
|
|
public boolean a(AxisAlignedBB axisalignedbb, Material material) {
|
|
int i = MathHelper.floor(axisalignedbb.a);
|
|
int j = MathHelper.floor(axisalignedbb.d + 1.0D);
|
|
int k = MathHelper.floor(axisalignedbb.b);
|
|
int l = MathHelper.floor(axisalignedbb.e + 1.0D);
|
|
int i1 = MathHelper.floor(axisalignedbb.c);
|
|
int j1 = MathHelper.floor(axisalignedbb.f + 1.0D);
|
|
|
|
for (int k1 = i; k1 < j; ++k1) {
|
|
for (int l1 = k; l1 < l; ++l1) {
|
|
for (int i2 = i1; i2 < j1; ++i2) {
|
|
if (this.getType(k1, l1, i2).getMaterial() == material) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public boolean b(AxisAlignedBB axisalignedbb, Material material) {
|
|
int i = MathHelper.floor(axisalignedbb.a);
|
|
int j = MathHelper.floor(axisalignedbb.d + 1.0D);
|
|
int k = MathHelper.floor(axisalignedbb.b);
|
|
int l = MathHelper.floor(axisalignedbb.e + 1.0D);
|
|
int i1 = MathHelper.floor(axisalignedbb.c);
|
|
int j1 = MathHelper.floor(axisalignedbb.f + 1.0D);
|
|
|
|
for (int k1 = i; k1 < j; ++k1) {
|
|
for (int l1 = k; l1 < l; ++l1) {
|
|
for (int i2 = i1; i2 < j1; ++i2) {
|
|
Block block = this.getType(k1, l1, i2);
|
|
|
|
if (block.getMaterial() == material) {
|
|
int j2 = this.getData(k1, l1, i2);
|
|
double d0 = (double) (l1 + 1);
|
|
|
|
if (j2 < 8) {
|
|
d0 = (double) (l1 + 1) - (double) j2 / 8.0D;
|
|
}
|
|
|
|
if (d0 >= axisalignedbb.b) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public Explosion explode(Entity entity, double d0, double d1, double d2, float f, boolean flag) {
|
|
return this.createExplosion(entity, d0, d1, d2, f, false, flag);
|
|
}
|
|
|
|
public Explosion createExplosion(Entity entity, double d0, double d1, double d2, float f, boolean flag, boolean flag1) {
|
|
Explosion explosion = new Explosion(this, entity, d0, d1, d2, f);
|
|
|
|
explosion.a = flag;
|
|
explosion.b = flag1;
|
|
explosion.a();
|
|
explosion.a(true);
|
|
return explosion;
|
|
}
|
|
|
|
public float a(Vec3D vec3d, AxisAlignedBB axisalignedbb) {
|
|
double d0 = 1.0D / ((axisalignedbb.d - axisalignedbb.a) * 2.0D + 1.0D);
|
|
double d1 = 1.0D / ((axisalignedbb.e - axisalignedbb.b) * 2.0D + 1.0D);
|
|
double d2 = 1.0D / ((axisalignedbb.f - axisalignedbb.c) * 2.0D + 1.0D);
|
|
int i = 0;
|
|
int j = 0;
|
|
|
|
Vec3D vec3d2 = vec3d.b.create(0, 0, 0); // CraftBukkit
|
|
for (float f = 0.0F; f <= 1.0F; f = (float) ((double) f + d0)) {
|
|
for (float f1 = 0.0F; f1 <= 1.0F; f1 = (float) ((double) f1 + d1)) {
|
|
for (float f2 = 0.0F; f2 <= 1.0F; f2 = (float) ((double) f2 + d2)) {
|
|
double d3 = axisalignedbb.a + (axisalignedbb.d - axisalignedbb.a) * (double) f;
|
|
double d4 = axisalignedbb.b + (axisalignedbb.e - axisalignedbb.b) * (double) f1;
|
|
double d5 = axisalignedbb.c + (axisalignedbb.f - axisalignedbb.c) * (double) f2;
|
|
|
|
if (this.a(vec3d2.b(d3, d4, d5), vec3d) == null) { // CraftBukkit
|
|
++i;
|
|
}
|
|
|
|
++j;
|
|
}
|
|
}
|
|
}
|
|
vec3d2.b.release(vec3d2); // CraftBukkit
|
|
|
|
return (float) i / (float) j;
|
|
}
|
|
|
|
public boolean douseFire(EntityHuman entityhuman, int i, int j, int k, int l) {
|
|
if (l == 0) {
|
|
--j;
|
|
}
|
|
|
|
if (l == 1) {
|
|
++j;
|
|
}
|
|
|
|
if (l == 2) {
|
|
--k;
|
|
}
|
|
|
|
if (l == 3) {
|
|
++k;
|
|
}
|
|
|
|
if (l == 4) {
|
|
--i;
|
|
}
|
|
|
|
if (l == 5) {
|
|
++i;
|
|
}
|
|
|
|
if (this.getType(i, j, k) == Blocks.FIRE) {
|
|
this.a(entityhuman, 1004, i, j, k, 0);
|
|
this.setAir(i, j, k);
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public TileEntity getTileEntity(int i, int j, int k) {
|
|
if (j >= 0 && j < 256) {
|
|
TileEntity tileentity = null;
|
|
int l;
|
|
TileEntity tileentity1;
|
|
|
|
if (this.N) {
|
|
for (l = 0; l < this.a.size(); ++l) {
|
|
tileentity1 = (TileEntity) this.a.get(l);
|
|
if (!tileentity1.r() && tileentity1.x == i && tileentity1.y == j && tileentity1.z == k) {
|
|
tileentity = tileentity1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (tileentity == null) {
|
|
Chunk chunk = this.getChunkAt(i >> 4, k >> 4);
|
|
|
|
if (chunk != null) {
|
|
tileentity = chunk.e(i & 15, j, k & 15);
|
|
}
|
|
}
|
|
|
|
if (tileentity == null) {
|
|
for (l = 0; l < this.a.size(); ++l) {
|
|
tileentity1 = (TileEntity) this.a.get(l);
|
|
if (!tileentity1.r() && tileentity1.x == i && tileentity1.y == j && tileentity1.z == k) {
|
|
tileentity = tileentity1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return tileentity;
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public void setTileEntity(int i, int j, int k, TileEntity tileentity) {
|
|
if (tileentity != null && !tileentity.r()) {
|
|
if (this.N) {
|
|
tileentity.x = i;
|
|
tileentity.y = j;
|
|
tileentity.z = k;
|
|
Iterator iterator = this.a.iterator();
|
|
|
|
while (iterator.hasNext()) {
|
|
TileEntity tileentity1 = (TileEntity) iterator.next();
|
|
|
|
if (tileentity1.x == i && tileentity1.y == j && tileentity1.z == k) {
|
|
tileentity1.s();
|
|
iterator.remove();
|
|
}
|
|
}
|
|
|
|
this.a.add(tileentity);
|
|
} else {
|
|
this.tileEntityList.add(tileentity);
|
|
Chunk chunk = this.getChunkAt(i >> 4, k >> 4);
|
|
|
|
if (chunk != null) {
|
|
chunk.a(i & 15, j, k & 15, tileentity);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void p(int i, int j, int k) {
|
|
TileEntity tileentity = this.getTileEntity(i, j, k);
|
|
|
|
if (tileentity != null && this.N) {
|
|
tileentity.s();
|
|
this.a.remove(tileentity);
|
|
} else {
|
|
if (tileentity != null) {
|
|
this.a.remove(tileentity);
|
|
this.tileEntityList.remove(tileentity);
|
|
}
|
|
|
|
Chunk chunk = this.getChunkAt(i >> 4, k >> 4);
|
|
|
|
if (chunk != null) {
|
|
chunk.f(i & 15, j, k & 15);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void a(TileEntity tileentity) {
|
|
this.b.add(tileentity);
|
|
}
|
|
|
|
public boolean q(int i, int j, int k) {
|
|
AxisAlignedBB axisalignedbb = this.getType(i, j, k).a(this, i, j, k);
|
|
|
|
return axisalignedbb != null && axisalignedbb.b() >= 1.0D;
|
|
}
|
|
|
|
public static boolean a(IBlockAccess iblockaccess, int i, int j, int k) {
|
|
Block block = iblockaccess.getType(i, j, k);
|
|
int l = iblockaccess.getData(i, j, k);
|
|
|
|
return block.getMaterial().k() && block.d() ? true : (block instanceof BlockStairs ? (l & 4) == 4 : (block instanceof BlockStepAbstract ? (l & 8) == 8 : (block instanceof BlockHopper ? true : (block instanceof BlockSnow ? (l & 7) == 7 : false))));
|
|
}
|
|
|
|
public boolean c(int i, int j, int k, boolean flag) {
|
|
if (i >= -30000000 && k >= -30000000 && i < 30000000 && k < 30000000) {
|
|
Chunk chunk = this.chunkProvider.getOrCreateChunk(i >> 4, k >> 4);
|
|
|
|
if (chunk != null && !chunk.isEmpty()) {
|
|
Block block = this.getType(i, j, k);
|
|
|
|
return block.getMaterial().k() && block.d();
|
|
} else {
|
|
return flag;
|
|
}
|
|
} else {
|
|
return flag;
|
|
}
|
|
}
|
|
|
|
public void A() {
|
|
int i = this.a(1.0F);
|
|
|
|
if (i != this.j) {
|
|
this.j = i;
|
|
}
|
|
}
|
|
|
|
public void setSpawnFlags(boolean flag, boolean flag1) {
|
|
this.allowMonsters = flag;
|
|
this.allowAnimals = flag1;
|
|
}
|
|
|
|
public void doTick() {
|
|
this.o();
|
|
}
|
|
|
|
private void a() {
|
|
if (this.worldData.hasStorm()) {
|
|
this.n = 1.0F;
|
|
if (this.worldData.isThundering()) {
|
|
this.p = 1.0F;
|
|
}
|
|
}
|
|
}
|
|
|
|
protected void o() {
|
|
if (!this.worldProvider.g) {
|
|
if (!this.isStatic) {
|
|
int i = this.worldData.getThunderDuration();
|
|
|
|
if (i <= 0) {
|
|
if (this.worldData.isThundering()) {
|
|
this.worldData.setThunderDuration(this.random.nextInt(12000) + 3600);
|
|
} else {
|
|
this.worldData.setThunderDuration(this.random.nextInt(168000) + 12000);
|
|
}
|
|
} else {
|
|
--i;
|
|
this.worldData.setThunderDuration(i);
|
|
if (i <= 0) {
|
|
// CraftBukkit start
|
|
ThunderChangeEvent thunder = new ThunderChangeEvent(this.getWorld(), !this.worldData.isThundering());
|
|
this.getServer().getPluginManager().callEvent(thunder);
|
|
if (!thunder.isCancelled()) {
|
|
this.worldData.setThundering(!this.worldData.isThundering());
|
|
}
|
|
// CraftBukkit end
|
|
}
|
|
}
|
|
|
|
this.o = this.p;
|
|
if (this.worldData.isThundering()) {
|
|
this.p = (float) ((double) this.p + 0.01D);
|
|
} else {
|
|
this.p = (float) ((double) this.p - 0.01D);
|
|
}
|
|
|
|
this.p = MathHelper.a(this.p, 0.0F, 1.0F);
|
|
int j = this.worldData.getWeatherDuration();
|
|
|
|
if (j <= 0) {
|
|
if (this.worldData.hasStorm()) {
|
|
this.worldData.setWeatherDuration(this.random.nextInt(12000) + 12000);
|
|
} else {
|
|
this.worldData.setWeatherDuration(this.random.nextInt(168000) + 12000);
|
|
}
|
|
} else {
|
|
--j;
|
|
this.worldData.setWeatherDuration(j);
|
|
if (j <= 0) {
|
|
// CraftBukkit start
|
|
WeatherChangeEvent weather = new WeatherChangeEvent(this.getWorld(), !this.worldData.hasStorm());
|
|
this.getServer().getPluginManager().callEvent(weather);
|
|
|
|
if (!weather.isCancelled()) {
|
|
this.worldData.setStorm(!this.worldData.hasStorm());
|
|
}
|
|
// CraftBukkit end
|
|
}
|
|
}
|
|
|
|
this.m = this.n;
|
|
if (this.worldData.hasStorm()) {
|
|
this.n = (float) ((double) this.n + 0.01D);
|
|
} else {
|
|
this.n = (float) ((double) this.n - 0.01D);
|
|
}
|
|
|
|
this.n = MathHelper.a(this.n, 0.0F, 1.0F);
|
|
}
|
|
}
|
|
}
|
|
|
|
protected void B() {
|
|
// this.chunkTickList.clear(); // CraftBukkit - removed
|
|
this.methodProfiler.a("buildList");
|
|
|
|
int i;
|
|
EntityHuman entityhuman;
|
|
int j;
|
|
int k;
|
|
|
|
for (i = 0; i < this.players.size(); ++i) {
|
|
entityhuman = (EntityHuman) this.players.get(i);
|
|
j = MathHelper.floor(entityhuman.locX / 16.0D);
|
|
k = MathHelper.floor(entityhuman.locZ / 16.0D);
|
|
byte b0 = 7;
|
|
|
|
for (int l = -b0; l <= b0; ++l) {
|
|
for (int i1 = -b0; i1 <= b0; ++i1) {
|
|
// CraftBukkit start - Don't tick chunks queued for unload
|
|
ChunkProviderServer chunkProviderServer = ((WorldServer) entityhuman.world).chunkProviderServer;
|
|
if (chunkProviderServer.unloadQueue.contains(l + j, i1 + k)) {
|
|
continue;
|
|
}
|
|
// CraftBukkit end
|
|
|
|
this.chunkTickList.add(org.bukkit.craftbukkit.util.LongHash.toLong(l + j, i1 + k)); // CraftBukkit
|
|
}
|
|
}
|
|
}
|
|
|
|
this.methodProfiler.b();
|
|
if (this.L > 0) {
|
|
--this.L;
|
|
}
|
|
|
|
this.methodProfiler.a("playerCheckLight");
|
|
if (!this.players.isEmpty()) {
|
|
i = this.random.nextInt(this.players.size());
|
|
entityhuman = (EntityHuman) this.players.get(i);
|
|
j = MathHelper.floor(entityhuman.locX) + this.random.nextInt(11) - 5;
|
|
k = MathHelper.floor(entityhuman.locY) + this.random.nextInt(11) - 5;
|
|
int j1 = MathHelper.floor(entityhuman.locZ) + this.random.nextInt(11) - 5;
|
|
|
|
this.t(j, k, j1);
|
|
}
|
|
|
|
this.methodProfiler.b();
|
|
}
|
|
|
|
protected void a(int i, int j, Chunk chunk) {
|
|
this.methodProfiler.c("moodSound");
|
|
if (this.L == 0 && !this.isStatic) {
|
|
this.k = this.k * 3 + 1013904223;
|
|
int k = this.k >> 2;
|
|
int l = k & 15;
|
|
int i1 = k >> 8 & 15;
|
|
int j1 = k >> 16 & 255;
|
|
Block block = chunk.getType(l, j1, i1);
|
|
|
|
l += i;
|
|
i1 += j;
|
|
if (block.getMaterial() == Material.AIR && this.j(l, j1, i1) <= this.random.nextInt(8) && this.b(EnumSkyBlock.SKY, l, j1, i1) <= 0) {
|
|
EntityHuman entityhuman = this.findNearbyPlayer((double) l + 0.5D, (double) j1 + 0.5D, (double) i1 + 0.5D, 8.0D);
|
|
|
|
if (entityhuman != null && entityhuman.e((double) l + 0.5D, (double) j1 + 0.5D, (double) i1 + 0.5D) > 4.0D) {
|
|
this.makeSound((double) l + 0.5D, (double) j1 + 0.5D, (double) i1 + 0.5D, "ambient.cave.cave", 0.7F, 0.8F + this.random.nextFloat() * 0.2F);
|
|
this.L = this.random.nextInt(12000) + 6000;
|
|
}
|
|
}
|
|
}
|
|
|
|
this.methodProfiler.c("checkLight");
|
|
chunk.o();
|
|
}
|
|
|
|
protected void g() {
|
|
this.B();
|
|
}
|
|
|
|
public boolean r(int i, int j, int k) {
|
|
return this.d(i, j, k, false);
|
|
}
|
|
|
|
public boolean s(int i, int j, int k) {
|
|
return this.d(i, j, k, true);
|
|
}
|
|
|
|
public boolean d(int i, int j, int k, boolean flag) {
|
|
BiomeBase biomebase = this.getBiome(i, k);
|
|
float f = biomebase.a(i, j, k);
|
|
|
|
if (f > 0.15F) {
|
|
return false;
|
|
} else {
|
|
if (j >= 0 && j < 256 && this.b(EnumSkyBlock.BLOCK, i, j, k) < 10) {
|
|
Block block = this.getType(i, j, k);
|
|
|
|
if ((block == Blocks.STATIONARY_WATER || block == Blocks.WATER) && this.getData(i, j, k) == 0) {
|
|
if (!flag) {
|
|
return true;
|
|
}
|
|
|
|
boolean flag1 = true;
|
|
|
|
if (flag1 && this.getType(i - 1, j, k).getMaterial() != Material.WATER) {
|
|
flag1 = false;
|
|
}
|
|
|
|
if (flag1 && this.getType(i + 1, j, k).getMaterial() != Material.WATER) {
|
|
flag1 = false;
|
|
}
|
|
|
|
if (flag1 && this.getType(i, j, k - 1).getMaterial() != Material.WATER) {
|
|
flag1 = false;
|
|
}
|
|
|
|
if (flag1 && this.getType(i, j, k + 1).getMaterial() != Material.WATER) {
|
|
flag1 = false;
|
|
}
|
|
|
|
if (!flag1) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public boolean e(int i, int j, int k, boolean flag) {
|
|
BiomeBase biomebase = this.getBiome(i, k);
|
|
float f = biomebase.a(i, j, k);
|
|
|
|
if (f > 0.15F) {
|
|
return false;
|
|
} else if (!flag) {
|
|
return true;
|
|
} else {
|
|
if (j >= 0 && j < 256 && this.b(EnumSkyBlock.BLOCK, i, j, k) < 10) {
|
|
Block block = this.getType(i, j, k);
|
|
|
|
if (block.getMaterial() == Material.AIR && Blocks.SNOW.canPlace(this, i, j, k)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public boolean t(int i, int j, int k) {
|
|
boolean flag = false;
|
|
|
|
if (!this.worldProvider.g) {
|
|
flag |= this.c(EnumSkyBlock.SKY, i, j, k);
|
|
}
|
|
|
|
flag |= this.c(EnumSkyBlock.BLOCK, i, j, k);
|
|
return flag;
|
|
}
|
|
|
|
private int a(int i, int j, int k, EnumSkyBlock enumskyblock) {
|
|
if (enumskyblock == EnumSkyBlock.SKY && this.i(i, j, k)) {
|
|
return 15;
|
|
} else {
|
|
Block block = this.getType(i, j, k);
|
|
int l = enumskyblock == EnumSkyBlock.SKY ? 0 : block.m();
|
|
int i1 = block.k();
|
|
|
|
if (i1 >= 15 && block.m() > 0) {
|
|
i1 = 1;
|
|
}
|
|
|
|
if (i1 < 1) {
|
|
i1 = 1;
|
|
}
|
|
|
|
if (i1 >= 15) {
|
|
return 0;
|
|
} else if (l >= 14) {
|
|
return l;
|
|
} else {
|
|
for (int j1 = 0; j1 < 6; ++j1) {
|
|
int k1 = i + Facing.b[j1];
|
|
int l1 = j + Facing.c[j1];
|
|
int i2 = k + Facing.d[j1];
|
|
int j2 = this.b(enumskyblock, k1, l1, i2) - i1;
|
|
|
|
if (j2 > l) {
|
|
l = j2;
|
|
}
|
|
|
|
if (l >= 14) {
|
|
return l;
|
|
}
|
|
}
|
|
|
|
return l;
|
|
}
|
|
}
|
|
}
|
|
|
|
public boolean c(EnumSkyBlock enumskyblock, int i, int j, int k) {
|
|
if (!this.areChunksLoaded(i, j, k, 17)) {
|
|
return false;
|
|
} else {
|
|
int l = 0;
|
|
int i1 = 0;
|
|
|
|
this.methodProfiler.a("getBrightness");
|
|
int j1 = this.b(enumskyblock, i, j, k);
|
|
int k1 = this.a(i, j, k, enumskyblock);
|
|
int l1;
|
|
int i2;
|
|
int j2;
|
|
int k2;
|
|
int l2;
|
|
int i3;
|
|
int j3;
|
|
int k3;
|
|
int l3;
|
|
|
|
if (k1 > j1) {
|
|
this.I[i1++] = 133152;
|
|
} else if (k1 < j1) {
|
|
this.I[i1++] = 133152 | j1 << 18;
|
|
|
|
while (l < i1) {
|
|
l1 = this.I[l++];
|
|
i2 = (l1 & 63) - 32 + i;
|
|
j2 = (l1 >> 6 & 63) - 32 + j;
|
|
k2 = (l1 >> 12 & 63) - 32 + k;
|
|
l2 = l1 >> 18 & 15;
|
|
i3 = this.b(enumskyblock, i2, j2, k2);
|
|
if (i3 == l2) {
|
|
this.b(enumskyblock, i2, j2, k2, 0);
|
|
if (l2 > 0) {
|
|
j3 = MathHelper.a(i2 - i);
|
|
l3 = MathHelper.a(j2 - j);
|
|
k3 = MathHelper.a(k2 - k);
|
|
if (j3 + l3 + k3 < 17) {
|
|
for (int i4 = 0; i4 < 6; ++i4) {
|
|
int j4 = i2 + Facing.b[i4];
|
|
int k4 = j2 + Facing.c[i4];
|
|
int l4 = k2 + Facing.d[i4];
|
|
int i5 = Math.max(1, this.getType(j4, k4, l4).k());
|
|
|
|
i3 = this.b(enumskyblock, j4, k4, l4);
|
|
if (i3 == l2 - i5 && i1 < this.I.length) {
|
|
this.I[i1++] = j4 - i + 32 | k4 - j + 32 << 6 | l4 - k + 32 << 12 | l2 - i5 << 18;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
l = 0;
|
|
}
|
|
|
|
this.methodProfiler.b();
|
|
this.methodProfiler.a("checkedPosition < toCheckCount");
|
|
|
|
while (l < i1) {
|
|
l1 = this.I[l++];
|
|
i2 = (l1 & 63) - 32 + i;
|
|
j2 = (l1 >> 6 & 63) - 32 + j;
|
|
k2 = (l1 >> 12 & 63) - 32 + k;
|
|
l2 = this.b(enumskyblock, i2, j2, k2);
|
|
i3 = this.a(i2, j2, k2, enumskyblock);
|
|
if (i3 != l2) {
|
|
this.b(enumskyblock, i2, j2, k2, i3);
|
|
if (i3 > l2) {
|
|
j3 = Math.abs(i2 - i);
|
|
l3 = Math.abs(j2 - j);
|
|
k3 = Math.abs(k2 - k);
|
|
boolean flag = i1 < this.I.length - 6;
|
|
|
|
if (j3 + l3 + k3 < 17 && flag) {
|
|
if (this.b(enumskyblock, i2 - 1, j2, k2) < i3) {
|
|
this.I[i1++] = i2 - 1 - i + 32 + (j2 - j + 32 << 6) + (k2 - k + 32 << 12);
|
|
}
|
|
|
|
if (this.b(enumskyblock, i2 + 1, j2, k2) < i3) {
|
|
this.I[i1++] = i2 + 1 - i + 32 + (j2 - j + 32 << 6) + (k2 - k + 32 << 12);
|
|
}
|
|
|
|
if (this.b(enumskyblock, i2, j2 - 1, k2) < i3) {
|
|
this.I[i1++] = i2 - i + 32 + (j2 - 1 - j + 32 << 6) + (k2 - k + 32 << 12);
|
|
}
|
|
|
|
if (this.b(enumskyblock, i2, j2 + 1, k2) < i3) {
|
|
this.I[i1++] = i2 - i + 32 + (j2 + 1 - j + 32 << 6) + (k2 - k + 32 << 12);
|
|
}
|
|
|
|
if (this.b(enumskyblock, i2, j2, k2 - 1) < i3) {
|
|
this.I[i1++] = i2 - i + 32 + (j2 - j + 32 << 6) + (k2 - 1 - k + 32 << 12);
|
|
}
|
|
|
|
if (this.b(enumskyblock, i2, j2, k2 + 1) < i3) {
|
|
this.I[i1++] = i2 - i + 32 + (j2 - j + 32 << 6) + (k2 + 1 - k + 32 << 12);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
this.methodProfiler.b();
|
|
return true;
|
|
}
|
|
}
|
|
|
|
public boolean a(boolean flag) {
|
|
return false;
|
|
}
|
|
|
|
public List a(Chunk chunk, boolean flag) {
|
|
return null;
|
|
}
|
|
|
|
public List getEntities(Entity entity, AxisAlignedBB axisalignedbb) {
|
|
return this.getEntities(entity, axisalignedbb, (IEntitySelector) null);
|
|
}
|
|
|
|
public List getEntities(Entity entity, AxisAlignedBB axisalignedbb, IEntitySelector ientityselector) {
|
|
ArrayList arraylist = new ArrayList();
|
|
int i = MathHelper.floor((axisalignedbb.a - 2.0D) / 16.0D);
|
|
int j = MathHelper.floor((axisalignedbb.d + 2.0D) / 16.0D);
|
|
int k = MathHelper.floor((axisalignedbb.c - 2.0D) / 16.0D);
|
|
int l = MathHelper.floor((axisalignedbb.f + 2.0D) / 16.0D);
|
|
|
|
for (int i1 = i; i1 <= j; ++i1) {
|
|
for (int j1 = k; j1 <= l; ++j1) {
|
|
if (this.isChunkLoaded(i1, j1)) {
|
|
this.getChunkAt(i1, j1).a(entity, axisalignedbb, arraylist, ientityselector);
|
|
}
|
|
}
|
|
}
|
|
|
|
return arraylist;
|
|
}
|
|
|
|
public List a(Class oclass, AxisAlignedBB axisalignedbb) {
|
|
return this.a(oclass, axisalignedbb, (IEntitySelector) null);
|
|
}
|
|
|
|
public List a(Class oclass, AxisAlignedBB axisalignedbb, IEntitySelector ientityselector) {
|
|
int i = MathHelper.floor((axisalignedbb.a - 2.0D) / 16.0D);
|
|
int j = MathHelper.floor((axisalignedbb.d + 2.0D) / 16.0D);
|
|
int k = MathHelper.floor((axisalignedbb.c - 2.0D) / 16.0D);
|
|
int l = MathHelper.floor((axisalignedbb.f + 2.0D) / 16.0D);
|
|
ArrayList arraylist = new ArrayList();
|
|
|
|
for (int i1 = i; i1 <= j; ++i1) {
|
|
for (int j1 = k; j1 <= l; ++j1) {
|
|
if (this.isChunkLoaded(i1, j1)) {
|
|
this.getChunkAt(i1, j1).a(oclass, axisalignedbb, arraylist, ientityselector);
|
|
}
|
|
}
|
|
}
|
|
|
|
return arraylist;
|
|
}
|
|
|
|
public Entity a(Class oclass, AxisAlignedBB axisalignedbb, Entity entity) {
|
|
List list = this.a(oclass, axisalignedbb);
|
|
Entity entity1 = null;
|
|
double d0 = Double.MAX_VALUE;
|
|
|
|
for (int i = 0; i < list.size(); ++i) {
|
|
Entity entity2 = (Entity) list.get(i);
|
|
|
|
if (entity2 != entity) {
|
|
double d1 = entity.e(entity2);
|
|
|
|
if (d1 <= d0) {
|
|
entity1 = entity2;
|
|
d0 = d1;
|
|
}
|
|
}
|
|
}
|
|
|
|
return entity1;
|
|
}
|
|
|
|
public abstract Entity getEntity(int i);
|
|
|
|
public void b(int i, int j, int k, TileEntity tileentity) {
|
|
if (this.isLoaded(i, j, k)) {
|
|
this.getChunkAtWorldCoords(i, k).e();
|
|
}
|
|
}
|
|
|
|
public int a(Class oclass) {
|
|
int i = 0;
|
|
|
|
for (int j = 0; j < this.entityList.size(); ++j) {
|
|
Entity entity = (Entity) this.entityList.get(j);
|
|
|
|
// CraftBukkit start - Split out persistent check, don't apply it to special persistent mobs
|
|
if (entity instanceof EntityInsentient) {
|
|
EntityInsentient entityinsentient = (EntityInsentient) entity;
|
|
if (entityinsentient.isTypeNotPersistent() && entityinsentient.isPersistent()) {
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if (oclass.isAssignableFrom(entity.getClass())) {
|
|
// if ((!(entity instanceof EntityInsentient) || !((EntityInsentient) entity).isPersistent()) && oclass.isAssignableFrom(entity.getClass())) {
|
|
// CraftBukkit end
|
|
++i;
|
|
}
|
|
}
|
|
|
|
return i;
|
|
}
|
|
|
|
public void a(List list) {
|
|
// CraftBukkit start
|
|
// this.entityList.addAll(list);
|
|
Entity entity = null;
|
|
|
|
for (int i = 0; i < list.size(); ++i) {
|
|
entity = (Entity) list.get(i);
|
|
if (entity == null) {
|
|
continue;
|
|
}
|
|
this.entityList.add(entity);
|
|
// CraftBukkit end
|
|
this.a((Entity) list.get(i));
|
|
}
|
|
}
|
|
|
|
public void b(List list) {
|
|
this.f.addAll(list);
|
|
}
|
|
|
|
public boolean mayPlace(Block block, int i, int j, int k, boolean flag, int l, Entity entity, ItemStack itemstack) {
|
|
Block block1 = this.getType(i, j, k);
|
|
AxisAlignedBB axisalignedbb = flag ? null : block.a(this, i, j, k);
|
|
|
|
// CraftBukkit start - store default return
|
|
boolean defaultReturn = axisalignedbb != null && !this.a(axisalignedbb, entity) ? false : (block1.getMaterial() == Material.ORIENTABLE && block == Blocks.ANVIL ? true : block1.getMaterial().isReplaceable() && block.canPlace(this, i, j, k, l, itemstack));
|
|
|
|
// CraftBukkit start
|
|
BlockCanBuildEvent event = new BlockCanBuildEvent(this.getWorld().getBlockAt(i, j, k), CraftMagicNumbers.getId(block), defaultReturn);
|
|
this.getServer().getPluginManager().callEvent(event);
|
|
|
|
return event.isBuildable();
|
|
// CraftBukkit end
|
|
}
|
|
|
|
public PathEntity findPath(Entity entity, Entity entity1, float f, boolean flag, boolean flag1, boolean flag2, boolean flag3) {
|
|
this.methodProfiler.a("pathfind");
|
|
int i = MathHelper.floor(entity.locX);
|
|
int j = MathHelper.floor(entity.locY + 1.0D);
|
|
int k = MathHelper.floor(entity.locZ);
|
|
int l = (int) (f + 16.0F);
|
|
int i1 = i - l;
|
|
int j1 = j - l;
|
|
int k1 = k - l;
|
|
int l1 = i + l;
|
|
int i2 = j + l;
|
|
int j2 = k + l;
|
|
ChunkCache chunkcache = new ChunkCache(this, i1, j1, k1, l1, i2, j2, 0);
|
|
PathEntity pathentity = (new Pathfinder(chunkcache, flag, flag1, flag2, flag3)).a(entity, entity1, f);
|
|
|
|
this.methodProfiler.b();
|
|
return pathentity;
|
|
}
|
|
|
|
public PathEntity a(Entity entity, int i, int j, int k, float f, boolean flag, boolean flag1, boolean flag2, boolean flag3) {
|
|
this.methodProfiler.a("pathfind");
|
|
int l = MathHelper.floor(entity.locX);
|
|
int i1 = MathHelper.floor(entity.locY);
|
|
int j1 = MathHelper.floor(entity.locZ);
|
|
int k1 = (int) (f + 8.0F);
|
|
int l1 = l - k1;
|
|
int i2 = i1 - k1;
|
|
int j2 = j1 - k1;
|
|
int k2 = l + k1;
|
|
int l2 = i1 + k1;
|
|
int i3 = j1 + k1;
|
|
ChunkCache chunkcache = new ChunkCache(this, l1, i2, j2, k2, l2, i3, 0);
|
|
PathEntity pathentity = (new Pathfinder(chunkcache, flag, flag1, flag2, flag3)).a(entity, i, j, k, f);
|
|
|
|
this.methodProfiler.b();
|
|
return pathentity;
|
|
}
|
|
|
|
public int getBlockPower(int i, int j, int k, int l) {
|
|
return this.getType(i, j, k).c(this, i, j, k, l);
|
|
}
|
|
|
|
public int getBlockPower(int i, int j, int k) {
|
|
byte b0 = 0;
|
|
int l = Math.max(b0, this.getBlockPower(i, j - 1, k, 0));
|
|
|
|
if (l >= 15) {
|
|
return l;
|
|
} else {
|
|
l = Math.max(l, this.getBlockPower(i, j + 1, k, 1));
|
|
if (l >= 15) {
|
|
return l;
|
|
} else {
|
|
l = Math.max(l, this.getBlockPower(i, j, k - 1, 2));
|
|
if (l >= 15) {
|
|
return l;
|
|
} else {
|
|
l = Math.max(l, this.getBlockPower(i, j, k + 1, 3));
|
|
if (l >= 15) {
|
|
return l;
|
|
} else {
|
|
l = Math.max(l, this.getBlockPower(i - 1, j, k, 4));
|
|
if (l >= 15) {
|
|
return l;
|
|
} else {
|
|
l = Math.max(l, this.getBlockPower(i + 1, j, k, 5));
|
|
return l >= 15 ? l : l;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public boolean isBlockFacePowered(int i, int j, int k, int l) {
|
|
return this.getBlockFacePower(i, j, k, l) > 0;
|
|
}
|
|
|
|
public int getBlockFacePower(int i, int j, int k, int l) {
|
|
return this.getType(i, j, k).r() ? this.getBlockPower(i, j, k) : this.getType(i, j, k).b(this, i, j, k, l);
|
|
}
|
|
|
|
public boolean isBlockIndirectlyPowered(int i, int j, int k) {
|
|
return this.getBlockFacePower(i, j - 1, k, 0) > 0 ? true : (this.getBlockFacePower(i, j + 1, k, 1) > 0 ? true : (this.getBlockFacePower(i, j, k - 1, 2) > 0 ? true : (this.getBlockFacePower(i, j, k + 1, 3) > 0 ? true : (this.getBlockFacePower(i - 1, j, k, 4) > 0 ? true : this.getBlockFacePower(i + 1, j, k, 5) > 0))));
|
|
}
|
|
|
|
public int getHighestNeighborSignal(int i, int j, int k) {
|
|
int l = 0;
|
|
|
|
for (int i1 = 0; i1 < 6; ++i1) {
|
|
int j1 = this.getBlockFacePower(i + Facing.b[i1], j + Facing.c[i1], k + Facing.d[i1], i1);
|
|
|
|
if (j1 >= 15) {
|
|
return 15;
|
|
}
|
|
|
|
if (j1 > l) {
|
|
l = j1;
|
|
}
|
|
}
|
|
|
|
return l;
|
|
}
|
|
|
|
public EntityHuman findNearbyPlayer(Entity entity, double d0) {
|
|
return this.findNearbyPlayer(entity.locX, entity.locY, entity.locZ, d0);
|
|
}
|
|
|
|
public EntityHuman findNearbyPlayer(double d0, double d1, double d2, double d3) {
|
|
double d4 = -1.0D;
|
|
EntityHuman entityhuman = null;
|
|
|
|
for (int i = 0; i < this.players.size(); ++i) {
|
|
EntityHuman entityhuman1 = (EntityHuman) this.players.get(i);
|
|
// CraftBukkit start - Fixed an NPE
|
|
if (entityhuman1 == null || entityhuman1.dead) {
|
|
continue;
|
|
}
|
|
// CraftBukkit end
|
|
double d5 = entityhuman1.e(d0, d1, d2);
|
|
|
|
if ((d3 < 0.0D || d5 < d3 * d3) && (d4 == -1.0D || d5 < d4)) {
|
|
d4 = d5;
|
|
entityhuman = entityhuman1;
|
|
}
|
|
}
|
|
|
|
return entityhuman;
|
|
}
|
|
|
|
public EntityHuman findNearbyVulnerablePlayer(Entity entity, double d0) {
|
|
return this.findNearbyVulnerablePlayer(entity.locX, entity.locY, entity.locZ, d0);
|
|
}
|
|
|
|
public EntityHuman findNearbyVulnerablePlayer(double d0, double d1, double d2, double d3) {
|
|
double d4 = -1.0D;
|
|
EntityHuman entityhuman = null;
|
|
|
|
for (int i = 0; i < this.players.size(); ++i) {
|
|
EntityHuman entityhuman1 = (EntityHuman) this.players.get(i);
|
|
// CraftBukkit start - Fixed an NPE
|
|
if (entityhuman1 == null || entityhuman1.dead) {
|
|
continue;
|
|
}
|
|
// CraftBukkit end
|
|
|
|
if (!entityhuman1.abilities.isInvulnerable && entityhuman1.isAlive()) {
|
|
double d5 = entityhuman1.e(d0, d1, d2);
|
|
double d6 = d3;
|
|
|
|
if (entityhuman1.isSneaking()) {
|
|
d6 = d3 * 0.800000011920929D;
|
|
}
|
|
|
|
if (entityhuman1.isInvisible()) {
|
|
float f = entityhuman1.bC();
|
|
|
|
if (f < 0.1F) {
|
|
f = 0.1F;
|
|
}
|
|
|
|
d6 *= (double) (0.7F * f);
|
|
}
|
|
|
|
if ((d3 < 0.0D || d5 < d6 * d6) && (d4 == -1.0D || d5 < d4)) {
|
|
d4 = d5;
|
|
entityhuman = entityhuman1;
|
|
}
|
|
}
|
|
}
|
|
|
|
return entityhuman;
|
|
}
|
|
|
|
public EntityHuman a(String s) {
|
|
for (int i = 0; i < this.players.size(); ++i) {
|
|
if (s.equals(((EntityHuman) this.players.get(i)).getName())) {
|
|
return (EntityHuman) this.players.get(i);
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public void F() throws ExceptionWorldConflict { // CraftBukkit - added throws
|
|
this.dataManager.checkSession();
|
|
}
|
|
|
|
public long getSeed() {
|
|
return this.worldData.getSeed();
|
|
}
|
|
|
|
public long getTime() {
|
|
return this.worldData.getTime();
|
|
}
|
|
|
|
public long getDayTime() {
|
|
return this.worldData.getDayTime();
|
|
}
|
|
|
|
public void setDayTime(long i) {
|
|
this.worldData.setDayTime(i);
|
|
}
|
|
|
|
public ChunkCoordinates getSpawn() {
|
|
return new ChunkCoordinates(this.worldData.c(), this.worldData.d(), this.worldData.e());
|
|
}
|
|
|
|
public void x(int i, int j, int k) {
|
|
this.worldData.setSpawn(i, j, k);
|
|
}
|
|
|
|
public boolean a(EntityHuman entityhuman, int i, int j, int k) {
|
|
return true;
|
|
}
|
|
|
|
public void broadcastEntityEffect(Entity entity, byte b0) {}
|
|
|
|
public IChunkProvider K() {
|
|
return this.chunkProvider;
|
|
}
|
|
|
|
public void playNote(int i, int j, int k, Block block, int l, int i1) {
|
|
block.a(this, i, j, k, l, i1);
|
|
}
|
|
|
|
public IDataManager getDataManager() {
|
|
return this.dataManager;
|
|
}
|
|
|
|
public WorldData getWorldData() {
|
|
return this.worldData;
|
|
}
|
|
|
|
public GameRules getGameRules() {
|
|
return this.worldData.getGameRules();
|
|
}
|
|
|
|
public void everyoneSleeping() {}
|
|
|
|
// CraftBukkit start
|
|
// Calls the method that checks to see if players are sleeping
|
|
// Called by CraftPlayer.setPermanentSleeping()
|
|
public void checkSleepStatus() {
|
|
if (!this.isStatic) {
|
|
this.everyoneSleeping();
|
|
}
|
|
}
|
|
// CraftBukkit end
|
|
|
|
public float h(float f) {
|
|
return (this.o + (this.p - this.o) * f) * this.j(f);
|
|
}
|
|
|
|
public float j(float f) {
|
|
return this.m + (this.n - this.m) * f;
|
|
}
|
|
|
|
public boolean O() {
|
|
return (double) this.h(1.0F) > 0.9D;
|
|
}
|
|
|
|
public boolean P() {
|
|
return (double) this.j(1.0F) > 0.2D;
|
|
}
|
|
|
|
public boolean isRainingAt(int i, int j, int k) {
|
|
if (!this.P()) {
|
|
return false;
|
|
} else if (!this.i(i, j, k)) {
|
|
return false;
|
|
} else if (this.h(i, k) > j) {
|
|
return false;
|
|
} else {
|
|
BiomeBase biomebase = this.getBiome(i, k);
|
|
|
|
return biomebase.d() ? false : (this.e(i, j, k, false) ? false : biomebase.e());
|
|
}
|
|
}
|
|
|
|
public boolean z(int i, int j, int k) {
|
|
BiomeBase biomebase = this.getBiome(i, k);
|
|
|
|
return biomebase.f();
|
|
}
|
|
|
|
public void a(String s, PersistentBase persistentbase) {
|
|
this.worldMaps.a(s, persistentbase);
|
|
}
|
|
|
|
public PersistentBase a(Class oclass, String s) {
|
|
return this.worldMaps.get(oclass, s);
|
|
}
|
|
|
|
public int b(String s) {
|
|
return this.worldMaps.a(s);
|
|
}
|
|
|
|
public void b(int i, int j, int k, int l, int i1) {
|
|
for (int j1 = 0; j1 < this.u.size(); ++j1) {
|
|
((IWorldAccess) this.u.get(j1)).a(i, j, k, l, i1);
|
|
}
|
|
}
|
|
|
|
public void triggerEffect(int i, int j, int k, int l, int i1) {
|
|
this.a((EntityHuman) null, i, j, k, l, i1);
|
|
}
|
|
|
|
public void a(EntityHuman entityhuman, int i, int j, int k, int l, int i1) {
|
|
try {
|
|
for (int j1 = 0; j1 < this.u.size(); ++j1) {
|
|
((IWorldAccess) this.u.get(j1)).a(entityhuman, i, j, k, l, i1);
|
|
}
|
|
} catch (Throwable throwable) {
|
|
CrashReport crashreport = CrashReport.a(throwable, "Playing level event");
|
|
CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Level event being played");
|
|
|
|
crashreportsystemdetails.a("Block coordinates", CrashReportSystemDetails.a(j, k, l));
|
|
crashreportsystemdetails.a("Event source", entityhuman);
|
|
crashreportsystemdetails.a("Event type", Integer.valueOf(i));
|
|
crashreportsystemdetails.a("Event data", Integer.valueOf(i1));
|
|
throw new ReportedException(crashreport);
|
|
}
|
|
}
|
|
|
|
public int getHeight() {
|
|
return 256;
|
|
}
|
|
|
|
public int R() {
|
|
return this.worldProvider.g ? 128 : 256;
|
|
}
|
|
|
|
public Random A(int i, int j, int k) {
|
|
long l = (long) i * 341873128712L + (long) j * 132897987541L + this.getWorldData().getSeed() + (long) k;
|
|
|
|
this.random.setSeed(l);
|
|
return this.random;
|
|
}
|
|
|
|
public ChunkPosition b(String s, int i, int j, int k) {
|
|
return this.K().findNearestMapFeature(this, s, i, j, k);
|
|
}
|
|
|
|
public CrashReportSystemDetails a(CrashReport crashreport) {
|
|
CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Affected level", 1);
|
|
|
|
crashreportsystemdetails.a("Level name", (this.worldData == null ? "????" : this.worldData.getName()));
|
|
crashreportsystemdetails.a("All players", (Callable) (new CrashReportPlayers(this)));
|
|
crashreportsystemdetails.a("Chunk stats", (Callable) (new CrashReportChunkStats(this)));
|
|
|
|
try {
|
|
this.worldData.a(crashreportsystemdetails);
|
|
} catch (Throwable throwable) {
|
|
crashreportsystemdetails.a("Level Data Unobtainable", throwable);
|
|
}
|
|
|
|
return crashreportsystemdetails;
|
|
}
|
|
|
|
public void d(int i, int j, int k, int l, int i1) {
|
|
for (int j1 = 0; j1 < this.u.size(); ++j1) {
|
|
IWorldAccess iworldaccess = (IWorldAccess) this.u.get(j1);
|
|
|
|
iworldaccess.b(i, j, k, l, i1);
|
|
}
|
|
}
|
|
|
|
public Vec3DPool getVec3DPool() {
|
|
return this.J;
|
|
}
|
|
|
|
public Calendar V() {
|
|
if (this.getTime() % 600L == 0L) {
|
|
this.K.setTimeInMillis(MinecraftServer.ap());
|
|
}
|
|
|
|
return this.K;
|
|
}
|
|
|
|
public Scoreboard getScoreboard() {
|
|
return this.scoreboard;
|
|
}
|
|
|
|
public void f(int i, int j, int k, Block block) {
|
|
for (int l = 0; l < 4; ++l) {
|
|
int i1 = i + Direction.a[l];
|
|
int j1 = k + Direction.b[l];
|
|
Block block1 = this.getType(i1, j, j1);
|
|
|
|
if (Blocks.REDSTONE_COMPARATOR_OFF.e(block1)) {
|
|
block1.doPhysics(this, i1, j, j1, block);
|
|
} else if (block1.r()) {
|
|
i1 += Direction.a[l];
|
|
j1 += Direction.b[l];
|
|
Block block2 = this.getType(i1, j, j1);
|
|
|
|
if (Blocks.REDSTONE_COMPARATOR_OFF.e(block2)) {
|
|
block2.doPhysics(this, i1, j, j1, block);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public float b(double d0, double d1, double d2) {
|
|
return this.B(MathHelper.floor(d0), MathHelper.floor(d1), MathHelper.floor(d2));
|
|
}
|
|
|
|
public float B(int i, int j, int k) {
|
|
float f = 0.0F;
|
|
boolean flag = this.difficulty == EnumDifficulty.HARD;
|
|
|
|
if (this.isLoaded(i, j, k)) {
|
|
float f1 = this.x();
|
|
|
|
f += MathHelper.a((float) this.getChunkAtWorldCoords(i, k).s / 3600000.0F, 0.0F, 1.0F) * (flag ? 1.0F : 0.75F);
|
|
f += f1 * 0.25F;
|
|
}
|
|
|
|
if (this.difficulty == EnumDifficulty.EASY || this.difficulty == EnumDifficulty.PEACEFUL) {
|
|
f *= (float) this.difficulty.a() / 2.0F;
|
|
}
|
|
|
|
return MathHelper.a(f, 0.0F, flag ? 1.5F : 1.0F);
|
|
}
|
|
|
|
public void X() {
|
|
Iterator iterator = this.u.iterator();
|
|
|
|
while (iterator.hasNext()) {
|
|
IWorldAccess iworldaccess = (IWorldAccess) iterator.next();
|
|
|
|
iworldaccess.b();
|
|
}
|
|
}
|
|
}
|