diff --git a/src/main/java/gregtech/api/interfaces/IGlobalWirelessEnergy.java b/src/main/java/gregtech/api/interfaces/IGlobalWirelessEnergy.java index be4db5412a7..47c03743a5e 100644 --- a/src/main/java/gregtech/api/interfaces/IGlobalWirelessEnergy.java +++ b/src/main/java/gregtech/api/interfaces/IGlobalWirelessEnergy.java @@ -1,25 +1,25 @@ package gregtech.api.interfaces; -import static gregtech.common.misc.GlobalVariableStorage.GlobalEnergy; -import static gregtech.common.misc.GlobalVariableStorage.GlobalEnergyName; -import static gregtech.common.misc.GlobalVariableStorage.GlobalEnergyTeam; - import java.math.BigInteger; import java.util.UUID; import net.minecraft.entity.player.EntityPlayer; import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.common.misc.GlobalEnergyWorldSavedData; +import gregtech.common.misc.WirelessNetworkManager; // If you are adding very late-game content feel free to tap into this interface. // The eventual goal is to bypass laser/dynamo stuff and have energy deposited directly from ultra-endgame // multi-blocks directly into the users network. +/** + * Use WirelessNetworkManager instead + */ +@Deprecated public interface IGlobalWirelessEnergy { // User 0 will join user 1 by calling this function. They will share the same energy network. default void joinUserNetwork(String user_uuid_0, String user_uuid_1) { - GlobalEnergyTeam.put(user_uuid_0, user_uuid_1); + WirelessNetworkManager.joinUserNetwork(user_uuid_0, user_uuid_1); } // Adds a user to the energy map if they do not already exist. Otherwise, do nothing. Will also check if the user @@ -27,35 +27,18 @@ default void joinUserNetwork(String user_uuid_0, String user_uuid_1) { // tick of a machine being placed only. default void strongCheckOrAddUser(EntityPlayer user) { - strongCheckOrAddUser( + WirelessNetworkManager.strongCheckOrAddUser( user.getUniqueID() .toString(), user.getDisplayName()); } default void strongCheckOrAddUser(UUID user_uuid, String user_name) { - strongCheckOrAddUser(user_uuid.toString(), user_name); + WirelessNetworkManager.strongCheckOrAddUser(user_uuid.toString(), user_name); } default void strongCheckOrAddUser(String user_uuid, String user_name) { - - // Check if the user has a team. Add them if not. - GlobalEnergyTeam.putIfAbsent(user_uuid, user_uuid); - - // Check if the user is in the global energy map. - GlobalEnergy.putIfAbsent(user_uuid, BigInteger.ZERO); - - // If the username linked to the users fixed uuid is not equal to their current name then remove it. - // This indicates that their username has changed. - if (!(GlobalEnergyName.getOrDefault(user_uuid, "") - .equals(user_name))) { - String old_name = GlobalEnergyName.get(user_uuid); - GlobalEnergyName.remove(old_name); - } - - // Add UUID -> Name, Name -> UUID. - GlobalEnergyName.put(user_name, user_uuid); - GlobalEnergyName.put(user_uuid, user_name); + WirelessNetworkManager.strongCheckOrAddUser(user_uuid, user_name); } // ------------------------------------------------------------------------------------ @@ -64,30 +47,7 @@ default void strongCheckOrAddUser(String user_uuid, String user_name) { // BigIntegers have much slower operations than longs/ints. You should call these methods // as infrequently as possible and bulk store values to add to the global map. default boolean addEUToGlobalEnergyMap(String userUUID, BigInteger EU) { - - // Mark the data as dirty and in need of saving. - try { - GlobalEnergyWorldSavedData.INSTANCE.markDirty(); - } catch (Exception exception) { - System.out.println("COULD NOT MARK GLOBAL ENERGY AS DIRTY IN ADD EU"); - exception.printStackTrace(); - } - - // Get the team UUID. Users are by default in a team with a UUID equal to their player UUID. - String teamUUID = GlobalEnergyTeam.getOrDefault(userUUID, userUUID); - - // Get the teams total energy stored. If they are not in the map, return 0 EU. - BigInteger totalEU = GlobalEnergy.getOrDefault(teamUUID, BigInteger.ZERO); - totalEU = totalEU.add(EU); - - // If there is sufficient EU then complete the operation and return true. - if (totalEU.signum() >= 0) { - GlobalEnergy.put(teamUUID, totalEU); - return true; - } - - // There is insufficient EU so cancel the operation and return false. - return false; + return WirelessNetworkManager.addEUToGlobalEnergyMap(userUUID, EU); } default boolean addEUToGlobalEnergyMap(UUID user_uuid, BigInteger EU) { @@ -113,28 +73,20 @@ default boolean addEUToGlobalEnergyMap(String user_uuid, int EU) { // ------------------------------------------------------------------------------------ default BigInteger getUserEU(String user_uuid) { - return GlobalEnergy.getOrDefault(GlobalEnergyTeam.getOrDefault(user_uuid, user_uuid), BigInteger.ZERO); + return WirelessNetworkManager.getUserEU(user_uuid); } // This overwrites the EU in the network. Only use this if you are absolutely sure you know what you are doing. default void setUserEU(String user_uuid, BigInteger EU) { - // Mark the data as dirty and in need of saving. - try { - GlobalEnergyWorldSavedData.INSTANCE.markDirty(); - } catch (Exception exception) { - System.out.println("COULD NOT MARK GLOBAL ENERGY AS DIRTY IN SET EU"); - exception.printStackTrace(); - } - - GlobalEnergy.put(GlobalEnergyTeam.get(user_uuid), EU); + WirelessNetworkManager.setUserEU(user_uuid, EU); } default String GetUsernameFromUUID(String uuid) { - return GlobalEnergyName.getOrDefault(GlobalEnergyTeam.getOrDefault(uuid, ""), ""); + return WirelessNetworkManager.getUsernameFromUUID(uuid); } default String getUUIDFromUsername(String username) { - return GlobalEnergyTeam.getOrDefault(GlobalEnergyName.getOrDefault(username, ""), ""); + return WirelessNetworkManager.getUUIDFromUsername(username); } /** @@ -143,24 +95,14 @@ default String getUUIDFromUsername(String username) { * @return */ default String getRawUUIDFromUsername(String username) { - return GlobalEnergyName.getOrDefault(username, ""); + return WirelessNetworkManager.getRawUUIDFromUsername(username); } static void clearGlobalEnergyInformationMaps() { - // Do not use this unless you are 100% certain you know what you are doing. - GlobalEnergy.clear(); - GlobalEnergyName.clear(); - GlobalEnergyTeam.clear(); + WirelessNetworkManager.clearGlobalEnergyInformationMaps(); } default String processInitialSettings(final IGregTechTileEntity machine) { - - // UUID and username of the owner. - final String UUID = machine.getOwnerUuid() - .toString(); - final String name = machine.getOwnerName(); - - strongCheckOrAddUser(UUID, name); - return UUID; + return WirelessNetworkManager.processInitialSettings(machine); } } diff --git a/src/main/java/gregtech/api/interfaces/tileentity/IEnergyConnected.java b/src/main/java/gregtech/api/interfaces/tileentity/IEnergyConnected.java index f866092d38d..91a9759e472 100644 --- a/src/main/java/gregtech/api/interfaces/tileentity/IEnergyConnected.java +++ b/src/main/java/gregtech/api/interfaces/tileentity/IEnergyConnected.java @@ -1,5 +1,9 @@ package gregtech.api.interfaces.tileentity; +import java.util.Objects; + +import javax.annotation.Nonnull; + import net.minecraft.tileentity.TileEntity; import net.minecraftforge.common.util.ForgeDirection; @@ -53,24 +57,25 @@ default boolean outputsEnergyTo(ForgeDirection side, boolean waitForActive) { */ final class Util { + // TODO: Deduplicate code by rewokring the Enet system using the GTCEu one as inspiration - BlueWeabo /** * Emits Energy to the E-net. Also compatible with adjacent IC2 TileEntities. * * @return the used Amperage. */ - public static long emitEnergyToNetwork(long aVoltage, long aAmperage, IEnergyConnected aEmitter) { - long rUsedAmperes = 0; - if (!(aEmitter instanceof IHasWorldObjectAndCoords emitterTile)) { + public static long emitEnergyToNetwork(long voltage, long amperage, IEnergyConnected emitter) { + long usedAmperes = 0; + if (!(emitter instanceof IHasWorldObjectAndCoords emitterTile)) { return 0; } for (final ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) { - if (rUsedAmperes > aAmperage) break; - if (!aEmitter.outputsEnergyTo(side)) { + if (usedAmperes > amperage) break; + if (!emitter.outputsEnergyTo(side)) { continue; } - final ForgeDirection oppositeSide = side.getOpposite(); + final ForgeDirection oppositeSide = Objects.requireNonNull(side.getOpposite()); final TileEntity tTileEntity = emitterTile.getTileEntityAtSide(side); if (tTileEntity instanceof PowerLogicHost host) { @@ -79,28 +84,95 @@ public static long emitEnergyToNetwork(long aVoltage, long aAmperage, IEnergyCon continue; } - rUsedAmperes += logic.injectEnergy(aVoltage, aAmperage - rUsedAmperes); + usedAmperes += logic.injectEnergy(voltage, amperage - usedAmperes); } else if (tTileEntity instanceof IEnergyConnected energyConnected) { - if (aEmitter.getColorization() >= 0) { + if (emitter.getColorization() >= 0) { final byte tColor = energyConnected.getColorization(); - if (tColor >= 0 && tColor != aEmitter.getColorization()) continue; + if (tColor >= 0 && tColor != emitter.getColorization()) continue; } - rUsedAmperes += energyConnected.injectEnergyUnits(oppositeSide, aVoltage, aAmperage - rUsedAmperes); + usedAmperes += energyConnected.injectEnergyUnits(oppositeSide, voltage, amperage - usedAmperes); } else if (tTileEntity instanceof IEnergySink sink) { - if (sink.acceptsEnergyFrom((TileEntity) aEmitter, oppositeSide)) { - while (aAmperage > rUsedAmperes && sink.getDemandedEnergy() > 0 - && sink.injectEnergy(oppositeSide, aVoltage, aVoltage) < aVoltage) rUsedAmperes++; + if (sink.acceptsEnergyFrom((TileEntity) emitter, oppositeSide)) { + while (amperage > usedAmperes && sink.getDemandedEnergy() > 0 + && sink.injectEnergy(oppositeSide, voltage, voltage) < voltage) usedAmperes++; } } else if (GregTech_API.mOutputRF && tTileEntity instanceof IEnergyReceiver receiver) { - final int rfOut = GT_Utility.safeInt(aVoltage * GregTech_API.mEUtoRF / 100); + final int rfOut = GT_Utility.safeInt(voltage * GregTech_API.mEUtoRF / 100); if (receiver.receiveEnergy(oppositeSide, rfOut, true) == rfOut) { receiver.receiveEnergy(oppositeSide, rfOut, false); - rUsedAmperes++; + usedAmperes++; + } + } + } + return usedAmperes; + } + + /** + * Same as {@link #emitEnergyToNetwork(long, long, IEnergyConnected)}, but instead we remove the energy directly from the logic itself. + * @param emitter The host, which is trying to emit energy in the network + * @param outputSide side from where energy is being outputted to. If its {@link ForgeDirection#UNKNOWN} then it doesn't emit energy to the network + */ + public static void emitEnergyToNetwork(@Nonnull final PowerLogicHost emitter, @Nonnull final ForgeDirection outputSide) { + if (outputSide == ForgeDirection.UNKNOWN) return; + final PowerLogic emitterLogic = emitter.getPowerLogic(); + long usedAmperes = 0; + long voltage = emitterLogic.getVoltage(); + long amperage = emitterLogic.getMaxAmperage(); + if (!(emitter instanceof final IHasWorldObjectAndCoords emitterTile)) { + return; + } + // We need to make sure we can actually output energy on this side. This is more of a safety check. + if (emitter.getPowerLogic(outputSide) == null) { + return; + } + + final ForgeDirection oppositeSide = Objects.requireNonNull(outputSide.getOpposite()); + final TileEntity tileEntity = emitterTile.getTileEntityAtSide(outputSide); + if (tileEntity instanceof PowerLogicHost host) { + + final PowerLogic logic = host.getPowerLogic(oppositeSide); + if (logic == null || logic.isEnergyReceiver()) { + return; + } + + usedAmperes += logic.injectEnergy(voltage, amperage); + emitterLogic.removeEnergyUnsafe(usedAmperes * voltage); + return; + } + + if (tileEntity instanceof IEnergyConnected energyConnected) { + if (emitter instanceof IColoredTileEntity coloredEmitter && coloredEmitter.getColorization() >= 0) { + final byte tColor = energyConnected.getColorization(); + if (tColor >= 0 && tColor != coloredEmitter.getColorization()) { + return; } } + usedAmperes += energyConnected.injectEnergyUnits(oppositeSide, voltage, amperage - usedAmperes); + emitterLogic.removeEnergyUnsafe(usedAmperes * voltage); + return; + } + + if (tileEntity instanceof IEnergySink sink) { + if (sink.acceptsEnergyFrom((TileEntity) emitter, oppositeSide)) { + while (amperage > usedAmperes && sink.getDemandedEnergy() > 0 + && sink.injectEnergy(oppositeSide, voltage, voltage) < voltage) { + usedAmperes++; + } + emitterLogic.removeEnergyUnsafe(usedAmperes * voltage); + return; + } + } + + if (GregTech_API.mOutputRF && tileEntity instanceof IEnergyReceiver receiver) { + final int rfOut = GT_Utility.safeInt(voltage * GregTech_API.mEUtoRF / 100); + if (receiver.receiveEnergy(oppositeSide, rfOut, true) == rfOut) { + receiver.receiveEnergy(oppositeSide, rfOut, false); + usedAmperes++; + emitterLogic.removeEnergyUnsafe(usedAmperes * voltage); + return; + } } - return rUsedAmperes; } } } diff --git a/src/main/java/gregtech/api/logic/PowerLogic.java b/src/main/java/gregtech/api/logic/PowerLogic.java index 2aee11f1eeb..ad19987a76e 100644 --- a/src/main/java/gregtech/api/logic/PowerLogic.java +++ b/src/main/java/gregtech/api/logic/PowerLogic.java @@ -1,5 +1,7 @@ package gregtech.api.logic; +import static gregtech.common.misc.WirelessNetworkManager.addEUToGlobalEnergyMap; + import java.util.UUID; import javax.annotation.Nonnull; @@ -7,9 +9,14 @@ import net.minecraft.nbt.NBTTagCompound; import gregtech.api.enums.GT_Values.NBT; -import gregtech.api.interfaces.IGlobalWirelessEnergy; -public class PowerLogic implements IGlobalWirelessEnergy { +/** + * 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; @@ -27,36 +34,54 @@ public class PowerLogic implements IGlobalWirelessEnergy { 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 setAmperage(long amperage) { + 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; @@ -64,6 +89,9 @@ public PowerLogic setCanUseWireless(boolean canUse, UUID 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; @@ -73,6 +101,9 @@ public boolean addEnergyUnsafe(long 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; @@ -81,10 +112,21 @@ public boolean addEnergy(long voltage, long amperage) { 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; @@ -95,6 +137,9 @@ public long injectEnergy(long voltage, long availableAmperage) { 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) { @@ -111,6 +156,9 @@ public boolean removeEnergyUnsafe(long 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; @@ -119,34 +167,60 @@ public boolean removeEnergy(long voltage, long amperage) { 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; } - public long getAmperage() { + /** + * @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); @@ -157,6 +231,11 @@ public void saveToNBT(NBTTagCompound nbt) { 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); @@ -166,6 +245,9 @@ public void loadFromNBT(NBTTagCompound nbt) { type = powerLogic.getInteger(NBT.POWER_LOGIC_TYPE); } + /** + * Can we use lasers for inputting EU + */ public boolean canUseLaser() { return canUseLaser; } diff --git a/src/main/java/gregtech/api/logic/interfaces/FluidInventoryLogicHost.java b/src/main/java/gregtech/api/logic/interfaces/FluidInventoryLogicHost.java index 38cd5ac65c3..c12333a4c6b 100644 --- a/src/main/java/gregtech/api/logic/interfaces/FluidInventoryLogicHost.java +++ b/src/main/java/gregtech/api/logic/interfaces/FluidInventoryLogicHost.java @@ -4,6 +4,7 @@ import java.util.HashSet; import java.util.Map.Entry; +import java.util.Objects; import java.util.Set; import java.util.UUID; @@ -26,7 +27,7 @@ public interface FluidInventoryLogicHost extends IFluidHandler { * * @param side The side from where fluids are being inputted or extracted from * @param type The type of inventory being accessed. For inputting its Input, For outputting its Output. - * @return The Fluid Logic responsible for said type. + * @return The Fluid Logic responsible for said type. Can return null if the side is invalid */ @Nullable FluidInventoryLogic getFluidLogic(@Nonnull ForgeDirection side, @Nonnull InventoryType type); @@ -38,11 +39,14 @@ public interface FluidInventoryLogicHost extends IFluidHandler { * @param id ID of the locked inventory. A null id is all inventories of said controller of said type * @return The Fluid Logic responsible for everything that should be done with said inventory */ - @Nullable + @Nonnull default FluidInventoryLogic getFluidLogic(@Nonnull InventoryType type, @Nullable UUID id) { - return getFluidLogic(ForgeDirection.UNKNOWN, type); + return Objects.requireNonNull(getFluidLogic(ForgeDirection.UNKNOWN, type)); } + /** + * Returns an empty set if the type is {@link InventoryType#Both} or when the machine isn't a controller. + */ @Nonnull default Set> getAllFluidInventoryLogics(@Nonnull InventoryType type) { return new HashSet<>(); diff --git a/src/main/java/gregtech/api/logic/interfaces/ItemInventoryLogicHost.java b/src/main/java/gregtech/api/logic/interfaces/ItemInventoryLogicHost.java index b60b93e45b6..a65f3c50f19 100644 --- a/src/main/java/gregtech/api/logic/interfaces/ItemInventoryLogicHost.java +++ b/src/main/java/gregtech/api/logic/interfaces/ItemInventoryLogicHost.java @@ -2,6 +2,7 @@ import java.util.HashSet; import java.util.Map.Entry; +import java.util.Objects; import java.util.Set; import java.util.UUID; @@ -23,7 +24,7 @@ public interface ItemInventoryLogicHost extends ISidedInventory { * * @param side The side from where items are being inputted or extracted from * @param type The type of inventory being accessed. For inputting its Input, For outputting its Output. - * @return The Item Logic responsible for said type. + * @return The Item Logic responsible for said type. Will return null if the side is not valid */ @Nullable ItemInventoryLogic getItemLogic(@Nonnull ForgeDirection side, @Nonnull InventoryType type); @@ -35,9 +36,9 @@ public interface ItemInventoryLogicHost extends ISidedInventory { * @param id ID of the locked inventory. A null id is all inventories of said controller of said type * @return The Item Logic responsible for everything that should be done with said inventory */ - @Nullable + @Nonnull default ItemInventoryLogic getItemLogic(@Nonnull InventoryType type, @Nullable UUID id) { - return getItemLogic(ForgeDirection.UNKNOWN, type); + return Objects.requireNonNull(getItemLogic(ForgeDirection.UNKNOWN, type)); } /** @@ -50,6 +51,10 @@ default InventoryType getItemInventoryType() { return null; } + /** + * Returns an empty set if the type is {@link InventoryType#Both} or this is used when the machine isn't a + * controller + */ @Nonnull default Set> getAllItemInventoryLogics(@Nonnull InventoryType type) { return new HashSet<>(); diff --git a/src/main/java/gregtech/api/logic/interfaces/PowerLogicHost.java b/src/main/java/gregtech/api/logic/interfaces/PowerLogicHost.java index 6ba788defde..46b04968258 100644 --- a/src/main/java/gregtech/api/logic/interfaces/PowerLogicHost.java +++ b/src/main/java/gregtech/api/logic/interfaces/PowerLogicHost.java @@ -1,22 +1,61 @@ package gregtech.api.logic.interfaces; +import java.util.Objects; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + import net.minecraftforge.common.util.ForgeDirection; +import gregtech.api.interfaces.tileentity.IEnergyConnected; import gregtech.api.logic.PowerLogic; +/** + * Power logic class for one to use to enable a machine to use energy + */ public interface PowerLogicHost { - PowerLogic getPowerLogic(ForgeDirection side); + /** + * + * @param side Side being access to try and get the power logic from + * @return Can return null if the side doesn't allow the return of the logic. + */ + @Nullable + PowerLogic getPowerLogic(@Nonnull ForgeDirection side); + /** + * Gives the power logic ignoring the side. + */ + @Nonnull default PowerLogic getPowerLogic() { - return getPowerLogic(ForgeDirection.UNKNOWN); + return Objects.requireNonNull(getPowerLogic(ForgeDirection.UNKNOWN)); } + /** + * Shortcut to the method of {@link PowerLogic#isEnergyReceiver()} + */ default boolean isEnergyReceiver() { - return false; + return getPowerLogic().isEnergyReceiver(); } + /** + * Shortcut to the method of {@link PowerLogic#isEnergyEmitter()} + */ default boolean isEnergyEmitter() { - return false; + return getPowerLogic().isEnergyEmitter(); } + + /** + * Method for emitting energy to other blocks and machines. Override when it needs to be changed. + */ + default void emitEnergyFromLogic() { + IEnergyConnected.Util.emitEnergyToNetwork(this, getPowerOutputSide()); + } + + /** + * From where does the machine output energy from? + * When the output side is {@link ForgeDirection#UNKNOWN} then it won't output energy + */ + @Nonnull + ForgeDirection getPowerOutputSide(); } diff --git a/src/main/java/gregtech/api/logic/interfaces/ProcessingLogicHost.java b/src/main/java/gregtech/api/logic/interfaces/ProcessingLogicHost.java index 22c1b8a730e..52ac7ec9253 100644 --- a/src/main/java/gregtech/api/logic/interfaces/ProcessingLogicHost.java +++ b/src/main/java/gregtech/api/logic/interfaces/ProcessingLogicHost.java @@ -1,5 +1,7 @@ package gregtech.api.logic.interfaces; +import javax.annotation.Nonnull; + import gregtech.api.enums.VoidingMode; import gregtech.api.interfaces.tileentity.IMachineProgress; import gregtech.api.interfaces.tileentity.IVoidable; @@ -8,21 +10,29 @@ public interface ProcessingLogicHost

> extends IVoidable, ItemInventoryLogicHost, FluidInventoryLogicHost, IMachineProgress { + /** + * Get the processing logic for the current machine + */ + @Nonnull P getProcessingLogic(); boolean isInputSeparated(); + /** + * Get what the machine can void or not + */ + @Nonnull VoidingMode getVoidMode(); /** * Called when the processing logic should be updated by {@link #needsUpdate()} */ - default void updateProcessingLogic(P processingLogic) {} + default void updateProcessingLogic(@Nonnull P processingLogic) {} /** - * called before the recipe check, but after any other updates + * Called before the recipe check, but after any other updates */ - default void setProcessingLogicPower(P processingLogic) {} + default void setProcessingLogicPower(@Nonnull P processingLogic) {} /** * DO NOT CALL YOURSELF!!! diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Wireless_Dynamo.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Wireless_Dynamo.java index 821c02d10f8..4b73210afd6 100644 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Wireless_Dynamo.java +++ b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Wireless_Dynamo.java @@ -2,6 +2,8 @@ import static gregtech.api.enums.GT_Values.AuthorColen; import static gregtech.api.enums.GT_Values.V; +import static gregtech.common.misc.WirelessNetworkManager.addEUToGlobalEnergyMap; +import static gregtech.common.misc.WirelessNetworkManager.strongCheckOrAddUser; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; @@ -9,14 +11,13 @@ import net.minecraftforge.common.util.ForgeDirection; import gregtech.api.enums.Textures; -import gregtech.api.interfaces.IGlobalWirelessEnergy; import gregtech.api.interfaces.ITexture; import gregtech.api.interfaces.tileentity.IGregTechTileEntity; import gregtech.api.interfaces.tileentity.IWirelessEnergyHatchInformation; import gregtech.api.metatileentity.MetaTileEntity; public class GT_MetaTileEntity_Wireless_Dynamo extends GT_MetaTileEntity_Hatch_Dynamo - implements IGlobalWirelessEnergy, IWirelessEnergyHatchInformation { + implements IWirelessEnergyHatchInformation { private String owner_uuid; private String owner_name; diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Wireless_Hatch.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Wireless_Hatch.java index 66a84dfa991..251a9dfcece 100644 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Wireless_Hatch.java +++ b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Wireless_Hatch.java @@ -2,6 +2,8 @@ import static gregtech.api.enums.GT_Values.AuthorColen; import static gregtech.api.enums.GT_Values.V; +import static gregtech.common.misc.WirelessNetworkManager.addEUToGlobalEnergyMap; +import static gregtech.common.misc.WirelessNetworkManager.strongCheckOrAddUser; import static java.lang.Long.min; import java.math.BigInteger; @@ -12,14 +14,13 @@ import net.minecraftforge.common.util.ForgeDirection; import gregtech.api.enums.Textures; -import gregtech.api.interfaces.IGlobalWirelessEnergy; import gregtech.api.interfaces.ITexture; import gregtech.api.interfaces.tileentity.IGregTechTileEntity; import gregtech.api.interfaces.tileentity.IWirelessEnergyHatchInformation; import gregtech.api.metatileentity.MetaTileEntity; public class GT_MetaTileEntity_Wireless_Hatch extends GT_MetaTileEntity_Hatch_Energy - implements IGlobalWirelessEnergy, IWirelessEnergyHatchInformation { + implements IWirelessEnergyHatchInformation { private final BigInteger eu_transferred_per_operation = BigInteger .valueOf(2 * V[mTier] * ticks_between_energy_addition); diff --git a/src/main/java/gregtech/api/multitileentity/base/MultiTileEntity.java b/src/main/java/gregtech/api/multitileentity/base/MultiTileEntity.java index eeebb524d0c..1ec8a0d680e 100644 --- a/src/main/java/gregtech/api/multitileentity/base/MultiTileEntity.java +++ b/src/main/java/gregtech/api/multitileentity/base/MultiTileEntity.java @@ -8,6 +8,8 @@ import java.util.List; import java.util.UUID; +import javax.annotation.Nonnull; + import net.minecraft.block.Block; import net.minecraft.client.Minecraft; import net.minecraft.creativetab.CreativeTabs; @@ -88,6 +90,7 @@ public abstract class MultiTileEntity extends CoverableTileEntity protected boolean needsUpdate = false; protected boolean hasInventoryChanged = false; protected boolean isPainted = false; + @Nonnull protected ForgeDirection facing = ForgeDirection.WEST; // Default to WEST, so it renders facing Left in the // inventory protected byte color; diff --git a/src/main/java/gregtech/api/multitileentity/machine/MultiTileBasicMachine.java b/src/main/java/gregtech/api/multitileentity/machine/MultiTileBasicMachine.java index 435b3f1ded8..ee814882d74 100644 --- a/src/main/java/gregtech/api/multitileentity/machine/MultiTileBasicMachine.java +++ b/src/main/java/gregtech/api/multitileentity/machine/MultiTileBasicMachine.java @@ -1,6 +1,7 @@ package gregtech.api.multitileentity.machine; import static gregtech.api.enums.GT_Values.*; +import static gregtech.api.enums.TickTime.MINUTE; import java.io.IOException; import java.util.ArrayList; @@ -35,7 +36,6 @@ import gregtech.api.enums.Textures; import gregtech.api.enums.Textures.BlockIcons.CustomIcon; import gregtech.api.interfaces.ITexture; -import gregtech.api.interfaces.tileentity.IMachineProgress; import gregtech.api.logic.FluidInventoryLogic; import gregtech.api.logic.ItemInventoryLogic; import gregtech.api.logic.MuTEProcessingLogic; @@ -53,7 +53,7 @@ import gregtech.client.GT_SoundLoop; public abstract class MultiTileBasicMachine

> extends TickableMultiTileEntity - implements IMultiTileMachine, IMachineProgress, ProcessingLogicHost

{ + implements IMultiTileMachine, ProcessingLogicHost

, PowerLogicHost { protected static final int ACTIVE = B[0]; protected static final int TICKS_BETWEEN_RECIPE_CHECKS = 5 * TickTime.SECOND; @@ -70,10 +70,6 @@ public abstract class MultiTileBasicMachine

> ex protected int maxParallel = 1; protected boolean active = false; - protected long storedEnergy = 0; - protected long voltage = 0; - protected long amperage = 1; - protected long eut = 0; protected int tier = 0; protected long burnTime = 0; protected long totalBurnTime = 0; @@ -85,8 +81,6 @@ public abstract class MultiTileBasicMachine

> ex protected boolean isElectric = true; protected boolean isSteam = false; protected boolean acceptsFuel = false; - protected boolean canUseWireless = false; - protected boolean canUseLaser = false; protected byte soundEvent = 0; protected int soundEventValue = 0; @@ -99,6 +93,8 @@ public abstract class MultiTileBasicMachine

> ex @Nonnull protected VoidingMode voidingMode = VoidingMode.VOID_NONE; protected boolean processingUpdate = false; + @Nonnull + protected PowerLogic power = createPowerLogic(); @SideOnly(Side.CLIENT) protected GT_SoundLoop activitySoundLoop; @@ -132,11 +128,11 @@ public void writeMultiTileNBT(NBTTagCompound nbt) { } nbt.setInteger(NBT.TIER, tier); - nbt.setLong(NBT.EUT_CONSUMPTION, eut); nbt.setLong(NBT.BURN_TIME_LEFT, burnTime); nbt.setLong(NBT.TOTAL_BURN_TIME, totalBurnTime); nbt.setBoolean(NBT.ALLOWED_WORK, canWork); nbt.setBoolean(NBT.ACTIVE, active); + power.saveToNBT(nbt); } protected void saveItemLogic(NBTTagCompound nbt) { @@ -173,11 +169,11 @@ public void readMultiTileNBT(NBTTagCompound nbt) { } tier = nbt.getInteger(NBT.TIER); - eut = nbt.getLong(NBT.EUT_CONSUMPTION); burnTime = nbt.getLong(NBT.BURN_TIME_LEFT); totalBurnTime = nbt.getLong(NBT.TOTAL_BURN_TIME); canWork = nbt.getBoolean(NBT.ALLOWED_WORK); active = nbt.getBoolean(NBT.ACTIVE); + power.loadFromNBT(nbt); } protected void loadItemLogic(NBTTagCompound nbt) { @@ -367,8 +363,6 @@ protected void runningTick(long tick) { if (this instanceof PowerLogicHost) { consumeEnergy(); } - - emitEnergy(); } /** @@ -378,11 +372,6 @@ protected boolean checkRecipe() { return false; } - /** - * Runs only on server side - */ - protected void emitEnergy() {} - /** * Runs only on server side */ @@ -539,22 +528,6 @@ protected void setFuel(boolean acceptsFuel) { this.acceptsFuel = acceptsFuel; } - protected boolean canUseWireless() { - return canUseWireless; - } - - protected boolean drainEut(long eut) { - return decreaseStoredEnergyUnits(eut, false); - } - - protected boolean generateEut(long eut) { - return increaseStoredEnergyUnits(eut, true); - } - - protected boolean isGenerator() { - return false; - } - protected boolean consumeFuel() { if (isElectric() || isSteam()) return false; if (isActive() && burnTime <= 0) { @@ -595,38 +568,36 @@ protected void addDebugInfo(EntityPlayer player, int logLevel, ArrayList list.add("Fuel: " + EnumChatFormatting.GOLD + burnTime + "/" + totalBurnTime); } - if (this instanceof PowerLogicHost powerLogicHost) { - PowerLogic logic = powerLogicHost.getPowerLogic(facing); - if (isElectric) { - list.add( - StatCollector.translateToLocal("GT5U.multiblock.energy") + ": " - + EnumChatFormatting.GREEN - + GT_Utility.formatNumbers(logic.getStoredEnergy()) - + EnumChatFormatting.RESET - + " EU / " - + EnumChatFormatting.YELLOW - + GT_Utility.formatNumbers(logic.getCapacity()) - + EnumChatFormatting.RESET - + " EU"); - list.add( - StatCollector.translateToLocal("GT5U.multiblock.usage") + ": " - + EnumChatFormatting.RED - + GT_Utility.formatNumbers(eut) - + EnumChatFormatting.RESET - + " EU/t"); - list.add( - StatCollector.translateToLocal("GT5U.multiblock.mei") + ": " - + EnumChatFormatting.YELLOW - + GT_Utility.formatNumbers(logic.getVoltage()) - + EnumChatFormatting.RESET - // TODO: Put ampere getter here, once that's variable - + " EU/t(*2A) " - + StatCollector.translateToLocal("GT5U.machines.tier") - + ": " - + EnumChatFormatting.YELLOW - + VN[GT_Utility.getTier(logic.getVoltage())] - + EnumChatFormatting.RESET); - } + PowerLogic logic = getPowerLogic(); + if (isElectric) { + list.add( + StatCollector.translateToLocal("GT5U.multiblock.energy") + ": " + + EnumChatFormatting.GREEN + + GT_Utility.formatNumbers(logic.getStoredEnergy()) + + EnumChatFormatting.RESET + + " EU / " + + EnumChatFormatting.YELLOW + + GT_Utility.formatNumbers(logic.getCapacity()) + + EnumChatFormatting.RESET + + " EU"); + list.add( + StatCollector.translateToLocal("GT5U.multiblock.usage") + ": " + + EnumChatFormatting.RED + + GT_Utility.formatNumbers(getProcessingLogic().getCalculatedEut()) + + EnumChatFormatting.RESET + + " EU/t"); + list.add( + StatCollector.translateToLocal("GT5U.multiblock.mei") + ": " + + EnumChatFormatting.YELLOW + + GT_Utility.formatNumbers(logic.getVoltage()) + + EnumChatFormatting.RESET + // TODO: Put ampere getter here, once that's variable + + " EU/t(*2A) " + + StatCollector.translateToLocal("GT5U.machines.tier") + + ": " + + EnumChatFormatting.YELLOW + + VN[GT_Utility.getTier(logic.getVoltage())] + + EnumChatFormatting.RESET); } addProgressStringToScanner(player, logLevel, list); @@ -673,17 +644,6 @@ protected void updateSlots() { fluidOutput.update(); } - /** - * Must always be a positive. If the multi generates Eu/t isGenerator() should be overridden to true - */ - protected void setEut(long eut) { - if (eut < 0) { - eut = -eut; - } - - this.eut = eut; - } - @Override public int getBooleans() { int booleans = 0; @@ -793,4 +753,26 @@ public void setProcessingUpdate(boolean update) { processingUpdate = update; } + @Override + @Nullable + public PowerLogic getPowerLogic(@Nonnull ForgeDirection side) { + if (side == facing) return null; + return power; + } + + @Override + @Nonnull + public ForgeDirection getPowerOutputSide() { + return Objects.requireNonNull(facing.getOpposite()); + } + + protected void updatePowerLogic() { + power.setEnergyCapacity(GT_Values.V[tier] * power.getMaxAmperage() * 2 * MINUTE); + power.setMaxVoltage(GT_Values.V[tier]); + } + + @Nonnull + protected PowerLogic createPowerLogic() { + return new PowerLogic().setType(PowerLogic.RECEIVER); + } } diff --git a/src/main/java/gregtech/api/multitileentity/multiblock/base/ComplexParallelController.java b/src/main/java/gregtech/api/multitileentity/multiblock/base/ComplexParallelController.java index 0dcf2628a5c..d62bcf592ea 100644 --- a/src/main/java/gregtech/api/multitileentity/multiblock/base/ComplexParallelController.java +++ b/src/main/java/gregtech/api/multitileentity/multiblock/base/ComplexParallelController.java @@ -12,7 +12,6 @@ import net.minecraft.util.StatCollector; import net.minecraft.world.World; -import gregtech.api.enums.GT_Values; import gregtech.api.logic.ComplexParallelProcessingLogic; import gregtech.api.util.GT_Utility; import gregtech.api.util.GT_Waila; @@ -20,7 +19,7 @@ import mcp.mobius.waila.api.IWailaDataAccessor; public abstract class ComplexParallelController, P extends ComplexParallelProcessingLogic

> - extends PowerController { + extends Controller { protected int maxComplexParallels = 0; protected int currentComplexParallels = 0; @@ -48,11 +47,6 @@ protected boolean hasPerfectOverclock() { return false; } - protected long getEutForComplexParallel(int index) { - // As default behavior we'll give the parallel all remaining EU we have - return GT_Values.V[tier] - eut; - } - @Override protected void addProgressStringToScanner(EntityPlayer player, int logLevel, ArrayList list) { P processing = getProcessingLogic(); @@ -106,7 +100,7 @@ public void getWailaBody(ItemStack itemStack, List currentTip, IWailaDat @Override public void setProcessingLogicPower(P processingLogic) { processingLogic.setAmperageOC(true); - processingLogic.setAvailableAmperage(getPowerLogic().getAmperage() / maxComplexParallels); + processingLogic.setAvailableAmperage(getPowerLogic().getMaxAmperage() / maxComplexParallels); processingLogic.setAvailableVoltage(getPowerLogic().getVoltage() / maxComplexParallels); } diff --git a/src/main/java/gregtech/api/multitileentity/multiblock/base/Controller.java b/src/main/java/gregtech/api/multitileentity/multiblock/base/Controller.java index b861cb79d60..a22380c27e5 100644 --- a/src/main/java/gregtech/api/multitileentity/multiblock/base/Controller.java +++ b/src/main/java/gregtech/api/multitileentity/multiblock/base/Controller.java @@ -1,6 +1,7 @@ package gregtech.api.multitileentity.multiblock.base; import static gregtech.api.util.GT_Utility.moveMultipleItemStacks; +import static gregtech.common.misc.WirelessNetworkManager.strongCheckOrAddUser; import static mcp.mobius.waila.api.SpecialChars.*; import java.lang.ref.WeakReference; @@ -25,6 +26,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.StatCollector; import net.minecraft.world.World; import net.minecraftforge.common.util.ForgeDirection; import net.minecraftforge.fluids.FluidStack; @@ -59,7 +61,6 @@ import gregtech.api.enums.VoidingMode; import gregtech.api.gui.modularui.GT_UITextures; import gregtech.api.interfaces.IDescribable; -import gregtech.api.interfaces.IGlobalWirelessEnergy; import gregtech.api.interfaces.fluid.IFluidStore; import gregtech.api.interfaces.modularui.ControllerWithOptionalFeatures; import gregtech.api.logic.ControllerFluidLogic; @@ -80,6 +81,7 @@ import gregtech.api.objects.GT_ItemStack; import gregtech.api.util.GT_Multiblock_Tooltip_Builder; import gregtech.api.util.GT_Recipe; +import gregtech.api.util.GT_Utility; import gregtech.api.util.GT_Waila; import gregtech.common.tileentities.casings.upgrade.Inventory; import mcp.mobius.waila.api.IWailaConfigHandler; @@ -90,7 +92,7 @@ */ public abstract class Controller, P extends MuTEProcessingLogic

> extends MultiTileBasicMachine

implements IAlignment, IMultiBlockController, IDescribable, IMTE_AddToolTips, - ISurvivalConstructable, ControllerWithOptionalFeatures, IGlobalWirelessEnergy { + ISurvivalConstructable, ControllerWithOptionalFeatures { public static final String ALL_INVENTORIES_NAME = "all"; protected static final int AUTO_OUTPUT_FREQUENCY_TICK = 20; @@ -167,6 +169,7 @@ public Controller() { */ public boolean checkMachine() { calculateTier(); + updatePowerLogic(); return tier > 0; } @@ -602,24 +605,6 @@ public void setCleanroom(boolean cleanroom) { isCleanroom = cleanroom; } - @Override - public void setWirelessSupport(boolean canUse) { - if (canUse) { - strongCheckOrAddUser(getOwnerUuid(), getOwnerName()); - } - canUseWireless = canUse; - } - - @Override - public void setLaserSupport(boolean canUse) { - canUseLaser = canUse; - } - - @Override - public void setMaxAmperage(long amperage) { - this.amperage = amperage; - } - protected void clearSpecialLists() { upgradeCasings.clear(); functionalCasings.clear(); @@ -1210,6 +1195,11 @@ public void getWailaNBTData(EntityPlayerMP player, TileEntity tile, NBTTagCompou tag.setInteger("progress", processing.getProgress()); tag.setInteger("maxProgress", processing.getDuration()); tag.setBoolean("structureOkay", structureOkay); + tag.setBoolean("isActive", isActive()); + if (isActive()) { + tag.setLong("energyUsage", getProcessingLogic().getCalculatedEut()); + tag.setLong("energyTier", tier); + } } @Override @@ -1227,6 +1217,26 @@ public void getWailaBody(ItemStack itemStack, List currentTip, IWailaDat currentTip.add( GT_Waila.getMachineProgressString(isActive, tag.getInteger("maxProgress"), tag.getInteger("progress"))); } + boolean isActive = tag.getBoolean("isActive"); + if (isActive) { + long energyTier = tag.getLong("energyTier"); + long actualEnergyUsage = tag.getLong("energyUsage"); + if (actualEnergyUsage > 0) { + currentTip.add( + StatCollector.translateToLocalFormatted( + "GT5U.waila.energy.use_with_amperage", + GT_Utility.formatNumbers(actualEnergyUsage), + GT_Utility.getAmperageForTier(actualEnergyUsage, (byte) energyTier), + GT_Utility.getColoredTierNameFromTier((byte) energyTier))); + } else if (actualEnergyUsage < 0) { + currentTip.add( + StatCollector.translateToLocalFormatted( + "GT5U.waila.energy.produce_with_amperage", + GT_Utility.formatNumbers(-actualEnergyUsage), + GT_Utility.getAmperageForTier(-actualEnergyUsage, (byte) energyTier), + GT_Utility.getColoredTierNameFromTier((byte) energyTier))); + } + } } @Override @@ -1275,4 +1285,21 @@ public Set> getAllItemInventoryLogics(@Nonnull I }; } + @Override + public void setWirelessSupport(boolean canUse) { + if (canUse) { + strongCheckOrAddUser(getOwnerUuid(), getOwnerName()); + } + power.setCanUseWireless(canUse, getOwnerUuid()); + } + + @Override + public void setLaserSupport(boolean canUse) { + power.setCanUseLaser(canUse); + } + + @Override + public void setMaxAmperage(long amperage) { + power.setMaxAmperage(amperage); + } } diff --git a/src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlockPart.java b/src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlockPart.java index 69e494e7654..02d52fdea77 100644 --- a/src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlockPart.java +++ b/src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlockPart.java @@ -504,8 +504,9 @@ public FluidInventoryLogic getFluidLogic(@Nonnull ForgeDirection side, @Nonnull // #region Energy - Depending on the part type - proxy to the multiblock controller, if we have one @Override - public PowerLogic getPowerLogic(ForgeDirection side) { - if (facing != side) { + @Nullable + public PowerLogic getPowerLogic(@Nonnull ForgeDirection side) { + if (side != facing && side != ForgeDirection.UNKNOWN) { return null; } @@ -691,4 +692,11 @@ public String getInventoryName() { } return ""; } + + @Override + @Nonnull + public ForgeDirection getPowerOutputSide() { + if (!modeSelected(ENERGY_OUT)) return ForgeDirection.UNKNOWN; + return facing; + } } diff --git a/src/main/java/gregtech/api/multitileentity/multiblock/base/PowerController.java b/src/main/java/gregtech/api/multitileentity/multiblock/base/PowerController.java deleted file mode 100644 index de9fb55612c..00000000000 --- a/src/main/java/gregtech/api/multitileentity/multiblock/base/PowerController.java +++ /dev/null @@ -1,115 +0,0 @@ -package gregtech.api.multitileentity.multiblock.base; - -import static gregtech.api.enums.TickTime.MINUTE; - -import java.util.List; - -import javax.annotation.Nonnull; - -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.StatCollector; -import net.minecraft.world.World; -import net.minecraftforge.common.util.ForgeDirection; - -import gregtech.api.enums.GT_Values; -import gregtech.api.logic.MuTEProcessingLogic; -import gregtech.api.logic.PowerLogic; -import gregtech.api.logic.interfaces.PowerLogicHost; -import gregtech.api.util.GT_Utility; -import mcp.mobius.waila.api.IWailaConfigHandler; -import mcp.mobius.waila.api.IWailaDataAccessor; - -public abstract class PowerController, P extends MuTEProcessingLogic

> - extends Controller implements PowerLogicHost { - - public PowerController() { - super(); - power = new PowerLogic().setType(PowerLogic.RECEIVER); - } - - @Nonnull - protected PowerLogic power; - - @Override - public void writeMultiTileNBT(NBTTagCompound nbt) { - super.writeMultiTileNBT(nbt); - power.saveToNBT(nbt); - } - - @Override - public void readMultiTileNBT(NBTTagCompound nbt) { - super.readMultiTileNBT(nbt); - power.loadFromNBT(nbt); - } - - @Override - @Nonnull - public PowerLogic getPowerLogic(@Nonnull ForgeDirection side) { - return power; - } - - @Override - public boolean checkMachine() { - boolean result = super.checkMachine(); - updatePowerLogic(); - return result; - } - - @Override - protected boolean checkRecipe() { - return false; - } - - protected boolean hasPerfectOverclock() { - return false; - } - - protected void updatePowerLogic() { - power.setEnergyCapacity(GT_Values.V[tier] * amperage * 2 * MINUTE); - power.setAmperage(amperage); - power.setMaxVoltage(GT_Values.V[tier]); - power.setCanUseLaser(canUseLaser); - power.setCanUseWireless(canUseWireless, getOwnerUuid()); - } - - @Override - public void getWailaNBTData(EntityPlayerMP player, TileEntity tile, NBTTagCompound tag, World world, int x, int y, - int z) { - super.getWailaNBTData(player, tile, tag, world, x, y, z); - tag.setBoolean("isActive", isActive()); - if (isActive()) { - tag.setLong("energyUsage", eut); - tag.setLong("energyTier", tier); - } - } - - @Override - public void getWailaBody(ItemStack itemStack, List currentTip, IWailaDataAccessor accessor, - IWailaConfigHandler config) { - super.getWailaBody(itemStack, currentTip, accessor, config); - final NBTTagCompound tag = accessor.getNBTData(); - boolean isActive = tag.getBoolean("isActive"); - if (isActive) { - long energyTier = tag.getLong("energyTier"); - long actualEnergyUsage = tag.getLong("energyUsage"); - if (actualEnergyUsage > 0) { - currentTip.add( - StatCollector.translateToLocalFormatted( - "GT5U.waila.energy.use_with_amperage", - GT_Utility.formatNumbers(actualEnergyUsage), - GT_Utility.getAmperageForTier(actualEnergyUsage, (byte) energyTier), - GT_Utility.getColoredTierNameFromTier((byte) energyTier))); - } else if (actualEnergyUsage < 0) { - currentTip.add( - StatCollector.translateToLocalFormatted( - "GT5U.waila.energy.produce_with_amperage", - GT_Utility.formatNumbers(-actualEnergyUsage), - GT_Utility.getAmperageForTier(-actualEnergyUsage, (byte) energyTier), - GT_Utility.getColoredTierNameFromTier((byte) energyTier))); - } - } - } -} diff --git a/src/main/java/gregtech/api/multitileentity/multiblock/base/StackableController.java b/src/main/java/gregtech/api/multitileentity/multiblock/base/StackableController.java index 49278d9b6c5..37ea3c889e1 100644 --- a/src/main/java/gregtech/api/multitileentity/multiblock/base/StackableController.java +++ b/src/main/java/gregtech/api/multitileentity/multiblock/base/StackableController.java @@ -7,7 +7,7 @@ import gregtech.api.logic.MuTEProcessingLogic; public abstract class StackableController, P extends MuTEProcessingLogic

> - extends PowerController { + extends Controller { protected static String STACKABLE_STOP = "STACKABLE_STOP"; protected static String STACKABLE_MIDDLE = "STACKABLE_MIDDLE"; diff --git a/src/main/java/gregtech/api/task/tasks/PowerOutputTask.java b/src/main/java/gregtech/api/task/tasks/PowerOutputTask.java new file mode 100644 index 00000000000..ef800635fb1 --- /dev/null +++ b/src/main/java/gregtech/api/task/tasks/PowerOutputTask.java @@ -0,0 +1,32 @@ +package gregtech.api.task.tasks; + +import javax.annotation.Nonnull; + +import gregtech.api.interfaces.tileentity.IMachineProgress; +import gregtech.api.logic.interfaces.PowerLogicHost; +import gregtech.api.task.TaskHost; +import gregtech.api.task.TickableTask; + +public class PowerOutputTask extends TickableTask { + + private static final String NAME = "powerOutput"; + + public PowerOutputTask(@Nonnull T taskHost) { + super(taskHost); + } + + @Override + @Nonnull + public String getName() { + return NAME; + } + + @Override + public void update(long tick, boolean isServerSide) { + if (!isServerSide) return; + if (!taskHost.isActive()) return; + if (!taskHost.isEnergyEmitter()) return; + taskHost.emitEnergyFromLogic(); + } + +} diff --git a/src/main/java/gregtech/common/GT_Proxy.java b/src/main/java/gregtech/common/GT_Proxy.java index 27bd68ffc50..4d8239ca479 100644 --- a/src/main/java/gregtech/common/GT_Proxy.java +++ b/src/main/java/gregtech/common/GT_Proxy.java @@ -139,7 +139,6 @@ import gregtech.api.enums.ToolDictNames; import gregtech.api.fluid.GT_FluidFactory; import gregtech.api.interfaces.IBlockOnWalkOver; -import gregtech.api.interfaces.IGlobalWirelessEnergy; import gregtech.api.interfaces.IProjectileItem; import gregtech.api.interfaces.IToolStats; import gregtech.api.interfaces.internal.IGT_Mod; @@ -176,7 +175,7 @@ import gregtech.common.misc.GlobalMetricsCoverDatabase; import gregtech.common.misc.spaceprojects.SpaceProjectWorldSavedData; -public abstract class GT_Proxy implements IGT_Mod, IGuiHandler, IFuelHandler, IGlobalWirelessEnergy { +public abstract class GT_Proxy implements IGT_Mod, IGuiHandler, IFuelHandler { private static final EnumSet PREVENTED_ORES = EnumSet.of( OreGenEvent.GenerateMinable.EventType.COAL, diff --git a/src/main/java/gregtech/common/misc/GT_Command.java b/src/main/java/gregtech/common/misc/GT_Command.java index 35e7a71f653..ad3293be907 100644 --- a/src/main/java/gregtech/common/misc/GT_Command.java +++ b/src/main/java/gregtech/common/misc/GT_Command.java @@ -1,5 +1,13 @@ package gregtech.common.misc; +import static gregtech.common.misc.WirelessNetworkManager.addEUToGlobalEnergyMap; +import static gregtech.common.misc.WirelessNetworkManager.getRawUUIDFromUsername; +import static gregtech.common.misc.WirelessNetworkManager.getUUIDFromUsername; +import static gregtech.common.misc.WirelessNetworkManager.getUserEU; +import static gregtech.common.misc.WirelessNetworkManager.getUsernameFromUUID; +import static gregtech.common.misc.WirelessNetworkManager.joinUserNetwork; +import static gregtech.common.misc.WirelessNetworkManager.setUserEU; + import java.lang.reflect.Field; import java.math.BigInteger; import java.util.ArrayList; @@ -16,12 +24,11 @@ import gregtech.GT_Mod; import gregtech.api.enums.GT_Values; -import gregtech.api.interfaces.IGlobalWirelessEnergy; import gregtech.api.objects.GT_ChunkManager; import gregtech.api.util.GT_Utility; import gregtech.common.GT_Pollution; -public final class GT_Command extends CommandBase implements IGlobalWirelessEnergy { +public final class GT_Command extends CommandBase { @Override public String getCommandName() { @@ -355,7 +362,7 @@ public void processCommand(ICommandSender sender, String[] strings) { "User " + formatted_username + " is currently in network of " + EnumChatFormatting.BLUE - + GetUsernameFromUUID(uuidTeam) + + getUsernameFromUUID(uuidTeam) + EnumChatFormatting.RESET + ".")); diff --git a/src/main/java/gregtech/common/misc/WirelessNetworkManager.java b/src/main/java/gregtech/common/misc/WirelessNetworkManager.java new file mode 100644 index 00000000000..dc11becdbbe --- /dev/null +++ b/src/main/java/gregtech/common/misc/WirelessNetworkManager.java @@ -0,0 +1,164 @@ +package gregtech.common.misc; + +import static gregtech.common.misc.GlobalVariableStorage.GlobalEnergy; +import static gregtech.common.misc.GlobalVariableStorage.GlobalEnergyName; +import static gregtech.common.misc.GlobalVariableStorage.GlobalEnergyTeam; + +import java.math.BigInteger; +import java.util.UUID; + +import net.minecraft.entity.player.EntityPlayer; + +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; + +public class WirelessNetworkManager { + + private WirelessNetworkManager() {} + + // User 0 will join user 1 by calling this function. They will share the same energy network. + public static void joinUserNetwork(String user_uuid_0, String user_uuid_1) { + GlobalEnergyTeam.put(user_uuid_0, user_uuid_1); + } + + // Adds a user to the energy map if they do not already exist. Otherwise, do nothing. Will also check if the user + // has changed their username and adjust the maps accordingly. This should be called infrequently. Ideally on first + // tick of a machine being placed only. + + public static void strongCheckOrAddUser(EntityPlayer user) { + strongCheckOrAddUser( + user.getUniqueID() + .toString(), + user.getDisplayName()); + } + + public static void strongCheckOrAddUser(UUID user_uuid, String user_name) { + strongCheckOrAddUser(user_uuid.toString(), user_name); + } + + public static void strongCheckOrAddUser(String user_uuid, String user_name) { + + // Check if the user has a team. Add them if not. + GlobalEnergyTeam.putIfAbsent(user_uuid, user_uuid); + + // Check if the user is in the global energy map. + GlobalEnergy.putIfAbsent(user_uuid, BigInteger.ZERO); + + // If the username linked to the users fixed uuid is not equal to their current name then remove it. + // This indicates that their username has changed. + if (!(GlobalEnergyName.getOrDefault(user_uuid, "") + .equals(user_name))) { + String old_name = GlobalEnergyName.get(user_uuid); + GlobalEnergyName.remove(old_name); + } + + // Add UUID -> Name, Name -> UUID. + GlobalEnergyName.put(user_name, user_uuid); + GlobalEnergyName.put(user_uuid, user_name); + } + + // ------------------------------------------------------------------------------------ + // Add EU to the users global energy. You can enter a negative number to subtract it. + // If the value goes below 0 it will return false and not perform the operation. + // BigIntegers have much slower operations than longs/ints. You should call these methods + // as infrequently as possible and bulk store values to add to the global map. + public static boolean addEUToGlobalEnergyMap(String userUUID, BigInteger EU) { + + // Mark the data as dirty and in need of saving. + try { + GlobalEnergyWorldSavedData.INSTANCE.markDirty(); + } catch (Exception exception) { + System.out.println("COULD NOT MARK GLOBAL ENERGY AS DIRTY IN ADD EU"); + exception.printStackTrace(); + } + + // Get the team UUID. Users are by default in a team with a UUID equal to their player UUID. + String teamUUID = GlobalEnergyTeam.getOrDefault(userUUID, userUUID); + + // Get the teams total energy stored. If they are not in the map, return 0 EU. + BigInteger totalEU = GlobalEnergy.getOrDefault(teamUUID, BigInteger.ZERO); + totalEU = totalEU.add(EU); + + // If there is sufficient EU then complete the operation and return true. + if (totalEU.signum() >= 0) { + GlobalEnergy.put(teamUUID, totalEU); + return true; + } + + // There is insufficient EU so cancel the operation and return false. + return false; + } + + public static boolean addEUToGlobalEnergyMap(UUID user_uuid, BigInteger EU) { + return addEUToGlobalEnergyMap(user_uuid.toString(), EU); + } + + public static boolean addEUToGlobalEnergyMap(UUID user_uuid, long EU) { + return addEUToGlobalEnergyMap(user_uuid.toString(), BigInteger.valueOf(EU)); + } + + public static boolean addEUToGlobalEnergyMap(UUID user_uuid, int EU) { + return addEUToGlobalEnergyMap(user_uuid.toString(), BigInteger.valueOf(EU)); + } + + public static boolean addEUToGlobalEnergyMap(String user_uuid, long EU) { + return addEUToGlobalEnergyMap(user_uuid, BigInteger.valueOf(EU)); + } + + public static boolean addEUToGlobalEnergyMap(String user_uuid, int EU) { + return addEUToGlobalEnergyMap(user_uuid, BigInteger.valueOf(EU)); + } + + // ------------------------------------------------------------------------------------ + + public static BigInteger getUserEU(String user_uuid) { + return GlobalEnergy.getOrDefault(GlobalEnergyTeam.getOrDefault(user_uuid, user_uuid), BigInteger.ZERO); + } + + // This overwrites the EU in the network. Only use this if you are absolutely sure you know what you are doing. + public static void setUserEU(String user_uuid, BigInteger EU) { + // Mark the data as dirty and in need of saving. + try { + GlobalEnergyWorldSavedData.INSTANCE.markDirty(); + } catch (Exception exception) { + System.out.println("COULD NOT MARK GLOBAL ENERGY AS DIRTY IN SET EU"); + exception.printStackTrace(); + } + + GlobalEnergy.put(GlobalEnergyTeam.get(user_uuid), EU); + } + + public static String getUsernameFromUUID(String uuid) { + return GlobalEnergyName.getOrDefault(GlobalEnergyTeam.getOrDefault(uuid, ""), ""); + } + + public static String getUUIDFromUsername(String username) { + return GlobalEnergyTeam.getOrDefault(GlobalEnergyName.getOrDefault(username, ""), ""); + } + + /** + * + * @param username + * @return + */ + public static String getRawUUIDFromUsername(String username) { + return GlobalEnergyName.getOrDefault(username, ""); + } + + public static void clearGlobalEnergyInformationMaps() { + // Do not use this unless you are 100% certain you know what you are doing. + GlobalEnergy.clear(); + GlobalEnergyName.clear(); + GlobalEnergyTeam.clear(); + } + + public static String processInitialSettings(final IGregTechTileEntity machine) { + + // UUID and username of the owner. + final String UUID = machine.getOwnerUuid() + .toString(); + final String name = machine.getOwnerName(); + + strongCheckOrAddUser(UUID, name); + return UUID; + } +} diff --git a/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_TranscendentPlasmaMixer.java b/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_TranscendentPlasmaMixer.java index e4873f6d9da..0a554d2ee91 100644 --- a/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_TranscendentPlasmaMixer.java +++ b/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_TranscendentPlasmaMixer.java @@ -11,6 +11,8 @@ import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FUSION1_GLOW; import static gregtech.api.enums.Textures.BlockIcons.casingTexturePages; import static gregtech.api.util.GT_StructureUtility.buildHatchAdder; +import static gregtech.common.misc.WirelessNetworkManager.addEUToGlobalEnergyMap; +import static gregtech.common.misc.WirelessNetworkManager.processInitialSettings; import static gregtech.common.tileentities.machines.multi.GT_MetaTileEntity_PlasmaForge.DIM_BRIDGE_CASING; import static gregtech.common.tileentities.machines.multi.GT_MetaTileEntity_PlasmaForge.DIM_INJECTION_CASING; import static gregtech.common.tileentities.machines.multi.GT_MetaTileEntity_PlasmaForge.DIM_TRANS_CASING; @@ -34,7 +36,6 @@ import com.gtnewhorizon.structurelib.structure.StructureDefinition; import gregtech.api.GregTech_API; -import gregtech.api.interfaces.IGlobalWirelessEnergy; import gregtech.api.interfaces.ITexture; import gregtech.api.interfaces.metatileentity.IMetaTileEntity; import gregtech.api.interfaces.tileentity.IGregTechTileEntity; @@ -52,7 +53,7 @@ public class GT_MetaTileEntity_TranscendentPlasmaMixer extends GT_MetaTileEntity_EnhancedMultiBlockBase - implements IGlobalWirelessEnergy, ISurvivalConstructable { + implements ISurvivalConstructable { private static final String[][] structure = new String[][] { { " CAC ", " ABA ", " ABA ", " A~A ", " ABA ", " ABA ", " CAC " }, diff --git a/src/test/java/gregtech/globalenergymap/IGlobalWirelessEnergy_UnitTest.java b/src/test/java/gregtech/globalenergymap/IGlobalWirelessEnergy_UnitTest.java index 5288773efa3..8e2b9f677e7 100644 --- a/src/test/java/gregtech/globalenergymap/IGlobalWirelessEnergy_UnitTest.java +++ b/src/test/java/gregtech/globalenergymap/IGlobalWirelessEnergy_UnitTest.java @@ -3,6 +3,12 @@ import static gregtech.common.misc.GlobalVariableStorage.GlobalEnergy; import static gregtech.common.misc.GlobalVariableStorage.GlobalEnergyName; import static gregtech.common.misc.GlobalVariableStorage.GlobalEnergyTeam; +import static gregtech.common.misc.WirelessNetworkManager.addEUToGlobalEnergyMap; +import static gregtech.common.misc.WirelessNetworkManager.clearGlobalEnergyInformationMaps; +import static gregtech.common.misc.WirelessNetworkManager.getUserEU; +import static gregtech.common.misc.WirelessNetworkManager.getUsernameFromUUID; +import static gregtech.common.misc.WirelessNetworkManager.joinUserNetwork; +import static gregtech.common.misc.WirelessNetworkManager.strongCheckOrAddUser; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -11,9 +17,7 @@ import org.junit.jupiter.api.Test; -import gregtech.api.interfaces.IGlobalWirelessEnergy; - -class IGlobalWirelessEnergy_UnitTest implements IGlobalWirelessEnergy { +class IGlobalWirelessEnergy_UnitTest { static final String message = "Comparison failed"; @@ -31,7 +35,7 @@ void IGlobalWirelessEnergy_AddingEU() { addEUToGlobalEnergyMap(test_id, 1L); assertEquals(GlobalEnergy.get(test_id), new BigInteger("3"), message); - IGlobalWirelessEnergy.clearGlobalEnergyInformationMaps(); + clearGlobalEnergyInformationMaps(); } @Test @@ -57,7 +61,7 @@ void IGlobalWirelessEnergy_NoNegativeEU() { assertTrue(addEUToGlobalEnergyMap(user_uuid, new BigInteger("-2"))); assertEquals(getUserEU(user_uuid), BigInteger.ZERO, message); - IGlobalWirelessEnergy.clearGlobalEnergyInformationMaps(); + clearGlobalEnergyInformationMaps(); } @Test @@ -70,7 +74,7 @@ void IGlobalWirelessEnergy_StrongCheckOrAddUser() { assertEquals(GlobalEnergyTeam.get(user_uuid), user_uuid, message); assertEquals(GlobalEnergyName.get(user_uuid), user_name, message); - IGlobalWirelessEnergy.clearGlobalEnergyInformationMaps(); + clearGlobalEnergyInformationMaps(); } @Test @@ -98,7 +102,7 @@ void IGlobalWirelessEnergy_NameChange() { assertEquals(GlobalEnergyName.get(user_uuid), user_name_0, message); assertEquals(GlobalEnergyName.get(user_name_0), user_uuid, message); - IGlobalWirelessEnergy.clearGlobalEnergyInformationMaps(); + clearGlobalEnergyInformationMaps(); } @Test @@ -154,7 +158,7 @@ void IGlobalWirelessEnergy_TeamChange() { assertEquals(getUserEU(user_uuid_1), BigInteger.ONE, message); assertEquals(getUserEU(user_uuid_2), BigInteger.ONE, message); - IGlobalWirelessEnergy.clearGlobalEnergyInformationMaps(); + clearGlobalEnergyInformationMaps(); } @Test @@ -168,14 +172,14 @@ void IGlobalWirelessEnergy_UUID() { strongCheckOrAddUser(user_uuid_0, user_name_0); strongCheckOrAddUser(user_uuid_1, user_name_1); - assertEquals(GetUsernameFromUUID(user_uuid_0), user_name_0, message); - assertEquals(GetUsernameFromUUID(user_uuid_1), user_name_1, message); + assertEquals(getUsernameFromUUID(user_uuid_0), user_name_0, message); + assertEquals(getUsernameFromUUID(user_uuid_1), user_name_1, message); joinUserNetwork(user_uuid_0, user_uuid_1); - assertEquals(GetUsernameFromUUID(user_uuid_0), user_name_1, message); - assertEquals(GetUsernameFromUUID(user_uuid_1), user_name_1, message); + assertEquals(getUsernameFromUUID(user_uuid_0), user_name_1, message); + assertEquals(getUsernameFromUUID(user_uuid_1), user_name_1, message); - IGlobalWirelessEnergy.clearGlobalEnergyInformationMaps(); + clearGlobalEnergyInformationMaps(); } }