/* * This file is part of Project-Zed. Project-Zed is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 * of the License, or (at your option) any later version. Project-Zed is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should * have received a copy of the GNU General Public License along with Project-Zed. If not, see <http://www.gnu * .org/licenses/> */ package com.projectzed.mod.util; import com.projectzed.api.util.FluidUtils; import net.minecraft.nbt.NBTTagCompound; import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidStack; /** * Largely immutable class (except for ability to adjust the amount of fluid as needed), used for * tracking and storing fluid based coolant for anything that uses a coolant. * * @author hockeyhurd * @version 1/14/2016. */ public final class Coolant { /** * An indication to class methods to treat the amount of coolant as if * */ public static final int FULL_FLAG = -1; private static final String NBT_TAG_PREFIX = "Coolant Fluid "; public static final Coolant AIR = new Coolant(null, FULL_FLAG, 1.0f); private final Fluid fluid; private int amount; private final float efficiency; /** * Creates coolant with default amount set to 'full'. * * @param fluid Fluid used. * @param efficiency Efficiency of coolant. */ public Coolant(Fluid fluid, float efficiency) { this(fluid, FULL_FLAG, efficiency); } /** * Creates coolant with a givent amount. * * @param fluid Fluid used. * @param amount Amount of coolant. * @param efficiency Efficiency of coolant. */ public Coolant(Fluid fluid, int amount, float efficiency) { this.fluid = fluid; this.amount = amount; this.efficiency = efficiency; } /** * Coolant's fluid. * * @return Fluid in coolant. */ public Fluid getFluid() { return fluid; } /** * Amount of coolant. * * @return Int amount of coolant (typically in millibuckets or 'mb'). */ public int getAmount() { return amount; } /** * Sets the amount of coolant. * * @param amount Int amount of coolant (typically in millibuckets or 'mb'). */ public void setAmount(int amount) { this.amount = amount; } /** * Adds the given amount to the total amount. * * @param amount Int amount to add. */ public void addAmount(int amount) { if (this.amount > FULL_FLAG) this.amount += amount; } /** * Gets the base efficiency of the coolant. * * @return Float base efficiency. */ public float getBaseEfficiency() { return efficiency; } /** * Gets a copy of the coolant object. * * @return Coolant copy object. */ public Coolant copy() { return new Coolant(fluid, amount, efficiency); } /** * Checks if the coolant is enough to fill a given dimensioned size reactor. * * @param width int. * @param height int. * @param depth int. * @param offset Amount to disregard (i.e. ReactantCore). * @return True if fills the reactor's chamber, else return false. */ public boolean isFullReactorChamber(int width, int height, int depth, int offset) { final int effectiveVolume = calculateChamberSize(width, height, depth, offset); return amount == FULL_FLAG || effectiveVolume == amount / Reference.Constants.MILLI_BUCKETS_PER_BLOCK_SPACE; } /** * Calculates the effective efficiency of the coolant. * * @param width int. * @param height int. * @param depth int. * @param offset Amount to disregard (i.e. ReactantCore). * @return Effective efficiency, calculated by the percentage filled of the reactor and the amount of coolant. */ public float getEffectiveEfficiency(int width, int height, int depth, int offset) { if (amount == FULL_FLAG) return efficiency; final int effectiveVolume = calculateChamberSize(width, height, depth, offset); final float percentFilled = (amount / Reference.Constants.MILLI_BUCKETS_PER_BLOCK_SPACE) / effectiveVolume; return percentFilled * efficiency; } /** * Checks if fluids between 2 coolants are equal. * * @param coolant Coolant to check and reference. * @return Boolean result. */ public boolean isFluidEqual(Coolant coolant) { return coolant != null && fluid != null && coolant.fluid != null && fluid.equals(coolant.fluid); } @Override public int hashCode() { int result = fluid != null ? fluid.hashCode() : 0; result = 31 * result + amount; result = 31 * result + (efficiency != +0.0f ? Float.floatToIntBits(efficiency) : 0); return result; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Coolant coolant = (Coolant) o; if (amount != coolant.amount) return false; if (Float.compare(coolant.efficiency, efficiency) != 0) return false; return !(fluid != null ? !fluid.equals(coolant.fluid) : coolant.fluid != null); } /** * Static function to read Coolant from NBT. * * @param comp NBTTagCompound to read from. * @return Coolant object. */ public static Coolant readNBT(NBTTagCompound comp) { String fluidName = comp.getString(NBT_TAG_PREFIX + "Fluid Name"); FluidStack fluidStack = FluidUtils.readNBT(comp, NBT_TAG_PREFIX + fluidName); float efficiency = comp.getFloat(NBT_TAG_PREFIX + "Efficiency"); return new Coolant(fluidStack.getFluid(), fluidStack.amount, efficiency); } /** * Method to save Coolant to NBT. * * @param comp NBTTagCompound to write to. * @param coolant Coolant object to write. */ public static void saveNBT(NBTTagCompound comp, Coolant coolant) { FluidStack fluidStack = FluidUtils.createFluidStack(coolant.fluid, coolant.amount); comp.setString(NBT_TAG_PREFIX + "Fluid Name", coolant.fluid.getName()); FluidUtils.saveNBT(comp, fluidStack, NBT_TAG_PREFIX + coolant.fluid.getName()); comp.setFloat(NBT_TAG_PREFIX + "Efficiency", coolant.efficiency); } /** * Static function to help calculate the chamber volume given the size in (whole) blocks. * * @param width int. * @param height int. * @param depth int. * @param offset Amount to disregard (i.e. ReactantCore). * @return Calculated nuclear reactor chamber size. */ public static int calculateChamberSize(int width, int height, int depth, int offset) { return (width - 2) * (height - 2) * (depth - 2) - offset; } }