package gregtech.api.logic; import static gregtech.common.misc.WirelessNetworkManager.addEUToGlobalEnergyMap; import java.util.UUID; import javax.annotation.Nonnull; import net.minecraft.nbt.NBTTagCompound; import gregtech.api.enums.GTValues.NBT; /** * Power logic for machines. This is used to store all the important variables for a machine to have energy and use it * in any way. * * @author BlueWeabo, Maxim */ public class PowerLogic { public static final int NONE = 0; public static final int RECEIVER = 1; public static final int EMITTER = 2; public static final int BOTH = RECEIVER | EMITTER; private static float wirelessChargeFactor = 0.5F; private long storedEnergy = 0; private long energyCapacity = 0; private long voltage = 0; private long amperage = 0; private int type = 0; private boolean canUseLaser = false; private boolean canUseWireless = false; private UUID owner; public PowerLogic() {} /** * Sets the max voltage the logic can accept */ @Nonnull public PowerLogic setMaxVoltage(long voltage) { this.voltage = voltage; return this; } /** * Sets the maximum amount of energy the machine can store inside of it */ @Nonnull public PowerLogic setEnergyCapacity(long energyCapacity) { this.energyCapacity = energyCapacity; return this; } /** * Sets the maximum amount of amps a machine can receive from an emitter */ @Nonnull public PowerLogic setMaxAmperage(long amperage) { this.amperage = amperage; return this; } /** * Sets the type of power logic this is. Whether it will receive EU or emit it to others, or do both */ @Nonnull public PowerLogic setType(int type) { this.type = type; return this; } /** * If this power logic can use lasers to be used for it */ @Nonnull public PowerLogic setCanUseLaser(boolean canUse) { canUseLaser = canUse; return this; } /** * If the power logic should use wireless EU first before using its internal buffer */ @Nonnull public PowerLogic setCanUseWireless(boolean canUse, UUID owner) { canUseWireless = canUse; this.owner = owner; return this; } /** * Adding energy directly to the buffer, but only if it has the capacity. */ public boolean addEnergyUnsafe(long totalEUAdded) { if (storedEnergy + totalEUAdded >= energyCapacity) { return false; } storedEnergy += totalEUAdded; return true; } /** * Adding energy to the buffer if the voltage given isn't higher than the voltage of the logic */ public boolean addEnergy(long voltage, long amperage) { if (voltage > this.voltage) { return false; } return addEnergyUnsafe(voltage * amperage); } /** * Same as {@link #addEnergy(long, long)}, but only 1 amp of it */ public boolean addEnergy(long voltage) { return addEnergy(voltage, 1); } /** * Injecting energy in the multiblock ampere per ampere until full or until we have added the maximum possible * amperes for this tick * * @param voltage At what voltage are the amps? * @param availableAmperage How much amperage do we have available * @return Amount of amperes used */ public long injectEnergy(long voltage, long availableAmperage) { if (canUseWireless) return 0; long usedAmperes = 0; while (addEnergy(voltage, 1) && usedAmperes < amperage) { usedAmperes++; } return usedAmperes; } /** * Remove energy from the logic only if it has enough to be removed. */ public boolean removeEnergyUnsafe(long totalEURemoved) { if (canUseWireless) { if (storedEnergy < energyCapacity * wirelessChargeFactor) { if (addEUToGlobalEnergyMap(owner, -(energyCapacity - storedEnergy))) { storedEnergy = energyCapacity; } } } if (storedEnergy - totalEURemoved < 0) { return false; } storedEnergy -= totalEURemoved; return true; } /** * Remove the given voltage for the amount of amperage if the removed isn't higher than the logic's voltage */ public boolean removeEnergy(long voltage, long amperage) { if (voltage > this.voltage) { return false; } return removeEnergyUnsafe(voltage * amperage); } /** * Same as {@link #removeEnergy(long, long)}, but with only 1 amperage */ public boolean removeEnergy(long voltage) { return removeEnergy(voltage, 1); } /** * @return The maximum energy that can be stored. */ public long getCapacity() { return energyCapacity; } /** * @return The maximum voltage that is available */ public long getVoltage() { return voltage; } /** * @return The current energy stored */ public long getStoredEnergy() { return storedEnergy; } /** * @return The current maximum Amperage */ public long getMaxAmperage() { return amperage; } /** * Is the logic a receiver to receive energy */ public boolean isEnergyReceiver() { return (type & RECEIVER) > 0; } /** * Is the logic a emitter to emit energy */ public boolean isEnergyEmitter() { return (type & EMITTER) > 0; } /** * Saves the power logic to its own nbt tag before saving it to the given one. * * @param nbt Tag where you want to save the power logic tag to. */ public void saveToNBT(NBTTagCompound nbt) { NBTTagCompound powerLogic = new NBTTagCompound(); powerLogic.setLong(NBT.POWER_LOGIC_ENERGY_CAPACITY, energyCapacity); powerLogic.setLong(NBT.POWER_LOGIC_STORED_ENERGY, storedEnergy); powerLogic.setLong(NBT.POWER_LOGIC_AMPERAGE, amperage); powerLogic.setLong(NBT.POWER_LOGIC_VOLTAGE, voltage); powerLogic.setInteger(NBT.POWER_LOGIC_TYPE, type); nbt.setTag(NBT.POWER_LOGIC, powerLogic); } /** * Loads the power logic from its own nbt after getting it from the given one * * @param nbt Tag where the power logic tag was saved to */ public void loadFromNBT(NBTTagCompound nbt) { NBTTagCompound powerLogic = nbt.getCompoundTag(NBT.POWER_LOGIC); energyCapacity = powerLogic.getLong(NBT.POWER_LOGIC_ENERGY_CAPACITY); storedEnergy = powerLogic.getLong(NBT.POWER_LOGIC_STORED_ENERGY); amperage = powerLogic.getLong(NBT.POWER_LOGIC_AMPERAGE); voltage = powerLogic.getLong(NBT.POWER_LOGIC_VOLTAGE); type = powerLogic.getInteger(NBT.POWER_LOGIC_TYPE); } /** * Can we use lasers for inputting EU */ public boolean canUseLaser() { return canUseLaser; } }