package tectech.thing.metaTileEntity.single; import static gregtech.api.enums.GTValues.V; import static java.lang.Math.round; import static net.minecraft.util.StatCollector.translateToLocal; import static net.minecraft.util.StatCollector.translateToLocalFormatted; import java.util.Arrays; import java.util.HashSet; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.EnumChatFormatting; import net.minecraftforge.common.util.ForgeDirection; import org.apache.commons.lang3.ArrayUtils; import com.google.common.collect.Multimap; import com.google.common.collect.MultimapBuilder; import com.gtnewhorizon.structurelib.util.Vec3Impl; import eu.usrv.yamcore.auxiliary.PlayerChatHelper; import gregtech.api.gui.modularui.GTUIInfos; import gregtech.api.interfaces.ITexture; import gregtech.api.interfaces.tileentity.IGregTechTileEntity; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.implementations.MTEBasicBatteryBuffer; import gregtech.mixin.interfaces.accessors.EntityPlayerMPAccessor; import tectech.loader.ConfigHandler; import tectech.loader.NetworkDispatcher; import tectech.mechanics.spark.RendererMessage; import tectech.mechanics.spark.ThaumSpark; import tectech.mechanics.tesla.ITeslaConnectable; import tectech.mechanics.tesla.ITeslaConnectableSimple; import tectech.thing.metaTileEntity.Textures; import tectech.util.CommonValues; import tectech.util.TTUtility; public class MTETeslaCoil extends MTEBasicBatteryBuffer implements ITeslaConnectable { // Interface fields private final Multimap<Integer, ITeslaConnectableSimple> teslaNodeMap = MultimapBuilder.treeKeys() .linkedListValues() .build(); private final HashSet<ThaumSpark> sparkList = new HashSet<>(); private int sparkCount = 20; private static final int transferRadiusMax = ConfigHandler.TeslaTweaks.TESLA_SINGLE_RANGE; private static final int transferRadiusMin = 4; // Minimum user configurable private int transferRadius = transferRadiusMax; // Default transferRadius setting public boolean powerPassToggle = false; // Power Pass for public viewing private static final int histSteps = 20; // Hysteresis Resolution private int histSettingLow = 3; // Hysteresis Low Limit private int histSettingHigh = 15; // Hysteresis High Limit private static final int histLowLimit = 1; // How low can you configure it? private static final int histHighLimit = 19; // How high can you configure it? private float histLow = (float) histSettingLow / histSteps; // Power pass is disabled if power is under this // fraction private float histHigh = (float) histSettingHigh / histSteps; // Power pass is enabled if power is over this // fraction private final long outputVoltage = V[mTier]; private boolean overdriveToggle = false; private String clientLocale = "en_US"; public MTETeslaCoil(int aID, String aName, String aNameRegional, int aTier, int aSlotCount) { super(aID, aName, aNameRegional, aTier, "", aSlotCount); TTUtility.setTier(aTier, this); } public MTETeslaCoil(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures, int aSlotCount) { super(aName, aTier, aDescription, aTextures, aSlotCount); } @Override public String[] getDescription() { String[] jargon = new String[] { CommonValues.THETA_MOVEMENT, translateToLocal("gt.blockmachines.machine.tt.tesla.desc.0"), // Your Tesla I/O machine of choice EnumChatFormatting.AQUA + translateToLocal("gt.blockmachines.machine.tt.tesla.desc.1") // Lightning // stoves for the // rich }; String[] sDesc = super.getDescription(); sDesc = Arrays.copyOfRange(sDesc, 1, sDesc.length); // Removes first element from array return ArrayUtils.addAll(jargon, sDesc); } @Override public boolean onSolderingToolRightClick(ForgeDirection side, ForgeDirection wrenchingSide, EntityPlayer aPlayer, float aX, float aY, float aZ) { if (overdriveToggle) { overdriveToggle = false; PlayerChatHelper .SendInfo(aPlayer, translateToLocalFormatted("tt.keyphrase.Overdrive_disengaged", clientLocale)); } else { overdriveToggle = true; PlayerChatHelper .SendInfo(aPlayer, translateToLocalFormatted("tt.keyphrase.Overdrive_engaged", clientLocale)); } return true; } @Override public void onScrewdriverRightClick(ForgeDirection side, EntityPlayer aPlayer, float aX, float aY, float aZ) { if (aPlayer.isSneaking()) { if (histSettingHigh < histHighLimit) { histSettingHigh++; } else { histSettingHigh = histSettingLow + 1; } histHigh = (float) histSettingHigh / histSteps; PlayerChatHelper.SendInfo( aPlayer, translateToLocalFormatted("tt.keyphrase.Hysteresis_high_set_to", clientLocale) + " " + round(histHigh * 100F) + "%"); } else { if (histSettingLow > histLowLimit) { histSettingLow--; } else { histSettingLow = histSettingHigh - 1; } histLow = (float) histSettingLow / histSteps; PlayerChatHelper.SendInfo( aPlayer, translateToLocalFormatted("tt.keyphrase.Hysteresis_low_set_to", clientLocale) + " " + round(histLow * 100F) + "%"); } } @Override public boolean onWireCutterRightClick(ForgeDirection side, ForgeDirection wrenchingSide, EntityPlayer aPlayer, float aX, float aY, float aZ) { if (aPlayer.isSneaking()) { if (transferRadius > transferRadiusMin) { transferRadius--; } } else { if (transferRadius < transferRadiusMax) { transferRadius++; } } PlayerChatHelper.SendInfo( aPlayer, translateToLocalFormatted("tt.keyphrase.Tesla_radius_set_to", clientLocale) + " " + transferRadius + "m"); return false; } // Cheeky skrub stuff to get machine to switch powerPass on soft mallet @Override public boolean hasAlternativeModeText() { return true; } @Override public String getAlternativeModeText() { // Hysteresis based ePowerPass Config long energyMax = getStoredEnergy()[1]; long energyStored = getStoredEnergy()[0]; float energyFrac = (float) energyStored / energyMax; // ePowerPass hist toggle if (energyFrac > histHigh) { powerPassToggle = true; } else if (energyFrac < histLow) { powerPassToggle = false; } else { powerPassToggle = !powerPassToggle; } // And after this cheeky-ness, toss the string XD return powerPassToggle ? translateToLocalFormatted("tt.keyphrase.Sending_power", clientLocale) + "!" : translateToLocalFormatted("tt.keyphrase.Receiving_power", clientLocale) + "!"; } @Override public boolean isFacingValid(ForgeDirection side) { return side != ForgeDirection.UP; } // Prevents output at the top side @Override public ITexture[][][] getTextureSet(ITexture[] aTextures) { ITexture[][][] rTextures = new ITexture[3][17][]; for (byte i = -1; i < 16; ++i) { rTextures[0][i + 1] = new ITexture[] { Textures.MACHINE_CASINGS_TT[this.mTier][i + 1] }; rTextures[1][i + 1] = new ITexture[] { Textures.MACHINE_CASINGS_TT[this.mTier][i + 1], Textures.TESLA_TRANSCEIVER_TOP_BA }; rTextures[2][i + 1] = new ITexture[] { Textures.MACHINE_CASINGS_TT[this.mTier][i + 1], this.mInventory.length == 16 ? Textures.OVERLAYS_ENERGY_OUT_POWER_TT[this.mTier] : (this.mInventory.length > 4 ? Textures.OVERLAYS_ENERGY_OUT_MULTI_TT[this.mTier] : Textures.OVERLAYS_ENERGY_OUT_TT[this.mTier]) }; } return rTextures; } @Override public ITexture[] getTexture(IGregTechTileEntity aBaseMetaTileEntity, ForgeDirection side, ForgeDirection facing, int colorIndex, boolean aActive, boolean aRedstone) { return this.mTextures[side == facing ? 2 : side == ForgeDirection.UP ? 1 : 0][colorIndex + 1]; } @Override public MetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { return new MTETeslaCoil(mName, mTier, mDescriptionArray, mTextures, mInventory.length); } @Override public void onFirstTick(IGregTechTileEntity aBaseMetaTileEntity) { super.onFirstTick(aBaseMetaTileEntity); if (!aBaseMetaTileEntity.isClientSide()) { TeslaUtil.teslaSimpleNodeSetAdd(this); TeslaUtil.generateTeslaNodeMap(this); } } @Override public void onRemoval() { super.onRemoval(); if (!this.getBaseMetaTileEntity() .isClientSide()) { TeslaUtil.teslaSimpleNodeSetRemove(this); } } @Override public void onUnload() { if (!this.getBaseMetaTileEntity() .isClientSide()) { TeslaUtil.teslaSimpleNodeSetRemove(this); } } @Override public void loadNBTData(NBTTagCompound aNBT) { super.loadNBTData(aNBT); TeslaUtil.teslaSimpleNodeSetAdd(this); } @Override public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { super.onPostTick(aBaseMetaTileEntity, aTick); if (aBaseMetaTileEntity.isClientSide()) { return; } // Hysteresis based ePowerPass Config long energyMax = getStoredEnergy()[1]; long energyStored = getStoredEnergy()[0]; float energyFrac = (float) energyStored / energyMax; // ePowerPass hist toggle if (!powerPassToggle && energyFrac > histHigh) { powerPassToggle = true; } else if (powerPassToggle && energyFrac < histLow) { powerPassToggle = false; } // Send Power TeslaUtil.powerTeslaNodeMap(this); // TODO Encapsulate the spark sender sparkCount--; if (sparkCount == 0) { sparkCount = 20; if (!sparkList.isEmpty()) { NetworkDispatcher.INSTANCE.sendToAllAround( new RendererMessage.RendererData(sparkList), aBaseMetaTileEntity.getWorld().provider.dimensionId, aBaseMetaTileEntity.getXCoord(), aBaseMetaTileEntity.getYCoord(), aBaseMetaTileEntity.getZCoord(), 256); sparkList.clear(); } } } @Override public boolean onRightclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer) { if (aBaseMetaTileEntity.isServerSide()) { if (aPlayer instanceof EntityPlayerMPAccessor) { clientLocale = ((EntityPlayerMPAccessor) aPlayer).gt5u$getTranslator(); } GTUIInfos.openGTTileEntityUI(aBaseMetaTileEntity, aPlayer); } return true; } @Override public byte getTeslaReceptionCapability() { return 1; } @Override public float getTeslaReceptionCoefficient() { return 1; } @Override public Multimap<Integer, ITeslaConnectableSimple> getTeslaNodeMap() { return teslaNodeMap; } @Override public HashSet<ThaumSpark> getSparkList() { return sparkList; } @Override public byte getTeslaTransmissionCapability() { return 2; } @Override public int getTeslaTransmissionRange() { return transferRadius; } @Override public boolean isOverdriveEnabled() { return overdriveToggle; } @Override public int getTeslaEnergyLossPerBlock() { return ConfigHandler.TeslaTweaks.TESLA_SINGLE_LOSS_PER_BLOCK; } @Override public float getTeslaOverdriveLossCoefficient() { return ConfigHandler.TeslaTweaks.TESLA_SINGLE_LOSS_FACTOR_OVERDRIVE; } @Override public long getTeslaOutputVoltage() { return outputVoltage; } @Override public long getTeslaOutputCurrent() { return mBatteryCount; } @Override public boolean teslaDrainEnergy(long teslaVoltageDrained) { if (getEUVar() < teslaVoltageDrained) { return false; } setEUVar(getEUVar() - teslaVoltageDrained); return true; } @Override public boolean isTeslaReadyToReceive() { return !this.powerPassToggle; } @Override public long getTeslaStoredEnergy() { return getEUVar(); } @Override public Vec3Impl getTeslaPosition() { return new Vec3Impl( this.getBaseMetaTileEntity() .getXCoord(), this.getBaseMetaTileEntity() .getYCoord(), this.getBaseMetaTileEntity() .getZCoord()); } @Override public Integer getTeslaDimension() { return this.getBaseMetaTileEntity() .getWorld().provider.dimensionId; } @Override public boolean teslaInjectEnergy(long teslaVoltageInjected) { return this.getBaseMetaTileEntity() .injectEnergyUnits(ForgeDirection.UP, teslaVoltageInjected, 1L) > 0L; } }