diff options
Diffstat (limited to 'src/main/java/gregtech/common/GT_Pollution.java')
-rw-r--r-- | src/main/java/gregtech/common/GT_Pollution.java | 507 |
1 files changed, 0 insertions, 507 deletions
diff --git a/src/main/java/gregtech/common/GT_Pollution.java b/src/main/java/gregtech/common/GT_Pollution.java deleted file mode 100644 index 6a2b1e1082..0000000000 --- a/src/main/java/gregtech/common/GT_Pollution.java +++ /dev/null @@ -1,507 +0,0 @@ -package gregtech.common; - -import static gregtech.api.objects.XSTR.XSTR_INSTANCE; -import static gregtech.common.GT_Proxy.dimensionWisePollution; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.function.Consumer; - -import javax.annotation.Nullable; -import javax.annotation.ParametersAreNonnullByDefault; - -import net.minecraft.block.Block; -import net.minecraft.block.material.Material; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.init.Blocks; -import net.minecraft.potion.Potion; -import net.minecraft.potion.PotionEffect; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.AxisAlignedBB; -import net.minecraft.world.ChunkCoordIntPair; -import net.minecraft.world.ChunkPosition; -import net.minecraft.world.World; -import net.minecraft.world.chunk.Chunk; -import net.minecraftforge.common.DimensionManager; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.event.world.ChunkDataEvent; -import net.minecraftforge.event.world.ChunkWatchEvent; -import net.minecraftforge.event.world.WorldEvent; - -import cpw.mods.fml.common.eventhandler.SubscribeEvent; -import cpw.mods.fml.common.gameevent.TickEvent; -import cpw.mods.fml.common.network.NetworkRegistry; -import gregtech.GT_Mod; -import gregtech.api.enums.GT_Values; -import gregtech.api.interfaces.ICleanroom; -import gregtech.api.interfaces.ICleanroomReceiver; -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.api.net.GT_Packet_Pollution; -import gregtech.api.util.GT_ChunkAssociatedData; -import gregtech.api.util.GT_Utility; -import gregtech.common.render.GT_PollutionRenderer; - -public class GT_Pollution { - - private static final Storage STORAGE = new Storage(); - /** - * Pollution dispersion until effects start: Calculation: ((Limit * 0.01) + 2000) * (4 <- spreading rate) - * <p> - * SMOG(500k) 466.7 pollution/sec Poison(750k) 633,3 pollution/sec Dying Plants(1mio) 800 pollution/sec Sour - * Rain(1.5mio) 1133.3 pollution/sec - * <p> - * Pollution producers (pollution/sec) Bronze Boiler(20) Lava Boiler(20) High Pressure Boiler(20) Bronze Blast - * Furnace(50) Diesel Generator(40/80/160) Gas Turbine(20/40/80) Charcoal Pile(100) - * <p> - * Large Diesel Engine(320) Electric Blast Furnace(100) Implosion Compressor(2000) Large Boiler(240) Large Gas - * Turbine(160) Multi Smelter(100) Pyrolyse Oven(400) - * <p> - * Machine Explosion(100,000) - * <p> - * Other Random Shit: lots and lots - * <p> - * Muffler Hatch Pollution reduction: ** inaccurate ** LV (0%), MV (30%), HV (52%), EV (66%), IV (76%), LuV (84%), - * ZPM (89%), UV (92%), MAX (95%) - */ - private List<ChunkCoordIntPair> pollutionList = new ArrayList<>(); // chunks left to process in this cycle - - private final Set<ChunkCoordIntPair> pollutedChunks = new HashSet<>(); // a global list of all chunks with positive - // pollution - private int operationsPerTick = 0; // how much chunks should be processed in each cycle - private static final short cycleLen = 1200; - private final World world; - private boolean blank = true; - public static int mPlayerPollution; - - private static final int POLLUTIONPACKET_MINVALUE = 1000; - - private static GT_PollutionEventHandler EVENT_HANDLER; - - public GT_Pollution(World world) { - this.world = world; - - if (EVENT_HANDLER == null) { - EVENT_HANDLER = new GT_PollutionEventHandler(); - MinecraftForge.EVENT_BUS.register(EVENT_HANDLER); - } - } - - public static void onWorldTick(TickEvent.WorldTickEvent aEvent) { // called from proxy - // return if pollution disabled - if (!GT_Mod.gregtechproxy.mPollution) return; - if (aEvent.phase == TickEvent.Phase.START) return; - final GT_Pollution pollutionInstance = dimensionWisePollution.get(aEvent.world.provider.dimensionId); - if (pollutionInstance == null) return; - pollutionInstance.tickPollutionInWorld((int) (aEvent.world.getTotalWorldTime() % cycleLen)); - } - - private void tickPollutionInWorld(int aTickID) { // called from method above - // gen data set - if (aTickID == 0 || blank) { - // make a snapshot of what to work on - pollutionList = new ArrayList<>(pollutedChunks); - // set operations per tick - if (pollutionList.size() > 0) operationsPerTick = Math.max(1, pollutionList.size() / cycleLen); - else operationsPerTick = 0; // SANity - blank = false; - } - - for (int chunksProcessed = 0; chunksProcessed < operationsPerTick; chunksProcessed++) { - if (pollutionList.size() == 0) break; // no more stuff to do - ChunkCoordIntPair actualPos = pollutionList.remove(pollutionList.size() - 1); // faster - // get pollution - ChunkData currentData = STORAGE.get(world, actualPos); - int tPollution = currentData.getAmount(); - // remove some - tPollution = (int) (0.9945f * tPollution); - - if (tPollution > 400000) { // Spread Pollution - - ChunkCoordIntPair[] tNeighbors = new ChunkCoordIntPair[4]; // array is faster - tNeighbors[0] = (new ChunkCoordIntPair(actualPos.chunkXPos + 1, actualPos.chunkZPos)); - tNeighbors[1] = (new ChunkCoordIntPair(actualPos.chunkXPos - 1, actualPos.chunkZPos)); - tNeighbors[2] = (new ChunkCoordIntPair(actualPos.chunkXPos, actualPos.chunkZPos + 1)); - tNeighbors[3] = (new ChunkCoordIntPair(actualPos.chunkXPos, actualPos.chunkZPos - 1)); - for (ChunkCoordIntPair neighborPosition : tNeighbors) { - ChunkData neighbor = STORAGE.get(world, neighborPosition); - int neighborPollution = neighbor.getAmount(); - if (neighborPollution * 6 < tPollution * 5) { // MATHEMATICS... - int tDiff = tPollution - neighborPollution; - tDiff = tDiff / 20; - neighborPollution = GT_Utility.safeInt((long) neighborPollution + tDiff); // tNPol += tDiff; - tPollution -= tDiff; - setChunkPollution(neighborPosition, neighborPollution); - } - } - - // Create Pollution effects - // Smog filter TODO - if (tPollution > GT_Mod.gregtechproxy.mPollutionSmogLimit) { - AxisAlignedBB chunk = AxisAlignedBB.getBoundingBox( - actualPos.chunkXPos << 4, - 0, - actualPos.chunkZPos << 4, - (actualPos.chunkXPos << 4) + 16, - 256, - (actualPos.chunkZPos << 4) + 16); - List<EntityLivingBase> tEntitys = world.getEntitiesWithinAABB(EntityLivingBase.class, chunk); - for (EntityLivingBase tEnt : tEntitys) { - if (tEnt instanceof EntityPlayerMP && ((EntityPlayerMP) tEnt).capabilities.isCreativeMode) - continue; - if (!(GT_Utility.isWearingFullGasHazmat(tEnt))) { - switch (XSTR_INSTANCE.nextInt(3)) { - default: - tEnt.addPotionEffect( - new PotionEffect( - Potion.digSlowdown.id, - Math.min(tPollution / 1000, 1000), - tPollution / 400000)); - case 1: - tEnt.addPotionEffect( - new PotionEffect( - Potion.weakness.id, - Math.min(tPollution / 1000, 1000), - tPollution / 400000)); - case 2: - tEnt.addPotionEffect( - new PotionEffect( - Potion.moveSlowdown.id, - Math.min(tPollution / 1000, 1000), - tPollution / 400000)); - } - } - } - - // Poison effects - if (tPollution > GT_Mod.gregtechproxy.mPollutionPoisonLimit) { - for (EntityLivingBase tEnt : tEntitys) { - if (tEnt instanceof EntityPlayerMP && ((EntityPlayerMP) tEnt).capabilities.isCreativeMode) - continue; - if (!GT_Utility.isWearingFullGasHazmat(tEnt)) { - switch (XSTR_INSTANCE.nextInt(4)) { - default: - tEnt.addPotionEffect(new PotionEffect(Potion.hunger.id, tPollution / 500000)); - case 1: - tEnt.addPotionEffect( - new PotionEffect( - Potion.confusion.id, - Math.min(tPollution / 2000, 1000), - 1)); - case 2: - tEnt.addPotionEffect( - new PotionEffect( - Potion.poison.id, - Math.min(tPollution / 4000, 1000), - tPollution / 500000)); - case 3: - tEnt.addPotionEffect( - new PotionEffect( - Potion.blindness.id, - Math.min(tPollution / 2000, 1000), - 1)); - } - } - } - - // killing plants - if (tPollution > GT_Mod.gregtechproxy.mPollutionVegetationLimit) { - int f = 20; - for (; f < (tPollution / 25000); f++) { - int x = (actualPos.chunkXPos << 4) + XSTR_INSTANCE.nextInt(16); - int y = 60 + (-f + XSTR_INSTANCE.nextInt(f * 2 + 1)); - int z = (actualPos.chunkZPos << 4) + XSTR_INSTANCE.nextInt(16); - damageBlock(world, x, y, z, tPollution > GT_Mod.gregtechproxy.mPollutionSourRainLimit); - } - } - } - } - } - // Write new pollution to Hashmap !!! - setChunkPollution(actualPos, tPollution); - - // Send new value to players nearby - if (tPollution > POLLUTIONPACKET_MINVALUE) { - NetworkRegistry.TargetPoint point = new NetworkRegistry.TargetPoint( - world.provider.dimensionId, - (actualPos.chunkXPos << 4), - 64, - (actualPos.chunkZPos << 4), - 256); - GT_Values.NW.sendToAllAround(new GT_Packet_Pollution(actualPos, tPollution), point); - } - } - } - - private void setChunkPollution(ChunkCoordIntPair coord, int pollution) { - mutatePollution(world, coord.chunkXPos, coord.chunkZPos, c -> c.setAmount(pollution), pollutedChunks); - } - - private static void damageBlock(World world, int x, int y, int z, boolean sourRain) { - if (world.isRemote) return; - Block tBlock = world.getBlock(x, y, z); - int tMeta = world.getBlockMetadata(x, y, z); - if (tBlock == Blocks.air || tBlock == Blocks.stone || tBlock == Blocks.sand || tBlock == Blocks.deadbush) - return; - - if (tBlock == Blocks.leaves || tBlock == Blocks.leaves2 || tBlock.getMaterial() == Material.leaves) - world.setBlockToAir(x, y, z); - if (tBlock == Blocks.reeds) { - tBlock.dropBlockAsItem(world, x, y, z, tMeta, 0); - world.setBlockToAir(x, y, z); - } - if (tBlock == Blocks.tallgrass) world.setBlock(x, y, z, Blocks.deadbush); - if (tBlock == Blocks.vine) { - tBlock.dropBlockAsItem(world, x, y, z, tMeta, 0); - world.setBlockToAir(x, y, z); - } - if (tBlock == Blocks.waterlily || tBlock == Blocks.wheat - || tBlock == Blocks.cactus - || tBlock.getMaterial() == Material.cactus - || tBlock == Blocks.melon_block - || tBlock == Blocks.melon_stem) { - tBlock.dropBlockAsItem(world, x, y, z, tMeta, 0); - world.setBlockToAir(x, y, z); - } - if (tBlock == Blocks.red_flower || tBlock == Blocks.yellow_flower - || tBlock == Blocks.carrots - || tBlock == Blocks.potatoes - || tBlock == Blocks.pumpkin - || tBlock == Blocks.pumpkin_stem) { - tBlock.dropBlockAsItem(world, x, y, z, tMeta, 0); - world.setBlockToAir(x, y, z); - } - if (tBlock == Blocks.sapling || tBlock.getMaterial() == Material.plants) - world.setBlock(x, y, z, Blocks.deadbush); - if (tBlock == Blocks.cocoa) { - tBlock.dropBlockAsItem(world, x, y, z, tMeta, 0); - world.setBlockToAir(x, y, z); - } - if (tBlock == Blocks.mossy_cobblestone) world.setBlock(x, y, z, Blocks.cobblestone); - if (tBlock == Blocks.grass || tBlock.getMaterial() == Material.grass) world.setBlock(x, y, z, Blocks.dirt); - if (tBlock == Blocks.farmland || tBlock == Blocks.dirt) { - world.setBlock(x, y, z, Blocks.sand); - } - - if (sourRain && world.isRaining() - && (tBlock == Blocks.gravel || tBlock == Blocks.cobblestone) - && world.getBlock(x, y + 1, z) == Blocks.air - && world.canBlockSeeTheSky(x, y, z)) { - if (tBlock == Blocks.cobblestone) { - world.setBlock(x, y, z, Blocks.gravel); - } else { - world.setBlock(x, y, z, Blocks.sand); - } - } - } - - private static GT_Pollution getPollutionManager(World world) { - return dimensionWisePollution.computeIfAbsent(world.provider.dimensionId, i -> new GT_Pollution(world)); - } - - /** @see #addPollution(TileEntity, int) */ - public static void addPollution(IGregTechTileEntity te, int aPollution) { - addPollution((TileEntity) te, aPollution); - } - - /** - * Also pollutes cleanroom if {@code te} is an instance of {@link ICleanroomReceiver}. - * - * @see #addPollution(World, int, int, int) - */ - public static void addPollution(TileEntity te, int aPollution) { - if (!GT_Mod.gregtechproxy.mPollution || aPollution == 0 || te.getWorldObj().isRemote) return; - - if (aPollution > 0 && te instanceof ICleanroomReceiver receiver) { - ICleanroom cleanroom = receiver.getCleanroom(); - if (cleanroom != null && cleanroom.isValidCleanroom()) { - cleanroom.pollute(); - } - } - - addPollution(te.getWorldObj(), te.xCoord >> 4, te.zCoord >> 4, aPollution); - } - - /** @see #addPollution(World, int, int, int) */ - public static void addPollution(Chunk ch, int aPollution) { - addPollution(ch.worldObj, ch.xPosition, ch.zPosition, aPollution); - } - - /** - * Add some pollution to given chunk. Can pass in negative to remove pollution. Will clamp the final pollution - * number to 0 if it would be changed into negative. - * - * @param w world to modify. do nothing if it's a client world - * @param chunkX chunk coordinate X, i.e. blockX >> 4 - * @param chunkZ chunk coordinate Z, i.e. blockZ >> 4 - * @param aPollution desired delta. Positive means the pollution in chunk would go higher. - */ - public static void addPollution(World w, int chunkX, int chunkZ, int aPollution) { - if (!GT_Mod.gregtechproxy.mPollution || aPollution == 0 || w.isRemote) return; - mutatePollution(w, chunkX, chunkZ, d -> d.changeAmount(aPollution), null); - } - - private static void mutatePollution(World world, int x, int z, Consumer<ChunkData> mutator, - @Nullable Set<ChunkCoordIntPair> chunks) { - ChunkData data = STORAGE.get(world, x, z); - boolean hadPollution = data.getAmount() > 0; - mutator.accept(data); - boolean hasPollution = data.getAmount() > 0; - if (hasPollution != hadPollution) { - if (chunks == null) chunks = getPollutionManager(world).pollutedChunks; - if (hasPollution) chunks.add(new ChunkCoordIntPair(x, z)); - else chunks.remove(new ChunkCoordIntPair(x, z)); - } - } - - /** @see #getPollution(World, int, int) */ - public static int getPollution(IGregTechTileEntity te) { - return getPollution(te.getWorld(), te.getXCoord() >> 4, te.getZCoord() >> 4); - } - - /** @see #getPollution(World, int, int) */ - public static int getPollution(Chunk ch) { - return getPollution(ch.worldObj, ch.xPosition, ch.zPosition); - } - - /** - * Get the pollution in specified chunk - * - * @param w world to look in. can be a client world, but that limits the knowledge to what server side send us - * @param chunkX chunk coordinate X, i.e. blockX >> 4 - * @param chunkZ chunk coordinate Z, i.e. blockZ >> 4 - * @return pollution amount. may be 0 if pollution is disabled, or if it's a client world and server did not send us - * info about this chunk - */ - public static int getPollution(World w, int chunkX, int chunkZ) { - if (!GT_Mod.gregtechproxy.mPollution) return 0; - if (w.isRemote) - // it really should be querying the client side stuff instead - return GT_PollutionRenderer.getKnownPollution(chunkX << 4, chunkZ << 4); - return STORAGE.get(w, chunkX, chunkZ) - .getAmount(); - } - - @Deprecated - public static int getPollution(ChunkCoordIntPair aCh, int aDim) { - return getPollution(DimensionManager.getWorld(aDim), aCh.chunkXPos, aCh.chunkZPos); - } - - public static boolean hasPollution(Chunk ch) { - if (!GT_Mod.gregtechproxy.mPollution) return false; - return STORAGE.isCreated(ch.worldObj, ch.getChunkCoordIntPair()) && STORAGE.get(ch) - .getAmount() > 0; - } - - // Add compatibility with old code - @Deprecated /* Don't use it... too weird way of passing position */ - public static void addPollution(World aWorld, ChunkPosition aPos, int aPollution) { - // The abuse of ChunkPosition to store block position and dim... - // is just bad especially when that is both used to store ChunkPos and BlockPos depending on context - addPollution(aWorld.getChunkFromBlockCoords(aPos.chunkPosX, aPos.chunkPosZ), aPollution); - } - - static void migrate(ChunkDataEvent.Load e) { - addPollution( - e.getChunk(), - e.getData() - .getInteger("GTPOLLUTION")); - } - - public static class GT_PollutionEventHandler { - - @SubscribeEvent - public void chunkWatch(ChunkWatchEvent.Watch event) { - if (!GT_Mod.gregtechproxy.mPollution) return; - World world = event.player.worldObj; - if (STORAGE.isCreated(world, event.chunk)) { - int pollution = STORAGE.get(world, event.chunk) - .getAmount(); - if (pollution > POLLUTIONPACKET_MINVALUE) - GT_Values.NW.sendToPlayer(new GT_Packet_Pollution(event.chunk, pollution), event.player); - } - } - - @SubscribeEvent - public void onWorldLoad(WorldEvent.Load e) { - // super class loads everything lazily. We force it to load them all. - if (!e.world.isRemote) STORAGE.loadAll(e.world); - } - } - - @ParametersAreNonnullByDefault - private static final class Storage extends GT_ChunkAssociatedData<ChunkData> { - - private Storage() { - super("Pollution", ChunkData.class, 64, (byte) 0, false); - } - - @Override - protected void writeElement(DataOutput output, ChunkData element, World world, int chunkX, int chunkZ) - throws IOException { - output.writeInt(element.getAmount()); - } - - @Override - protected ChunkData readElement(DataInput input, int version, World world, int chunkX, int chunkZ) - throws IOException { - if (version != 0) throw new IOException("Region file corrupted"); - ChunkData data = new ChunkData(input.readInt()); - if (data.getAmount() > 0) - getPollutionManager(world).pollutedChunks.add(new ChunkCoordIntPair(chunkX, chunkZ)); - return data; - } - - @Override - protected ChunkData createElement(World world, int chunkX, int chunkZ) { - return new ChunkData(); - } - - @Override - public void loadAll(World w) { - super.loadAll(w); - } - - public boolean isCreated(World world, ChunkCoordIntPair coord) { - return isCreated(world.provider.dimensionId, coord.chunkXPos, coord.chunkZPos); - } - } - - private static final class ChunkData implements GT_ChunkAssociatedData.IData { - - public int amount; - - private ChunkData() { - this(0); - } - - private ChunkData(int amount) { - this.amount = Math.max(0, amount); - } - - /** - * Current pollution amount. - */ - public int getAmount() { - return amount; - } - - public void setAmount(int amount) { - this.amount = Math.max(amount, 0); - } - - public void changeAmount(int delta) { - this.amount = Math.max(GT_Utility.safeInt(amount + (long) delta, 0), 0); - } - - @Override - public boolean isSameAsDefault() { - return amount == 0; - } - } -} |