aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/gregtech/common/tileentities/boilers/MTEBoilerBronze.java
blob: e951656d23762c96e858aa70d8ebe7dc387350ca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
package gregtech.common.tileentities.boilers;

import static gregtech.api.enums.Textures.BlockIcons.BOILER_FRONT;
import static gregtech.api.enums.Textures.BlockIcons.BOILER_FRONT_ACTIVE;
import static gregtech.api.enums.Textures.BlockIcons.BOILER_FRONT_ACTIVE_GLOW;
import static gregtech.api.enums.Textures.BlockIcons.BOILER_FRONT_GLOW;
import static gregtech.api.enums.Textures.BlockIcons.MACHINE_BRONZEBRICKS_BOTTOM;
import static gregtech.api.enums.Textures.BlockIcons.MACHINE_BRONZEBRICKS_SIDE;
import static gregtech.api.enums.Textures.BlockIcons.MACHINE_BRONZEBRICKS_TOP;
import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_PIPE;
import static gregtech.api.objects.XSTR.XSTR_INSTANCE;

import java.util.Optional;
import java.util.stream.Stream;

import net.minecraft.block.Block;
import net.minecraft.init.Blocks;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntityFurnace;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.fluids.FluidContainerRegistry;

import org.jetbrains.annotations.NotNull;

import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import gregtech.GTMod;
import gregtech.api.enums.Materials;
import gregtech.api.enums.OrePrefixes;
import gregtech.api.enums.ParticleFX;
import gregtech.api.interfaces.ITexture;
import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
import gregtech.api.metatileentity.MetaTileEntity;
import gregtech.api.objects.XSTR;
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;

public class MTEBoilerBronze extends MTEBoiler {

    public MTEBoilerBronze(int aID, String aName, String aNameRegional) {
        super(
            aID,
            aName,
            aNameRegional,
            new String[] { "An early way to get Steam Power", "Produces 120L of Steam per second",
                "Causes " + GTMod.gregtechproxy.mPollutionSmallCoalBoilerPerSecond + " Pollution per second" });
    }

    public MTEBoilerBronze(int aID, String aName, String aNameRegional, String[] aDescription) {
        super(aID, aName, aNameRegional, aDescription);
    }

    public MTEBoilerBronze(String aName, int aTier, String aDescription, ITexture[][][] aTextures) {
        super(aName, aTier, aDescription, aTextures);
    }

    public MTEBoilerBronze(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) {
        super(aName, aTier, aDescription, aTextures);
    }

    @Override
    public ITexture[][][] getTextureSet(ITexture[] aTextures) {
        ITexture[][][] rTextures = new ITexture[5][17][];
        final ITexture[] texBottom = { TextureFactory.of(MACHINE_BRONZEBRICKS_BOTTOM) },
            texTop = { TextureFactory.of(MACHINE_BRONZEBRICKS_TOP), TextureFactory.of(OVERLAY_PIPE) },
            texSide = { TextureFactory.of(MACHINE_BRONZEBRICKS_SIDE), TextureFactory.of(OVERLAY_PIPE) },
            texFront = { TextureFactory.of(MACHINE_BRONZEBRICKS_SIDE), TextureFactory.of(BOILER_FRONT),
                TextureFactory.builder()
                    .addIcon(BOILER_FRONT_GLOW)
                    .glow()
                    .build() },
            texFrontActive = { TextureFactory.of(MACHINE_BRONZEBRICKS_SIDE), TextureFactory.of(BOILER_FRONT_ACTIVE),
                TextureFactory.builder()
                    .addIcon(BOILER_FRONT_ACTIVE_GLOW)
                    .glow()
                    .build() };
        for (int i = 0; i < 17; i++) {
            rTextures[0][i] = texBottom;
            rTextures[1][i] = texTop;
            rTextures[2][i] = texSide;
            rTextures[3][i] = texFront;
            rTextures[4][i] = texFrontActive;
        }
        return rTextures;
    }

    @Override
    public MetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) {
        return new MTEBoilerBronze(this.mName, this.mTier, this.mDescriptionArray, this.mTextures);
    }

    /**
     * Draws random flames and smoke particles in front of active boiler
     *
     * @param aBaseMetaTileEntity The entity that will handle the {@link Block#randomDisplayTick}
     */
    @SideOnly(Side.CLIENT)
    @Override
    public void onRandomDisplayTick(IGregTechTileEntity aBaseMetaTileEntity) {
        if (aBaseMetaTileEntity.isActive()) {

            final ForgeDirection frontFacing = aBaseMetaTileEntity.getFrontFacing();

            if ((frontFacing.flag & (ForgeDirection.UP.flag | ForgeDirection.DOWN.flag)) == 0
                && aBaseMetaTileEntity.getCoverIDAtSide(frontFacing) == 0
                && !aBaseMetaTileEntity.getOpacityAtSide(frontFacing)) {

                final double oX = aBaseMetaTileEntity.getOffsetX(frontFacing, 1) + 8D / 16D;
                final double oY = aBaseMetaTileEntity.getOffsetY(frontFacing, 1);
                final double oZ = aBaseMetaTileEntity.getOffsetZ(frontFacing, 1) + 8D / 16D;
                final double offset = -0.48D;
                final double horizontal = XSTR_INSTANCE.nextFloat() * 10D / 16D - 5D / 16D;

                final double x, y, z;

                y = oY + XSTR_INSTANCE.nextFloat() * 6D / 16D;

                if (frontFacing == ForgeDirection.WEST) {
                    x = oX - offset;
                    z = oZ + horizontal;
                } else if (frontFacing == ForgeDirection.EAST) {
                    x = oX + offset;
                    z = oZ + horizontal;
                } else if (frontFacing == ForgeDirection.NORTH) {
                    x = oX + horizontal;
                    z = oZ - offset;
                } else // if (frontFacing == ForgeDirection.SOUTH)
                {
                    x = oX + horizontal;
                    z = oZ + offset;
                }

                ParticleEventBuilder particleEventBuilder = (new ParticleEventBuilder()).setMotion(0D, 0D, 0D)
                    .setPosition(x, y, z)
                    .setWorld(getBaseMetaTileEntity().getWorld());
                particleEventBuilder.setIdentifier(ParticleFX.SMOKE)
                    .run();
                particleEventBuilder.setIdentifier(ParticleFX.FLAME)
                    .run();
            }
        }
    }

    @Override
    public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) {
        super.onPostTick(aBaseMetaTileEntity, aTick);
        if ((aBaseMetaTileEntity.isServerSide()) && (aTick > 20L)
            && this.mProcessingEnergy > 0
            && (aTick % 20L == 0L)) {
            Pollution.addPollution(getBaseMetaTileEntity(), getPollution());
        }
    }

    @Override
    protected int getPollution() {
        return GTMod.gregtechproxy.mPollutionSmallCoalBoilerPerSecond;
    }

    @Override
    protected int getProductionPerSecond() {
        return 120;
    }

    @Override
    protected int getMaxTemperature() {
        return 500;
    }

    @Override
    protected int getEnergyConsumption() {
        return 1;
    }

    @Override
    protected int getCooldownInterval() {
        return 45;
    }

    @Override
    protected void updateFuel(IGregTechTileEntity aBaseMetaTileEntity, long aTick) {
        ItemStack fuel = mInventory[2];
        int burnTime = TileEntityFurnace.getItemBurnTime(fuel);
        getCombustionPotential(fuel, burnTime).ifPresent(ashMaterial -> {
            aBaseMetaTileEntity.decrStackSize(2, 1);
            this.mProcessingEnergy += burnTime / 10;
            boolean isABlock = !Block.getBlockFromItem(fuel.getItem())
                .equals(Blocks.air);
            combustFuel(burnTime, isABlock).map(dustSize -> GTOreDictUnificator.get(dustSize, ashMaterial, 1L))
                .ifPresent(ashes -> aBaseMetaTileEntity.addStackToSlot(3, ashes));
        });
    }

    private static Optional<Materials> getCombustionPotential(ItemStack fuel, int burnTime) {
        if (burnTime / 10 <= 0 || FluidContainerRegistry.isFilledContainer(fuel)) {
            return Optional.empty();
        }
        String lowerCaseBlockName = Block.getBlockFromItem(fuel.getItem())
            .getUnlocalizedName()
            .toLowerCase();
        if (couldProduceDarkAshes(fuel, lowerCaseBlockName)) {
            return Optional.of(Materials.DarkAsh);
        }
        if (couldProduceRegularAshes(fuel, lowerCaseBlockName, burnTime)) {
            return Optional.of(Materials.Ash);
        }
        return Optional.empty();
    }

    private static boolean couldProduceDarkAshes(ItemStack fuel, String lowerCaseBlockName) {
        return GTUtility.isPartOfMaterials(fuel, Materials.Coal) || GTUtility.isPartOfMaterials(fuel, Materials.Lignite)
            || lowerCaseBlockName.matches("tile\\..+compressedcoal");
    }

    private static boolean couldProduceRegularAshes(ItemStack fuel, String lowerCaseBlockName, int burnTime) {
        return GTUtility.isPartOfMaterials(fuel, Materials.Charcoal)
            || GTUtility.isPartOfMaterials(fuel, Materials.Diamond)
            || (Stream.of("^tile\\..+charcoal", "^tile\\..+coke", "^tile\\..+railcraft.cube")
                .anyMatch(lowerCaseBlockName::matches))
            || Stream.of("fuelCoke", "fuelCactusCharcoal", "fuelCactusCoke", "fuelSugarCharcoal", "fuelSugarCoke")
                .anyMatch(name -> GTOreDictUnificator.isItemStackInstanceOf(fuel, name))
            || burnTime >= 2000;
    }

    private static Optional<OrePrefixes> combustFuel(int burnTime, boolean isABlock) {
        if (isABlock) {
            return Optional.of(OrePrefixes.dust);
        } else if (XSTR.XSTR_INSTANCE.nextInt(getAshChanceBound(burnTime)) == 0) {
            if (burnTime > 100000) {
                return Optional.of(OrePrefixes.dust);
            } else if (burnTime > 10000) {
                return Optional.of(OrePrefixes.dustSmall);
            } else {
                return Optional.of(OrePrefixes.dustTiny);
            }
        }
        return Optional.empty();
    }

    /**
     * The upper bound for the chance to get ash from combustion
     * <br>
     * Ash chance scales based on burn time from 14% at 0 up to 50% at 2000
     *
     * @param burnTime number assumed to be positive
     * @return an upper bound between 7 and 2.
     */
    private static int getAshChanceBound(int burnTime) {
        return (5 - (Math.min(burnTime, 2000) / 400)) + 2;
    }

    @Override
    protected boolean isItemValidFuel(@NotNull ItemStack stack) {
        return getCombustionPotential(stack, TileEntityFurnace.getItemBurnTime(stack)).isPresent();
    }

}