From 901cb0d294b0c4f114bb247fbd7d6f97e7484f3c Mon Sep 17 00:00:00 2001 From: Alexdoru <57050655+Alexdoru@users.noreply.github.com> Date: Mon, 21 Oct 2024 21:21:33 +0200 Subject: Import pollution mixins from hodgepodge (#3395) Co-authored-by: Martin Robertz Co-authored-by: boubou19 --- .../api/graphs/consumers/NodeEnergyReceiver.java | 2 +- .../api/interfaces/ICleanroomReceiver.java | 2 +- .../api/metatileentity/BaseMetaTileEntity.java | 2 +- .../implementations/MTEBasicGenerator.java | 2 +- .../implementations/MTEHatchMuffler.java | 2 +- .../implementations/MTEMultiBlockBase.java | 2 +- .../gregtech/api/task/tasks/PollutionTask.java | 2 +- src/main/java/gregtech/api/util/GTUtility.java | 2 +- src/main/java/gregtech/asm/GTCorePlugin.java | 4 +- .../java/gregtech/client/GTGUIClientConfig.java | 2 + src/main/java/gregtech/common/GTClient.java | 4 +- src/main/java/gregtech/common/GTProxy.java | 1 + src/main/java/gregtech/common/Pollution.java | 507 -------------------- src/main/java/gregtech/common/config/Gregtech.java | 127 ----- .../common/entities/EntityFXPollution.java | 59 --- .../gregtech/common/misc/GTClientPollutionMap.java | 140 ------ src/main/java/gregtech/common/misc/GTCommand.java | 2 +- .../gregtech/common/pollution/BlockMatcher.java | 96 ++++ .../common/pollution/ColorOverrideType.java | 28 ++ .../common/pollution/EntityFXPollution.java | 59 +++ .../common/pollution/GTClientPollutionMap.java | 140 ++++++ .../java/gregtech/common/pollution/Pollution.java | 533 +++++++++++++++++++++ .../gregtech/common/pollution/PollutionConfig.java | 397 +++++++++++++++ .../common/pollution/PollutionRenderer.java | 249 ++++++++++ .../common/pollution/PollutionTooltip.java | 108 +++++ .../gregtech/common/render/PollutionRenderer.java | 251 ---------- .../common/tileentities/boilers/MTEBoiler.java | 2 +- .../tileentities/boilers/MTEBoilerBronze.java | 2 +- .../machines/multi/MTECharcoalPit.java | 2 +- .../machines/multi/MTEPrimitiveBlastFurnace.java | 2 +- .../java/gregtech/loaders/preload/GTPreLoad.java | 55 +-- src/main/java/gregtech/mixin/Mixin.java | 69 ++- 32 files changed, 1728 insertions(+), 1127 deletions(-) delete mode 100644 src/main/java/gregtech/common/Pollution.java delete mode 100644 src/main/java/gregtech/common/entities/EntityFXPollution.java delete mode 100644 src/main/java/gregtech/common/misc/GTClientPollutionMap.java create mode 100644 src/main/java/gregtech/common/pollution/BlockMatcher.java create mode 100644 src/main/java/gregtech/common/pollution/ColorOverrideType.java create mode 100644 src/main/java/gregtech/common/pollution/EntityFXPollution.java create mode 100644 src/main/java/gregtech/common/pollution/GTClientPollutionMap.java create mode 100644 src/main/java/gregtech/common/pollution/Pollution.java create mode 100644 src/main/java/gregtech/common/pollution/PollutionConfig.java create mode 100644 src/main/java/gregtech/common/pollution/PollutionRenderer.java create mode 100644 src/main/java/gregtech/common/pollution/PollutionTooltip.java delete mode 100644 src/main/java/gregtech/common/render/PollutionRenderer.java (limited to 'src/main/java/gregtech') diff --git a/src/main/java/gregtech/api/graphs/consumers/NodeEnergyReceiver.java b/src/main/java/gregtech/api/graphs/consumers/NodeEnergyReceiver.java index e9364f922b..3d6a33fe7f 100644 --- a/src/main/java/gregtech/api/graphs/consumers/NodeEnergyReceiver.java +++ b/src/main/java/gregtech/api/graphs/consumers/NodeEnergyReceiver.java @@ -14,7 +14,7 @@ import gregtech.api.enums.GTValues; import gregtech.api.enums.SoundResource; import gregtech.api.util.GTUtility; import gregtech.api.util.WorldSpawnedEventBuilder; -import gregtech.common.Pollution; +import gregtech.common.pollution.Pollution; // consumer for RF machines public class NodeEnergyReceiver extends ConsumerNode { diff --git a/src/main/java/gregtech/api/interfaces/ICleanroomReceiver.java b/src/main/java/gregtech/api/interfaces/ICleanroomReceiver.java index b26c7035c7..c7c488ccbd 100644 --- a/src/main/java/gregtech/api/interfaces/ICleanroomReceiver.java +++ b/src/main/java/gregtech/api/interfaces/ICleanroomReceiver.java @@ -4,7 +4,7 @@ import javax.annotation.Nullable; import net.minecraft.tileentity.TileEntity; -import gregtech.common.Pollution; +import gregtech.common.pollution.Pollution; /** * Implement this interface for TileEntities that can have association to cleanroom. diff --git a/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java index e39f78cee0..da81e7d9cb 100644 --- a/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java @@ -83,8 +83,8 @@ import gregtech.api.util.GTOreDictUnificator; import gregtech.api.util.GTUtility; import gregtech.api.util.shutdown.ShutDownReason; import gregtech.api.util.shutdown.ShutDownReasonRegistry; -import gregtech.common.Pollution; import gregtech.common.covers.CoverInfo; +import gregtech.common.pollution.Pollution; import ic2.api.Direction; import mcp.mobius.waila.api.IWailaConfigHandler; import mcp.mobius.waila.api.IWailaDataAccessor; diff --git a/src/main/java/gregtech/api/metatileentity/implementations/MTEBasicGenerator.java b/src/main/java/gregtech/api/metatileentity/implementations/MTEBasicGenerator.java index 963acf191f..8ab0da4349 100644 --- a/src/main/java/gregtech/api/metatileentity/implementations/MTEBasicGenerator.java +++ b/src/main/java/gregtech/api/metatileentity/implementations/MTEBasicGenerator.java @@ -22,7 +22,7 @@ import gregtech.api.recipe.maps.FuelBackend; import gregtech.api.util.GTOreDictUnificator; import gregtech.api.util.GTRecipe; import gregtech.api.util.GTUtility; -import gregtech.common.Pollution; +import gregtech.common.pollution.Pollution; public abstract class MTEBasicGenerator extends MTEBasicTank implements RecipeMapWorkable { diff --git a/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchMuffler.java b/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchMuffler.java index 179ba56254..576389de80 100644 --- a/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchMuffler.java +++ b/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchMuffler.java @@ -18,7 +18,7 @@ import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.render.TextureFactory; import gregtech.api.util.GTLanguageManager; import gregtech.api.util.WorldSpawnedEventBuilder; -import gregtech.common.Pollution; +import gregtech.common.pollution.Pollution; @SuppressWarnings("unused") // Unused API is expected within scope public class MTEHatchMuffler extends MTEHatch { diff --git a/src/main/java/gregtech/api/metatileentity/implementations/MTEMultiBlockBase.java b/src/main/java/gregtech/api/metatileentity/implementations/MTEMultiBlockBase.java index 363c45bfc9..ce508433ec 100644 --- a/src/main/java/gregtech/api/metatileentity/implementations/MTEMultiBlockBase.java +++ b/src/main/java/gregtech/api/metatileentity/implementations/MTEMultiBlockBase.java @@ -95,11 +95,11 @@ import gregtech.api.util.VoidProtectionHelper; import gregtech.api.util.shutdown.ShutDownReason; import gregtech.api.util.shutdown.ShutDownReasonRegistry; import gregtech.client.GTSoundLoop; -import gregtech.common.Pollution; import gregtech.common.config.MachineStats; import gregtech.common.gui.modularui.widget.CheckRecipeResultSyncer; import gregtech.common.gui.modularui.widget.ShutDownReasonSyncer; import gregtech.common.items.MetaGeneratedTool01; +import gregtech.common.pollution.Pollution; import gregtech.common.tileentities.machines.IDualInputHatch; import gregtech.common.tileentities.machines.IDualInputInventory; import gregtech.common.tileentities.machines.IRecipeProcessingAwareHatch; diff --git a/src/main/java/gregtech/api/task/tasks/PollutionTask.java b/src/main/java/gregtech/api/task/tasks/PollutionTask.java index 3770409fb1..c8c9705e6c 100644 --- a/src/main/java/gregtech/api/task/tasks/PollutionTask.java +++ b/src/main/java/gregtech/api/task/tasks/PollutionTask.java @@ -8,7 +8,7 @@ import gregtech.api.enums.TickTime; import gregtech.api.interfaces.tileentity.IMachineProgress; import gregtech.api.task.TaskHost; import gregtech.api.task.TickableTask; -import gregtech.common.Pollution; +import gregtech.common.pollution.Pollution; public class PollutionTask extends TickableTask { diff --git a/src/main/java/gregtech/api/util/GTUtility.java b/src/main/java/gregtech/api/util/GTUtility.java index 83cd5ced7a..da805f995d 100644 --- a/src/main/java/gregtech/api/util/GTUtility.java +++ b/src/main/java/gregtech/api/util/GTUtility.java @@ -167,8 +167,8 @@ import gregtech.api.objects.ItemData; import gregtech.api.recipe.RecipeMaps; import gregtech.api.threads.RunnableSound; import gregtech.api.util.extensions.ArrayExt; -import gregtech.common.Pollution; import gregtech.common.blocks.BlockOresAbstract; +import gregtech.common.pollution.Pollution; import ic2.api.recipe.IRecipeInput; import ic2.api.recipe.RecipeInputItemStack; import ic2.api.recipe.RecipeInputOreDict; diff --git a/src/main/java/gregtech/asm/GTCorePlugin.java b/src/main/java/gregtech/asm/GTCorePlugin.java index 3b8aa08d16..f8dde28c58 100644 --- a/src/main/java/gregtech/asm/GTCorePlugin.java +++ b/src/main/java/gregtech/asm/GTCorePlugin.java @@ -10,6 +10,7 @@ import com.gtnewhorizon.gtnhmixins.IEarlyMixinLoader; import bartworks.common.configs.Configuration; import cpw.mods.fml.relauncher.IFMLLoadingPlugin; +import gregtech.common.pollution.PollutionConfig; import gregtech.mixin.Mixin; import gtPlusPlus.core.config.ASMConfiguration; @@ -20,8 +21,9 @@ public class GTCorePlugin implements IFMLLoadingPlugin, IEarlyMixinLoader { static { try { - ConfigurationManager.registerConfig(Configuration.class); ConfigurationManager.registerConfig(ASMConfiguration.class); + ConfigurationManager.registerConfig(Configuration.class); + ConfigurationManager.registerConfig(PollutionConfig.class); } catch (ConfigException e) { throw new RuntimeException(e); } diff --git a/src/main/java/gregtech/client/GTGUIClientConfig.java b/src/main/java/gregtech/client/GTGUIClientConfig.java index cf063acf55..875e62f7f8 100644 --- a/src/main/java/gregtech/client/GTGUIClientConfig.java +++ b/src/main/java/gregtech/client/GTGUIClientConfig.java @@ -11,6 +11,7 @@ import gregtech.common.config.Client; import gregtech.common.config.Gregtech; import gregtech.common.config.MachineStats; import gregtech.common.config.Worldgen; +import gregtech.common.pollution.PollutionConfig; public class GTGUIClientConfig extends SimpleGuiConfig { @@ -23,6 +24,7 @@ public class GTGUIClientConfig extends SimpleGuiConfig { Client.class, Gregtech.class, MachineStats.class, + PollutionConfig.class, Worldgen.class); } } diff --git a/src/main/java/gregtech/common/GTClient.java b/src/main/java/gregtech/common/GTClient.java index 844731e82f..7cd673c001 100644 --- a/src/main/java/gregtech/common/GTClient.java +++ b/src/main/java/gregtech/common/GTClient.java @@ -92,6 +92,8 @@ import gregtech.client.GTMouseEventHandler; import gregtech.client.SeekingOggCodec; import gregtech.common.blocks.BlockFrameBox; import gregtech.common.blocks.ItemMachines; +import gregtech.common.pollution.Pollution; +import gregtech.common.pollution.PollutionRenderer; import gregtech.common.render.BlackholeRenderer; import gregtech.common.render.DroneRender; import gregtech.common.render.FlaskRenderer; @@ -101,7 +103,6 @@ import gregtech.common.render.GTRendererBlock; import gregtech.common.render.LaserRenderer; import gregtech.common.render.MetaGeneratedToolRenderer; import gregtech.common.render.MultiTileRenderer; -import gregtech.common.render.PollutionRenderer; import gregtech.common.render.WormholeRenderer; import gregtech.common.render.items.DataStickRenderer; import gregtech.common.render.items.InfiniteSprayCanRenderer; @@ -670,6 +671,7 @@ public class GTClient extends GTProxy implements Runnable { .forEach(CoverBehaviorBase::reloadColorOverride); } }); + Pollution.onPostInitClient(); } @Override diff --git a/src/main/java/gregtech/common/GTProxy.java b/src/main/java/gregtech/common/GTProxy.java index 643811234d..e7cb627c91 100644 --- a/src/main/java/gregtech/common/GTProxy.java +++ b/src/main/java/gregtech/common/GTProxy.java @@ -167,6 +167,7 @@ import gregtech.common.items.MetaGeneratedTool01; import gregtech.common.misc.GlobalEnergyWorldSavedData; import gregtech.common.misc.GlobalMetricsCoverDatabase; import gregtech.common.misc.spaceprojects.SpaceProjectWorldSavedData; +import gregtech.common.pollution.Pollution; import gregtech.common.tileentities.machines.multi.drone.MTEDroneCentre; import gregtech.nei.GTNEIDefaultHandler; diff --git a/src/main/java/gregtech/common/Pollution.java b/src/main/java/gregtech/common/Pollution.java deleted file mode 100644 index 4245a0ef12..0000000000 --- a/src/main/java/gregtech/common/Pollution.java +++ /dev/null @@ -1,507 +0,0 @@ -package gregtech.common; - -import static gregtech.api.objects.XSTR.XSTR_INSTANCE; -import static gregtech.common.GTProxy.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.GTMod; -import gregtech.api.enums.GTValues; -import gregtech.api.interfaces.ICleanroom; -import gregtech.api.interfaces.ICleanroomReceiver; -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.api.net.GTPacketPollution; -import gregtech.api.util.GTChunkAssociatedData; -import gregtech.api.util.GTUtility; -import gregtech.common.render.PollutionRenderer; - -public class Pollution { - - private static final Storage STORAGE = new Storage(); - /** - * Pollution dispersion until effects start: Calculation: ((Limit * 0.01) + 2000) * (4 <- spreading rate) - *

- * 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 - *

- * 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) - *

- * Large Diesel Engine(320) Electric Blast Furnace(100) Implosion Compressor(2000) Large Boiler(240) Large Gas - * Turbine(160) Multi Smelter(100) Pyrolyse Oven(400) - *

- * Machine Explosion(100,000) - *

- * Other Random Shit: lots and lots - *

- * 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 pollutionList = new ArrayList<>(); // chunks left to process in this cycle - - private final Set 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 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 (!GTMod.gregtechproxy.mPollution) return; - if (aEvent.phase == TickEvent.Phase.START) return; - final 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.isEmpty()) operationsPerTick = Math.max(1, pollutionList.size() / cycleLen); - else operationsPerTick = 0; // SANity - blank = false; - } - - for (int chunksProcessed = 0; chunksProcessed < operationsPerTick; chunksProcessed++) { - if (pollutionList.isEmpty()) 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 = GTUtility.safeInt((long) neighborPollution + tDiff); // tNPol += tDiff; - tPollution -= tDiff; - setChunkPollution(neighborPosition, neighborPollution); - } - } - - // Create Pollution effects - // Smog filter TODO - if (tPollution > GTMod.gregtechproxy.mPollutionSmogLimit) { - AxisAlignedBB chunk = AxisAlignedBB.getBoundingBox( - actualPos.chunkXPos << 4, - 0, - actualPos.chunkZPos << 4, - (actualPos.chunkXPos << 4) + 16, - 256, - (actualPos.chunkZPos << 4) + 16); - List tEntitys = world.getEntitiesWithinAABB(EntityLivingBase.class, chunk); - for (EntityLivingBase tEnt : tEntitys) { - if (tEnt instanceof EntityPlayerMP && ((EntityPlayerMP) tEnt).capabilities.isCreativeMode) - continue; - if (!(GTUtility.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 > GTMod.gregtechproxy.mPollutionPoisonLimit) { - for (EntityLivingBase tEnt : tEntitys) { - if (tEnt instanceof EntityPlayerMP && ((EntityPlayerMP) tEnt).capabilities.isCreativeMode) - continue; - if (!GTUtility.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 > GTMod.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 > GTMod.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); - GTValues.NW.sendToAllAround(new GTPacketPollution(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 Pollution getPollutionManager(World world) { - return dimensionWisePollution.computeIfAbsent(world.provider.dimensionId, i -> new 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 (!GTMod.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 (!GTMod.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 mutator, - @Nullable Set 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 (!GTMod.gregtechproxy.mPollution) return 0; - if (w.isRemote) - // it really should be querying the client side stuff instead - return 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 (!GTMod.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 (!GTMod.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) - GTValues.NW.sendToPlayer(new GTPacketPollution(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 GTChunkAssociatedData { - - 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 GTChunkAssociatedData.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(GTUtility.safeInt(amount + (long) delta, 0), 0); - } - - @Override - public boolean isSameAsDefault() { - return amount == 0; - } - } -} diff --git a/src/main/java/gregtech/common/config/Gregtech.java b/src/main/java/gregtech/common/config/Gregtech.java index a293b6cba7..e852a6b022 100644 --- a/src/main/java/gregtech/common/config/Gregtech.java +++ b/src/main/java/gregtech/common/config/Gregtech.java @@ -27,9 +27,6 @@ public class Gregtech { @Config.Comment("Ore drop behavior section") public static final OreDropBehavior oreDropBehavior = new OreDropBehavior(); - @Config.Comment("Pollution section") - public static final Pollution pollution = new Pollution(); - @Config.LangKey("GT5U.gui.config.gregtech.debug") public static class Debug { @@ -558,128 +555,4 @@ public class Gregtech { @Config.RequiresMcRestart public GTProxy.OreDropSystem setting = GTProxy.OreDropSystem.FortuneItem; } - - @Config.LangKey("GT5U.gui.config.gregtech.pollution") - public static class Pollution { - - @Config.Comment("if true, enables pollution in the game.") - @Config.DefaultBoolean(true) - @Config.RequiresMcRestart - public boolean pollution; - - @Config.Comment("Controls the threshold starting from which you can see fog.") - @Config.DefaultInt(550_000) - @Config.RequiresMcRestart - public int pollutionSmogLimit; - @Config.Comment("Controls the threshold starting from which players get poison effect.") - @Config.DefaultInt(750_000) - @Config.RequiresMcRestart - public int pollutionPoisonLimit; - @Config.Comment("Controls the threshold starting from which vegetation starts to be killed.") - @Config.DefaultInt(1_000_000) - @Config.RequiresMcRestart - public int pollutionVegetationLimit; - @Config.Comment("Controls the threshold starting from which if it rains, will turn cobblestone into gravel and gravel into sand.") - @Config.DefaultInt(2_000_000) - @Config.RequiresMcRestart - public int pollutionSourRainLimit; - @Config.Comment("Controls the pollution released by an explosion.") - @Config.DefaultInt(100_000) - @Config.RequiresMcRestart - public int pollutionOnExplosion; - @Config.Comment("Controls the pollution released per second by the bricked blast furnace.") - @Config.DefaultInt(200) - @Config.RequiresMcRestart - public int pollutionPrimitveBlastFurnacePerSecond; - @Config.Comment("Controls the pollution released per second by the charcoal pile igniter.") - @Config.DefaultInt(100) - @Config.RequiresMcRestart - public int pollutionCharcoalPitPerSecond; - @Config.Comment("Controls the pollution released per second by the EBF.") - @Config.DefaultInt(400) - @Config.RequiresMcRestart - public int pollutionEBFPerSecond; - @Config.Comment("Controls the pollution released per second by the large combustion engine.") - @Config.DefaultInt(480) - @Config.RequiresMcRestart - public int pollutionLargeCombustionEnginePerSecond; - @Config.Comment("Controls the pollution released per second by the extreme combustion engine.") - @Config.DefaultInt(3_840) - @Config.RequiresMcRestart - public int pollutionExtremeCombustionEnginePerSecond; - @Config.Comment("Controls the pollution released per second by the implosion compressor.") - @Config.DefaultInt(10_000) - @Config.RequiresMcRestart - public int pollutionImplosionCompressorPerSecond; - @Config.Comment("Controls the pollution released per second by the large bronze boiler.") - @Config.DefaultInt(1_000) - @Config.RequiresMcRestart - public int pollutionLargeBronzeBoilerPerSecond; - @Config.Comment("Controls the pollution released per second by the large steel boiler.") - @Config.DefaultInt(2_000) - @Config.RequiresMcRestart - public int pollutionLargeSteelBoilerPerSecond; - @Config.Comment("Controls the pollution released per second by the large titanium boiler.") - @Config.DefaultInt(3_000) - @Config.RequiresMcRestart - public int pollutionLargeTitaniumBoilerPerSecond; - @Config.Comment("Controls the pollution released per second by the large tungstensteel boiler.") - @Config.DefaultInt(4_000) - @Config.RequiresMcRestart - public int pollutionLargeTungstenSteelBoilerPerSecond; - @Config.Comment("Controls the pollution reduction obtained with each increment of the circuit when throttling large boilers.") - @Config.DefaultFloat(1.0f / 24.0f) // divided by 24 because there are 24 circuit configs. - @Config.RequiresMcRestart - public float pollutionReleasedByThrottle; - @Config.Comment("Controls the pollution released per second by the large gas turbine.") - @Config.DefaultInt(300) - @Config.RequiresMcRestart - public int pollutionLargeGasTurbinePerSecond; - @Config.Comment("Controls the pollution released per second by the multi smelter.") - @Config.DefaultInt(400) - @Config.RequiresMcRestart - public int pollutionMultiSmelterPerSecond; - @Config.Comment("Controls the pollution released per second by the pyrolyse oven.") - @Config.DefaultInt(300) - @Config.RequiresMcRestart - public int pollutionPyrolyseOvenPerSecond; - @Config.Comment("Controls the pollution released per second by the small coil boiler.") - @Config.DefaultInt(20) - @Config.RequiresMcRestart - public int pollutionSmallCoalBoilerPerSecond; - @Config.Comment("Controls the pollution released per second by the high pressure lava boiler.") - @Config.DefaultInt(20) - @Config.RequiresMcRestart - public int pollutionHighPressureLavaBoilerPerSecond; - @Config.Comment("Controls the pollution released per second by the high pressure coil boiler.") - @Config.DefaultInt(30) - @Config.RequiresMcRestart - public int pollutionHighPressureCoalBoilerPerSecond; - - @Config.Comment("Controls the pollution released per second by the base diesel generator.") - @Config.DefaultInt(40) - @Config.RequiresMcRestart - public int pollutionBaseDieselGeneratorPerSecond; - - // reading double as strings, not perfect, but better than nothing - @Config.Comment({ - "Pollution released by tier, with the following formula: PollutionBaseDieselGeneratorPerSecond * PollutionDieselGeneratorReleasedByTier[Tier]", - "The first entry has meaning as it is here to since machine tier with array index: LV is 1, etc." }) - @Config.DefaultDoubleList({ 0.1, 1.0, 0.9, 0.8 }) - @Config.RequiresMcRestart - public double[] pollutionDieselGeneratorReleasedByTier; - - @Config.Comment("Controls the pollution released per second by the base gas turbine.") - @Config.DefaultInt(40) - @Config.RequiresMcRestart - public int pollutionBaseGasTurbinePerSecond; - - // reading double as strings, not perfect, but better than nothing - @Config.Comment({ - "Pollution released by tier, with the following formula: PollutionBaseGasTurbinePerSecond * PollutionGasTurbineReleasedByTier[Tier]", - "The first entry has meaning as it is here to since machine tier with array index: LV is 1, etc." }) - @Config.DefaultDoubleList({ 0.1, 1.0, 0.9, 0.8, 0.7, 0.6 }) - @Config.RequiresMcRestart - public double[] pollutionGasTurbineReleasedByTier; - } } diff --git a/src/main/java/gregtech/common/entities/EntityFXPollution.java b/src/main/java/gregtech/common/entities/EntityFXPollution.java deleted file mode 100644 index facd3d3364..0000000000 --- a/src/main/java/gregtech/common/entities/EntityFXPollution.java +++ /dev/null @@ -1,59 +0,0 @@ -package gregtech.common.entities; - -import java.util.Random; - -import net.minecraft.client.particle.EntityFX; -import net.minecraft.world.World; - -public class EntityFXPollution extends EntityFX { - - public EntityFXPollution(World world, double x, double y, double z) { - super(world, x, y, z, 0, 0, 0); - - this.particleRed = 0.25F; - this.particleGreen = 0.2F; - this.particleBlue = 0.25F; - - this.motionX *= 0.1D; - this.motionY *= -0.1D; - this.motionZ *= 0.1F; - - Random random = world.rand; - this.motionX += random.nextFloat() * -1.9D * random.nextFloat() * 0.1D; - this.motionY += random.nextFloat() * -0.5D * random.nextFloat() * 0.1D * 5.0D; - this.motionZ += random.nextFloat() * -1.9D * random.nextFloat() * 0.1D; - - this.particleTextureIndexX = 0; - this.particleTextureIndexY = 0; - - this.particleMaxAge = (int) ((double) 20 / ((double) random.nextFloat() * 0.8D + 0.2D)); - - this.particleScale *= 0.75F; - this.noClip = true; - } - - @Override - public void onUpdate() { - this.prevPosX = this.posX; - this.prevPosY = this.posY; - this.prevPosZ = this.posZ; - - if (this.particleAge++ >= this.particleMaxAge) { - this.setDead(); - } else { - this.motionY -= 5.0E-4D; - this.moveEntity(this.motionX, this.motionY, this.motionZ); - if (this.posY == this.prevPosY) { - this.motionX *= 1.1D; - this.motionZ *= 1.1D; - } - this.motionX *= 0.96D; - this.motionY *= 0.96D; - this.motionZ *= 0.96D; - if (this.onGround) { - this.motionX *= 0.7D; - this.motionZ *= 0.7D; - } - } - } -} diff --git a/src/main/java/gregtech/common/misc/GTClientPollutionMap.java b/src/main/java/gregtech/common/misc/GTClientPollutionMap.java deleted file mode 100644 index 546f8e8d12..0000000000 --- a/src/main/java/gregtech/common/misc/GTClientPollutionMap.java +++ /dev/null @@ -1,140 +0,0 @@ -package gregtech.common.misc; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.entity.EntityClientPlayerMP; -import net.minecraft.util.MathHelper; - -public class GTClientPollutionMap { - - private static final byte RADIUS = 24; - private static final byte DISTANCE_RELOAD_MAP = 5; // When player moved x chunks, shift the map to new center. - private static final byte SIZE = RADIUS * 2 + 1; // Area to keep stored. - - private int x0, z0; - private int dim; - - private boolean initialized = false; - - private static short[][] chunkMatrix; // short because reasons. - - public GTClientPollutionMap() {} - - public void reset() { - initialized = false; - } - - private void initialize(int playerChunkX, int playerChunkZ, int dimension) { - initialized = true; - chunkMatrix = new short[SIZE][SIZE]; - x0 = playerChunkX; - z0 = playerChunkZ; - dim = dimension; - } - - public void addChunkPollution(int chunkX, int chunkZ, int pollution) { - EntityClientPlayerMP player = Minecraft.getMinecraft().thePlayer; - if (player == null || player.worldObj == null) return; - - int playerXChunk = MathHelper.floor_double(player.posX) >> 4; - int playerZChunk = MathHelper.floor_double(player.posZ) >> 4; // posX/Z seems to be always loaded, - - if (!initialized) { - initialize(playerXChunk, playerZChunk, player.dimension); - } - - if (dim != player.dimension) { - initialize(playerXChunk, playerZChunk, player.dimension); - } - - if (Math.abs(x0 - playerXChunk) > DISTANCE_RELOAD_MAP || Math.abs(z0 - playerZChunk) > DISTANCE_RELOAD_MAP) - shiftCenter(playerXChunk, playerZChunk); - - int relX = chunkX - x0 + RADIUS; - if (relX >= SIZE || relX < 0) // out of bounds - return; - int relZ = chunkZ - z0 + RADIUS; - if (relZ >= SIZE || relZ < 0) // out of bounds - return; - - pollution = pollution / 225; - if (pollution > Short.MAX_VALUE) // Sanity - chunkMatrix[relX][relZ] = Short.MAX_VALUE; // Max pollution = 7,3mill - else if (pollution < 0) chunkMatrix[relX][relZ] = 0; - else chunkMatrix[relX][relZ] = (short) (pollution); - } - - // xy interpolation, between 4 chunks as corners, unknown treated as 0. - public int getPollution(double fx, double fz) { - if (!initialized) return 0; - int x = MathHelper.floor_double(fx); - int z = MathHelper.floor_double(fz); - int xDiff = ((x - 8) >> 4) - x0; - int zDiff = ((z - 8) >> 4) - z0; - - if (xDiff < -RADIUS || zDiff < -RADIUS || xDiff >= RADIUS || zDiff >= RADIUS) return 0; - - // coordinates in shifted chunk. - x = (x - 8) % 16; - z = (z - 8) % 16; - if (x < 0) x = 16 + x; - if (z < 0) z = 16 + z; - - int xi = 15 - x; - int zi = 15 - z; - - // read pollution in 4 corner chunks - int offsetX = RADIUS + xDiff; - int offsetZ = RADIUS + zDiff; - - int c00 = chunkMatrix[offsetX][offsetZ]; - int c10 = chunkMatrix[offsetX + 1][offsetZ]; - int c01 = chunkMatrix[offsetX][offsetZ + 1]; - int c11 = chunkMatrix[offsetX + 1][offsetZ + 1]; - - // Is divided by 15*15 but is handled when storing chunk data. - return c00 * xi * zi + c10 * x * zi + c01 * xi * z + c11 * x * z; - } - - // shift the matrix to fit new center - private void shiftCenter(int chunkX, int chunkZ) { - int xDiff = chunkX - x0; - int zDiff = chunkZ - z0; - boolean[] allEmpty = new boolean[SIZE]; // skip check z row if its empty. - if (xDiff > 0) for (byte x = 0; x < SIZE; x++) { - int xOff = x + xDiff; - if (xOff < SIZE) { - chunkMatrix[x] = chunkMatrix[xOff].clone(); - } else { - chunkMatrix[x] = new short[SIZE]; - allEmpty[x] = true; - } - } - else if (xDiff < 0) for (byte x = SIZE - 1; x >= 0; x--) { - int xOff = x + xDiff; - if (xOff > 0) { - chunkMatrix[x] = chunkMatrix[xOff].clone(); - } else { - chunkMatrix[x] = new short[SIZE]; - allEmpty[x] = true; - } - } - - if (zDiff > 0) for (byte x = 0; x < SIZE; x++) { - if (allEmpty[x]) continue; - for (int z = 0; z < SIZE; z++) { - int zOff = z + zDiff; - chunkMatrix[x][z] = (zOff < SIZE) ? chunkMatrix[x][zOff] : 0; - } - } - else if (zDiff < 0) for (byte x = 0; x < SIZE; x++) { - if (allEmpty[x]) continue; - for (int z = SIZE - 1; z >= 0; z--) { - int zOff = z + zDiff; - chunkMatrix[x][z] = (zOff > 0) ? chunkMatrix[x][zOff] : 0; - } - } - - x0 = chunkX; - z0 = chunkZ; - } -} diff --git a/src/main/java/gregtech/common/misc/GTCommand.java b/src/main/java/gregtech/common/misc/GTCommand.java index f1590ec792..e6fbe12144 100644 --- a/src/main/java/gregtech/common/misc/GTCommand.java +++ b/src/main/java/gregtech/common/misc/GTCommand.java @@ -25,8 +25,8 @@ import gregtech.api.enums.GTValues; import gregtech.api.objects.GTChunkManager; import gregtech.api.util.GTMusicSystem; import gregtech.api.util.GTUtility; -import gregtech.common.Pollution; import gregtech.common.misc.spaceprojects.SpaceProjectManager; +import gregtech.common.pollution.Pollution; public final class GTCommand extends CommandBase { diff --git a/src/main/java/gregtech/common/pollution/BlockMatcher.java b/src/main/java/gregtech/common/pollution/BlockMatcher.java new file mode 100644 index 0000000000..a701d323bd --- /dev/null +++ b/src/main/java/gregtech/common/pollution/BlockMatcher.java @@ -0,0 +1,96 @@ +package gregtech.common.pollution; + +import java.util.Map; +import java.util.Set; + +import net.minecraft.block.Block; +import net.minecraft.client.multiplayer.WorldClient; +import net.minecraftforge.event.world.WorldEvent; + +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; + +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import cpw.mods.fml.common.registry.FMLControlledNamespacedRegistry; +import cpw.mods.fml.common.registry.GameData; +import gregtech.GTMod; + +// Shamelessly Taken from BetterFoliage by octarine-noise +public class BlockMatcher { + + public Map, ColorOverrideType> whiteList = Maps.newHashMap(); + public Set> blackList = Sets.newHashSet(); + public Map blockIDs = Maps.newHashMap(); + + public ColorOverrideType matchesID(int blockId) { + return blockIDs.get(blockId); + } + + public ColorOverrideType matchesID(Block block) { + return blockIDs.get(Block.blockRegistry.getIDForObject(block)); + } + + public void updateClassList(String[] cfg) { + whiteList.clear(); + blackList.clear(); + for (String line : cfg) { + GTMod.GT_FML_LOGGER.info("Checking for block:" + line); + String[] lines = line.split(":"); + ColorOverrideType type = null; + if (lines.length > 1) { + try { + type = ColorOverrideType.fromName(lines[1].trim()); + } catch (NumberFormatException e) { + GTMod.GT_FML_LOGGER.error(String.format("Invalid type [%s]", line)); + continue; + } + } + + if (lines[0].startsWith("-")) { + try { + blackList.add(Class.forName(lines[0].substring(1))); + GTMod.GT_FML_LOGGER.info("\t added blacklist:" + lines[0].substring(1)); + } catch (ClassNotFoundException ignored) {} + } else { + if (type == null) { + GTMod.GT_FML_LOGGER.error(String.format("Invalid type [%s]", line)); + continue; + } + + try { + whiteList.put(Class.forName(lines[0]), type); + GTMod.GT_FML_LOGGER.info("\t added whitelist:" + lines[0]); + } catch (ClassNotFoundException ignored) {} + } + } + // updateBlockIDs(); + } + + private void updateBlockIDs() { + blockIDs.clear(); + FMLControlledNamespacedRegistry blockRegistry = GameData.getBlockRegistry(); + for (Block block : blockRegistry.typeSafeIterable()) { + ColorOverrideType t = matchesClass(block); + if (t != null) blockIDs.put(Block.blockRegistry.getIDForObject(block), t); + } + } + + private ColorOverrideType matchesClass(Block block) { + for (Class clazz : blackList) if (clazz.isAssignableFrom(block.getClass())) return null; + for (Class clazz : whiteList.keySet()) + if (clazz.isAssignableFrom(block.getClass())) return whiteList.get(clazz); + return null; + } + + /** + * Caches block IDs on world load for fast lookup + * + * @param event + */ + @SubscribeEvent + public void handleWorldLoad(WorldEvent.Load event) { + if (event.world instanceof WorldClient) { + updateBlockIDs(); + } + } +} diff --git a/src/main/java/gregtech/common/pollution/ColorOverrideType.java b/src/main/java/gregtech/common/pollution/ColorOverrideType.java new file mode 100644 index 0000000000..de0a44a835 --- /dev/null +++ b/src/main/java/gregtech/common/pollution/ColorOverrideType.java @@ -0,0 +1,28 @@ +package gregtech.common.pollution; + +public enum ColorOverrideType { + + FLOWER, + GRASS, + LEAVES, + LIQUID; + + public static ColorOverrideType fromName(String name) { + return switch (name) { + case "FLOWER" -> FLOWER; + case "GRASS" -> GRASS; + case "LEAVES" -> LEAVES; + case "LIQUID" -> LIQUID; + default -> throw new RuntimeException(); + }; + } + + public int getColor(int oColor, int x, int z) { + return switch (this) { + case FLOWER -> PollutionRenderer.colorFoliage(oColor, x, z); + case GRASS -> PollutionRenderer.colorGrass(oColor, x, z); + case LEAVES -> PollutionRenderer.colorLeaves(oColor, x, z); + case LIQUID -> PollutionRenderer.colorLiquid(oColor, x, z); + }; + } +} diff --git a/src/main/java/gregtech/common/pollution/EntityFXPollution.java b/src/main/java/gregtech/common/pollution/EntityFXPollution.java new file mode 100644 index 0000000000..f1a1f18447 --- /dev/null +++ b/src/main/java/gregtech/common/pollution/EntityFXPollution.java @@ -0,0 +1,59 @@ +package gregtech.common.pollution; + +import java.util.Random; + +import net.minecraft.client.particle.EntityFX; +import net.minecraft.world.World; + +public class EntityFXPollution extends EntityFX { + + public EntityFXPollution(World world, double x, double y, double z) { + super(world, x, y, z, 0, 0, 0); + + this.particleRed = 0.25F; + this.particleGreen = 0.2F; + this.particleBlue = 0.25F; + + this.motionX *= 0.1D; + this.motionY *= -0.1D; + this.motionZ *= 0.1F; + + Random random = world.rand; + this.motionX += random.nextFloat() * -1.9D * random.nextFloat() * 0.1D; + this.motionY += random.nextFloat() * -0.5D * random.nextFloat() * 0.1D * 5.0D; + this.motionZ += random.nextFloat() * -1.9D * random.nextFloat() * 0.1D; + + this.particleTextureIndexX = 0; + this.particleTextureIndexY = 0; + + this.particleMaxAge = (int) ((double) 20 / ((double) random.nextFloat() * 0.8D + 0.2D)); + + this.particleScale *= 0.75F; + this.noClip = true; + } + + @Override + public void onUpdate() { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + + if (this.particleAge++ >= this.particleMaxAge) { + this.setDead(); + } else { + this.motionY -= 5.0E-4D; + this.moveEntity(this.motionX, this.motionY, this.motionZ); + if (this.posY == this.prevPosY) { + this.motionX *= 1.1D; + this.motionZ *= 1.1D; + } + this.motionX *= 0.96D; + this.motionY *= 0.96D; + this.motionZ *= 0.96D; + if (this.onGround) { + this.motionX *= 0.7D; + this.motionZ *= 0.7D; + } + } + } +} diff --git a/src/main/java/gregtech/common/pollution/GTClientPollutionMap.java b/src/main/java/gregtech/common/pollution/GTClientPollutionMap.java new file mode 100644 index 0000000000..0fd1da309b --- /dev/null +++ b/src/main/java/gregtech/common/pollution/GTClientPollutionMap.java @@ -0,0 +1,140 @@ +package gregtech.common.pollution; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.EntityClientPlayerMP; +import net.minecraft.util.MathHelper; + +public class GTClientPollutionMap { + + private static final byte RADIUS = 24; + private static final byte DISTANCE_RELOAD_MAP = 5; // When player moved x chunks, shift the map to new center. + private static final byte SIZE = RADIUS * 2 + 1; // Area to keep stored. + + private int x0, z0; + private int dim; + + private boolean initialized = false; + + private static short[][] chunkMatrix; // short because reasons. + + public GTClientPollutionMap() {} + + public void reset() { + initialized = false; + } + + private void initialize(int playerChunkX, int playerChunkZ, int dimension) { + initialized = true; + chunkMatrix = new short[SIZE][SIZE]; + x0 = playerChunkX; + z0 = playerChunkZ; + dim = dimension; + } + + public void addChunkPollution(int chunkX, int chunkZ, int pollution) { + EntityClientPlayerMP player = Minecraft.getMinecraft().thePlayer; + if (player == null || player.worldObj == null) return; + + int playerXChunk = MathHelper.floor_double(player.posX) >> 4; + int playerZChunk = MathHelper.floor_double(player.posZ) >> 4; // posX/Z seems to be always loaded, + + if (!initialized) { + initialize(playerXChunk, playerZChunk, player.dimension); + } + + if (dim != player.dimension) { + initialize(playerXChunk, playerZChunk, player.dimension); + } + + if (Math.abs(x0 - playerXChunk) > DISTANCE_RELOAD_MAP || Math.abs(z0 - playerZChunk) > DISTANCE_RELOAD_MAP) + shiftCenter(playerXChunk, playerZChunk); + + int relX = chunkX - x0 + RADIUS; + if (relX >= SIZE || relX < 0) // out of bounds + return; + int relZ = chunkZ - z0 + RADIUS; + if (relZ >= SIZE || relZ < 0) // out of bounds + return; + + pollution = pollution / 225; + if (pollution > Short.MAX_VALUE) // Sanity + chunkMatrix[relX][relZ] = Short.MAX_VALUE; // Max pollution = 7,3mill + else if (pollution < 0) chunkMatrix[relX][relZ] = 0; + else chunkMatrix[relX][relZ] = (short) (pollution); + } + + // xy interpolation, between 4 chunks as corners, unknown treated as 0. + public int getPollution(double fx, double fz) { + if (!initialized) return 0; + int x = MathHelper.floor_double(fx); + int z = MathHelper.floor_double(fz); + int xDiff = ((x - 8) >> 4) - x0; + int zDiff = ((z - 8) >> 4) - z0; + + if (xDiff < -RADIUS || zDiff < -RADIUS || xDiff >= RADIUS || zDiff >= RADIUS) return 0; + + // coordinates in shifted chunk. + x = (x - 8) % 16; + z = (z - 8) % 16; + if (x < 0) x = 16 + x; + if (z < 0) z = 16 + z; + + int xi = 15 - x; + int zi = 15 - z; + + // read pollution in 4 corner chunks + int offsetX = RADIUS + xDiff; + int offsetZ = RADIUS + zDiff; + + int c00 = chunkMatrix[offsetX][offsetZ]; + int c10 = chunkMatrix[offsetX + 1][offsetZ]; + int c01 = chunkMatrix[offsetX][offsetZ + 1]; + int c11 = chunkMatrix[offsetX + 1][offsetZ + 1]; + + // Is divided by 15*15 but is handled when storing chunk data. + return c00 * xi * zi + c10 * x * zi + c01 * xi * z + c11 * x * z; + } + + // shift the matrix to fit new center + private void shiftCenter(int chunkX, int chunkZ) { + int xDiff = chunkX - x0; + int zDiff = chunkZ - z0; + boolean[] allEmpty = new boolean[SIZE]; // skip check z row if its empty. + if (xDiff > 0) for (byte x = 0; x < SIZE; x++) { + int xOff = x + xDiff; + if (xOff < SIZE) { + chunkMatrix[x] = chunkMatrix[xOff].clone(); + } else { + chunkMatrix[x] = new short[SIZE]; + allEmpty[x] = true; + } + } + else if (xDiff < 0) for (byte x = SIZE - 1; x >= 0; x--) { + int xOff = x + xDiff; + if (xOff > 0) { + chunkMatrix[x] = chunkMatrix[xOff].clone(); + } else { + chunkMatrix[x] = new short[SIZE]; + allEmpty[x] = true; + } + } + + if (zDiff > 0) for (byte x = 0; x < SIZE; x++) { + if (allEmpty[x]) continue; + for (int z = 0; z < SIZE; z++) { + int zOff = z + zDiff; + chunkMatrix[x][z] = (zOff < SIZE) ? chunkMatrix[x][zOff] : 0; + } + } + else if (zDiff < 0) for (byte x = 0; x < SIZE; x++) { + if (allEmpty[x]) continue; + for (int z = SIZE - 1; z >= 0; z--) { + int zOff = z + zDiff; + chunkMatrix[x][z] = (zOff > 0) ? chunkMatrix[x][zOff] : 0; + } + } + + x0 = chunkX; + z0 = chunkZ; + } +} diff --git a/src/main/java/gregtech/common/pollution/Pollution.java b/src/main/java/gregtech/common/pollution/Pollution.java new file mode 100644 index 0000000000..10b8ffcfa7 --- /dev/null +++ b/src/main/java/gregtech/common/pollution/Pollution.java @@ -0,0 +1,533 @@ +package gregtech.common.pollution; + +import static gregtech.api.objects.XSTR.XSTR_INSTANCE; +import static gregtech.common.GTProxy.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.GTMod; +import gregtech.api.enums.GTValues; +import gregtech.api.interfaces.ICleanroom; +import gregtech.api.interfaces.ICleanroomReceiver; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.net.GTPacketPollution; +import gregtech.api.util.GTChunkAssociatedData; +import gregtech.api.util.GTUtility; + +public class Pollution { + + private static final Storage STORAGE = new Storage(); + /** + * Pollution dispersion until effects start: Calculation: ((Limit * 0.01) + 2000) * (4 <- spreading rate) + *

+ * 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 + *

+ * 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) + *

+ * Large Diesel Engine(320) Electric Blast Furnace(100) Implosion Compressor(2000) Large Boiler(240) Large Gas + * Turbine(160) Multi Smelter(100) Pyrolyse Oven(400) + *

+ * Machine Explosion(100,000) + *

+ * Other Random Shit: lots and lots + *

+ * 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 pollutionList = new ArrayList<>(); // chunks left to process in this cycle + + private final Set 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 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 (!GTMod.gregtechproxy.mPollution) return; + if (aEvent.phase == TickEvent.Phase.START) return; + final Pollution pollutionInstance = dimensionWisePollution.get(aEvent.world.provider.dimensionId); + if (pollutionInstance == null) return; + pollutionInstance.tickPollutionInWorld((int) (aEvent.world.getTotalWorldTime() % cycleLen)); + } + + public static BlockMatcher standardBlocks; + public static BlockMatcher liquidBlocks; + public static BlockMatcher doublePlants; + public static BlockMatcher crossedSquares; + public static BlockMatcher blockVine; + + public static void onPostInitClient() { + if (PollutionConfig.pollution) { + standardBlocks = new BlockMatcher(); + liquidBlocks = new BlockMatcher(); + doublePlants = new BlockMatcher(); + crossedSquares = new BlockMatcher(); + blockVine = new BlockMatcher(); + standardBlocks.updateClassList(PollutionConfig.renderStandardBlock); + liquidBlocks.updateClassList(PollutionConfig.renderBlockLiquid); + doublePlants.updateClassList(PollutionConfig.renderBlockDoublePlant); + crossedSquares.updateClassList(PollutionConfig.renderCrossedSquares); + blockVine.updateClassList(PollutionConfig.renderblockVine); + MinecraftForge.EVENT_BUS.register(standardBlocks); + MinecraftForge.EVENT_BUS.register(liquidBlocks); + MinecraftForge.EVENT_BUS.register(doublePlants); + MinecraftForge.EVENT_BUS.register(crossedSquares); + MinecraftForge.EVENT_BUS.register(blockVine); + MinecraftForge.EVENT_BUS.register(new PollutionTooltip()); + } + } + + 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.isEmpty()) operationsPerTick = Math.max(1, pollutionList.size() / cycleLen); + else operationsPerTick = 0; // SANity + blank = false; + } + + for (int chunksProcessed = 0; chunksProcessed < operationsPerTick; chunksProcessed++) { + if (pollutionList.isEmpty()) 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 = GTUtility.safeInt((long) neighborPollution + tDiff); // tNPol += tDiff; + tPollution -= tDiff; + setChunkPollution(neighborPosition, neighborPollution); + } + } + + // Create Pollution effects + // Smog filter TODO + if (tPollution > GTMod.gregtechproxy.mPollutionSmogLimit) { + AxisAlignedBB chunk = AxisAlignedBB.getBoundingBox( + actualPos.chunkXPos << 4, + 0, + actualPos.chunkZPos << 4, + (actualPos.chunkXPos << 4) + 16, + 256, + (actualPos.chunkZPos << 4) + 16); + List tEntitys = world.getEntitiesWithinAABB(EntityLivingBase.class, chunk); + for (EntityLivingBase tEnt : tEntitys) { + if (tEnt instanceof EntityPlayerMP && ((EntityPlayerMP) tEnt).capabilities.isCreativeMode) + continue; + if (!(GTUtility.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 > GTMod.gregtechproxy.mPollutionPoisonLimit) { + for (EntityLivingBase tEnt : tEntitys) { + if (tEnt instanceof EntityPlayerMP && ((EntityPlayerMP) tEnt).capabilities.isCreativeMode) + continue; + if (!GTUtility.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 > GTMod.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 > GTMod.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); + GTValues.NW.sendToAllAround(new GTPacketPollution(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 Pollution getPollutionManager(World world) { + return dimensionWisePollution.computeIfAbsent(world.provider.dimensionId, i -> new 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 (!GTMod.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 (!GTMod.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 mutator, + @Nullable Set 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 (!GTMod.gregtechproxy.mPollution) return 0; + if (w.isRemote) + // it really should be querying the client side stuff instead + return 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 (!GTMod.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); + } + + public 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 (!GTMod.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) + GTValues.NW.sendToPlayer(new GTPacketPollution(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 GTChunkAssociatedData { + + 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 GTChunkAssociatedData.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(GTUtility.safeInt(amount + (long) delta, 0), 0); + } + + @Override + public boolean isSameAsDefault() { + return amount == 0; + } + } +} diff --git a/src/main/java/gregtech/common/pollution/PollutionConfig.java b/src/main/java/gregtech/common/pollution/PollutionConfig.java new file mode 100644 index 0000000000..90098791c4 --- /dev/null +++ b/src/main/java/gregtech/common/pollution/PollutionConfig.java @@ -0,0 +1,397 @@ +package gregtech.common.pollution; + +import com.gtnewhorizon.gtnhlib.config.Config; + +import gregtech.api.enums.Mods; + +// needs to be loaded early from the coremod because +// it decides to load some mixins or not +@Config(modid = Mods.Names.GREG_TECH, category = "Pollution", configSubDirectory = "GregTech", filename = "Pollution") +public class PollutionConfig { + + // override name to be at the top of the cfg file + @Config.Name("Activate Pollution") + @Config.Comment("if true, enables pollution in the game.") + @Config.DefaultBoolean(true) + @Config.RequiresMcRestart + public static boolean pollution; + + @Config.Comment("Controls the threshold starting from which you can see fog.") + @Config.DefaultInt(550_000) + @Config.RequiresMcRestart + public static int pollutionSmogLimit; + @Config.Comment("Controls the threshold starting from which players get poison effect.") + @Config.DefaultInt(750_000) + @Config.RequiresMcRestart + public static int pollutionPoisonLimit; + @Config.Comment("Controls the threshold starting from which vegetation starts to be killed.") + @Config.DefaultInt(1_000_000) + @Config.RequiresMcRestart + public static int pollutionVegetationLimit; + @Config.Comment("Controls the threshold starting from which if it rains, will turn cobblestone into gravel and gravel into sand.") + @Config.DefaultInt(2_000_000) + @Config.RequiresMcRestart + public static int pollutionSourRainLimit; + @Config.Comment("Controls the pollution released by an explosion.") + @Config.DefaultInt(100_000) + @Config.RequiresMcRestart + public static int pollutionOnExplosion; + @Config.Comment("Controls the pollution released per second by the bricked blast furnace.") + @Config.DefaultInt(200) + @Config.RequiresMcRestart + public static int pollutionPrimitveBlastFurnacePerSecond; + @Config.Comment("Controls the pollution released per second by the charcoal pile igniter.") + @Config.DefaultInt(100) + @Config.RequiresMcRestart + public static int pollutionCharcoalPitPerSecond; + @Config.Comment("Controls the pollution released per second by the EBF.") + @Config.DefaultInt(400) + @Config.RequiresMcRestart + public static int pollutionEBFPerSecond; + @Config.Comment("Controls the pollution released per second by the large combustion engine.") + @Config.DefaultInt(480) + @Config.RequiresMcRestart + public static int pollutionLargeCombustionEnginePerSecond; + @Config.Comment("Controls the pollution released per second by the extreme combustion engine.") + @Config.DefaultInt(3_840) + @Config.RequiresMcRestart + public static int pollutionExtremeCombustionEnginePerSecond; + @Config.Comment("Controls the pollution released per second by the implosion compressor.") + @Config.DefaultInt(10_000) + @Config.RequiresMcRestart + public static int pollutionImplosionCompressorPerSecond; + @Config.Comment("Controls the pollution released per second by the large bronze boiler.") + @Config.DefaultInt(1_000) + @Config.RequiresMcRestart + public static int pollutionLargeBronzeBoilerPerSecond; + @Config.Comment("Controls the pollution released per second by the large steel boiler.") + @Config.DefaultInt(2_000) + @Config.RequiresMcRestart + public static int pollutionLargeSteelBoilerPerSecond; + @Config.Comment("Controls the pollution released per second by the large titanium boiler.") + @Config.DefaultInt(3_000) + @Config.RequiresMcRestart + public static int pollutionLargeTitaniumBoilerPerSecond; + @Config.Comment("Controls the pollution released per second by the large tungstensteel boiler.") + @Config.DefaultInt(4_000) + @Config.RequiresMcRestart + public static int pollutionLargeTungstenSteelBoilerPerSecond; + @Config.Comment("Controls the pollution reduction obtained with each increment of the circuit when throttling large boilers.") + @Config.DefaultFloat(1.0f / 24.0f) // divided by 24 because there are 24 circuit configs. + @Config.RequiresMcRestart + public static float pollutionReleasedByThrottle; + @Config.Comment("Controls the pollution released per second by the large gas turbine.") + @Config.DefaultInt(300) + @Config.RequiresMcRestart + public static int pollutionLargeGasTurbinePerSecond; + @Config.Comment("Controls the pollution released per second by the multi smelter.") + @Config.DefaultInt(400) + @Config.RequiresMcRestart + public static int pollutionMultiSmelterPerSecond; + @Config.Comment("Controls the pollution released per second by the pyrolyse oven.") + @Config.DefaultInt(300) + @Config.RequiresMcRestart + public static int pollutionPyrolyseOvenPerSecond; + @Config.Comment("Controls the pollution released per second by the small coil boiler.") + @Config.DefaultInt(20) + @Config.RequiresMcRestart + public static int pollutionSmallCoalBoilerPerSecond; + @Config.Comment("Controls the pollution released per second by the high pressure lava boiler.") + @Config.DefaultInt(20) + @Config.RequiresMcRestart + public static int pollutionHighPressureLavaBoilerPerSecond; + @Config.Comment("Controls the pollution released per second by the high pressure coil boiler.") + @Config.DefaultInt(30) + @Config.RequiresMcRestart + public static int pollutionHighPressureCoalBoilerPerSecond; + + @Config.Comment("Controls the pollution released per second by the base diesel generator.") + @Config.DefaultInt(40) + @Config.RequiresMcRestart + public static int pollutionBaseDieselGeneratorPerSecond; + + // reading double as strings, not perfect, but better than nothing + @Config.Comment({ + "Pollution released by tier, with the following formula: PollutionBaseDieselGeneratorPerSecond * PollutionDieselGeneratorReleasedByTier[Tier]", + "The first entry has meaning as it is here to since machine tier with array index: LV is 1, etc." }) + @Config.DefaultDoubleList({ 0.1, 1.0, 0.9, 0.8 }) + @Config.RequiresMcRestart + public static double[] pollutionDieselGeneratorReleasedByTier; + + @Config.Comment("Controls the pollution released per second by the base gas turbine.") + @Config.DefaultInt(40) + @Config.RequiresMcRestart + public static int pollutionBaseGasTurbinePerSecond; + + // reading double as strings, not perfect, but better than nothing + @Config.Comment({ + "Pollution released by tier, with the following formula: PollutionBaseGasTurbinePerSecond * PollutionGasTurbineReleasedByTier[Tier]", + "The first entry has meaning as it is here to since machine tier with array index: LV is 1, etc." }) + @Config.DefaultDoubleList({ 0.1, 1.0, 0.9, 0.8, 0.7, 0.6 }) + @Config.RequiresMcRestart + public static double[] pollutionGasTurbineReleasedByTier; + + // Minecraft + @Config.Comment("Explosion pollution") + @Config.DefaultFloat(333.34f) + public static float explosionPollutionAmount; + + @Config.Comment("Make furnaces Pollute") + @Config.DefaultBoolean(true) + @Config.RequiresMcRestart + public static boolean furnacesPollute; + + @Config.Comment("Furnace pollution per second, min 1!") + @Config.DefaultInt(20) + public static int furnacePollutionAmount; + + // Galacticraft + + @Config.Comment("Pollution Amount for Rockets") + @Config.DefaultInt(10000) + public static int rocketPollutionAmount; + + @Config.Comment("Make rockets Pollute") + @Config.DefaultBoolean(true) + @Config.RequiresMcRestart + public static boolean rocketsPollute; + + // Railcraft + + @Config.Comment("Pollution Amount for Advanced Coke Ovens") + @Config.DefaultInt(80) + public static int advancedCokeOvenPollutionAmount; + + @Config.Comment("Pollution Amount for Coke Ovens") + @Config.DefaultInt(10) + public static int cokeOvenPollutionAmount; + + @Config.Comment("Pollution Amount for RC Firebox") + @Config.DefaultInt(20) + public static int fireboxPollutionAmount; + + @Config.Comment("Pollution Amount for hobbyist steam engine") + @Config.DefaultInt(20) + public static int hobbyistEnginePollutionAmount; + + @Config.Comment("Make Railcraft Pollute") + @Config.DefaultBoolean(true) + @Config.RequiresMcRestart + public static boolean railcraftPollutes; + + @Config.Comment("Pollution Amount for tunnel bore") + @Config.DefaultInt(2) + public static int tunnelBorePollutionAmount; + + // bartworks + @Config.Comment("How much should the Simple Stirling Water Pump produce pollution per second") + @Config.DefaultInt(5) + public static int pollutionHeatedWaterPumpSecond; + + @Config.Comment("How much should the MBF produce pollution per tick per ingot. Then it'll be multiplied by the amount of ingots done in parallel") + @Config.DefaultInt(400) + public static int basePollutionMBFSecond; + + @Config.Comment("Changes colors of certain blocks based on pollution levels") + @Config.DefaultBoolean(true) + @Config.RequiresMcRestart + public static boolean pollutionBlockRecolor; + + @Config.Comment("Double Plant Blocks - Recolor Block List") + @Config.DefaultStringList({ "net.minecraft.block.BlockDoublePlant:FLOWER", }) + @Config.RequiresMcRestart + public static String[] renderBlockDoublePlant; + + @Config.Comment("Liquid Blocks - Recolor Block List") + @Config.DefaultStringList({ "net.minecraft.block.BlockLiquid:LIQUID" }) + @Config.RequiresMcRestart + public static String[] renderBlockLiquid; + + @Config.Comment("Block Vine - Recolor Block List") + @Config.DefaultStringList({ "net.minecraft.block.BlockVine:FLOWER", }) + @Config.RequiresMcRestart + public static String[] renderblockVine; + + @Config.Comment("Crossed Squares - Recolor Block List") + @Config.DefaultStringList({ "net.minecraft.block.BlockTallGrass:FLOWER", "net.minecraft.block.BlockFlower:FLOWER", + "biomesoplenty.common.blocks.BlockBOPFlower:FLOWER", "biomesoplenty.common.blocks.BlockBOPFlower2:FLOWER", + "biomesoplenty.common.blocks.BlockBOPFoliage:FLOWER", }) + @Config.RequiresMcRestart + public static String[] renderCrossedSquares; + + @Config.Comment("Standard Blocks - Recolor Block List") + @Config.DefaultStringList({ "net.minecraft.block.BlockGrass:GRASS", "net.minecraft.block.BlockLeavesBase:LEAVES", + "biomesoplenty.common.blocks.BlockOriginGrass:GRASS", "biomesoplenty.common.blocks.BlockLongGrass:GRASS", + "biomesoplenty.common.blocks.BlockNewGrass:GRASS", "tconstruct.blocks.slime.SlimeGrass:GRASS", + "thaumcraft.common.blocks.BlockMagicalLeaves:LEAVES", }) + @Config.RequiresMcRestart + public static String[] renderStandardBlock; + + // gt++ + @Config.Comment("pollution rate in gibbl/s for the Amazon warehousing depot") + @Config.DefaultInt(40) + public static int pollutionPerSecondMultiPackager; + @Config.Comment("pollution rate in gibbl/s for the Alloy blast smelter") + @Config.DefaultInt(300) + public static int pollutionPerSecondMultiIndustrialAlloySmelter; + @Config.Comment("pollution rate in gibbl/s for the High current arc furnace") + @Config.DefaultInt(2_400) + public static int pollutionPerSecondMultiIndustrialArcFurnace; + @Config.Comment("pollution rate in gibbl/s for the Industrial centrifuge") + @Config.DefaultInt(300) + public static int pollutionPerSecondMultiIndustrialCentrifuge; + @Config.Comment("pollution rate in gibbl/s for the Industrial coke oven") + @Config.DefaultInt(80) + public static int pollutionPerSecondMultiIndustrialCokeOven; + @Config.Comment("pollution rate in gibbl/s for the Cutting factory") + @Config.DefaultInt(160) + public static int pollutionPerSecondMultiIndustrialCuttingMachine; + @Config.Comment("pollution rate in gibbl/s for the Utupu-Tanuri") + @Config.DefaultInt(500) + public static int pollutionPerSecondMultiIndustrialDehydrator; + @Config.Comment("pollution rate in gibbl/s for the Industrial electrolyzer") + @Config.DefaultInt(300) + public static int pollutionPerSecondMultiIndustrialElectrolyzer; + @Config.Comment("pollution rate in gibbl/s for the Industrial extrusion machine") + @Config.DefaultInt(1_000) + public static int pollutionPerSecondMultiIndustrialExtruder; + @Config.Comment("pollution rate in gibbl/s for the Maceration stack") + @Config.DefaultInt(400) + public static int pollutionPerSecondMultiIndustrialMacerator; + @Config.Comment("pollution rate in gibbl/s for the Industrial mixing machine") + @Config.DefaultInt(800) + public static int pollutionPerSecondMultiIndustrialMixer; + @Config.Comment("pollution rate in gibbl/s for the Large processing factory in metal mode") + @Config.DefaultInt(400) + public static int pollutionPerSecondMultiIndustrialMultiMachine_ModeMetal; + @Config.Comment("pollution rate in gibbl/s for the Large processing factory in fluid mode") + @Config.DefaultInt(400) + public static int pollutionPerSecondMultiIndustrialMultiMachine_ModeFluid; + @Config.Comment("pollution rate in gibbl/s for the Large processing factory in misc mode") + @Config.DefaultInt(600) + public static int pollutionPerSecondMultiIndustrialMultiMachine_ModeMisc; + @Config.Comment("pollution rate in gibbl/s for the Industrial material press in forming mode") + @Config.DefaultInt(240) + public static int pollutionPerSecondMultiIndustrialPlatePress_ModeForming; + @Config.Comment("pollution rate in gibbl/s for the Industrial material press in bending mode") + @Config.DefaultInt(480) + public static int pollutionPerSecondMultiIndustrialPlatePress_ModeBending; + @Config.Comment("pollution rate in gibbl/s for the Industrial Forge Hammer") + @Config.DefaultInt(250) + public static int pollutionPerSecondMultiIndustrialForgeHammer; + @Config.Comment("pollution rate in gibbl/s for the Large Sifter") + @Config.DefaultInt(40) + public static int pollutionPerSecondMultiIndustrialSifter; + @Config.Comment("pollution rate in gibbl/s for the Large thermal refinery") + @Config.DefaultInt(1_000) + public static int pollutionPerSecondMultiIndustrialThermalCentrifuge; + @Config.Comment("pollution rate in gibbl/s for the Industrial fluid heater") + @Config.DefaultInt(1_000) + public static int pollutionPerSecondMultiIndustrialFluidHeater; + @Config.Comment("pollution rate in gibbl/s for the Cryogenic freezer") + @Config.DefaultInt(500) + public static int pollutionPerSecondMultiIndustrialVacuumFreezer; + @Config.Comment("pollution rate in gibbl/s for the Ore washing plant in chemical bath mode") + @Config.DefaultInt(400) + public static int pollutionPerSecondMultiIndustrialWashPlant_ModeChemBath; + @Config.Comment("pollution rate in gibbl/s for the Ore washing plant in ore washer mode") + @Config.DefaultInt(100) + public static int pollutionPerSecondMultiIndustrialWashPlant_ModeWasher; + @Config.Comment("pollution rate in gibbl/s for the Wire factory") + @Config.DefaultInt(100) + public static int pollutionPerSecondMultiIndustrialWireMill; + @Config.Comment("pollution rate in gibbl/s for the IsaMill grinding machine") + @Config.DefaultInt(1_280) + public static int pollutionPerSecondMultiIsaMill; + @Config.Comment("pollution rate in gibbl/s for the Dangote distillus in distillery mode") + @Config.DefaultInt(240) + public static int pollutionPerSecondMultiAdvDistillationTower_ModeDistillery; + @Config.Comment("pollution rate in gibbl/s for the Dangote distillus in distillation tower mode") + @Config.DefaultInt(480) + public static int pollutionPerSecondMultiAdvDistillationTower_ModeDT; + @Config.Comment("pollution rate in gibbl/s for the Volcanus") + @Config.DefaultInt(500) + public static int pollutionPerSecondMultiAdvEBF; + @Config.Comment("pollution rate in gibbl/s for the Density^2") + @Config.DefaultInt(5_000) + public static int pollutionPerSecondMultiAdvImplosion; + @Config.Comment("pollution rate in gibbl/s for the Alloy blast furnace") + @Config.DefaultInt(200) + public static int pollutionPerSecondMultiABS; + @Config.Comment("pollution rate in gibbl/s for the Cyclotron") + @Config.DefaultInt(200) + public static int pollutionPerSecondMultiCyclotron; + @Config.Comment("pollution rate in gibbl/s for the Zuhai - fishing port") + @Config.DefaultInt(20) + public static int pollutionPerSecondMultiIndustrialFishingPond; + // pollutionPerSecondMultiLargeRocketEngine; + @Config.Comment("pollution rate in gibbl/s for the Large semifluid burner") + @Config.DefaultInt(1_280) + public static int pollutionPerSecondMultiLargeSemiFluidGenerator; + @Config.Comment("pollution rate in gibbl/s for the Matter fabrication CPU") + @Config.DefaultInt(40) + public static int pollutionPerSecondMultiMassFabricator; + @Config.Comment("pollution rate in gibbl/s for the Reactor fuel processing plant") + @Config.DefaultInt(4_000) + public static int pollutionPerSecondMultiRefinery; + @Config.Comment("pollution rate in gibbl/s for the Industrial Rock Breaker") + @Config.DefaultInt(100) + public static int pollutionPerSecondMultiIndustrialRockBreaker; + @Config.Comment("pollution rate in gibbl/s for the Industrial Chisel") + @Config.DefaultInt(50) + public static int pollutionPerSecondMultiIndustrialChisel; + @Config.Comment("pollution rate in gibbl/s for the Tree growth simulator") + @Config.DefaultInt(100) + public static int pollutionPerSecondMultiTreeFarm; + @Config.Comment("pollution rate in gibbl/s for the Flotation cell regulator") + @Config.DefaultInt(0) + public static int pollutionPerSecondMultiFrothFlotationCell; + @Config.Comment("pollution rate in gibbl/s for the Large-Scale auto assembler v1.01") + @Config.DefaultInt(500) + public static int pollutionPerSecondMultiAutoCrafter; + @Config.Comment("pollution rate in gibbl/s for the Nuclear salt processing plant") + @Config.DefaultInt(500) + public static int pollutionPerSecondNuclearSaltProcessingPlant; + @Config.Comment("pollution rate in gibbl/s for the Multiblock Molecular Transformer") + @Config.DefaultInt(1_000) + public static int pollutionPerSecondMultiMolecularTransformer; + + @Config.Comment("pollution rate in gibbl/s for the Elemental Duplicator") + @Config.DefaultInt(1_000) + public static int pollutionPerSecondElementalDuplicator; + + @Config.Comment("pollution rate in gibbl/s for the Thermal boiler") + @Config.DefaultInt(700) + public static int pollutionPerSecondMultiThermalBoiler; + @Config.Comment("pollution rate in gibbl/s for the Algae farm") + @Config.DefaultInt(0) + public static int pollutionPerSecondMultiAlgaePond; + @Config.Comment("base pollution rate in gibbl/s for the single block semi fluid generators") + @Config.DefaultInt(40) + public static int basePollutionPerSecondSemiFluidGenerator; + @Config.Comment("coefficient applied to the base rate of the single block semi fluid generators based on its tier (first is tier 0 aka ULV)") + @Config.DefaultDoubleList({ 0.0, 2.0, 4.0, 8.0, 12.0, 16.0 }) + public static double[] pollutionReleasedByTierSemiFluidGenerator; + @Config.Comment("base pollution rate in gibbl/s for the single block boilers") + @Config.DefaultInt(35) + public static int basePollutionPerSecondBoiler; + @Config.Comment("coefficient applied to the base rate of the single block boilers based on its tier (first is tier 0 aka ULV)") + @Config.DefaultDoubleList({ 0.0, 1.0, 1.43, 1.86 }) + public static double[] pollutionReleasedByTierBoiler; + @Config.Comment("minimum base pollution rate in gibbl/s for the single block rocket engines") + @Config.DefaultInt(250) + public static int baseMinPollutionPerSecondRocketFuelGenerator; + @Config.Comment("maximum base pollution rate in gibbl/s for the single block rocket engines") + @Config.DefaultInt(2_000) + public static int baseMaxPollutionPerSecondRocketFuelGenerator; + @Config.Comment("coefficient applied to the base rate of the single block rocket engines based on its tier (first is tier 0 aka ULV)") + @Config.DefaultDoubleList({ 0.0, 0.0, 0.0, 0.0, 1.0, 2.0, 3.0 }) + public static double[] pollutionReleasedByTierRocketFuelGenerator; + @Config.Comment("base pollution rate in gibbl/s for the geothermal engines") + @Config.DefaultInt(100) + public static int basePollutionPerSecondGeothermalGenerator; + @Config.Comment("coefficient applied to the base rate of the single block geothermal engines based on its tier (first is tier 0 aka ULV)") + @Config.DefaultDoubleList({ 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0 }) + public static double[] pollutionReleasedByTierGeothermalGenerator; + +} diff --git a/src/main/java/gregtech/common/pollution/PollutionRenderer.java b/src/main/java/gregtech/common/pollution/PollutionRenderer.java new file mode 100644 index 0000000000..d0b76a58b1 --- /dev/null +++ b/src/main/java/gregtech/common/pollution/PollutionRenderer.java @@ -0,0 +1,249 @@ +package gregtech.common.pollution; + +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; +import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.EntityClientPlayerMP; +import net.minecraft.client.particle.EntityFX; +import net.minecraft.client.renderer.OpenGlHelper; +import net.minecraft.potion.Potion; +import net.minecraft.util.MathHelper; +import net.minecraft.world.ChunkCoordIntPair; +import net.minecraft.world.World; +import net.minecraftforge.client.event.EntityViewRenderEvent; +import net.minecraftforge.event.world.WorldEvent; + +import org.lwjgl.opengl.GL11; + +import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.common.eventhandler.EventPriority; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import cpw.mods.fml.common.gameevent.TickEvent; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import gregtech.GTMod; + +@SideOnly(Side.CLIENT) +public class PollutionRenderer { + + private static GTClientPollutionMap pollutionMap; + private static int playerPollution = 0; + + private static final boolean DEBUG = false; + + // PARTICLES_POLLUTION_START + PARTICLES_POLLUTION_END -> Max Particles + private static final int PARTICLES_MAX_NUM = 100; + private static final int PARTICLES_POLLUTION_START = 400000; + private static final int PARTICLES_POLLUTION_END = 3500000; + + private static final int FOG_START_AT_POLLUTION = 400000; + private static final int FOG_MAX_AT_POLLUTION = 7000000; + // jump from linear to exponential fog. x*FOG_MAX_AT_POLLUTION+FOG_START_AT_POLLUTION + private static final double FOG_START_EXP_RATIO = 0.02D; + + private static final float[] fogColor = { 0.3f, 0.25f, 0.1f }; + private static final short[] grassColor = { 230, 180, 40 }; + private static final short[] leavesColor = { 160, 80, 15 }; + private static final short[] liquidColor = { 160, 200, 10 }; + private static final short[] foliageColor = { 160, 80, 15 }; + + // TODO need to soft update some blocks, grass and leaves does more often than liquid it looks like. + + public PollutionRenderer() { + pollutionMap = new GTClientPollutionMap(); + } + + public void preLoad() { + net.minecraftforge.common.MinecraftForge.EVENT_BUS.register(this); + FMLCommonHandler.instance() + .bus() + .register(this); + } + + public void processPacket(ChunkCoordIntPair chunk, int pollution) { + pollutionMap.addChunkPollution(chunk.chunkXPos, chunk.chunkZPos, pollution); + } + + @SubscribeEvent(priority = EventPriority.HIGH) + public void enteredWorld(WorldEvent.Load event) { + EntityClientPlayerMP p = Minecraft.getMinecraft().thePlayer; + if (!event.world.isRemote || p == null) return; + pollutionMap.reset(); + } + + private static int color(int color, int pollution, int low, float high, short[] colors) { + if (pollution < low) return color; + + int r = (color >> 16) & 0xFF; + int g = (color >> 8) & 0xFF; + int b = color & 0xFF; + float p = (pollution - low) / high; + if (p > 1) p = 1; + float pi = 1 - p; + + r = ((int) (r * pi + p * colors[0])) & 0xFF; + g = ((int) (g * pi + p * colors[1])) & 0xFF; + b = ((int) (b * pi + p * colors[2])) & 0xFF; + + return (r & 0xFF) << 16 | (g & 0xFF) << 8 | b & 0xFF; + } + + // Methods for hodgepodge to color grass / foliage blocks etc. + public static int colorGrass(int oColor, int x, int z) { + return color(oColor, pollutionMap.getPollution(x, z) / 1000, 350, 600, grassColor); + } + + public static int colorLeaves(int oColor, int x, int z) { + return color(oColor, pollutionMap.getPollution(x, z) / 1000, 300, 500, leavesColor); + } + + public static int colorLiquid(int oColor, int x, int z) { + return color(oColor, pollutionMap.getPollution(x, z) / 1000, 300, 500, liquidColor); + } + + public static int colorFoliage(int oColor, int x, int z) { + return color(oColor, pollutionMap.getPollution(x, z) / 1000, 300, 500, foliageColor); + } + + public static int getKnownPollution(int x, int z) { + return pollutionMap.getPollution(x, z); + } + + @SubscribeEvent(priority = EventPriority.LOW) + public void manipulateColor(EntityViewRenderEvent.FogColors event) { + if (!DEBUG && Minecraft.getMinecraft().thePlayer.capabilities.isCreativeMode) return; + + if (event.block.getMaterial() == Material.water || event.block.getMaterial() == Material.lava) return; + + float x = fogIntensityLastTick > 1 ? 1F : (float) fogIntensityLastTick; + float xi = 1 - x; + + event.red = xi * event.red + x * fogColor[0]; + event.green = xi * event.green + x * fogColor[1]; + event.blue = xi * event.blue + x * fogColor[2]; + } + + private static final int END_MAX_DISTANCE = 192 - 1; + private static double fogIntensityLastTick = 0; + + @SubscribeEvent(priority = EventPriority.LOWEST) + public void renderGTPollutionFog(EntityViewRenderEvent.RenderFogEvent event) { + if (!GTMod.gregtechproxy.mRenderPollutionFog) return; + + if ((!DEBUG && Minecraft.getMinecraft().thePlayer.capabilities.isCreativeMode) + || (fogIntensityLastTick < FOG_START_EXP_RATIO)) return; + + if (event.fogMode == 0) { + double v = 1 - fogIntensityLastTick / FOG_START_EXP_RATIO; + // trying to smooth out jump from linear to exponential + GL11.glFogi(GL11.GL_FOG_MODE, GL11.GL_LINEAR); + GL11.glFogf(GL11.GL_FOG_START, (float) ((END_MAX_DISTANCE - 20) * 0.75F * v + 20)); + GL11.glFogf(GL11.GL_FOG_END, (float) (END_MAX_DISTANCE * (0.75F + v * 0.25F))); + } + // else if ( event.fogMode < 0) { } + } + + @SubscribeEvent(priority = EventPriority.LOWEST) + public void renderGTPollutionFog(EntityViewRenderEvent.FogDensity event) { + if (!GTMod.gregtechproxy.mRenderPollutionFog) return; + + if (!DEBUG && Minecraft.getMinecraft().thePlayer.capabilities.isCreativeMode) return; + + if (event.entity.isPotionActive(Potion.blindness) || (fogIntensityLastTick < FOG_START_EXP_RATIO) + || event.block.getMaterial() == Material.water + || event.block.getMaterial() == Material.lava) return; + + GL11.glFogi(GL11.GL_FOG_MODE, GL11.GL_EXP2); + event.density = (float) Math.pow(fogIntensityLastTick - FOG_START_EXP_RATIO, .75F) / 5 + 0.01F; + event.setCanceled(true); + } + + private double lastUpdate = 0; + + @SubscribeEvent(priority = EventPriority.HIGHEST) + public void onRenderTick(TickEvent.RenderTickEvent event) { + Minecraft mc = Minecraft.getMinecraft(); + if (mc == null) return; + EntityClientPlayerMP player = mc.thePlayer; + if (player == null) return; + + if (event.phase == TickEvent.Phase.START) { + if (event.renderTickTime < lastUpdate) lastUpdate = lastUpdate - 1; + float step = (float) ((event.renderTickTime - lastUpdate) / 50); + lastUpdate = event.renderTickTime; + + float fogIntensity = (playerPollution - FOG_START_AT_POLLUTION) / (float) FOG_MAX_AT_POLLUTION; + if (fogIntensity > 1) fogIntensity = 1; + else if (fogIntensity < 0) fogIntensity = 0; + + double e = fogIntensity - fogIntensityLastTick; + if (e != 0) { + if (e > 0.2) e = 0.2D; + else if (e < -0.5) e = -0.5D; + + if (e > 0.001D || e < -0.001D) fogIntensityLastTick += step * e; + else fogIntensityLastTick = fogIntensity; + } + } else if (DEBUG) { + drawPollution("Intensity: " + (fogIntensityLastTick * 10000), 0); + drawPollution( + "Pollution: " + pollutionMap.getPollution( + Minecraft.getMinecraft().thePlayer.lastTickPosX, + Minecraft.getMinecraft().thePlayer.lastTickPosZ), + 20); + drawPollution( + "Density: " + + ((float) (Math.pow(fogIntensityLastTick - FOG_START_EXP_RATIO, .75F) / 5 + 0.01F) * 10000), + 40); + } + } + + // Adding dirt particles in the air + @SubscribeEvent(priority = EventPriority.HIGHEST) + public void onClientTick(TickEvent.ClientTickEvent event) { + if (!GTMod.gregtechproxy.mRenderDirtParticles) return; + Minecraft mc = Minecraft.getMinecraft(); + if (mc == null) return; + EntityClientPlayerMP player = mc.thePlayer; + if (player == null || (player.capabilities.isCreativeMode && !DEBUG)) return; + + World w = player.worldObj; + playerPollution = pollutionMap.getPollution(player.lastTickPosX, player.lastTickPosZ); + + float intensity = ((float) playerPollution - PARTICLES_POLLUTION_START) / PARTICLES_POLLUTION_END; + if (intensity < 0) return; + else if (intensity > 1) intensity = 1; + else intensity *= intensity; + + int x = MathHelper.floor_double(player.posX); + int y = MathHelper.floor_double(player.posY); + int z = MathHelper.floor_double(player.posZ); + + int numParticles = Math.round(intensity * PARTICLES_MAX_NUM); + + for (int l = 0; l < numParticles; ++l) { + int i1 = x + w.rand.nextInt(16) - w.rand.nextInt(16); + int j1 = y + w.rand.nextInt(16) - w.rand.nextInt(16); + int k1 = z + w.rand.nextInt(16) - w.rand.nextInt(16); + Block block = w.getBlock(i1, j1, k1); + + if (block.getMaterial() == Material.air) { + EntityFX fx = new EntityFXPollution( + w, + (float) i1 + w.rand.nextFloat(), + (float) j1 + w.rand.nextFloat(), + (float) k1 + w.rand.nextFloat()); + mc.effectRenderer.addEffect(fx); + } + } + } + + private void drawPollution(String text, int off) { + GL11.glPushMatrix(); + GL11.glEnable(GL11.GL_BLEND); + OpenGlHelper.glBlendFunc(770, 771, 1, 0); + Minecraft.getMinecraft().fontRenderer.drawStringWithShadow(text, 0, off, 0xFFFFFFFF); + GL11.glDisable(GL11.GL_BLEND); + GL11.glPopMatrix(); + } +} diff --git a/src/main/java/gregtech/common/pollution/PollutionTooltip.java b/src/main/java/gregtech/common/pollution/PollutionTooltip.java new file mode 100644 index 0000000000..0fa338a624 --- /dev/null +++ b/src/main/java/gregtech/common/pollution/PollutionTooltip.java @@ -0,0 +1,108 @@ +package gregtech.common.pollution; + +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraftforge.event.entity.player.ItemTooltipEvent; + +import cpw.mods.fml.common.eventhandler.EventPriority; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import gregtech.api.enums.Mods; +import gregtech.api.util.GTModHandler; +import gregtech.api.util.GTUtility; + +public class PollutionTooltip { + + private static final String PRODUCES_POLLUTION_FORMAT = "Produces %d Pollution/Second"; + private static final String MULTI_POLLUTION_FORMAT = "A complete Multiblock produces %d Pollution/Second"; + + @SubscribeEvent(priority = EventPriority.LOWEST) + public void getTooltip(ItemTooltipEvent event) { + if (event.itemStack == null) return; + + if (PollutionConfig.furnacesPollute) { + String furnacePollution = String.format(PRODUCES_POLLUTION_FORMAT, PollutionConfig.furnacePollutionAmount); + + // Furnace and Iron Furnace + if (GTUtility.areStacksEqual(event.itemStack, new ItemStack(Blocks.furnace)) + || GTUtility.areStacksEqual(event.itemStack, GTModHandler.getModItem("IC2", "blockMachine", 1, 1))) { + event.toolTip.add(furnacePollution); + } + + // Alchemical Furnace + if (Mods.Thaumcraft.isModLoaded()) { + if (GTUtility + .areStacksEqual(event.itemStack, GTModHandler.getModItem("Thaumcraft", "blockStoneDevice", 1, 0))) { + event.toolTip.add(furnacePollution); + } + } + + // Advanced Alchemical Furnace + if (Mods.ThaumicBases.isModLoaded()) { + if (GTUtility + .areStacksEqual(event.itemStack, GTModHandler.getModItem("thaumicbases", "advAlchFurnace", 1, 0))) { + event.toolTip.add(furnacePollution); + } + } + } + + if (Mods.Railcraft.isModLoaded() && PollutionConfig.railcraftPollutes) { + + // Solid and Liquid Boiler Firebox + if (GTUtility.areStacksEqual(event.itemStack, GTModHandler.getModItem("Railcraft", "machine.beta", 1, 5)) + || GTUtility + .areStacksEqual(event.itemStack, GTModHandler.getModItem("Railcraft", "machine.beta", 1, 6))) { + event.toolTip.add( + String.format("Produces %d Pollution/Second per firebox", PollutionConfig.fireboxPollutionAmount)); + } + + // Tunnel Bore + if (GTUtility.areStacksEqual(event.itemStack, GTModHandler.getModItem("Railcraft", "cart.bore", 1, 0))) { + event.toolTip.add(String.format(PRODUCES_POLLUTION_FORMAT, PollutionConfig.tunnelBorePollutionAmount)); + } + + // Coke Oven Brick + if (GTUtility + .areStacksEqual(event.itemStack, GTModHandler.getModItem("Railcraft", "machine.alpha", 1, 7))) { + event.toolTip.add(String.format(MULTI_POLLUTION_FORMAT, PollutionConfig.cokeOvenPollutionAmount)); + } + + // Advanced Coke Oven Brick + if (GTUtility + .areStacksEqual(event.itemStack, GTModHandler.getModItem("Railcraft", "machine.alpha", 1, 12))) { + event.toolTip + .add(String.format(MULTI_POLLUTION_FORMAT, PollutionConfig.advancedCokeOvenPollutionAmount)); + } + + // Hobbyist's Steam Engine + if (GTUtility.areStacksEqual(event.itemStack, GTModHandler.getModItem("Railcraft", "machine.beta", 1, 7))) { + event.toolTip + .add(String.format(PRODUCES_POLLUTION_FORMAT, PollutionConfig.hobbyistEnginePollutionAmount)); + } + } + + // Galacticraft (and Galaxy Space) rockets + if (Mods.GalacticraftCore.isModLoaded() && PollutionConfig.rocketsPollute + && event.itemStack.getItem() != null) { + String simpleName = event.itemStack.getItem() + .getClass() + .getSimpleName(); + // TODO I'm sure there is a better way to check the tier of a rocket.... + if (simpleName.contains("Rocket")) { + for (char d : simpleName.toCharArray()) { + if (Character.isDigit(d)) { + int tier = Character.getNumericValue(d); + event.toolTip.add( + String.format( + "Produces %d Pollution/Second when ignited", + (PollutionConfig.rocketPollutionAmount * tier / 100))); + event.toolTip.add( + String.format( + "Produces %d Pollution/Second when flying", + PollutionConfig.rocketPollutionAmount * tier)); + break; + } + } + } + } + } +} diff --git a/src/main/java/gregtech/common/render/PollutionRenderer.java b/src/main/java/gregtech/common/render/PollutionRenderer.java deleted file mode 100644 index 3b97fc820f..0000000000 --- a/src/main/java/gregtech/common/render/PollutionRenderer.java +++ /dev/null @@ -1,251 +0,0 @@ -package gregtech.common.render; - -import net.minecraft.block.Block; -import net.minecraft.block.material.Material; -import net.minecraft.client.Minecraft; -import net.minecraft.client.entity.EntityClientPlayerMP; -import net.minecraft.client.particle.EntityFX; -import net.minecraft.client.renderer.OpenGlHelper; -import net.minecraft.potion.Potion; -import net.minecraft.util.MathHelper; -import net.minecraft.world.ChunkCoordIntPair; -import net.minecraft.world.World; -import net.minecraftforge.client.event.EntityViewRenderEvent; -import net.minecraftforge.event.world.WorldEvent; - -import org.lwjgl.opengl.GL11; - -import cpw.mods.fml.common.FMLCommonHandler; -import cpw.mods.fml.common.eventhandler.EventPriority; -import cpw.mods.fml.common.eventhandler.SubscribeEvent; -import cpw.mods.fml.common.gameevent.TickEvent; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -import gregtech.GTMod; -import gregtech.common.entities.EntityFXPollution; -import gregtech.common.misc.GTClientPollutionMap; - -@SideOnly(Side.CLIENT) -public class PollutionRenderer { - - private static GTClientPollutionMap pollutionMap; - private static int playerPollution = 0; - - private static final boolean DEBUG = false; - - // PARTICLES_POLLUTION_START + PARTICLES_POLLUTION_END -> Max Particles - private static final int PARTICLES_MAX_NUM = 100; - private static final int PARTICLES_POLLUTION_START = 400000; - private static final int PARTICLES_POLLUTION_END = 3500000; - - private static final int FOG_START_AT_POLLUTION = 400000; - private static final int FOG_MAX_AT_POLLUTION = 7000000; - // jump from linear to exponential fog. x*FOG_MAX_AT_POLLUTION+FOG_START_AT_POLLUTION - private static final double FOG_START_EXP_RATIO = 0.02D; - - private static final float[] fogColor = { 0.3f, 0.25f, 0.1f }; - private static final short[] grassColor = { 230, 180, 40 }; - private static final short[] leavesColor = { 160, 80, 15 }; - private static final short[] liquidColor = { 160, 200, 10 }; - private static final short[] foliageColor = { 160, 80, 15 }; - - // TODO need to soft update some blocks, grass and leaves does more often than liquid it looks like. - - public PollutionRenderer() { - pollutionMap = new GTClientPollutionMap(); - } - - public void preLoad() { - net.minecraftforge.common.MinecraftForge.EVENT_BUS.register(this); - FMLCommonHandler.instance() - .bus() - .register(this); - } - - public void processPacket(ChunkCoordIntPair chunk, int pollution) { - pollutionMap.addChunkPollution(chunk.chunkXPos, chunk.chunkZPos, pollution); - } - - @SubscribeEvent(priority = EventPriority.HIGH) - public void enteredWorld(WorldEvent.Load event) { - EntityClientPlayerMP p = Minecraft.getMinecraft().thePlayer; - if (!event.world.isRemote || p == null) return; - pollutionMap.reset(); - } - - private static int color(int color, int pollution, int low, float high, short[] colors) { - if (pollution < low) return color; - - int r = (color >> 16) & 0xFF; - int g = (color >> 8) & 0xFF; - int b = color & 0xFF; - float p = (pollution - low) / high; - if (p > 1) p = 1; - float pi = 1 - p; - - r = ((int) (r * pi + p * colors[0])) & 0xFF; - g = ((int) (g * pi + p * colors[1])) & 0xFF; - b = ((int) (b * pi + p * colors[2])) & 0xFF; - - return (r & 0xFF) << 16 | (g & 0xFF) << 8 | b & 0xFF; - } - - // Methods for hodgepodge to color grass / foliage blocks etc. - public static int colorGrass(int oColor, int x, int z) { - return color(oColor, pollutionMap.getPollution(x, z) / 1000, 350, 600, grassColor); - } - - public static int colorLeaves(int oColor, int x, int z) { - return color(oColor, pollutionMap.getPollution(x, z) / 1000, 300, 500, leavesColor); - } - - public static int colorLiquid(int oColor, int x, int z) { - return color(oColor, pollutionMap.getPollution(x, z) / 1000, 300, 500, liquidColor); - } - - public static int colorFoliage(int oColor, int x, int z) { - return color(oColor, pollutionMap.getPollution(x, z) / 1000, 300, 500, foliageColor); - } - - public static int getKnownPollution(int x, int z) { - return pollutionMap.getPollution(x, z); - } - - @SubscribeEvent(priority = EventPriority.LOW) - public void manipulateColor(EntityViewRenderEvent.FogColors event) { - if (!DEBUG && Minecraft.getMinecraft().thePlayer.capabilities.isCreativeMode) return; - - if (event.block.getMaterial() == Material.water || event.block.getMaterial() == Material.lava) return; - - float x = fogIntensityLastTick > 1 ? 1F : (float) fogIntensityLastTick; - float xi = 1 - x; - - event.red = xi * event.red + x * fogColor[0]; - event.green = xi * event.green + x * fogColor[1]; - event.blue = xi * event.blue + x * fogColor[2]; - } - - private static final int END_MAX_DISTANCE = 192 - 1; - private static double fogIntensityLastTick = 0; - - @SubscribeEvent(priority = EventPriority.LOWEST) - public void renderGTPollutionFog(EntityViewRenderEvent.RenderFogEvent event) { - if (!GTMod.gregtechproxy.mRenderPollutionFog) return; - - if ((!DEBUG && Minecraft.getMinecraft().thePlayer.capabilities.isCreativeMode) - || (fogIntensityLastTick < FOG_START_EXP_RATIO)) return; - - if (event.fogMode == 0) { - double v = 1 - fogIntensityLastTick / FOG_START_EXP_RATIO; - // trying to smooth out jump from linear to exponential - GL11.glFogi(GL11.GL_FOG_MODE, GL11.GL_LINEAR); - GL11.glFogf(GL11.GL_FOG_START, (float) ((END_MAX_DISTANCE - 20) * 0.75F * v + 20)); - GL11.glFogf(GL11.GL_FOG_END, (float) (END_MAX_DISTANCE * (0.75F + v * 0.25F))); - } - // else if ( event.fogMode < 0) { } - } - - @SubscribeEvent(priority = EventPriority.LOWEST) - public void renderGTPollutionFog(EntityViewRenderEvent.FogDensity event) { - if (!GTMod.gregtechproxy.mRenderPollutionFog) return; - - if (!DEBUG && Minecraft.getMinecraft().thePlayer.capabilities.isCreativeMode) return; - - if (event.entity.isPotionActive(Potion.blindness) || (fogIntensityLastTick < FOG_START_EXP_RATIO) - || event.block.getMaterial() == Material.water - || event.block.getMaterial() == Material.lava) return; - - GL11.glFogi(GL11.GL_FOG_MODE, GL11.GL_EXP2); - event.density = (float) Math.pow(fogIntensityLastTick - FOG_START_EXP_RATIO, .75F) / 5 + 0.01F; - event.setCanceled(true); - } - - private double lastUpdate = 0; - - @SubscribeEvent(priority = EventPriority.HIGHEST) - public void onRenderTick(TickEvent.RenderTickEvent event) { - Minecraft mc = Minecraft.getMinecraft(); - if (mc == null) return; - EntityClientPlayerMP player = mc.thePlayer; - if (player == null) return; - - if (event.phase == TickEvent.Phase.START) { - if (event.renderTickTime < lastUpdate) lastUpdate = lastUpdate - 1; - float step = (float) ((event.renderTickTime - lastUpdate) / 50); - lastUpdate = event.renderTickTime; - - float fogIntensity = (playerPollution - FOG_START_AT_POLLUTION) / (float) FOG_MAX_AT_POLLUTION; - if (fogIntensity > 1) fogIntensity = 1; - else if (fogIntensity < 0) fogIntensity = 0; - - double e = fogIntensity - fogIntensityLastTick; - if (e != 0) { - if (e > 0.2) e = 0.2D; - else if (e < -0.5) e = -0.5D; - - if (e > 0.001D || e < -0.001D) fogIntensityLastTick += step * e; - else fogIntensityLastTick = fogIntensity; - } - } else if (DEBUG) { - drawPollution("Intensity: " + (fogIntensityLastTick * 10000), 0); - drawPollution( - "Pollution: " + pollutionMap.getPollution( - Minecraft.getMinecraft().thePlayer.lastTickPosX, - Minecraft.getMinecraft().thePlayer.lastTickPosZ), - 20); - drawPollution( - "Density: " - + ((float) (Math.pow(fogIntensityLastTick - FOG_START_EXP_RATIO, .75F) / 5 + 0.01F) * 10000), - 40); - } - } - - // Adding dirt particles in the air - @SubscribeEvent(priority = EventPriority.HIGHEST) - public void onClientTick(TickEvent.ClientTickEvent event) { - if (!GTMod.gregtechproxy.mRenderDirtParticles) return; - Minecraft mc = Minecraft.getMinecraft(); - if (mc == null) return; - EntityClientPlayerMP player = mc.thePlayer; - if (player == null || (player.capabilities.isCreativeMode && !DEBUG)) return; - - World w = player.worldObj; - playerPollution = pollutionMap.getPollution(player.lastTickPosX, player.lastTickPosZ); - - float intensity = ((float) playerPollution - PARTICLES_POLLUTION_START) / PARTICLES_POLLUTION_END; - if (intensity < 0) return; - else if (intensity > 1) intensity = 1; - else intensity *= intensity; - - int x = MathHelper.floor_double(player.posX); - int y = MathHelper.floor_double(player.posY); - int z = MathHelper.floor_double(player.posZ); - - int numParticles = Math.round(intensity * PARTICLES_MAX_NUM); - - for (int l = 0; l < numParticles; ++l) { - int i1 = x + w.rand.nextInt(16) - w.rand.nextInt(16); - int j1 = y + w.rand.nextInt(16) - w.rand.nextInt(16); - int k1 = z + w.rand.nextInt(16) - w.rand.nextInt(16); - Block block = w.getBlock(i1, j1, k1); - - if (block.getMaterial() == Material.air) { - EntityFX fx = new EntityFXPollution( - w, - (float) i1 + w.rand.nextFloat(), - (float) j1 + w.rand.nextFloat(), - (float) k1 + w.rand.nextFloat()); - mc.effectRenderer.addEffect(fx); - } - } - } - - private void drawPollution(String text, int off) { - GL11.glPushMatrix(); - GL11.glEnable(GL11.GL_BLEND); - OpenGlHelper.glBlendFunc(770, 771, 1, 0); - Minecraft.getMinecraft().fontRenderer.drawStringWithShadow(text, 0, off, 0xFFFFFFFF); - GL11.glDisable(GL11.GL_BLEND); - GL11.glPopMatrix(); - } -} diff --git a/src/main/java/gregtech/common/tileentities/boilers/MTEBoiler.java b/src/main/java/gregtech/common/tileentities/boilers/MTEBoiler.java index b49da44e97..a84cb8ac91 100644 --- a/src/main/java/gregtech/common/tileentities/boilers/MTEBoiler.java +++ b/src/main/java/gregtech/common/tileentities/boilers/MTEBoiler.java @@ -41,7 +41,7 @@ import gregtech.api.util.GTLog; import gregtech.api.util.GTModHandler; import gregtech.api.util.GTUtility; import gregtech.api.util.WorldSpawnedEventBuilder.ParticleEventBuilder; -import gregtech.common.Pollution; +import gregtech.common.pollution.Pollution; public abstract class MTEBoiler extends MTEBasicTank implements IGetTitleColor, IAddUIWidgets { diff --git a/src/main/java/gregtech/common/tileentities/boilers/MTEBoilerBronze.java b/src/main/java/gregtech/common/tileentities/boilers/MTEBoilerBronze.java index e951656d23..632ff0ac1f 100644 --- a/src/main/java/gregtech/common/tileentities/boilers/MTEBoilerBronze.java +++ b/src/main/java/gregtech/common/tileentities/boilers/MTEBoilerBronze.java @@ -36,7 +36,7 @@ import gregtech.api.render.TextureFactory; import gregtech.api.util.GTOreDictUnificator; import gregtech.api.util.GTUtility; import gregtech.api.util.WorldSpawnedEventBuilder.ParticleEventBuilder; -import gregtech.common.Pollution; +import gregtech.common.pollution.Pollution; public class MTEBoilerBronze extends MTEBoiler { diff --git a/src/main/java/gregtech/common/tileentities/machines/multi/MTECharcoalPit.java b/src/main/java/gregtech/common/tileentities/machines/multi/MTECharcoalPit.java index bfa672577d..f39ea70422 100644 --- a/src/main/java/gregtech/common/tileentities/machines/multi/MTECharcoalPit.java +++ b/src/main/java/gregtech/common/tileentities/machines/multi/MTECharcoalPit.java @@ -35,7 +35,7 @@ import gregtech.api.recipe.check.CheckRecipeResultRegistry; import gregtech.api.render.TextureFactory; import gregtech.api.util.MultiblockTooltipBuilder; import gregtech.api.util.WorldSpawnedEventBuilder; -import gregtech.common.Pollution; +import gregtech.common.pollution.Pollution; public class MTECharcoalPit extends MTETooltipMultiBlockBase implements ISecondaryDescribable { diff --git a/src/main/java/gregtech/common/tileentities/machines/multi/MTEPrimitiveBlastFurnace.java b/src/main/java/gregtech/common/tileentities/machines/multi/MTEPrimitiveBlastFurnace.java index 0011a0efad..9c92733322 100644 --- a/src/main/java/gregtech/common/tileentities/machines/multi/MTEPrimitiveBlastFurnace.java +++ b/src/main/java/gregtech/common/tileentities/machines/multi/MTEPrimitiveBlastFurnace.java @@ -49,7 +49,7 @@ import gregtech.api.util.GTRecipe; import gregtech.api.util.GTUtility; import gregtech.api.util.WorldSpawnedEventBuilder; import gregtech.api.util.WorldSpawnedEventBuilder.ParticleEventBuilder; -import gregtech.common.Pollution; +import gregtech.common.pollution.Pollution; public abstract class MTEPrimitiveBlastFurnace extends MetaTileEntity implements IAlignment, ISurvivalConstructable, RecipeMapWorkable, IAddUIWidgets, IGetTitleColor { diff --git a/src/main/java/gregtech/loaders/preload/GTPreLoad.java b/src/main/java/gregtech/loaders/preload/GTPreLoad.java index bef36a2bdb..a3d6572dd9 100644 --- a/src/main/java/gregtech/loaders/preload/GTPreLoad.java +++ b/src/main/java/gregtech/loaders/preload/GTPreLoad.java @@ -45,6 +45,7 @@ import gregtech.common.config.Gregtech; import gregtech.common.config.MachineStats; import gregtech.common.config.OPStuff; import gregtech.common.config.Worldgen; +import gregtech.common.pollution.PollutionConfig; import gregtech.common.tileentities.machines.long_distance.MTELongDistancePipelineBase; public class GTPreLoad { @@ -445,31 +446,31 @@ public class GTPreLoad { loadClientConfig(); // Pollution - GTMod.gregtechproxy.mPollution = Gregtech.pollution.pollution; - GTMod.gregtechproxy.mPollutionSmogLimit = Gregtech.pollution.pollutionSmogLimit; - GTMod.gregtechproxy.mPollutionPoisonLimit = Gregtech.pollution.pollutionPoisonLimit; - GTMod.gregtechproxy.mPollutionVegetationLimit = Gregtech.pollution.pollutionVegetationLimit; - GTMod.gregtechproxy.mPollutionSourRainLimit = Gregtech.pollution.pollutionSourRainLimit; - GTMod.gregtechproxy.mPollutionOnExplosion = Gregtech.pollution.pollutionOnExplosion; - GTMod.gregtechproxy.mPollutionPrimitveBlastFurnacePerSecond = Gregtech.pollution.pollutionPrimitveBlastFurnacePerSecond; - GTMod.gregtechproxy.mPollutionCharcoalPitPerSecond = Gregtech.pollution.pollutionCharcoalPitPerSecond; - GTMod.gregtechproxy.mPollutionEBFPerSecond = Gregtech.pollution.pollutionEBFPerSecond; - GTMod.gregtechproxy.mPollutionLargeCombustionEnginePerSecond = Gregtech.pollution.pollutionLargeCombustionEnginePerSecond; - GTMod.gregtechproxy.mPollutionExtremeCombustionEnginePerSecond = Gregtech.pollution.pollutionExtremeCombustionEnginePerSecond; - GTMod.gregtechproxy.mPollutionImplosionCompressorPerSecond = Gregtech.pollution.pollutionImplosionCompressorPerSecond; - GTMod.gregtechproxy.mPollutionLargeBronzeBoilerPerSecond = Gregtech.pollution.pollutionLargeBronzeBoilerPerSecond; - GTMod.gregtechproxy.mPollutionLargeSteelBoilerPerSecond = Gregtech.pollution.pollutionLargeSteelBoilerPerSecond; - GTMod.gregtechproxy.mPollutionLargeTitaniumBoilerPerSecond = Gregtech.pollution.pollutionLargeTitaniumBoilerPerSecond; - GTMod.gregtechproxy.mPollutionLargeTungstenSteelBoilerPerSecond = Gregtech.pollution.pollutionLargeTungstenSteelBoilerPerSecond; - GTMod.gregtechproxy.mPollutionReleasedByThrottle = Gregtech.pollution.pollutionReleasedByThrottle; - GTMod.gregtechproxy.mPollutionLargeGasTurbinePerSecond = Gregtech.pollution.pollutionLargeGasTurbinePerSecond; - GTMod.gregtechproxy.mPollutionMultiSmelterPerSecond = Gregtech.pollution.pollutionMultiSmelterPerSecond; - GTMod.gregtechproxy.mPollutionPyrolyseOvenPerSecond = Gregtech.pollution.pollutionPyrolyseOvenPerSecond; - GTMod.gregtechproxy.mPollutionSmallCoalBoilerPerSecond = Gregtech.pollution.pollutionSmallCoalBoilerPerSecond; - GTMod.gregtechproxy.mPollutionHighPressureLavaBoilerPerSecond = Gregtech.pollution.pollutionHighPressureLavaBoilerPerSecond; - GTMod.gregtechproxy.mPollutionHighPressureCoalBoilerPerSecond = Gregtech.pollution.pollutionHighPressureCoalBoilerPerSecond; - GTMod.gregtechproxy.mPollutionBaseDieselGeneratorPerSecond = Gregtech.pollution.pollutionBaseDieselGeneratorPerSecond; - double[] mPollutionDieselGeneratorReleasedByTier = Gregtech.pollution.pollutionDieselGeneratorReleasedByTier; + GTMod.gregtechproxy.mPollution = PollutionConfig.pollution; + GTMod.gregtechproxy.mPollutionSmogLimit = PollutionConfig.pollutionSmogLimit; + GTMod.gregtechproxy.mPollutionPoisonLimit = PollutionConfig.pollutionPoisonLimit; + GTMod.gregtechproxy.mPollutionVegetationLimit = PollutionConfig.pollutionVegetationLimit; + GTMod.gregtechproxy.mPollutionSourRainLimit = PollutionConfig.pollutionSourRainLimit; + GTMod.gregtechproxy.mPollutionOnExplosion = PollutionConfig.pollutionOnExplosion; + GTMod.gregtechproxy.mPollutionPrimitveBlastFurnacePerSecond = PollutionConfig.pollutionPrimitveBlastFurnacePerSecond; + GTMod.gregtechproxy.mPollutionCharcoalPitPerSecond = PollutionConfig.pollutionCharcoalPitPerSecond; + GTMod.gregtechproxy.mPollutionEBFPerSecond = PollutionConfig.pollutionEBFPerSecond; + GTMod.gregtechproxy.mPollutionLargeCombustionEnginePerSecond = PollutionConfig.pollutionLargeCombustionEnginePerSecond; + GTMod.gregtechproxy.mPollutionExtremeCombustionEnginePerSecond = PollutionConfig.pollutionExtremeCombustionEnginePerSecond; + GTMod.gregtechproxy.mPollutionImplosionCompressorPerSecond = PollutionConfig.pollutionImplosionCompressorPerSecond; + GTMod.gregtechproxy.mPollutionLargeBronzeBoilerPerSecond = PollutionConfig.pollutionLargeBronzeBoilerPerSecond; + GTMod.gregtechproxy.mPollutionLargeSteelBoilerPerSecond = PollutionConfig.pollutionLargeSteelBoilerPerSecond; + GTMod.gregtechproxy.mPollutionLargeTitaniumBoilerPerSecond = PollutionConfig.pollutionLargeTitaniumBoilerPerSecond; + GTMod.gregtechproxy.mPollutionLargeTungstenSteelBoilerPerSecond = PollutionConfig.pollutionLargeTungstenSteelBoilerPerSecond; + GTMod.gregtechproxy.mPollutionReleasedByThrottle = PollutionConfig.pollutionReleasedByThrottle; + GTMod.gregtechproxy.mPollutionLargeGasTurbinePerSecond = PollutionConfig.pollutionLargeGasTurbinePerSecond; + GTMod.gregtechproxy.mPollutionMultiSmelterPerSecond = PollutionConfig.pollutionMultiSmelterPerSecond; + GTMod.gregtechproxy.mPollutionPyrolyseOvenPerSecond = PollutionConfig.pollutionPyrolyseOvenPerSecond; + GTMod.gregtechproxy.mPollutionSmallCoalBoilerPerSecond = PollutionConfig.pollutionSmallCoalBoilerPerSecond; + GTMod.gregtechproxy.mPollutionHighPressureLavaBoilerPerSecond = PollutionConfig.pollutionHighPressureLavaBoilerPerSecond; + GTMod.gregtechproxy.mPollutionHighPressureCoalBoilerPerSecond = PollutionConfig.pollutionHighPressureCoalBoilerPerSecond; + GTMod.gregtechproxy.mPollutionBaseDieselGeneratorPerSecond = PollutionConfig.pollutionBaseDieselGeneratorPerSecond; + double[] mPollutionDieselGeneratorReleasedByTier = PollutionConfig.pollutionDieselGeneratorReleasedByTier; if (mPollutionDieselGeneratorReleasedByTier.length == GTMod.gregtechproxy.mPollutionDieselGeneratorReleasedByTier.length) { GTMod.gregtechproxy.mPollutionDieselGeneratorReleasedByTier = mPollutionDieselGeneratorReleasedByTier; @@ -477,8 +478,8 @@ public class GTPreLoad { GT_FML_LOGGER .error("The Length of the Diesel Turbine Pollution Array Config must be the same as the Default"); } - GTMod.gregtechproxy.mPollutionBaseGasTurbinePerSecond = Gregtech.pollution.pollutionBaseGasTurbinePerSecond; - double[] mPollutionGasTurbineReleasedByTier = Gregtech.pollution.pollutionGasTurbineReleasedByTier; + GTMod.gregtechproxy.mPollutionBaseGasTurbinePerSecond = PollutionConfig.pollutionBaseGasTurbinePerSecond; + double[] mPollutionGasTurbineReleasedByTier = PollutionConfig.pollutionGasTurbineReleasedByTier; if (mPollutionGasTurbineReleasedByTier.length == GTMod.gregtechproxy.mPollutionGasTurbineReleasedByTier.length) { GTMod.gregtechproxy.mPollutionGasTurbineReleasedByTier = mPollutionGasTurbineReleasedByTier; diff --git a/src/main/java/gregtech/mixin/Mixin.java b/src/main/java/gregtech/mixin/Mixin.java index b9ba1db098..001477b5d1 100644 --- a/src/main/java/gregtech/mixin/Mixin.java +++ b/src/main/java/gregtech/mixin/Mixin.java @@ -14,6 +14,7 @@ import org.apache.logging.log4j.Logger; import bartworks.common.configs.Configuration; import cpw.mods.fml.relauncher.FMLLaunchHandler; +import gregtech.common.pollution.PollutionConfig; public enum Mixin { @@ -64,7 +65,73 @@ public enum Mixin { .addTargetedMod(TargetedMod.IC2) .setApplyIf(() -> true) .setPhase(Phase.LATE) - .setSide(Side.BOTH)); + .setSide(Side.BOTH)), + IC2_HAZMAT(new Builder("Hazmat").setPhase(Phase.LATE) + .setSide(Side.BOTH) + .addMixinClasses("ic2.MixinIc2Hazmat") + .setApplyIf(() -> true) + .addTargetedMod(TargetedMod.IC2) + .addExcludedMod(TargetedMod.GT6)), + + // Pollution + POLLUTION_RENDER_BLOCKS(new Builder("Changes colors of certain blocks based on pollution levels") + .addMixinClasses("minecraft.pollution.MixinRenderBlocks_PollutionWithoutOptifine") + .addTargetedMod(TargetedMod.VANILLA) + .addExcludedMod(TargetedMod.OPTIFINE) + .setSide(Side.CLIENT) + .setApplyIf(() -> PollutionConfig.pollution && PollutionConfig.pollutionBlockRecolor) + .setPhase(Phase.EARLY)), + POLLUTION_RENDER_BLOCKS_OPTIFINE(new Builder("Changes colors of certain blocks based on pollution levels") + .addMixinClasses("minecraft.pollution.MixinRenderBlocks_PollutionWithOptifine") + .addTargetedMod(TargetedMod.VANILLA) + .addTargetedMod(TargetedMod.OPTIFINE) + .addExcludedMod(TargetedMod.ANGELICA) + .setSide(Side.CLIENT) + .setApplyIf(() -> PollutionConfig.pollution && PollutionConfig.pollutionBlockRecolor) + .setPhase(Phase.EARLY)), + POLLUTION_RENDER_BLOCKS_BOP(new Builder("Changes colors of certain blocks based on pollution levels") + .addMixinClasses("biomesoplenty.MixinFoliageRendererPollution") + .addTargetedMod(TargetedMod.BOP) + .setSide(Side.CLIENT) + .setApplyIf(() -> PollutionConfig.pollution && PollutionConfig.pollutionBlockRecolor) + .setPhase(Phase.LATE)), + POLLUTION_MINECRAFT_FURNACE(new Builder("Minecraft Furnace Pollutes").setPhase(Phase.EARLY) + .addMixinClasses("minecraft.pollution.MixinTileEntityFurnacePollution") + .setSide(Side.BOTH) + .setApplyIf(() -> PollutionConfig.pollution && PollutionConfig.furnacesPollute) + .addTargetedMod(TargetedMod.VANILLA)), + POLLUTION_MINECRAFT_EXPLOSION(new Builder("Minecraft explosions pollute").setPhase(Phase.EARLY) + .addMixinClasses("minecraft.pollution.MixinExplosionPollution") + .setSide(Side.BOTH) + .setApplyIf(() -> PollutionConfig.pollution && PollutionConfig.explosionPollutionAmount != 0F) + .addTargetedMod(TargetedMod.VANILLA)), + POLLUTION_IC2_IRON_FURNACE( + new Builder("Ic2 Iron Furnace Pollutes").addMixinClasses("ic2.MixinIC2IronFurnacePollution") + .setPhase(Phase.LATE) + .setSide(Side.BOTH) + .setApplyIf(() -> PollutionConfig.pollution && PollutionConfig.furnacesPollute) + .addTargetedMod(TargetedMod.IC2)), + POLLUTION_THAUMCRAFT_ALCHEMICAL_FURNACE(new Builder("Thaumcraft Alchemical Construct Pollutes") + .addMixinClasses("thaumcraft.MixinThaumcraftAlchemyFurnacePollution") + .setPhase(Phase.LATE) + .setSide(Side.BOTH) + .setApplyIf(() -> PollutionConfig.pollution && PollutionConfig.furnacesPollute) + .addTargetedMod(TargetedMod.THAUMCRAFT)), + POLLUTION_RAILCRAFT(new Builder("Make Railcraft Pollute") + .addMixinClasses( + "railcraft.MixinRailcraftBoilerPollution", + "railcraft.MixinRailcraftCokeOvenPollution", + "railcraft.MixinRailcraftTunnelBorePollution") + .setPhase(Phase.LATE) + .setSide(Side.BOTH) + .setApplyIf(() -> PollutionConfig.pollution && PollutionConfig.railcraftPollutes) + .addTargetedMod(TargetedMod.RAILCRAFT)), + POLLUTION_ROCKET( + new Builder("Make Rockets Pollute").addMixinClasses("galacticraftcore.MixinGalacticraftRocketPollution") + .setPhase(Phase.LATE) + .setSide(Side.BOTH) + .setApplyIf(() -> PollutionConfig.pollution && PollutionConfig.rocketsPollute) + .addTargetedMod(TargetedMod.GALACTICRAFT_CORE)); public static final Logger LOGGER = LogManager.getLogger("GregTech-Mixin"); -- cgit