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 entities = Lists.newArrayList(); protected final List unloaded = Lists.newArrayList(); protected final List tiles = Lists.newArrayList(); protected final List tickable = Lists.newArrayList(); protected final List addedTiles = Lists.newArrayList(); protected final List removeTiles = Lists.newArrayList(); public final List players = Lists.newArrayList(); public final List effects = Lists.newArrayList(); protected final IntHashMap entityIds = new IntHashMap(); protected final Set active = Sets.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 ents = this.getEntitiesInAABBexcluding(entity, new BoundingBox(target, target.add(1, 1, 1)), new Predicate() { 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 getCollidingBoundingBoxes(Entity entityIn, BoundingBox bb) { List list = Lists.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 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 getCollisionBoxes(BoundingBox bb) { List list = Lists.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 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 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 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 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 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 getEntitiesWithinAABBExcludingEntity(Entity entityIn, BoundingBox bb) { return this.getEntitiesInAABBexcluding(entityIn, bb, null); } public List getEntitiesInAABBexcluding(Entity entityIn, BoundingBox boundingBox, Predicate predicate) { List list = Lists.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 List getEntitiesWithinAABB(Class classEntity, BoundingBox bb) { return this.getEntitiesWithinAABB(classEntity, bb, null); } public List getEntitiesWithinAABB(Class clazz, BoundingBox aabb, Predicate 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 list = Lists.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 entityCollection) { this.entities.addAll(entityCollection); for(Entity entity : entityCollection) { this.onEntityAdded(entity); } } public void unloadEntities(Collection 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 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); }