tcr/java/src/game/world/World.java
2025-03-12 18:13:11 +01:00

2139 lines
60 KiB
Java
Executable file

package game.world;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.function.Predicate;
import game.ExtMath;
import game.biome.Biome;
import game.block.Block;
import game.block.BlockHopper;
import game.block.BlockLiquid;
import game.block.BlockSlab;
import game.block.BlockSnow;
import game.block.BlockStairs;
import game.block.LeavesType;
import game.collect.Lists;
import game.collect.Sets;
import game.dimension.Dimension;
import game.entity.Entity;
import game.entity.item.EntityExplosion;
import game.entity.npc.EntityNPC;
import game.init.BlockRegistry;
import game.init.Blocks;
import game.init.SoundEvent;
import game.item.ItemStack;
import game.material.Material;
import game.renderer.particle.ParticleType;
import game.rng.Random;
import game.tileentity.ITickable;
import game.tileentity.TileEntity;
public abstract class World implements IWorldAccess {
public static final float[][] BRIGHTNESS = new float[16][16];
static {
for(int l = 0; l < 16; l++) {
float f = (float)l / 15.0f;
for(int i = 0; i <= 15; ++i) {
float f1 = 1.0F - (float)i / 15.0F;
BRIGHTNESS[l][i] = (1.0F - f1) / (f1 * 3.0F + 1.0F) * (1.0F - f) + f;
}
}
}
public static final float[] MOON_PHASES = new float[] {1.0F, 0.75F, 0.5F, 0.25F, 0.0F, 0.25F, 0.5F, 0.75F};
public static final int MAX_SIZE = 67108864;
public static final int HEIGHT = 512;
public static final long START_TIME = 4385238000L;
public static final float ABSOLUTE_ZERO = -273.15f;
// private static final Calendar calendar = Calendar.getInstance();
// private static long lastUpdate;
public final boolean client;
public final boolean debug;
public double gravity = 1.0;
protected long timeFactor = 1L;
public final Random rand = new Random();
public final List<Entity> entities = Lists.<Entity>newArrayList();
protected final List<Entity> unloaded = Lists.<Entity>newArrayList();
protected final List<TileEntity> tiles = Lists.<TileEntity>newArrayList();
protected final List<TileEntity> tickable = Lists.<TileEntity>newArrayList();
protected final List<TileEntity> addedTiles = Lists.<TileEntity>newArrayList();
protected final List<TileEntity> removeTiles = Lists.<TileEntity>newArrayList();
public final List<EntityNPC> players = Lists.<EntityNPC>newArrayList();
public final List<Entity> effects = Lists.<Entity>newArrayList();
protected final IntHashMap<Entity> entityIds = new IntHashMap();
protected final Set<ChunkPos> active = Sets.<ChunkPos>newHashSet();
protected final int[] lightUpdate = new int[32768];
public final Dimension dimension;
protected boolean loadTiles;
protected int subtract;
protected float rain;
protected float darkness;
protected float fog;
protected float temp;
protected Weather weather;
protected long daytime;
// public static Calendar getCurrentDate() {
// long curTime = System.currentTimeMillis();
// if(curTime - lastUpdate >= 30000L) {
// lastUpdate = curTime;
// calendar.setTimeInMillis(curTime);
// }
// return calendar;
// }
public boolean isBlockSolid(BlockPos pos) {
return isSolidSurface(this.getState(pos));
}
public static boolean isSolidSurface(State state) {
Block block = state.getBlock();
return block.getMaterial().isOpaque() && block.isFullCube() ? true
: (block instanceof BlockStairs ? state.getValue(BlockStairs.HALF) == BlockStairs.EnumHalf.TOP
: (block instanceof BlockSlab ? (state.getValue(BlockSlab.DOUBLE) || state.getValue(BlockSlab.FACING) == Facing.UP)
: (block instanceof BlockHopper ? true
: (block instanceof BlockSnow ? ((Integer)state.getValue(BlockSnow.LAYERS)).intValue() == 7
: false))));
}
public static boolean isValid(BlockPos pos) {
return pos.getX() >= -MAX_SIZE && pos.getZ() >= -MAX_SIZE && pos.getX() < MAX_SIZE && pos.getZ() < MAX_SIZE &&
pos.getY() >= 0 && pos.getY() < 512;
}
public static boolean isValidXZ(BlockPos pos) {
return pos.getX() >= -MAX_SIZE && pos.getZ() >= -MAX_SIZE && pos.getX() < MAX_SIZE && pos.getZ() < MAX_SIZE;
}
protected World(Dimension dim, boolean client, boolean debug) {
// this.profiler = profiler;
// this.info = info;
// this.dimInfo = info.getDimension(dim.getDimensionId());
this.dimension = dim;
// this.storage = storage;
this.client = client;
this.debug = debug;
this.weather = dim.getWeather();
}
public void setGravity(float gravity) {
this.gravity = (double)this.dimension.getGravity() * 0.1 * gravity;
if(Math.abs(this.gravity) < 0.075)
this.gravity = Math.signum(this.gravity) * 0.075;
}
public Biome getBiomeGenForCoords(final BlockPos pos) {
if(this.isBlockLoaded(pos))
return this.getChunk(pos).getBiome(pos, null);
else
return Biome.DEF_BIOME;
}
public boolean isAirBlock(BlockPos pos) {
return this.getState(pos).getBlock().getMaterial() == Material.air;
}
public boolean isBlockLoaded(BlockPos pos) {
return this.isBlockLoaded(pos, true);
}
public boolean isBlockLoaded(BlockPos pos, boolean allowEmpty) {
return !isValid(pos) ? false : this.isLoaded(pos.getX() >> 4, pos.getZ() >> 4, allowEmpty);
}
public boolean isAreaLoaded(BlockPos center, int radius) {
return this.isAreaLoaded(center, radius, true);
}
public boolean isAreaLoaded(BlockPos center, int radius, boolean allowEmpty) {
return this.isAreaLoaded(center.getX() - radius, center.getY() - radius, center.getZ() - radius, center.getX() + radius,
center.getY() + radius, center.getZ() + radius, allowEmpty);
}
public boolean isAreaLoaded(BlockPos from, BlockPos to) {
return this.isAreaLoaded(from, to, true);
}
public boolean isAreaLoaded(BlockPos from, BlockPos to, boolean allowEmpty) {
return this.isAreaLoaded(from.getX(), from.getY(), from.getZ(), to.getX(), to.getY(), to.getZ(), allowEmpty);
}
private boolean isAreaLoaded(int xStart, int yStart, int zStart, int xEnd, int yEnd, int zEnd, boolean allowEmpty) {
if(yEnd >= 0 && yStart < 512) {
xStart = xStart >> 4;
zStart = zStart >> 4;
xEnd = xEnd >> 4;
zEnd = zEnd >> 4;
for(int i = xStart; i <= xEnd; ++i) {
for(int j = zStart; j <= zEnd; ++j) {
if(!this.isLoaded(i, j, allowEmpty)) {
return false;
}
}
}
return true;
}
else {
return false;
}
}
protected boolean isLoaded(int x, int z, boolean allowEmpty) {
return allowEmpty || !this.getChunk(x, z).isEmpty();
}
public Chunk getChunk(BlockPos pos) {
return this.getChunk(pos.getX() >> 4, pos.getZ() >> 4);
}
/**
* Flag 1 will cause a block update Flag 2 will send the change to clients Flag
* 4 prevents the block from being re-rendered on client worlds
*/
public boolean setState(BlockPos pos, State newState, int flags) {
if(!isValid(pos)) {
return false;
}
else if(!this.client && this.debug) {
return false;
}
else {
Chunk chunk = this.getChunk(pos);
Block block = newState.getBlock();
State iblockstate = chunk.setState(pos, newState);
if(iblockstate == null) {
return false;
}
else {
Block block1 = iblockstate.getBlock();
if(block.getLightOpacity() != block1.getLightOpacity() || block.getLightValue() != block1.getLightValue()) {
// this.profiler.start("checkLight");
this.checkLight(pos);
// this.profiler.end();
}
if((flags & 2) != 0 && (!this.client || (flags & 4) == 0) && chunk.isPopulated()) {
this.markBlockForUpdate(pos);
}
if(!this.client && (flags & 1) != 0) {
this.notifyNeighborsRespectDebug(pos, iblockstate.getBlock());
if(block.hasComparatorInputOverride()) {
this.updateComparatorOutputLevel(pos, block);
}
}
return true;
}
}
}
public boolean setState(BlockPos pos, State state) {
return this.setState(pos, state, 3);
}
public boolean setBlockToAir(BlockPos pos) {
return this.setState(pos, Blocks.air.getState(), 3);
}
public boolean destroyBlock(BlockPos pos, boolean dropBlock) {
State iblockstate = this.getState(pos);
Block block = iblockstate.getBlock();
if(block.getMaterial() == Material.air) {
return false;
}
else {
this.playAuxSFX(2001, pos, BlockRegistry.getStateId(iblockstate));
if(dropBlock) {
block.dropBlockAsItem(this, pos, iblockstate, 0);
}
return this.setState(pos, Blocks.air.getState(), 3);
}
}
public void notifyNeighborsRespectDebug(BlockPos pos, Block blockType) {
if(!this.debug) {
this.notifyNeighborsOfStateChange(pos, blockType);
}
}
public void markBlocksDirtyVertical(int x1, int z1, int x2, int z2) {
if(x2 > z2) {
int i = z2;
z2 = x2;
x2 = i;
}
if(!this.dimension.hasNoLight()) {
for(int j = x2; j <= z2; ++j) {
this.checkLightFor(LightType.SKY, new BlockPos(x1, j, z1));
}
}
this.markBlockRangeForRenderUpdate(x1, x2, z1, x1, z2, z1);
}
public void markBlockRangeForRenderUpdate(BlockPos rangeMin, BlockPos rangeMax) {
this.markBlockRangeForRenderUpdate(rangeMin.getX(), rangeMin.getY(), rangeMin.getZ(), rangeMax.getX(), rangeMax.getY(), rangeMax.getZ());
}
public void notifyNeighborsOfStateChange(BlockPos pos, Block blockType) {
this.notifyBlockOfStateChange(pos.west(), blockType);
this.notifyBlockOfStateChange(pos.east(), blockType);
this.notifyBlockOfStateChange(pos.down(), blockType);
this.notifyBlockOfStateChange(pos.up(), blockType);
this.notifyBlockOfStateChange(pos.north(), blockType);
this.notifyBlockOfStateChange(pos.south(), blockType);
}
public void notifyNeighborsOfStateExcept(BlockPos pos, Block blockType, Facing skipSide) {
if(skipSide != Facing.WEST) {
this.notifyBlockOfStateChange(pos.west(), blockType);
}
if(skipSide != Facing.EAST) {
this.notifyBlockOfStateChange(pos.east(), blockType);
}
if(skipSide != Facing.DOWN) {
this.notifyBlockOfStateChange(pos.down(), blockType);
}
if(skipSide != Facing.UP) {
this.notifyBlockOfStateChange(pos.up(), blockType);
}
if(skipSide != Facing.NORTH) {
this.notifyBlockOfStateChange(pos.north(), blockType);
}
if(skipSide != Facing.SOUTH) {
this.notifyBlockOfStateChange(pos.south(), blockType);
}
}
public void notifyBlockOfStateChange(BlockPos pos, final Block blockIn) {
if(!this.client) {
State iblockstate = this.getState(pos);
iblockstate.getBlock().onNeighborBlockChange(this, pos, iblockstate, blockIn);
}
}
public boolean canSeeSky(BlockPos pos) {
return this.getChunk(pos).canSeeSky(pos);
}
public int getLight(BlockPos pos) {
if(pos.getY() < 0) {
return 0;
}
else {
if(pos.getY() >= 512) {
pos = new BlockPos(pos.getX(), 511, pos.getZ());
}
return this.getChunk(pos).getLightSub(pos, 0);
}
}
public int getLightFromNeighbors(BlockPos pos) {
return this.getLight(pos, true);
}
private int getLight(BlockPos pos, boolean checkNeighbors) {
if(pos.getX() >= -MAX_SIZE && pos.getZ() >= -MAX_SIZE && pos.getX() < MAX_SIZE && pos.getZ() < MAX_SIZE) {
if(checkNeighbors && this.getState(pos).getBlock().getSumBrightness()) {
int i1 = this.getLight(pos.up(), false);
int i = this.getLight(pos.east(), false);
int j = this.getLight(pos.west(), false);
int k = this.getLight(pos.south(), false);
int l = this.getLight(pos.north(), false);
if(i > i1) {
i1 = i;
}
if(j > i1) {
i1 = j;
}
if(k > i1) {
i1 = k;
}
if(l > i1) {
i1 = l;
}
return i1;
}
else if(pos.getY() < 0) {
return 0;
}
else {
if(pos.getY() >= 512) {
pos = new BlockPos(pos.getX(), 511, pos.getZ());
}
Chunk chunk = this.getChunk(pos);
return chunk.getLightSub(pos, this.subtract);
}
}
else {
return 15;
}
}
public BlockPos getHeight(BlockPos pos) {
int i;
if(pos.getX() >= -MAX_SIZE && pos.getZ() >= -MAX_SIZE && pos.getX() < MAX_SIZE && pos.getZ() < MAX_SIZE) {
if(this.isLoaded(pos.getX() >> 4, pos.getZ() >> 4, true)) {
i = this.getChunk(pos.getX() >> 4, pos.getZ() >> 4).getHeight(pos.getX() & 15, pos.getZ() & 15);
}
else {
i = 0;
}
}
else {
i = this.getSeaLevel() + 1;
}
return new BlockPos(pos.getX(), i, pos.getZ());
}
public int getChunksLowestHorizon(int x, int z) {
if(x >= -MAX_SIZE && z >= -MAX_SIZE && x < MAX_SIZE && z < MAX_SIZE) {
if(!this.isLoaded(x >> 4, z >> 4, true)) {
return 0;
}
else {
Chunk chunk = this.getChunk(x >> 4, z >> 4);
return chunk.getLowest();
}
}
else {
return this.getSeaLevel() + 1;
}
}
public int getLightFromNeighborsFor(LightType type, BlockPos pos) {
if(this.dimension.hasNoLight() && type == LightType.SKY) {
return 0;
}
else {
if(pos.getY() < 0) {
pos = new BlockPos(pos.getX(), 0, pos.getZ());
}
if(!isValid(pos)) {
return type.defValue;
}
else if(!this.isBlockLoaded(pos)) {
return type.defValue;
}
else if(this.getState(pos).getBlock().getSumBrightness()) {
int i1 = this.getLightFor(type, pos.up());
int i = this.getLightFor(type, pos.east());
int j = this.getLightFor(type, pos.west());
int k = this.getLightFor(type, pos.south());
int l = this.getLightFor(type, pos.north());
if(i > i1) {
i1 = i;
}
if(j > i1) {
i1 = j;
}
if(k > i1) {
i1 = k;
}
if(l > i1) {
i1 = l;
}
return i1;
}
else {
Chunk chunk = this.getChunk(pos);
return chunk.getLight(type, pos);
}
}
}
public int getLightFor(LightType type, BlockPos pos) {
if(pos.getY() < 0) {
pos = new BlockPos(pos.getX(), 0, pos.getZ());
}
if(!isValid(pos)) {
return type.defValue;
}
else if(!this.isBlockLoaded(pos)) {
return type.defValue;
}
else {
Chunk chunk = this.getChunk(pos);
return chunk.getLight(type, pos);
}
}
public void setLightFor(LightType type, BlockPos pos, int lightValue) {
if(isValid(pos)) {
if(this.isBlockLoaded(pos)) {
Chunk chunk = this.getChunk(pos);
chunk.setLight(type, pos, lightValue);
this.notifyLightSet(pos);
}
}
}
public int getCombinedLight(BlockPos pos, int lightValue) {
int i = this.getLightFromNeighborsFor(LightType.SKY, pos);
int j = this.getLightFromNeighborsFor(LightType.BLOCK, pos);
if(j < lightValue) {
j = lightValue;
}
return i << 20 | j << 4;
}
public float getLightBrightness(BlockPos pos) {
return BRIGHTNESS[this.dimension.getBrightness()][this.getLightFromNeighbors(pos)];
}
public State getState(BlockPos pos) {
if(!isValid(pos)) {
return Blocks.air.getState();
}
else {
Chunk chunk = this.getChunk(pos);
return chunk.getState(pos);
}
}
public BlockPos getBlockTrace(Entity entity, int distance) {
double range = (double)distance;
double theta = 0.2;
double yaw = (entity.rotYaw + 90) % 360;
double pitch = entity.rotPitch * -1;
double dist = 0.0;
double h = theta * Math.cos(Math.toRadians(pitch));
Vec3 offset = new Vec3(h * Math.cos(Math.toRadians(yaw)), theta * Math.sin(Math.toRadians(pitch)),
h * Math.sin(Math.toRadians(yaw)));
Vec3 shift = new Vec3(entity.posX, entity.posY + entity.getEyeHeight(), entity.posZ);
BlockPos target = new BlockPos(ExtMath.floord(shift.xCoord), ExtMath.floord(shift.yCoord), ExtMath.floord(shift.zCoord));
BlockPos prev = target;
while(true) {
prev = target;
do {
dist += theta;
shift = offset.addVector(shift.xCoord, shift.yCoord, shift.zCoord);
target = new BlockPos(ExtMath.floord(shift.xCoord), ExtMath.floord(shift.yCoord), ExtMath.floord(shift.zCoord));
}
while(dist <= range && target.getX() == prev.getX() && target.getY() == prev.getY() && target.getZ() == prev.getZ());
if(dist > range)
return null;
if(this.getState(new BlockPos(target.getX(), target.getY(), target.getZ()))
.getBlock().getMaterial().blocksMovement())
break;
List<Entity> ents = this.getEntitiesInAABBexcluding(entity, new BoundingBox(target, target.add(1, 1, 1)),
new Predicate<Entity>() {
public boolean test(Entity entity) {
return entity.canBeCollidedWith();
}
});
if(!ents.isEmpty())
break;
}
return target;
}
public HitPosition rayTraceBlocks(Vec3 p_72933_1_, Vec3 p_72933_2_) {
return this.rayTraceBlocks(p_72933_1_, p_72933_2_, false, false, false);
}
public HitPosition rayTraceBlocks(Vec3 start, Vec3 end, boolean stopOnLiquid) {
return this.rayTraceBlocks(start, end, stopOnLiquid, false, false);
}
public HitPosition rayTraceBlocks(Vec3 vec31, Vec3 vec32, boolean stopOnLiquid, boolean ignoreBlockWithoutBoundingBox,
boolean returnLastUncollidableBlock) {
if(!Double.isNaN(vec31.xCoord) && !Double.isNaN(vec31.yCoord) && !Double.isNaN(vec31.zCoord)) {
if(!Double.isNaN(vec32.xCoord) && !Double.isNaN(vec32.yCoord) && !Double.isNaN(vec32.zCoord)) {
int i = ExtMath.floord(vec32.xCoord);
int j = ExtMath.floord(vec32.yCoord);
int k = ExtMath.floord(vec32.zCoord);
int l = ExtMath.floord(vec31.xCoord);
int i1 = ExtMath.floord(vec31.yCoord);
int j1 = ExtMath.floord(vec31.zCoord);
BlockPos blockpos = new BlockPos(l, i1, j1);
State iblockstate = this.getState(blockpos);
Block block = iblockstate.getBlock();
if((!ignoreBlockWithoutBoundingBox || block.getCollisionBoundingBox(this, blockpos, iblockstate) != null)
&& block.canCollideCheck(iblockstate, stopOnLiquid)) {
HitPosition movingobjectposition = block.collisionRayTrace(this, blockpos, vec31, vec32);
if(movingobjectposition != null) {
return movingobjectposition;
}
}
HitPosition movingobjectposition2 = null;
int k1 = 200;
while(k1-- >= 0) {
if(Double.isNaN(vec31.xCoord) || Double.isNaN(vec31.yCoord) || Double.isNaN(vec31.zCoord)) {
return null;
}
if(l == i && i1 == j && j1 == k) {
return returnLastUncollidableBlock ? movingobjectposition2 : null;
}
boolean flag2 = true;
boolean flag = true;
boolean flag1 = 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 {
flag2 = false;
}
if(j > i1) {
d1 = (double)i1 + 1.0D;
}
else if(j < i1) {
d1 = (double)i1 + 0.0D;
}
else {
flag = false;
}
if(k > j1) {
d2 = (double)j1 + 1.0D;
}
else if(k < j1) {
d2 = (double)j1 + 0.0D;
}
else {
flag1 = false;
}
double d3 = 999.0D;
double d4 = 999.0D;
double d5 = 999.0D;
double d6 = vec32.xCoord - vec31.xCoord;
double d7 = vec32.yCoord - vec31.yCoord;
double d8 = vec32.zCoord - vec31.zCoord;
if(flag2) {
d3 = (d0 - vec31.xCoord) / d6;
}
if(flag) {
d4 = (d1 - vec31.yCoord) / d7;
}
if(flag1) {
d5 = (d2 - vec31.zCoord) / d8;
}
if(d3 == -0.0D) {
d3 = -1.0E-4D;
}
if(d4 == -0.0D) {
d4 = -1.0E-4D;
}
if(d5 == -0.0D) {
d5 = -1.0E-4D;
}
Facing enumfacing;
if(d3 < d4 && d3 < d5) {
enumfacing = i > l ? Facing.WEST : Facing.EAST;
vec31 = new Vec3(d0, vec31.yCoord + d7 * d3, vec31.zCoord + d8 * d3);
}
else if(d4 < d5) {
enumfacing = j > i1 ? Facing.DOWN : Facing.UP;
vec31 = new Vec3(vec31.xCoord + d6 * d4, d1, vec31.zCoord + d8 * d4);
}
else {
enumfacing = k > j1 ? Facing.NORTH : Facing.SOUTH;
vec31 = new Vec3(vec31.xCoord + d6 * d5, vec31.yCoord + d7 * d5, d2);
}
l = ExtMath.floord(vec31.xCoord) - (enumfacing == Facing.EAST ? 1 : 0);
i1 = ExtMath.floord(vec31.yCoord) - (enumfacing == Facing.UP ? 1 : 0);
j1 = ExtMath.floord(vec31.zCoord) - (enumfacing == Facing.SOUTH ? 1 : 0);
blockpos = new BlockPos(l, i1, j1);
State iblockstate1 = this.getState(blockpos);
Block block1 = iblockstate1.getBlock();
if(!ignoreBlockWithoutBoundingBox || block1.getCollisionBoundingBox(this, blockpos, iblockstate1) != null) {
if(block1.canCollideCheck(iblockstate1, stopOnLiquid)) {
HitPosition movingobjectposition1 = block1.collisionRayTrace(this, blockpos, vec31, vec32);
if(movingobjectposition1 != null) {
return movingobjectposition1;
}
}
else {
movingobjectposition2 = new HitPosition(HitPosition.ObjectType.MISS, vec31, enumfacing, blockpos);
}
}
}
return returnLastUncollidableBlock ? movingobjectposition2 : null;
}
else {
return null;
}
}
else {
return null;
}
}
public void playSoundAtEntity(Entity entityIn, SoundEvent name, float volume, float pitch) {
this.playSound(name, entityIn.posX, entityIn.posY, entityIn.posZ, volume, pitch);
}
public boolean spawnEntityInWorld(Entity entityIn) {
int i = ExtMath.floord(entityIn.posX / 16.0D);
int j = ExtMath.floord(entityIn.posZ / 16.0D);
boolean flag = entityIn.forceSpawn;
if(entityIn.isPlayer()) {
flag = true;
}
if(!flag && !this.isLoaded(i, j, true)) {
return false;
}
else {
if(entityIn.isPlayer()) {
EntityNPC entityplayer = (EntityNPC)entityIn;
this.players.add(entityplayer);
// this.updateAllPlayersSleepingFlag();
}
this.getChunk(i, j).addEntity(entityIn);
this.entities.add(entityIn);
this.onEntityAdded(entityIn);
return true;
}
}
public void removeEntity(Entity entityIn) {
if(entityIn.passenger != null) {
entityIn.passenger.mountEntity((Entity)null);
}
if(entityIn.vehicle != null) {
entityIn.mountEntity((Entity)null);
}
entityIn.setDead();
if(entityIn.isPlayer()) {
this.players.remove(entityIn);
// this.updateAllPlayersSleepingFlag();
this.onEntityRemoved(entityIn);
}
}
public List<BoundingBox> getCollidingBoundingBoxes(Entity entityIn, BoundingBox bb) {
List<BoundingBox> list = Lists.<BoundingBox>newArrayList();
int i = ExtMath.floord(bb.minX);
int j = ExtMath.floord(bb.maxX + 1.0D);
int k = ExtMath.floord(bb.minY);
int l = ExtMath.floord(bb.maxY + 1.0D);
int i1 = ExtMath.floord(bb.minZ);
int j1 = ExtMath.floord(bb.maxZ + 1.0D);
// Border worldborder = this.getWorldBorder();
boolean flag = entityIn.isOutsideBorder();
boolean flag1 = this.isInsideBorder(entityIn);
State iblockstate = Blocks.stone.getState();
BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos();
for(int k1 = i; k1 < j; ++k1) {
for(int l1 = i1; l1 < j1; ++l1) {
if(this.isBlockLoaded(blockpos$mutableblockpos.set(k1, 64, l1))) {
for(int i2 = k - 1; i2 < l; ++i2) {
blockpos$mutableblockpos.set(k1, i2, l1);
if(flag && flag1) {
entityIn.setOutsideBorder(false);
}
else if(!flag && !flag1) {
entityIn.setOutsideBorder(true);
}
State iblockstate1 = iblockstate;
if(isValidXZ(blockpos$mutableblockpos) || !flag1) {
iblockstate1 = this.getState(blockpos$mutableblockpos);
}
iblockstate1.getBlock().addCollisionBoxesToList(this, blockpos$mutableblockpos, iblockstate1, bb, list, entityIn);
}
}
}
}
double d0 = 0.25D;
List<Entity> list1 = this.getEntitiesWithinAABBExcludingEntity(entityIn, bb.expand(d0, d0, d0));
for(int j2 = 0; j2 < list1.size(); ++j2) {
if(entityIn.passenger != list1 && entityIn.vehicle != list1) {
BoundingBox axisalignedbb = ((Entity)list1.get(j2)).getCollisionBoundingBox();
if(axisalignedbb != null && axisalignedbb.intersectsWith(bb)) {
list.add(axisalignedbb);
}
axisalignedbb = entityIn.getCollisionBox((Entity)list1.get(j2));
if(axisalignedbb != null && axisalignedbb.intersectsWith(bb)) {
list.add(axisalignedbb);
}
}
}
return list;
}
private boolean isInsideBorder(Entity entityIn) {
double d0 = (double)-MAX_SIZE; // worldBorderIn.minX();
double d2 = (double)MAX_SIZE; // worldBorderIn.maxX();
if(entityIn.isOutsideBorder()) {
++d0;
--d2;
}
else {
--d0;
++d2;
}
return entityIn.posX > d0 && entityIn.posX < d2 && entityIn.posZ > d0 && entityIn.posZ < d2;
}
public List<BoundingBox> getCollisionBoxes(BoundingBox bb) {
List<BoundingBox> list = Lists.<BoundingBox>newArrayList();
int i = ExtMath.floord(bb.minX);
int j = ExtMath.floord(bb.maxX + 1.0D);
int k = ExtMath.floord(bb.minY);
int l = ExtMath.floord(bb.maxY + 1.0D);
int i1 = ExtMath.floord(bb.minZ);
int j1 = ExtMath.floord(bb.maxZ + 1.0D);
BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos();
for(int k1 = i; k1 < j; ++k1) {
for(int l1 = i1; l1 < j1; ++l1) {
if(this.isBlockLoaded(blockpos$mutableblockpos.set(k1, 64, l1))) {
for(int i2 = k - 1; i2 < l; ++i2) {
blockpos$mutableblockpos.set(k1, i2, l1);
State iblockstate;
if(k1 >= -MAX_SIZE && k1 < MAX_SIZE && l1 >= -MAX_SIZE && l1 < MAX_SIZE) {
iblockstate = this.getState(blockpos$mutableblockpos);
}
else {
iblockstate = Blocks.bedrock.getState();
}
iblockstate.getBlock().addCollisionBoxesToList(this, blockpos$mutableblockpos, iblockstate, bb, list, (Entity)null);
}
}
}
}
return list;
}
private float calculateCelestialAngle(long worldTime, float partialTicks) {
int i = (int)(worldTime % this.dimension.getRotationalPeriod());
float f = ((float)i + partialTicks) / (float)this.dimension.getRotationalPeriod() - 0.5F;
if(f < 0.0F) {
++f;
}
if(f > 1.0F) {
--f;
}
f = 1.0F - (float)((Math.cos((double)f * Math.PI) + 1.0D) / 2.0D);
f = f + (f - f) / 3.0F;
return f;
}
public int calculateSkylightSubtracted(boolean current) {
float f = !this.dimension.getType().days ? 0.5f : this.calculateCelestialAngle(current ? this.daytime :
(this.dimension.getRotationalPeriod() / 4L), 1.0f);
float f1 = 1.0F - (ExtMath.cos(f * (float)Math.PI * 2.0F) * 2.0F + 0.5F);
f1 = ExtMath.clampf(f1, 0.0F, 1.0F);
f1 = 1.0F - f1;
f1 = (float)((double)f1 * (1.0D - (double)(this.getRainStrength() * 5.0F) / 16.0D));
f1 = (float)((double)f1 * (1.0D - (double)(this.getDarkness() * 5.0F) / 16.0D));
f1 = 1.0F - f1;
return (int)(f1 * 11.0F);
}
public float getCelestialAngle(float partialTicks) {
return !this.dimension.getType().days ? 0.5f : this.calculateCelestialAngle(this.daytime, partialTicks);
}
public int getMoonPhase() {
return (int)(this.daytime / this.dimension.getRotationalPeriod() % 8L + 8L) % 8;
}
public float getCurrentMoonPhaseFactor() {
return MOON_PHASES[this.getMoonPhase()];
}
public float getCelestialAngleRadians(float partialTicks) {
float f = this.getCelestialAngle(partialTicks);
return f * (float)Math.PI * 2.0F;
}
public BlockPos getPrecipitationHeight(BlockPos pos) {
return this.getChunk(pos).getPrecipitation(pos);
}
public void updateEntities() {
// this.profiler.start("entities");
// this.profiler.start("global");
for(int i = 0; i < this.effects.size(); ++i) {
Entity entity = (Entity)this.effects.get(i);
++entity.ticksExisted;
entity.onUpdate();
if(entity.dead) {
this.effects.remove(i--);
}
}
// this.profiler.next("remove");
this.entities.removeAll(this.unloaded);
for(int k = 0; k < this.unloaded.size(); ++k) {
Entity entity1 = (Entity)this.unloaded.get(k);
int j = entity1.chunkCoordX;
int l1 = entity1.chunkCoordZ;
if(entity1.addedToChunk && this.isLoaded(j, l1, true)) {
this.getChunk(j, l1).removeEntity(entity1);
}
}
for(int l = 0; l < this.unloaded.size(); ++l) {
this.onEntityRemoved((Entity)this.unloaded.get(l));
}
this.unloaded.clear();
// this.profiler.next("regular");
for(int i1 = 0; i1 < this.entities.size(); ++i1) {
Entity entity2 = this.entities.get(i1);
if(entity2.vehicle != null) {
if(!entity2.vehicle.dead && entity2.vehicle.passenger == entity2) {
continue;
}
entity2.vehicle.passenger = null;
entity2.vehicle = null;
}
// this.profiler.start("tick");
if(!entity2.dead) {
this.updateEntity(entity2, true);
}
// this.profiler.end();
}
// this.profiler.next("dead");
Iterator<Entity> ents = this.entities.iterator();
while(ents.hasNext()) {
Entity entity2 = ents.next();
if(entity2.dead) {
int k1 = entity2.chunkCoordX;
int i2 = entity2.chunkCoordZ;
if(entity2.addedToChunk && this.isLoaded(k1, i2, true)) {
this.getChunk(k1, i2).removeEntity(entity2);
}
ents.remove();
this.onEntityRemoved(entity2);
}
}
// this.profiler.next("blockEntities");
this.loadTiles = true;
Iterator<TileEntity> iterator = this.tickable.iterator();
while(iterator.hasNext()) {
TileEntity tileentity = (TileEntity)iterator.next();
if(!tileentity.isInvalid() && tileentity.hasWorldObj()) {
BlockPos blockpos = tileentity.getPos();
if(this.isBlockLoaded(blockpos)) { // && this.border.contains(blockpos)) {
((ITickable)tileentity).update();
}
}
if(tileentity.isInvalid()) {
iterator.remove();
this.tiles.remove(tileentity);
if(this.isBlockLoaded(tileentity.getPos())) {
this.getChunk(tileentity.getPos()).removeTileEntity(tileentity.getPos());
}
}
}
this.loadTiles = false;
if(!this.removeTiles.isEmpty()) {
this.tickable.removeAll(this.removeTiles);
this.tiles.removeAll(this.removeTiles);
this.removeTiles.clear();
}
// this.profiler.next("pendingBlockEntities");
if(!this.addedTiles.isEmpty()) {
for(int j1 = 0; j1 < this.addedTiles.size(); ++j1) {
TileEntity tileentity1 = (TileEntity)this.addedTiles.get(j1);
if(!tileentity1.isInvalid()) {
if(!this.tiles.contains(tileentity1)) {
this.addTileEntity(tileentity1);
}
if(this.isBlockLoaded(tileentity1.getPos())) {
this.getChunk(tileentity1.getPos()).addTileEntity(tileentity1.getPos(), tileentity1);
}
this.markBlockForUpdate(tileentity1.getPos());
}
}
this.addedTiles.clear();
}
// this.profiler.end();
// this.profiler.end();
}
public boolean addTileEntity(TileEntity tile) {
boolean flag = this.tiles.add(tile);
if(flag && tile instanceof ITickable) {
this.tickable.add(tile);
}
return flag;
}
public void addTileEntities(Collection<TileEntity> tileEntityCollection) {
if(this.loadTiles) {
this.addedTiles.addAll(tileEntityCollection);
}
else {
for(TileEntity tileentity : tileEntityCollection) {
this.tiles.add(tileentity);
if(tileentity instanceof ITickable) {
this.tickable.add(tileentity);
}
}
}
}
public void updateEntity(Entity entityIn, boolean forceUpdate) {
int i = ExtMath.floord(entityIn.posX);
int j = ExtMath.floord(entityIn.posZ);
int k = 32;
if(!forceUpdate || this.isAreaLoaded(i - k, 0, j - k, i + k, 0, j + k, true)) {
entityIn.lastTickPosX = entityIn.posX;
entityIn.lastTickPosY = entityIn.posY;
entityIn.lastTickPosZ = entityIn.posZ;
entityIn.prevYaw = entityIn.rotYaw;
entityIn.prevPitch = entityIn.rotPitch;
if(forceUpdate && entityIn.addedToChunk) {
++entityIn.ticksExisted;
if(entityIn.vehicle != null) {
entityIn.updateRidden();
}
else {
entityIn.onUpdate();
}
}
// this.profiler.start("chunkCheck");
if(Double.isNaN(entityIn.posX) || Double.isInfinite(entityIn.posX)) {
entityIn.posX = entityIn.lastTickPosX;
}
if(Double.isNaN(entityIn.posY) || Double.isInfinite(entityIn.posY)) {
entityIn.posY = entityIn.lastTickPosY;
}
if(Double.isNaN(entityIn.posZ) || Double.isInfinite(entityIn.posZ)) {
entityIn.posZ = entityIn.lastTickPosZ;
}
if(Double.isNaN((double)entityIn.rotPitch) || Double.isInfinite((double)entityIn.rotPitch)) {
entityIn.rotPitch = entityIn.prevPitch;
}
if(Double.isNaN((double)entityIn.rotYaw) || Double.isInfinite((double)entityIn.rotYaw)) {
entityIn.rotYaw = entityIn.prevYaw;
}
int l = ExtMath.floord(entityIn.posX / 16.0D);
int i1 = ExtMath.floord(entityIn.posY / 16.0D);
int j1 = ExtMath.floord(entityIn.posZ / 16.0D);
if(!entityIn.addedToChunk || entityIn.chunkCoordX != l || entityIn.chunkCoordY != i1 || entityIn.chunkCoordZ != j1) {
if(entityIn.addedToChunk && this.isLoaded(entityIn.chunkCoordX, entityIn.chunkCoordZ, true)) {
this.getChunk(entityIn.chunkCoordX, entityIn.chunkCoordZ).removeEntity(entityIn); // fix red. method
}
if(this.isLoaded(l, j1, true)) {
entityIn.addedToChunk = true;
this.getChunk(l, j1).addEntity(entityIn);
}
else {
entityIn.addedToChunk = false;
}
}
// this.profiler.end();
if(forceUpdate && entityIn.addedToChunk && entityIn.passenger != null) {
if(!entityIn.passenger.dead && entityIn.passenger.vehicle == entityIn) {
this.updateEntity(entityIn.passenger, true);
}
else {
entityIn.passenger.vehicle = null;
entityIn.passenger = null;
}
}
}
}
public boolean checkNoEntityCollision(BoundingBox bb) {
return this.checkNoEntityCollision(bb, (Entity)null);
}
public boolean checkNoEntityCollision(BoundingBox bb, Entity entityIn) {
List<Entity> list = this.getEntitiesWithinAABBExcludingEntity((Entity)null, bb);
for(int i = 0; i < list.size(); ++i) {
Entity entity = (Entity)list.get(i);
if(!entity.dead && entity.preventSpawning && entity != entityIn
&& (entityIn == null || entityIn.vehicle != entity && entityIn.passenger != entity)) {
return false;
}
}
return true;
}
public boolean isAnyLiquid(BoundingBox bb) {
int i = ExtMath.floord(bb.minX);
int j = ExtMath.floord(bb.maxX);
int k = ExtMath.floord(bb.minY);
int l = ExtMath.floord(bb.maxY);
int i1 = ExtMath.floord(bb.minZ);
int j1 = ExtMath.floord(bb.maxZ);
BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos();
for(int k1 = i; k1 <= j; ++k1) {
for(int l1 = k; l1 <= l; ++l1) {
for(int i2 = i1; i2 <= j1; ++i2) {
Block block = this.getState(blockpos$mutableblockpos.set(k1, l1, i2)).getBlock();
if(block.getMaterial().isLiquid()) {
return true;
}
}
}
}
return false;
}
public boolean isFlammableWithin(BoundingBox bb) {
int i = ExtMath.floord(bb.minX);
int j = ExtMath.floord(bb.maxX + 1.0D);
int k = ExtMath.floord(bb.minY);
int l = ExtMath.floord(bb.maxY + 1.0D);
int i1 = ExtMath.floord(bb.minZ);
int j1 = ExtMath.floord(bb.maxZ + 1.0D);
if(this.isAreaLoaded(i, k, i1, j, l, j1, true)) {
BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos();
for(int k1 = i; k1 < j; ++k1) {
for(int l1 = k; l1 < l; ++l1) {
for(int i2 = i1; i2 < j1; ++i2) {
Block block = this.getState(blockpos$mutableblockpos.set(k1, l1, i2)).getBlock();
if(block == Blocks.fire || block == Blocks.flowing_lava || block == Blocks.lava) {
return true;
}
}
}
}
}
return false;
}
public boolean handleLiquidAcceleration(BoundingBox bb, Entity entityIn) {
int i = ExtMath.floord(bb.minX);
int j = ExtMath.floord(bb.maxX + 1.0D);
int k = ExtMath.floord(bb.minY);
int l = ExtMath.floord(bb.maxY + 1.0D);
int i1 = ExtMath.floord(bb.minZ);
int j1 = ExtMath.floord(bb.maxZ + 1.0D);
if(!this.isAreaLoaded(i, k, i1, j, l, j1, true)) {
return false;
}
else {
boolean flag = false;
Vec3 vec3 = new Vec3(0.0D, 0.0D, 0.0D);
BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos();
for(int k1 = i; k1 < j; ++k1) {
for(int l1 = k; l1 < l; ++l1) {
for(int i2 = i1; i2 < j1; ++i2) {
blockpos$mutableblockpos.set(k1, l1, i2);
State iblockstate = this.getState(blockpos$mutableblockpos);
Block block = iblockstate.getBlock();
if(block.getMaterial().isColdLiquid()) {
double d0 = (double)((float)(l1 + 1)
- BlockLiquid.getLiquidHeightPercent(((Integer)iblockstate.getValue(BlockLiquid.LEVEL)).intValue()));
if((double)l >= d0) {
flag = true;
vec3 = block.modifyAcceleration(this, blockpos$mutableblockpos, entityIn, vec3);
}
}
}
}
}
if(vec3.lengthVector() > 0.0D && entityIn.isPushedByWater()) {
vec3 = vec3.normalize();
double d1 = 0.014D;
entityIn.motionX += vec3.xCoord * d1;
entityIn.motionY += vec3.yCoord * d1;
entityIn.motionZ += vec3.zCoord * d1;
}
return flag;
}
}
public boolean isMaterialInMolten(BoundingBox bb) {
int i = ExtMath.floord(bb.minX);
int j = ExtMath.floord(bb.maxX + 1.0D);
int k = ExtMath.floord(bb.minY);
int l = ExtMath.floord(bb.maxY + 1.0D);
int i1 = ExtMath.floord(bb.minZ);
int j1 = ExtMath.floord(bb.maxZ + 1.0D);
BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos();
for(int k1 = i; k1 < j; ++k1) {
for(int l1 = k; l1 < l; ++l1) {
for(int i2 = i1; i2 < j1; ++i2) {
if(this.getState(blockpos$mutableblockpos.set(k1, l1, i2)).getBlock().getMaterial().isHotLiquid()) {
return true;
}
}
}
}
return false;
}
public boolean isAABBInLiquid(BoundingBox bb) {
int i = ExtMath.floord(bb.minX);
int j = ExtMath.floord(bb.maxX + 1.0D);
int k = ExtMath.floord(bb.minY);
int l = ExtMath.floord(bb.maxY + 1.0D);
int i1 = ExtMath.floord(bb.minZ);
int j1 = ExtMath.floord(bb.maxZ + 1.0D);
BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos();
for(int k1 = i; k1 < j; ++k1) {
for(int l1 = k; l1 < l; ++l1) {
for(int i2 = i1; i2 < j1; ++i2) {
State iblockstate = this.getState(blockpos$mutableblockpos.set(k1, l1, i2));
Block block = iblockstate.getBlock();
if(block.getMaterial().isColdLiquid()) {
int j2 = ((Integer)iblockstate.getValue(BlockLiquid.LEVEL)).intValue();
double d0 = (double)(l1 + 1);
if(j2 < 8) {
d0 = (double)(l1 + 1) - (double)j2 / 8.0D;
}
if(d0 >= bb.minY) {
return true;
}
}
}
}
}
return false;
}
public Explosion createExplosion(Entity entityIn, double x, double y, double z, float strength, boolean isSmoking) {
return this.newExplosion(entityIn, x, y, z, strength, false, isSmoking, false);
}
public Explosion createAltExplosion(Entity entityIn, double x, double y, double z, float strength, boolean isSmoking) {
return this.newExplosion(entityIn, x, y, z, strength, false, isSmoking, true);
}
public Explosion newExplosion(Entity entityIn, double x, double y, double z, float strength, boolean isFlaming, boolean isSmoking, boolean altSound) {
Explosion explosion = new Explosion(this, entityIn, x, y, z, strength, isFlaming, isSmoking);
explosion.doExplosionA();
explosion.doExplosionB(true, altSound);
return explosion;
}
public EntityExplosion newExplosion(double x, double y, double z, int strength) {
EntityExplosion explosion = new EntityExplosion(this, x, y, z, strength);
this.spawnEntityInWorld(explosion);
return explosion;
}
public float getBlockDensity(Vec3 vec, BoundingBox bb) {
double d0 = 1.0D / ((bb.maxX - bb.minX) * 2.0D + 1.0D);
double d1 = 1.0D / ((bb.maxY - bb.minY) * 2.0D + 1.0D);
double d2 = 1.0D / ((bb.maxZ - bb.minZ) * 2.0D + 1.0D);
double d3 = (1.0D - Math.floor(1.0D / d0) * d0) / 2.0D;
double d4 = (1.0D - Math.floor(1.0D / d2) * d2) / 2.0D;
if(d0 >= 0.0D && d1 >= 0.0D && d2 >= 0.0D) {
int i = 0;
int j = 0;
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 d5 = bb.minX + (bb.maxX - bb.minX) * (double)f;
double d6 = bb.minY + (bb.maxY - bb.minY) * (double)f1;
double d7 = bb.minZ + (bb.maxZ - bb.minZ) * (double)f2;
if(this.rayTraceBlocks(new Vec3(d5 + d3, d6, d7 + d4), vec) == null) {
++i;
}
++j;
}
}
}
return (float)i / (float)j;
}
else {
return 0.0F;
}
}
public boolean extinguishFire(EntityNPC player, BlockPos pos, Facing side) {
pos = pos.offset(side);
if(this.getState(pos).getBlock() == Blocks.fire) {
this.playAuxSFX(player, 1004, pos, 0);
this.setBlockToAir(pos);
return true;
}
else {
return false;
}
}
public TileEntity getTileEntity(BlockPos pos) {
if(!isValid(pos)) {
return null;
}
else {
TileEntity tileentity = null;
if(this.loadTiles) {
for(int i = 0; i < this.addedTiles.size(); ++i) {
TileEntity tileentity1 = (TileEntity)this.addedTiles.get(i);
if(!tileentity1.isInvalid() && tileentity1.getPos().equals(pos)) {
tileentity = tileentity1;
break;
}
}
}
if(tileentity == null) {
tileentity = this.getChunk(pos).getTileEntity(pos, TileEntity.EnumCreateEntityType.IMMEDIATE);
}
if(tileentity == null) {
for(int j = 0; j < this.addedTiles.size(); ++j) {
TileEntity tileentity2 = (TileEntity)this.addedTiles.get(j);
if(!tileentity2.isInvalid() && tileentity2.getPos().equals(pos)) {
tileentity = tileentity2;
break;
}
}
}
return tileentity;
}
}
public void setTileEntity(BlockPos pos, TileEntity tileEntityIn) {
if(tileEntityIn != null && !tileEntityIn.isInvalid()) {
if(this.loadTiles) {
tileEntityIn.setPos(pos);
Iterator<TileEntity> iterator = this.addedTiles.iterator();
while(iterator.hasNext()) {
TileEntity tileentity = (TileEntity)iterator.next();
if(tileentity.getPos().equals(pos)) {
tileentity.invalidate();
iterator.remove();
}
}
this.addedTiles.add(tileEntityIn);
}
else {
this.addTileEntity(tileEntityIn);
this.getChunk(pos).addTileEntity(pos, tileEntityIn);
}
}
}
public void removeTileEntity(BlockPos pos) {
TileEntity tileentity = this.getTileEntity(pos);
if(tileentity != null && this.loadTiles) {
tileentity.invalidate();
this.addedTiles.remove(tileentity);
}
else {
if(tileentity != null) {
this.addedTiles.remove(tileentity);
this.tiles.remove(tileentity);
this.tickable.remove(tileentity);
}
this.getChunk(pos).removeTileEntity(pos);
}
}
public void markTileEntityForRemoval(TileEntity tileEntityIn) {
this.removeTiles.add(tileEntityIn);
}
protected void calculateInitialSkylight() {
int light = this.calculateSkylightSubtracted(false);
if(light != this.subtract)
this.subtract = light;
}
protected void calculateInitialWeather() {
this.rain = this.weather.hasDownfall() ? 1.0f : 0.0f;
this.darkness = this.weather.isDark() ? 1.0f : 0.0f;
this.fog = this.weather.getFogIntensity();
this.temp = this.getBaseTemperature() + this.weather.getTemperature();
}
protected void setActivePlayerChunksAndCheckLight(int l) {
this.active.clear();
// this.profiler.start("buildList");
for(int i = 0; i < this.players.size(); ++i) {
EntityNPC entityplayer = (EntityNPC)this.players.get(i);
int j = ExtMath.floord(entityplayer.posX / 16.0D);
int k = ExtMath.floord(entityplayer.posZ / 16.0D);
// int l = this.getRenderDistanceChunks();
for(int i1 = -l; i1 <= l; ++i1) {
for(int j1 = -l; j1 <= l; ++j1) {
this.active.add(new ChunkPos(i1 + j, j1 + k));
}
}
}
// this.profiler.end();
//
// this.profiler.start("playerCheckLight");
if(!this.players.isEmpty()) {
int k1 = this.rand.zrange(this.players.size());
EntityNPC entityplayer1 = (EntityNPC)this.players.get(k1);
int l1 = ExtMath.floord(entityplayer1.posX) + this.rand.zrange(11) - 5;
int i2 = ExtMath.floord(entityplayer1.posY) + this.rand.zrange(11) - 5;
int j2 = ExtMath.floord(entityplayer1.posZ) + this.rand.zrange(11) - 5;
this.checkLight(new BlockPos(l1, i2, j2));
}
// this.profiler.end();
}
public float getTempOffset() {
return this.temp;
}
protected float getBaseTemperature() {
return this.dimension.getTemperature() + this.dimension.getOrbitOffset() *
ExtMath.sin((((float)(this.daytime % this.dimension.getOrbitalPeriod()) / (float)this.dimension.getOrbitalPeriod())
-0.125f) * (float)Math.PI * 2.0f);
}
public LeavesType getLeavesGen(BlockPos pos) {
return this.canFreezeAt(pos) ? LeavesType.SNOWY : ((!this.dimension.getType().days || this.dimension.getOrbitOffset() == 0.0f) ?
this.dimension.getLeavesType() : LeavesType.values()[(int)((this.daytime %
this.dimension.getOrbitalPeriod()) * (long)LeavesType.values().length / this.dimension.getOrbitalPeriod())]);
}
public float getTemperatureK(BlockPos pos) {
return this.temp + this.getBiomeGenForCoords(pos).getFloatTemperature(pos);
}
public float getTemperatureC(BlockPos pos) {
return World.ABSOLUTE_ZERO + this.getTemperatureK(pos);
}
public boolean canFreezeAt(BlockPos pos) {
return this.getTemperatureC(pos) <= 0.0F;
}
public boolean canBurnAt(BlockPos pos) {
return this.getTemperatureC(pos) >= 194.0f;
}
public boolean doesWaterVaporize(BlockPos pos) {
return this.getTemperatureC(pos) >= 100.0f;
}
public boolean isLavaFaster(BlockPos pos) {
return this.getTemperatureC(pos) >= 314.0f;
}
public boolean canSnowAt(BlockPos pos, boolean checkLight, boolean allowLayers) {
if(!this.canFreezeAt(pos)) {
return false;
}
else if(!checkLight) {
return true;
}
else {
if(pos.getY() >= 0 && pos.getY() < 512 && this.getLightFor(LightType.BLOCK, pos) < 10) {
Block block = this.getState(pos).getBlock();
if((block.getMaterial() == Material.air || (allowLayers && block == Blocks.snow_layer))
&& Blocks.snow_layer.canPlaceBlockAt(this, pos)) {
return true;
}
}
return false;
}
}
public boolean checkLight(BlockPos pos) {
boolean flag = false;
if(!this.dimension.hasNoLight()) {
flag |= this.checkLightFor(LightType.SKY, pos);
}
flag = flag | this.checkLightFor(LightType.BLOCK, pos);
return flag;
}
private int getRawLight(BlockPos pos, LightType lightType) {
if(lightType == LightType.SKY && this.canSeeSky(pos)) {
return 15;
}
else {
Block block = this.getState(pos).getBlock();
int i = lightType == LightType.SKY ? 0 : block.getLightValue();
int j = block.getLightOpacity();
if(j >= 15 && block.getLightValue() > 0) {
j = 1;
}
if(j < 1) {
j = 1;
}
if(j >= 15) {
return 0;
}
else if(i >= 14) {
return i;
}
else {
for(Facing enumfacing : Facing.values()) {
BlockPos blockpos = pos.offset(enumfacing);
int k = this.getLightFor(lightType, blockpos) - j;
if(k > i) {
i = k;
}
if(i >= 14) {
return i;
}
}
return i;
}
}
}
public boolean checkLightFor(LightType lightType, BlockPos pos) {
if(!this.isAreaLoaded(pos, 17, false)) {
return false;
}
else {
int i = 0;
int j = 0;
// this.profiler.start("getBrightness");
int k = this.getLightFor(lightType, pos);
int l = this.getRawLight(pos, lightType);
int i1 = pos.getX();
int j1 = pos.getY();
int k1 = pos.getZ();
if(l > k) {
this.lightUpdate[j++] = 133152;
}
else if(l < k) {
this.lightUpdate[j++] = 133152 | k << 18;
while(i < j) {
int l1 = this.lightUpdate[i++];
int i2 = (l1 & 63) - 32 + i1;
int j2 = (l1 >> 6 & 63) - 32 + j1;
int k2 = (l1 >> 12 & 63) - 32 + k1;
int l2 = l1 >> 18 & 15;
BlockPos blockpos = new BlockPos(i2, j2, k2);
int i3 = this.getLightFor(lightType, blockpos);
if(i3 == l2) {
this.setLightFor(lightType, blockpos, 0);
if(l2 > 0) {
int j3 = ExtMath.absi(i2 - i1);
int k3 = ExtMath.absi(j2 - j1);
int l3 = ExtMath.absi(k2 - k1);
if(j3 + k3 + l3 < 17) {
BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos();
for(Facing enumfacing : Facing.values()) {
int i4 = i2 + enumfacing.getFrontOffsetX();
int j4 = j2 + enumfacing.getFrontOffsetY();
int k4 = k2 + enumfacing.getFrontOffsetZ();
blockpos$mutableblockpos.set(i4, j4, k4);
int l4 = Math.max(1, this.getState(blockpos$mutableblockpos).getBlock().getLightOpacity());
i3 = this.getLightFor(lightType, blockpos$mutableblockpos);
if(i3 == l2 - l4 && j < this.lightUpdate.length) {
this.lightUpdate[j++] = i4 - i1 + 32 | j4 - j1 + 32 << 6 | k4 - k1 + 32 << 12 | l2 - l4 << 18;
}
}
}
}
}
}
i = 0;
}
// this.profiler.end();
// this.profiler.start("checkedPosition < toCheckCount");
while(i < j) {
int i5 = this.lightUpdate[i++];
int j5 = (i5 & 63) - 32 + i1;
int k5 = (i5 >> 6 & 63) - 32 + j1;
int l5 = (i5 >> 12 & 63) - 32 + k1;
BlockPos blockpos1 = new BlockPos(j5, k5, l5);
int i6 = this.getLightFor(lightType, blockpos1);
int j6 = this.getRawLight(blockpos1, lightType);
if(j6 != i6) {
this.setLightFor(lightType, blockpos1, j6);
if(j6 > i6) {
int k6 = Math.abs(j5 - i1);
int l6 = Math.abs(k5 - j1);
int i7 = Math.abs(l5 - k1);
boolean flag = j < this.lightUpdate.length - 6;
if(k6 + l6 + i7 < 17 && flag) {
if(this.getLightFor(lightType, blockpos1.west()) < j6) {
this.lightUpdate[j++] = j5 - 1 - i1 + 32 + (k5 - j1 + 32 << 6) + (l5 - k1 + 32 << 12);
}
if(this.getLightFor(lightType, blockpos1.east()) < j6) {
this.lightUpdate[j++] = j5 + 1 - i1 + 32 + (k5 - j1 + 32 << 6) + (l5 - k1 + 32 << 12);
}
if(this.getLightFor(lightType, blockpos1.down()) < j6) {
this.lightUpdate[j++] = j5 - i1 + 32 + (k5 - 1 - j1 + 32 << 6) + (l5 - k1 + 32 << 12);
}
if(this.getLightFor(lightType, blockpos1.up()) < j6) {
this.lightUpdate[j++] = j5 - i1 + 32 + (k5 + 1 - j1 + 32 << 6) + (l5 - k1 + 32 << 12);
}
if(this.getLightFor(lightType, blockpos1.north()) < j6) {
this.lightUpdate[j++] = j5 - i1 + 32 + (k5 - j1 + 32 << 6) + (l5 - 1 - k1 + 32 << 12);
}
if(this.getLightFor(lightType, blockpos1.south()) < j6) {
this.lightUpdate[j++] = j5 - i1 + 32 + (k5 - j1 + 32 << 6) + (l5 + 1 - k1 + 32 << 12);
}
}
}
}
}
// this.profiler.end();
return true;
}
}
public List<Entity> getEntitiesWithinAABBExcludingEntity(Entity entityIn, BoundingBox bb) {
return this.getEntitiesInAABBexcluding(entityIn, bb, null);
}
public List<Entity> getEntitiesInAABBexcluding(Entity entityIn, BoundingBox boundingBox, Predicate<? super Entity> predicate) {
List<Entity> list = Lists.<Entity>newArrayList();
int i = ExtMath.floord((boundingBox.minX - 2.0D) / 16.0D);
int j = ExtMath.floord((boundingBox.maxX + 2.0D) / 16.0D);
int k = ExtMath.floord((boundingBox.minZ - 2.0D) / 16.0D);
int l = ExtMath.floord((boundingBox.maxZ + 2.0D) / 16.0D);
for(int i1 = i; i1 <= j; ++i1) {
for(int j1 = k; j1 <= l; ++j1) {
if(this.isLoaded(i1, j1, true)) {
this.getChunk(i1, j1).getEntities(entityIn, boundingBox, list, predicate);
}
}
}
return list;
}
public <T extends Entity> List<T> getEntitiesWithinAABB(Class<? extends T> classEntity, BoundingBox bb) {
return this.<T>getEntitiesWithinAABB(classEntity, bb, null);
}
public <T extends Entity> List<T> getEntitiesWithinAABB(Class<? extends T> clazz, BoundingBox aabb, Predicate<? super T> filter) {
int i = ExtMath.floord((aabb.minX - 2.0D) / 16.0D);
int j = ExtMath.floord((aabb.maxX + 2.0D) / 16.0D);
int k = ExtMath.floord((aabb.minZ - 2.0D) / 16.0D);
int l = ExtMath.floord((aabb.maxZ + 2.0D) / 16.0D);
List<T> list = Lists.<T>newArrayList();
for(int i1 = i; i1 <= j; ++i1) {
for(int j1 = k; j1 <= l; ++j1) {
if(this.isLoaded(i1, j1, true)) {
this.getChunk(i1, j1).getEntities(clazz, aabb, list, filter);
}
}
}
return list;
}
public Entity getEntityByID(int id) {
return (Entity)this.entityIds.lookup(id);
}
public void markChunkDirty(BlockPos pos, TileEntity unusedTileEntity) {
if(this.isBlockLoaded(pos)) {
this.getChunk(pos).setModified();
}
}
public void loadEntities(Collection<Entity> entityCollection) {
this.entities.addAll(entityCollection);
for(Entity entity : entityCollection) {
this.onEntityAdded(entity);
}
}
public void unloadEntities(Collection<Entity> entityCollection) {
this.unloaded.addAll(entityCollection);
}
public boolean canBlockBePlaced(Block blockIn, BlockPos pos, boolean p_175716_3_, Facing side, Entity entityIn, ItemStack itemStackIn) {
Block block = this.getState(pos).getBlock();
BoundingBox axisalignedbb = p_175716_3_ ? null : blockIn.getCollisionBoundingBox(this, pos, blockIn.getState());
return axisalignedbb != null && !this.checkNoEntityCollision(axisalignedbb, entityIn) ? false
: (block.getMaterial() == Material.circuits && blockIn == Blocks.anvil ? true
: block.getMaterial().isReplaceable() && blockIn.canReplace(this, pos, side, itemStackIn));
}
public int getSeaLevel() {
return 63;
}
private int getStrongPower(BlockPos pos, Facing direction) {
State iblockstate = this.getState(pos);
return iblockstate.getBlock().getStrongPower(this, pos, iblockstate, direction);
}
public int getStrongPower(BlockPos pos) {
int i = 0;
i = Math.max(i, this.getStrongPower(pos.down(), Facing.DOWN));
if(i >= 15) {
return i;
}
else {
i = Math.max(i, this.getStrongPower(pos.up(), Facing.UP));
if(i >= 15) {
return i;
}
else {
i = Math.max(i, this.getStrongPower(pos.north(), Facing.NORTH));
if(i >= 15) {
return i;
}
else {
i = Math.max(i, this.getStrongPower(pos.south(), Facing.SOUTH));
if(i >= 15) {
return i;
}
else {
i = Math.max(i, this.getStrongPower(pos.west(), Facing.WEST));
if(i >= 15) {
return i;
}
else {
i = Math.max(i, this.getStrongPower(pos.east(), Facing.EAST));
return i >= 15 ? i : i;
}
}
}
}
}
}
public boolean isSidePowered(BlockPos pos, Facing side) {
return this.getRedstonePower(pos, side) > 0;
}
public int getRedstonePower(BlockPos pos, Facing facing) {
State iblockstate = this.getState(pos);
Block block = iblockstate.getBlock();
return block.isNormalCube() ? this.getStrongPower(pos) : block.getWeakPower(this, pos, iblockstate, facing);
}
public boolean isBlockPowered(BlockPos pos) {
return this.getRedstonePower(pos.down(), Facing.DOWN) > 0 ? true
: (this.getRedstonePower(pos.up(), Facing.UP) > 0 ? true
: (this.getRedstonePower(pos.north(), Facing.NORTH) > 0 ? true
: (this.getRedstonePower(pos.south(), Facing.SOUTH) > 0 ? true
: (this.getRedstonePower(pos.west(), Facing.WEST) > 0 ? true
: this.getRedstonePower(pos.east(), Facing.EAST) > 0))));
}
public int isBlockIndirectlyGettingPowered(BlockPos pos) {
int i = 0;
for(Facing enumfacing : Facing.values()) {
int j = this.getRedstonePower(pos.offset(enumfacing), enumfacing);
if(j >= 15) {
return 15;
}
if(j > i) {
i = j;
}
}
return i;
}
public EntityNPC getClosestPlayerToEntity(Entity entityIn, double distance) {
return this.getClosestPlayer(entityIn.posX, entityIn.posY, entityIn.posZ, distance);
}
public EntityNPC getClosestPlayer(double x, double y, double z, double distance) {
double d0 = -1.0D;
EntityNPC entityplayer = null;
for(int i = 0; i < this.players.size(); ++i) {
EntityNPC entityplayer1 = (EntityNPC)this.players.get(i);
// if(EntitySelectors.NOT_SPECTATING.apply(entityplayer1)) {
double d1 = entityplayer1.getDistanceSq(x, y, z);
if((distance < 0.0D || d1 < distance * distance) && (d0 == -1.0D || d1 < d0)) {
d0 = d1;
entityplayer = entityplayer1;
}
// }
}
return entityplayer;
}
public boolean isAnyPlayerWithinRangeAt(double x, double y, double z, double range) {
for(int i = 0; i < this.players.size(); ++i) {
EntityNPC entityplayer = (EntityNPC)this.players.get(i);
// if(EntitySelectors.NOT_SPECTATING.apply(entityplayer)) {
double d0 = entityplayer.getDistanceSq(x, y, z);
if(range < 0.0D || d0 < range * range) {
return true;
}
// }
}
return false;
}
// public EntityNPC getPlayer(String name) {
// for(int i = 0; i < this.players.size(); ++i) {
// EntityNPC entityplayer = this.players.get(i);
//
// if(name.equalsIgnoreCase(entityplayer.getUser())) {
// return entityplayer;
// }
// }
//
// return null;
// }
public void setTimeFactor(int factor) {
this.timeFactor = Math.max((long)factor, 1L);
// if(this.timeFactor > Constants.EARTH_DAY)
// this.timeFactor = (this.timeFactor - (this.timeFactor % Constants.EARTH_DAY)) + 1L;
}
public void setEntityState(Entity entityIn, byte state) {
}
public void addBlockEvent(BlockPos pos, Block blockIn, int eventID, int eventParam) {
blockIn.onBlockEventReceived(this, pos, this.getState(pos), eventID, eventParam);
}
public Weather getWeather() {
return this.weather;
}
public long getDayTime() {
return this.daytime;
}
public void setWeather(Weather weather) {
this.weather = weather;
}
public void setDayTime(long time) {
this.daytime = time;
}
public float getDarkness() {
return this.darkness;
}
public void setDarkness(float dark) {
this.darkness = dark;
}
public float getRainStrength() {
return this.rain;
}
public void setRainStrength(float strength) {
this.rain = strength;
}
public float getFogStrength() {
return this.fog;
}
public void setFogStrength(float strength) {
this.fog = strength;
}
public void setTemperature(float temp) {
this.temp = temp;
}
public boolean isDark() {
return this.darkness > 0.9f;
}
public boolean isThundering() {
return this.isDark() && this.weather.hasThunder() && (!this.weather.hasDownfall() || this.hasDownfall());
}
public boolean hasDownfall() {
return this.rain > 0.2f;
}
public boolean isRaining() {
return this.hasDownfall() && this.weather.canRain();
}
public boolean isRainingAt(BlockPos strikePosition, boolean wet) {
if(wet ? !this.isRaining() : !this.hasDownfall()) {
return false;
}
else if(!this.canSeeSky(strikePosition)) {
return false;
}
else if(this.getPrecipitationHeight(strikePosition).getY() > strikePosition.getY()) {
return false;
}
return !this.canSnowAt(strikePosition, false, false);
// else {
// Biome biomegenbase = this.getBiomeGenForCoords(strikePosition);
// return biomegenbase.isSnowyBiome() ? false : ( ? false : biomegenbase.canRain());
// }
}
// public void setItemData(String dataID, WorldSavedData worldSavedDataIn) {
// }
//
// public WorldSavedData loadItemData(Class<? extends WorldSavedData> clazz, String dataID) {
// return null;
// }
//
// public int getNextMapId() {
// return 0;
// }
public final void playAuxSFX(int type, BlockPos pos, int data) {
this.playAuxSFX(null, type, pos, data);
}
public void updateComparatorOutputLevel(BlockPos pos, Block blockIn) {
for(Facing enumfacing : Facing.Plane.HORIZONTAL) {
BlockPos blockpos = pos.offset(enumfacing);
if(this.isBlockLoaded(blockpos)) {
State iblockstate = this.getState(blockpos);
if(Blocks.comparator.isAssociated(iblockstate.getBlock())) {
iblockstate.getBlock().onNeighborBlockChange(this, blockpos, iblockstate, blockIn);
}
else if(iblockstate.getBlock().isNormalCube()) {
blockpos = blockpos.offset(enumfacing);
iblockstate = this.getState(blockpos);
if(Blocks.comparator.isAssociated(iblockstate.getBlock())) {
iblockstate.getBlock().onNeighborBlockChange(this, blockpos, iblockstate, blockIn);
}
}
}
}
}
// public DifficultyInstance getDifficultyForLocation(BlockPos pos) {
// return null;
// }
public void scheduleUpdate(BlockPos pos, Block blockIn, int delay) {
}
public void spawnParticle(ParticleType particleType, double xCoord, double yCoord, double zCoord, double xOffset, double yOffset,
double zOffset, int... data) {
}
// public Difficulty getDifficulty() {
// return this.difficulty;
// }
// public void setDifficulty(Difficulty diff) {
// this.difficulty = diff;
// }
public abstract Chunk getChunk(int x, int z);
public abstract void markBlockForUpdate(BlockPos pos);
protected abstract void notifyLightSet(BlockPos pos);
public abstract void markBlockRangeForRenderUpdate(int x1, int y1, int z1, int x2, int y2, int z2);
public abstract void playSound(SoundEvent sound, double x, double y, double z, float volume, float pitch);
protected abstract void onEntityAdded(Entity entityIn);
protected abstract void onEntityRemoved(Entity entityIn);
// public abstract void broadcastSound(int soundID, BlockPos pos, int data);
public abstract void playAuxSFX(EntityNPC player, int sfxType, BlockPos blockPosIn, int data);
public abstract void sendBlockBreakProgress(int breakerId, BlockPos pos, int progress);
}