diff --git a/src/main/java/WayofTime/bloodmagic/altar/BloodAltar.java b/src/main/java/WayofTime/bloodmagic/altar/BloodAltar.java index 7d492d0c..f888c575 100644 --- a/src/main/java/WayofTime/bloodmagic/altar/BloodAltar.java +++ b/src/main/java/WayofTime/bloodmagic/altar/BloodAltar.java @@ -1,16 +1,75 @@ package WayofTime.bloodmagic.altar; -import WayofTime.bloodmagic.api.BlockStack; -import WayofTime.bloodmagic.api.altar.*; -import WayofTime.bloodmagic.block.BlockBloodRune; -import WayofTime.bloodmagic.util.Utils; -import net.minecraft.util.BlockPos; -import net.minecraft.world.World; - import java.util.List; +import net.minecraft.block.state.IBlockState; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.BlockPos; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.world.World; +import net.minecraftforge.fluids.FluidContainerRegistry; +import net.minecraftforge.fluids.FluidStack; +import WayofTime.bloodmagic.api.BlockStack; +import WayofTime.bloodmagic.api.BloodMagicAPI; +import WayofTime.bloodmagic.api.Constants; +import WayofTime.bloodmagic.api.altar.AltarComponent; +import WayofTime.bloodmagic.api.altar.AltarUpgrade; +import WayofTime.bloodmagic.api.altar.EnumAltarComponent; +import WayofTime.bloodmagic.api.altar.EnumAltarTier; +import WayofTime.bloodmagic.api.altar.IAltarComponent; +import WayofTime.bloodmagic.api.orb.IBloodOrb; +import WayofTime.bloodmagic.api.registry.AltarRecipeRegistry; +import WayofTime.bloodmagic.api.util.helper.NetworkHelper; +import WayofTime.bloodmagic.block.BlockBloodRune; +import WayofTime.bloodmagic.block.BlockLifeEssence; +import WayofTime.bloodmagic.tile.TileAltar; +import WayofTime.bloodmagic.util.Utils; + +import com.google.common.base.Enums; +import com.google.common.base.Strings; + public class BloodAltar { + private TileAltar tileAltar; + private int internalCounter = 0; + + public boolean isActive; + protected FluidStack fluidOutput = new FluidStack(BlockLifeEssence.getLifeEssence(), 0); + protected FluidStack fluidInput = new FluidStack(BlockLifeEssence.getLifeEssence(), 0); + private EnumAltarTier altarTier = EnumAltarTier.ONE; + private AltarUpgrade upgrade; + private int capacity = FluidContainerRegistry.BUCKET_VOLUME * 10; + private FluidStack fluid = new FluidStack(BloodMagicAPI.getLifeEssence(), 0); + private int liquidRequired; //mB + private boolean canBeFilled; + private int consumptionRate; + private int drainRate; + private float consumptionMultiplier; + private float efficiencyMultiplier; + private float sacrificeEfficiencyMultiplier; + private float selfSacrificeEfficiencyMultiplier; + private float capacityMultiplier = 1; + private float orbCapacityMultiplier; + private float dislocationMultiplier; + private int accelerationUpgrades; + private boolean isUpgraded; + private boolean isResultBlock; + private int bufferCapacity = FluidContainerRegistry.BUCKET_VOLUME; + private int progress; + private int lockdownDuration; + private int demonBloodDuration; + + private int cooldownAfterCrafting = 500; + + private ItemStack result; + + public BloodAltar(TileAltar tileAltar) + { + this.tileAltar = tileAltar; + } + static { EnumAltarTier.ONE.buildComponents(); EnumAltarTier.TWO.buildComponents(); @@ -112,4 +171,392 @@ public class BloodAltar { return upgrades; } + + public void readFromNBT(NBTTagCompound tagCompound) { + if (!tagCompound.hasKey(Constants.NBT.EMPTY)) { + FluidStack fluid = FluidStack.loadFluidStackFromNBT(tagCompound); + + if (fluid != null) + setMainFluid(fluid); + + FluidStack fluidOut = new FluidStack(BloodMagicAPI.getLifeEssence(), tagCompound.getInteger(Constants.NBT.OUTPUT_AMOUNT)); + setOutputFluid(fluidOut); + + FluidStack fluidIn = new FluidStack(BloodMagicAPI.getLifeEssence(), tagCompound.getInteger(Constants.NBT.INPUT_AMOUNT)); + setInputFluid(fluidIn); + } + + internalCounter = tagCompound.getInteger("internalCounter"); + altarTier = Enums.getIfPresent(EnumAltarTier.class, tagCompound.getString(Constants.NBT.ALTAR_TIER)).or(EnumAltarTier.ONE); + isActive = tagCompound.getBoolean(Constants.NBT.ALTAR_ACTIVE); + liquidRequired = tagCompound.getInteger(Constants.NBT.ALTAR_LIQUID_REQ); + canBeFilled = tagCompound.getBoolean(Constants.NBT.ALTAR_FILLABLE); + isUpgraded = tagCompound.getBoolean(Constants.NBT.ALTAR_UPGRADED); + consumptionRate = tagCompound.getInteger(Constants.NBT.ALTAR_CONSUMPTION_RATE); + drainRate = tagCompound.getInteger(Constants.NBT.ALTAR_DRAIN_RATE); + consumptionMultiplier = tagCompound.getFloat(Constants.NBT.ALTAR_CONSUMPTION_MULTIPLIER); + efficiencyMultiplier = tagCompound.getFloat(Constants.NBT.ALTAR_EFFICIENCY_MULTIPLIER); + selfSacrificeEfficiencyMultiplier = tagCompound.getFloat(Constants.NBT.ALTAR_SELF_SACRIFICE_MULTIPLIER); + sacrificeEfficiencyMultiplier = tagCompound.getFloat(Constants.NBT.ALTAR_SACRIFICE_MULTIPLIER); + capacityMultiplier = tagCompound.getFloat(Constants.NBT.ALTAR_CAPACITY_MULTIPLIER); + orbCapacityMultiplier = tagCompound.getFloat(Constants.NBT.ALTAR_ORB_CAPACITY_MULTIPLIER); + dislocationMultiplier = tagCompound.getFloat(Constants.NBT.ALTAR_DISLOCATION_MULTIPLIER); + capacity = tagCompound.getInteger(Constants.NBT.ALTAR_CAPACITY); + bufferCapacity = tagCompound.getInteger(Constants.NBT.ALTAR_BUFFER_CAPACITY); + progress = tagCompound.getInteger(Constants.NBT.ALTAR_PROGRESS); + isResultBlock = tagCompound.getBoolean(Constants.NBT.ALTAR_IS_RESULT_BLOCK); + lockdownDuration = tagCompound.getInteger(Constants.NBT.ALTAR_LOCKDOWN_DURATION); + accelerationUpgrades = tagCompound.getInteger(Constants.NBT.ALTAR_ACCELERATION_UPGRADES); + demonBloodDuration = tagCompound.getInteger(Constants.NBT.ALTAR_DEMON_BLOOD_DURATION); + cooldownAfterCrafting = tagCompound.getInteger(Constants.NBT.ALTAR_COOLDOWN_AFTER_CRAFTING); + } + + public void writeToNBT(NBTTagCompound tagCompound) { + + if (fluid != null) + fluid.writeToNBT(tagCompound); + else + tagCompound.setString(Constants.NBT.EMPTY, ""); + + if (fluidOutput != null) + tagCompound.setInteger(Constants.NBT.OUTPUT_AMOUNT, fluidOutput.amount); + + if (fluidInput != null) + tagCompound.setInteger(Constants.NBT.INPUT_AMOUNT, fluidInput.amount); + + tagCompound.setInteger("internalCounter", internalCounter); + tagCompound.setString(Constants.NBT.ALTAR_TIER, altarTier.name()); + tagCompound.setBoolean(Constants.NBT.ALTAR_ACTIVE, isActive); + tagCompound.setInteger(Constants.NBT.ALTAR_LIQUID_REQ, liquidRequired); + tagCompound.setBoolean(Constants.NBT.ALTAR_FILLABLE, canBeFilled); + tagCompound.setBoolean(Constants.NBT.ALTAR_UPGRADED, isUpgraded); + tagCompound.setInteger(Constants.NBT.ALTAR_CONSUMPTION_RATE, consumptionRate); + tagCompound.setInteger(Constants.NBT.ALTAR_DRAIN_RATE, drainRate); + tagCompound.setFloat(Constants.NBT.ALTAR_CONSUMPTION_MULTIPLIER, consumptionMultiplier); + tagCompound.setFloat(Constants.NBT.ALTAR_EFFICIENCY_MULTIPLIER, efficiencyMultiplier); + tagCompound.setFloat(Constants.NBT.ALTAR_SACRIFICE_MULTIPLIER, sacrificeEfficiencyMultiplier); + tagCompound.setFloat(Constants.NBT.ALTAR_SELF_SACRIFICE_MULTIPLIER, selfSacrificeEfficiencyMultiplier); + tagCompound.setBoolean(Constants.NBT.ALTAR_IS_RESULT_BLOCK, isResultBlock); + tagCompound.setFloat(Constants.NBT.ALTAR_CAPACITY_MULTIPLIER, capacityMultiplier); + tagCompound.setFloat(Constants.NBT.ALTAR_ORB_CAPACITY_MULTIPLIER, orbCapacityMultiplier); + tagCompound.setFloat(Constants.NBT.ALTAR_DISLOCATION_MULTIPLIER, dislocationMultiplier); + tagCompound.setInteger(Constants.NBT.ALTAR_CAPACITY, capacity); + tagCompound.setInteger(Constants.NBT.ALTAR_PROGRESS, progress); + tagCompound.setInteger(Constants.NBT.ALTAR_BUFFER_CAPACITY, bufferCapacity); + tagCompound.setInteger(Constants.NBT.ALTAR_LOCKDOWN_DURATION, lockdownDuration); + tagCompound.setInteger(Constants.NBT.ALTAR_ACCELERATION_UPGRADES, accelerationUpgrades); + tagCompound.setInteger(Constants.NBT.ALTAR_DEMON_BLOOD_DURATION, demonBloodDuration); + tagCompound.setInteger(Constants.NBT.ALTAR_COOLDOWN_AFTER_CRAFTING, cooldownAfterCrafting); + } + + public void startCycle() { + if (tileAltar.getWorld() != null) + tileAltar.getWorld().markBlockForUpdate(tileAltar.getPos()); + + checkTier(); + + if (fluid == null || fluid.amount <= 0) + return; + + if (!isActive) + progress = 0; + + if (tileAltar.getStackInSlot(0) != null) { + // Do recipes + for (ItemStack itemStack : AltarRecipeRegistry.getRecipes().keySet()) { + if (tileAltar.getStackInSlot(0).getIsItemStackEqual(AltarRecipeRegistry.getRecipes().get(itemStack).getInput())) { + AltarRecipeRegistry.AltarRecipe recipe = AltarRecipeRegistry.getRecipeForInput(itemStack); + + if (altarTier.ordinal() >= recipe.getMinTier().ordinal()) { + this.isActive = true; + this.result = new ItemStack(recipe.getOutput().getItem(), 1, recipe.getOutput().getMetadata()); + this.liquidRequired = recipe.getSyphon(); + this.canBeFilled = recipe.isUseTag(); + this.consumptionRate = recipe.getConsumeRate(); + this.drainRate = recipe.getDrainRate(); + return; + } + } + } + } + + isActive = false; + } + + public void update() + { + World world = tileAltar.getWorld(); + BlockPos pos = tileAltar.getPos(); + + if (world.isRemote) + return; + + internalCounter++; //Used instead of the world time for checks that do not happen every tick + + if (lockdownDuration > 0) + lockdownDuration--; + + if (internalCounter % 20 == 0) { + for(EnumFacing facing : EnumFacing.VALUES){ + BlockPos newPos = pos.offset(facing); + IBlockState block = world.getBlockState(newPos); + block.getBlock().onNeighborBlockChange(world, newPos, block, block.getBlock()); + } + } + if (internalCounter % (Math.max(20 - this.accelerationUpgrades, 1)) == 0) { + int syphonMax = (int) (20 * this.dislocationMultiplier); + int fluidInputted; + int fluidOutputted; + fluidInputted = Math.min(syphonMax, -this.fluid.amount + capacity); + fluidInputted = Math.min(this.fluidInput.amount, fluidInputted); + this.fluid.amount += fluidInputted; + this.fluidInput.amount -= fluidInputted; + fluidOutputted = Math.min(syphonMax, this.bufferCapacity - this.fluidOutput.amount); + fluidOutputted = Math.min(this.fluid.amount, fluidOutputted); + this.fluidOutput.amount += fluidOutputted; + this.fluid.amount -= fluidOutputted; + } + + if (internalCounter % 100 == 0 && (this.isActive || this.cooldownAfterCrafting <= 0)) + startCycle(); + + updateAltar(); + } + + private void updateAltar() { + if (!isActive) { + if (cooldownAfterCrafting > 0) + cooldownAfterCrafting--; + return; + } + + if (tileAltar.getStackInSlot(0) == null) + return; + + World world = tileAltar.getWorld(); + BlockPos pos = tileAltar.getPos(); + + if (world.isRemote) + return; + + float f = 1.0F; + float f1 = f * 0.6F + 0.4F; + float f2 = f * f * 0.7F - 0.5F; + float f3 = f * f * 0.6F - 0.7F; + + if (!canBeFilled) { + if (fluid != null && fluid.amount >= 1) { + int stackSize = tileAltar.getStackInSlot(0).stackSize; + int liquidDrained = Math.min((int) (altarTier.ordinal() >= 2 ? consumptionRate * (1 + consumptionMultiplier) : consumptionRate), fluid.amount); + + if (liquidDrained > (liquidRequired * stackSize - progress)) + liquidDrained = liquidRequired * stackSize - progress; + + fluid.amount = fluid.amount - liquidDrained; + progress += liquidDrained; + + if (internalCounter % 4 == 0) + world.spawnParticle(EnumParticleTypes.REDSTONE, pos.getX() + Math.random() - Math.random(), pos.getY() + Math.random() - Math.random(), pos.getZ() + Math.random() - Math.random(), f1, f2, f3); + + if (progress >= liquidRequired * stackSize) { + ItemStack result = this.result; + + if (result != null) + result.stackSize *= stackSize; + + tileAltar.setInventorySlotContents(0, result); + progress = 0; + + for (int i = 0; i < 8; i++) + world.spawnParticle(EnumParticleTypes.REDSTONE, pos.getX() + Math.random() - Math.random(), pos.getY() + Math.random() - Math.random(), pos.getZ() + Math.random() - Math.random(), f1, f2, f3); + + this.isActive = false; + } + } else if (progress > 0) { + progress -= (int) (efficiencyMultiplier * drainRate); + + if (internalCounter % 2 == 0) + world.spawnParticle(EnumParticleTypes.REDSTONE, pos.getX() + Math.random() - Math.random(), pos.getY() + Math.random() - Math.random(), pos.getZ() + Math.random() - Math.random(), f1, f2, f3); + } + } else { + ItemStack returnedItem = tileAltar.getStackInSlot(0); + + if (!(returnedItem.getItem() instanceof IBloodOrb)) + return; + + IBloodOrb item = (IBloodOrb) (returnedItem.getItem()); + NBTTagCompound itemTag = returnedItem.getTagCompound(); + + if (itemTag == null) + return; + + String ownerName = itemTag.getString(Constants.NBT.OWNER_NAME); + + if (Strings.isNullOrEmpty(ownerName)) + return; + + if (fluid != null && fluid.amount >= 1) { + int liquidDrained = Math.min((int) (altarTier.ordinal() >= 2 ? consumptionRate * (1 + consumptionMultiplier) : consumptionRate), fluid.amount); + + int drain = NetworkHelper.getSoulNetwork(ownerName, world).addLifeEssence(liquidDrained, (int) (item.getMaxEssence(returnedItem.getMetadata()) * this.orbCapacityMultiplier)); + + fluid.amount = fluid.amount - drain; + + if (internalCounter % 4 == 0) + world.spawnParticle(EnumParticleTypes.REDSTONE, pos.getX() + Math.random() - Math.random(), pos.getY() + Math.random() - Math.random(), pos.getZ() + Math.random() - Math.random(), f1, f2, f3); + } + } + if (world != null) + world.markBlockForUpdate(pos); + } + + public void checkTier() { + EnumAltarTier tier = BloodAltar.getAltarTier(tileAltar.getWorld(), tileAltar.getPos()); + this.altarTier = tier; + + upgrade = BloodAltar.getUpgrades(tileAltar.getWorld(), tileAltar.getPos(), tier); + + if (tier.equals(EnumAltarTier.ONE)) { + upgrade = null; + isUpgraded = false; + this.consumptionMultiplier = 0; + this.efficiencyMultiplier = 1; + this.sacrificeEfficiencyMultiplier = 0; + this.selfSacrificeEfficiencyMultiplier = 0; + this.capacityMultiplier = 1; + this.orbCapacityMultiplier = 1; + this.dislocationMultiplier = 1; + this.accelerationUpgrades = 0; + return; + } else if (!tier.equals(EnumAltarTier.ONE) && upgrade != null) { + this.isUpgraded = true; + this.consumptionMultiplier = (float) (0.20 * upgrade.getSpeedCount()); + this.efficiencyMultiplier = (float) Math.pow(0.85, upgrade.getEfficiencyCount()); + this.sacrificeEfficiencyMultiplier = (float) (0.10 * upgrade.getSacrificeCount()); + this.selfSacrificeEfficiencyMultiplier = (float) (0.10 * upgrade.getSelfSacrificeCount()); + this.capacityMultiplier = (float) ((1 * Math.pow(1.10, upgrade.getBetterCapacityCount()) + 0.20 * upgrade.getCapacityCount())); + this.dislocationMultiplier = (float) (Math.pow(1.2, upgrade.getDisplacementCount())); + this.orbCapacityMultiplier = (float) (1 + 0.02 * upgrade.getOrbCapacityCount()); + this.accelerationUpgrades = upgrade.getAccelerationCount(); + } + + this.capacity = (int) (FluidContainerRegistry.BUCKET_VOLUME * 10 * capacityMultiplier); + this.bufferCapacity = (int) (FluidContainerRegistry.BUCKET_VOLUME * 1 * capacityMultiplier); + + if (this.fluid.amount > this.capacity) this.fluid.amount = this.capacity; + if (this.fluidOutput.amount > this.bufferCapacity) this.fluidOutput.amount = this.bufferCapacity; + if (this.fluidInput.amount > this.bufferCapacity) this.fluidInput.amount = this.bufferCapacity; + + tileAltar.getWorld().markBlockForUpdate(tileAltar.getPos()); + } + + public int fillMainTank(int amount) { + int filledAmount = Math.min(capacity - fluid.amount, amount); + fluid.amount += filledAmount; + + return filledAmount; + } + + public void sacrificialDaggerCall(int amount, boolean isSacrifice) { + if (this.lockdownDuration > 0) { + int amt = (int) Math.min(bufferCapacity - fluidInput.amount, (isSacrifice ? 1 + sacrificeEfficiencyMultiplier : 1 + selfSacrificeEfficiencyMultiplier) * amount); + fluidInput.amount += amt; + } else { + fluid.amount += Math.min(capacity - fluid.amount, (isSacrifice ? 1 + sacrificeEfficiencyMultiplier : 1 + selfSacrificeEfficiencyMultiplier) * amount); + } + } + + public void setMainFluid(FluidStack fluid) { + this.fluid = fluid; + } + + public void setOutputFluid(FluidStack fluid) { + this.fluidOutput = fluid; + } + + public void setInputFluid(FluidStack fluid) { + this.fluidInput = fluid; + } + + public AltarUpgrade getUpgrade() { + return upgrade; + } + + public void setUpgrade(AltarUpgrade upgrade) { + this.upgrade = upgrade; + } + + public int getCapacity() { + return capacity; + } + + public FluidStack getFluid() { + return fluid; + } + + public int getFluidAmount() { + return fluid.amount; + } + + public int getCurrentBlood() { + return getFluidAmount(); + } + + public EnumAltarTier getTier() { + return altarTier; + } + + public void setTier(EnumAltarTier tier) { + this.altarTier = tier; + } + + public int getProgress() { + return progress; + } + + public float getSacrificeMultiplier() { + return sacrificeEfficiencyMultiplier; + } + + public float getSelfSacrificeMultiplier() { + return selfSacrificeEfficiencyMultiplier; + } + + public float getOrbMultiplier() { + return orbCapacityMultiplier; + } + + public float getDislocationMultiplier() { + return dislocationMultiplier; + } + + public int getBufferCapacity() { + return bufferCapacity; + } + + public void addToDemonBloodDuration(int dur) { + this.demonBloodDuration += dur; + } + + public boolean hasDemonBlood() { + return this.demonBloodDuration > 0; + } + + public void decrementDemonBlood() { + this.demonBloodDuration = Math.max(0, this.demonBloodDuration - 1); + } + + public void setActive() { + isActive = false; + } + + public boolean isActive() { + return isActive; + } + + public void requestPauseAfterCrafting(int amount) { + if (this.isActive) { + this.cooldownAfterCrafting = amount; + } + } } diff --git a/src/main/java/WayofTime/bloodmagic/api/altar/IBloodAltar.java b/src/main/java/WayofTime/bloodmagic/api/altar/IBloodAltar.java index 1d08735f..9eb25e38 100644 --- a/src/main/java/WayofTime/bloodmagic/api/altar/IBloodAltar.java +++ b/src/main/java/WayofTime/bloodmagic/api/altar/IBloodAltar.java @@ -25,6 +25,12 @@ public interface IBloodAltar { void startCycle(); void checkTier(); + + boolean isActive(); + + void setActive(); + + int fillMainTank(int amount); /** * Will set the altar to initiate a cooldown cycle after it crafts before starting to craft again, giving the user time to interact with the altar. @@ -33,10 +39,4 @@ public interface IBloodAltar { * @param cooldown - How long the cooldown should last */ void requestPauseAfterCrafting(int cooldown); - - void addToDemonBloodDuration(int dur); - - boolean hasDemonBlood(); - - void decrementDemonBlood(); } diff --git a/src/main/java/WayofTime/bloodmagic/livingArmour/LivingArmour.java b/src/main/java/WayofTime/bloodmagic/livingArmour/LivingArmour.java index 05c2bf50..c594fff9 100644 --- a/src/main/java/WayofTime/bloodmagic/livingArmour/LivingArmour.java +++ b/src/main/java/WayofTime/bloodmagic/livingArmour/LivingArmour.java @@ -42,7 +42,7 @@ public class LivingArmour { continue; } - tracker.onTick(world, player, this); + tracker.onTick(world, player, this); //TODO: Check if the upgrades need to be updated. } } diff --git a/src/main/java/WayofTime/bloodmagic/tile/TileAltar.java b/src/main/java/WayofTime/bloodmagic/tile/TileAltar.java index 4ce125d9..c07b00a4 100644 --- a/src/main/java/WayofTime/bloodmagic/tile/TileAltar.java +++ b/src/main/java/WayofTime/bloodmagic/tile/TileAltar.java @@ -1,363 +1,54 @@ package WayofTime.bloodmagic.tile; -import WayofTime.bloodmagic.altar.BloodAltar; -import WayofTime.bloodmagic.api.BloodMagicAPI; -import WayofTime.bloodmagic.api.Constants; -import WayofTime.bloodmagic.api.altar.AltarUpgrade; -import WayofTime.bloodmagic.api.altar.EnumAltarTier; -import WayofTime.bloodmagic.api.altar.IBloodAltar; -import WayofTime.bloodmagic.api.orb.IBloodOrb; -import WayofTime.bloodmagic.api.registry.AltarRecipeRegistry; -import WayofTime.bloodmagic.api.util.helper.NetworkHelper; -import WayofTime.bloodmagic.block.BlockLifeEssence; -import com.google.common.base.Enums; -import com.google.common.base.Strings; -import net.minecraft.block.state.IBlockState; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.BlockPos; import net.minecraft.util.EnumFacing; -import net.minecraft.util.EnumParticleTypes; import net.minecraft.util.ITickable; -import net.minecraftforge.fluids.*; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.FluidTankInfo; +import net.minecraftforge.fluids.IFluidHandler; +import net.minecraftforge.fluids.IFluidTank; +import WayofTime.bloodmagic.altar.BloodAltar; +import WayofTime.bloodmagic.api.altar.EnumAltarTier; +import WayofTime.bloodmagic.api.altar.IBloodAltar; public class TileAltar extends TileInventory implements IBloodAltar, ITickable, IFluidTank, IFluidHandler { - public boolean isActive; - protected FluidStack fluidOutput = new FluidStack(BlockLifeEssence.getLifeEssence(), 0); - protected FluidStack fluidInput = new FluidStack(BlockLifeEssence.getLifeEssence(), 0); - private EnumAltarTier altarTier = EnumAltarTier.ONE; - private AltarUpgrade upgrade; - private int capacity = FluidContainerRegistry.BUCKET_VOLUME * 10; - private FluidStack fluid = new FluidStack(BloodMagicAPI.getLifeEssence(), 0); - private int liquidRequired; //mB - private boolean canBeFilled; - private int consumptionRate; - private int drainRate; - private float consumptionMultiplier; - private float efficiencyMultiplier; - private float sacrificeEfficiencyMultiplier; - private float selfSacrificeEfficiencyMultiplier; - private float capacityMultiplier = 1; - private float orbCapacityMultiplier; - private float dislocationMultiplier; - private int accelerationUpgrades; - private boolean isUpgraded; - private boolean isResultBlock; - private int bufferCapacity = FluidContainerRegistry.BUCKET_VOLUME; - private int progress; - private int lockdownDuration; - private int demonBloodDuration; - - private int cooldownAfterCrafting = 500; - - private ItemStack result; - + private BloodAltar bloodAltar; + public TileAltar() { super(1, "altar"); + this.bloodAltar = new BloodAltar(this); } @Override public void readFromNBT(NBTTagCompound tagCompound) { super.readFromNBT(tagCompound); - if (!tagCompound.hasKey(Constants.NBT.EMPTY)) { - FluidStack fluid = FluidStack.loadFluidStackFromNBT(tagCompound); - - if (fluid != null) - setMainFluid(fluid); - - FluidStack fluidOut = new FluidStack(BloodMagicAPI.getLifeEssence(), tagCompound.getInteger(Constants.NBT.OUTPUT_AMOUNT)); - setOutputFluid(fluidOut); - - FluidStack fluidIn = new FluidStack(BloodMagicAPI.getLifeEssence(), tagCompound.getInteger(Constants.NBT.INPUT_AMOUNT)); - setInputFluid(fluidIn); - } - - altarTier = Enums.getIfPresent(EnumAltarTier.class, tagCompound.getString(Constants.NBT.ALTAR_TIER)).or(EnumAltarTier.ONE); - isActive = tagCompound.getBoolean(Constants.NBT.ALTAR_ACTIVE); - liquidRequired = tagCompound.getInteger(Constants.NBT.ALTAR_LIQUID_REQ); - canBeFilled = tagCompound.getBoolean(Constants.NBT.ALTAR_FILLABLE); - isUpgraded = tagCompound.getBoolean(Constants.NBT.ALTAR_UPGRADED); - consumptionRate = tagCompound.getInteger(Constants.NBT.ALTAR_CONSUMPTION_RATE); - drainRate = tagCompound.getInteger(Constants.NBT.ALTAR_DRAIN_RATE); - consumptionMultiplier = tagCompound.getFloat(Constants.NBT.ALTAR_CONSUMPTION_MULTIPLIER); - efficiencyMultiplier = tagCompound.getFloat(Constants.NBT.ALTAR_EFFICIENCY_MULTIPLIER); - selfSacrificeEfficiencyMultiplier = tagCompound.getFloat(Constants.NBT.ALTAR_SELF_SACRIFICE_MULTIPLIER); - sacrificeEfficiencyMultiplier = tagCompound.getFloat(Constants.NBT.ALTAR_SACRIFICE_MULTIPLIER); - capacityMultiplier = tagCompound.getFloat(Constants.NBT.ALTAR_CAPACITY_MULTIPLIER); - orbCapacityMultiplier = tagCompound.getFloat(Constants.NBT.ALTAR_ORB_CAPACITY_MULTIPLIER); - dislocationMultiplier = tagCompound.getFloat(Constants.NBT.ALTAR_DISLOCATION_MULTIPLIER); - capacity = tagCompound.getInteger(Constants.NBT.ALTAR_CAPACITY); - bufferCapacity = tagCompound.getInteger(Constants.NBT.ALTAR_BUFFER_CAPACITY); - progress = tagCompound.getInteger(Constants.NBT.ALTAR_PROGRESS); - isResultBlock = tagCompound.getBoolean(Constants.NBT.ALTAR_IS_RESULT_BLOCK); - lockdownDuration = tagCompound.getInteger(Constants.NBT.ALTAR_LOCKDOWN_DURATION); - accelerationUpgrades = tagCompound.getInteger(Constants.NBT.ALTAR_ACCELERATION_UPGRADES); - demonBloodDuration = tagCompound.getInteger(Constants.NBT.ALTAR_DEMON_BLOOD_DURATION); - cooldownAfterCrafting = tagCompound.getInteger(Constants.NBT.ALTAR_COOLDOWN_AFTER_CRAFTING); + NBTTagCompound altarTag = tagCompound.getCompoundTag("bloodAltar"); + + this.bloodAltar.readFromNBT(altarTag); } @Override public void writeToNBT(NBTTagCompound tagCompound) { super.writeToNBT(tagCompound); - if (fluid != null) - fluid.writeToNBT(tagCompound); - else - tagCompound.setString(Constants.NBT.EMPTY, ""); - - if (fluidOutput != null) - tagCompound.setInteger(Constants.NBT.OUTPUT_AMOUNT, fluidOutput.amount); - - if (fluidInput != null) - tagCompound.setInteger(Constants.NBT.INPUT_AMOUNT, fluidInput.amount); - - tagCompound.setString(Constants.NBT.ALTAR_TIER, altarTier.name()); - tagCompound.setBoolean(Constants.NBT.ALTAR_ACTIVE, isActive); - tagCompound.setInteger(Constants.NBT.ALTAR_LIQUID_REQ, liquidRequired); - tagCompound.setBoolean(Constants.NBT.ALTAR_FILLABLE, canBeFilled); - tagCompound.setBoolean(Constants.NBT.ALTAR_UPGRADED, isUpgraded); - tagCompound.setInteger(Constants.NBT.ALTAR_CONSUMPTION_RATE, consumptionRate); - tagCompound.setInteger(Constants.NBT.ALTAR_DRAIN_RATE, drainRate); - tagCompound.setFloat(Constants.NBT.ALTAR_CONSUMPTION_MULTIPLIER, consumptionMultiplier); - tagCompound.setFloat(Constants.NBT.ALTAR_EFFICIENCY_MULTIPLIER, efficiencyMultiplier); - tagCompound.setFloat(Constants.NBT.ALTAR_SACRIFICE_MULTIPLIER, sacrificeEfficiencyMultiplier); - tagCompound.setFloat(Constants.NBT.ALTAR_SELF_SACRIFICE_MULTIPLIER, selfSacrificeEfficiencyMultiplier); - tagCompound.setBoolean(Constants.NBT.ALTAR_IS_RESULT_BLOCK, isResultBlock); - tagCompound.setFloat(Constants.NBT.ALTAR_CAPACITY_MULTIPLIER, capacityMultiplier); - tagCompound.setFloat(Constants.NBT.ALTAR_ORB_CAPACITY_MULTIPLIER, orbCapacityMultiplier); - tagCompound.setFloat(Constants.NBT.ALTAR_DISLOCATION_MULTIPLIER, dislocationMultiplier); - tagCompound.setInteger(Constants.NBT.ALTAR_CAPACITY, capacity); - tagCompound.setInteger(Constants.NBT.ALTAR_PROGRESS, progress); - tagCompound.setInteger(Constants.NBT.ALTAR_BUFFER_CAPACITY, bufferCapacity); - tagCompound.setInteger(Constants.NBT.ALTAR_LOCKDOWN_DURATION, lockdownDuration); - tagCompound.setInteger(Constants.NBT.ALTAR_ACCELERATION_UPGRADES, accelerationUpgrades); - tagCompound.setInteger(Constants.NBT.ALTAR_DEMON_BLOOD_DURATION, demonBloodDuration); - tagCompound.setInteger(Constants.NBT.ALTAR_COOLDOWN_AFTER_CRAFTING, cooldownAfterCrafting); + NBTTagCompound altarTag = new NBTTagCompound(); + this.bloodAltar.writeToNBT(altarTag); + + tagCompound.setTag("bloodAltar", altarTag); } @Override public void update() { - if (getWorld().isRemote) - return; - - this.decrementDemonBlood(); - - if (lockdownDuration > 0) - lockdownDuration--; - - if (!getWorld().isRemote && getWorld().getWorldTime() % 20 == 0) { - IBlockState block = getWorld().getBlockState(new BlockPos(this.pos.getX() + 1, this.pos.getY(), this.pos.getZ())); - block.getBlock().onNeighborBlockChange(getWorld(), new BlockPos(this.pos.getX() + 1, this.pos.getY(), this.pos.getZ()), block, block.getBlock()); - block = getWorld().getBlockState(new BlockPos(this.pos.getX() + 1, this.pos.getY(), this.pos.getZ())); - block.getBlock().onNeighborBlockChange(getWorld(), new BlockPos(this.pos.getX() - 1, this.pos.getY(), this.pos.getZ()), block, block.getBlock()); - block = getWorld().getBlockState(new BlockPos(this.pos.getX(), this.pos.getY() + 1, this.pos.getZ())); - block.getBlock().onNeighborBlockChange(getWorld(), new BlockPos(this.pos.getX(), this.pos.getY() + 1, this.pos.getZ()), block, block.getBlock()); - block = getWorld().getBlockState(new BlockPos(this.pos.getX(), this.pos.getY() - 1, this.pos.getZ())); - block.getBlock().onNeighborBlockChange(getWorld(), new BlockPos(this.pos.getX(), this.pos.getY() - 1, this.pos.getZ()), block, block.getBlock()); - block = getWorld().getBlockState(new BlockPos(this.pos.getX(), this.pos.getY(), this.pos.getZ() + 1)); - block.getBlock().onNeighborBlockChange(getWorld(), new BlockPos(this.pos.getX(), this.pos.getY(), this.pos.getZ() + 1), block, block.getBlock()); - block = getWorld().getBlockState(new BlockPos(this.pos.getX(), this.pos.getY(), this.pos.getZ() - 1)); - block.getBlock().onNeighborBlockChange(getWorld(), new BlockPos(this.pos.getX(), this.pos.getY(), this.pos.getZ() - 1), block, block.getBlock()); - } - if (getWorld().getTotalWorldTime() % (Math.max(20 - this.accelerationUpgrades, 1)) == 0) { - int syphonMax = (int) (20 * this.dislocationMultiplier); - int fluidInputted; - int fluidOutputted; - fluidInputted = Math.min(syphonMax, -this.fluid.amount + capacity); - fluidInputted = Math.min(this.fluidInput.amount, fluidInputted); - this.fluid.amount += fluidInputted; - this.fluidInput.amount -= fluidInputted; - fluidOutputted = Math.min(syphonMax, this.bufferCapacity - this.fluidOutput.amount); - fluidOutputted = Math.min(this.fluid.amount, fluidOutputted); - this.fluidOutput.amount += fluidOutputted; - this.fluid.amount -= fluidOutputted; - } - - if (getWorld().getTotalWorldTime() % 100 == 0 && (this.isActive || this.cooldownAfterCrafting <= 0)) - startCycle(); - - updateAltar(); - } - - @Override - public void startCycle() { - if (getWorld() != null) - getWorld().markBlockForUpdate(pos); - - checkTier(); - - if (fluid == null || fluid.amount <= 0) - return; - - if (!isActive) - progress = 0; - - if (getStackInSlot(0) != null) { - // Do recipes - for (ItemStack itemStack : AltarRecipeRegistry.getRecipes().keySet()) { - if (getStackInSlot(0).getIsItemStackEqual(AltarRecipeRegistry.getRecipes().get(itemStack).getInput())) { - AltarRecipeRegistry.AltarRecipe recipe = AltarRecipeRegistry.getRecipeForInput(itemStack); - - if (altarTier.ordinal() >= recipe.getMinTier().ordinal()) { - this.isActive = true; - this.result = new ItemStack(recipe.getOutput().getItem(), 1, recipe.getOutput().getMetadata()); - this.liquidRequired = recipe.getSyphon(); - this.canBeFilled = recipe.isUseTag(); - this.consumptionRate = recipe.getConsumeRate(); - this.drainRate = recipe.getDrainRate(); - return; - } - } - } - } - - isActive = false; - } - - private void updateAltar() { - if (!isActive) { - if (cooldownAfterCrafting > 0) - cooldownAfterCrafting--; - return; - } - - if (getStackInSlot(0) == null) - return; - - int worldTime = (int) (getWorld().getWorldTime() % 24000); - - if (getWorld().isRemote) - return; - - float f = 1.0F; - float f1 = f * 0.6F + 0.4F; - float f2 = f * f * 0.7F - 0.5F; - float f3 = f * f * 0.6F - 0.7F; - - if (!canBeFilled) { - if (fluid != null && fluid.amount >= 1) { - int stackSize = getStackInSlot(0).stackSize; - int liquidDrained = Math.min((int) (altarTier.ordinal() >= 2 ? consumptionRate * (1 + consumptionMultiplier) : consumptionRate), fluid.amount); - - if (liquidDrained > (liquidRequired * stackSize - progress)) - liquidDrained = liquidRequired * stackSize - progress; - - fluid.amount = fluid.amount - liquidDrained; - progress += liquidDrained; - - if (worldTime % 4 == 0) - getWorld().spawnParticle(EnumParticleTypes.REDSTONE, this.pos.getX() + Math.random() - Math.random(), this.pos.getY() + Math.random() - Math.random(), this.pos.getZ() + Math.random() - Math.random(), f1, f2, f3); - - if (progress >= liquidRequired * stackSize) { - ItemStack result = this.result; - - if (result != null) - result.stackSize *= stackSize; - - setInventorySlotContents(0, result); - progress = 0; - - for (int i = 0; i < 8; i++) - getWorld().spawnParticle(EnumParticleTypes.REDSTONE, this.pos.getX() + Math.random() - Math.random(), this.pos.getY() + Math.random() - Math.random(), this.pos.getZ() + Math.random() - Math.random(), f1, f2, f3); - - this.isActive = false; - } - } else if (progress > 0) { - progress -= (int) (efficiencyMultiplier * drainRate); - - if (worldTime % 2 == 0) - getWorld().spawnParticle(EnumParticleTypes.REDSTONE, this.pos.getX() + Math.random() - Math.random(), this.pos.getY() + Math.random() - Math.random(), this.pos.getZ() + Math.random() - Math.random(), f1, f2, f3); - } - } else { - ItemStack returnedItem = getStackInSlot(0); - - if (!(returnedItem.getItem() instanceof IBloodOrb)) - return; - - IBloodOrb item = (IBloodOrb) (returnedItem.getItem()); - NBTTagCompound itemTag = returnedItem.getTagCompound(); - - if (itemTag == null) - return; - - String ownerName = itemTag.getString(Constants.NBT.OWNER_NAME); - - if (Strings.isNullOrEmpty(ownerName)) - return; - - if (fluid != null && fluid.amount >= 1) { - int liquidDrained = Math.min((int) (altarTier.ordinal() >= 2 ? consumptionRate * (1 + consumptionMultiplier) : consumptionRate), fluid.amount); - - int drain = NetworkHelper.getSoulNetwork(ownerName, getWorld()).addLifeEssence(liquidDrained, (int) (item.getMaxEssence(returnedItem.getMetadata()) * this.orbCapacityMultiplier)); - - fluid.amount = fluid.amount - drain; - - if (worldTime % 4 == 0) - getWorld().spawnParticle(EnumParticleTypes.REDSTONE, this.pos.getX() + Math.random() - Math.random(), this.pos.getY() + Math.random() - Math.random(), this.pos.getZ() + Math.random() - Math.random(), f1, f2, f3); - } - } - if (getWorld() != null) - getWorld().markBlockForUpdate(pos); - } - - @Override - public void checkTier() { - EnumAltarTier tier = BloodAltar.getAltarTier(getWorld(), getPos()); - this.altarTier = tier; - - upgrade = BloodAltar.getUpgrades(getWorld(), pos, tier); - - if (tier.equals(EnumAltarTier.ONE)) { - upgrade = null; - isUpgraded = false; - this.consumptionMultiplier = 0; - this.efficiencyMultiplier = 1; - this.sacrificeEfficiencyMultiplier = 0; - this.selfSacrificeEfficiencyMultiplier = 0; - this.capacityMultiplier = 1; - this.orbCapacityMultiplier = 1; - this.dislocationMultiplier = 1; - this.accelerationUpgrades = 0; - return; - } else if (!tier.equals(EnumAltarTier.ONE) && upgrade != null) { - this.isUpgraded = true; - this.consumptionMultiplier = (float) (0.20 * upgrade.getSpeedCount()); - this.efficiencyMultiplier = (float) Math.pow(0.85, upgrade.getEfficiencyCount()); - this.sacrificeEfficiencyMultiplier = (float) (0.10 * upgrade.getSacrificeCount()); - this.selfSacrificeEfficiencyMultiplier = (float) (0.10 * upgrade.getSelfSacrificeCount()); - this.capacityMultiplier = (float) ((1 * Math.pow(1.10, upgrade.getBetterCapacityCount()) + 0.20 * upgrade.getCapacityCount())); - this.dislocationMultiplier = (float) (Math.pow(1.2, upgrade.getDisplacementCount())); - this.orbCapacityMultiplier = (float) (1 + 0.02 * upgrade.getOrbCapacityCount()); - this.accelerationUpgrades = upgrade.getAccelerationCount(); - } - - this.capacity = (int) (FluidContainerRegistry.BUCKET_VOLUME * 10 * capacityMultiplier); - this.bufferCapacity = (int) (FluidContainerRegistry.BUCKET_VOLUME * 1 * capacityMultiplier); - - if (this.fluid.amount > this.capacity) this.fluid.amount = this.capacity; - if (this.fluidOutput.amount > this.bufferCapacity) this.fluidOutput.amount = this.bufferCapacity; - if (this.fluidInput.amount > this.bufferCapacity) this.fluidInput.amount = this.bufferCapacity; - - worldObj.markBlockForUpdate(pos); - } - - public int fillMainTank(int amount) { - int filledAmount = Math.min(capacity - fluid.amount, amount); - fluid.amount += filledAmount; - - return filledAmount; + bloodAltar.update(); } @Override public void sacrificialDaggerCall(int amount, boolean isSacrifice) { - if (this.lockdownDuration > 0) { - int amt = (int) Math.min(bufferCapacity - fluidInput.amount, (isSacrifice ? 1 + sacrificeEfficiencyMultiplier : 1 + selfSacrificeEfficiencyMultiplier) * amount); - fluidInput.amount += amt; - } else { - fluid.amount += Math.min(capacity - fluid.amount, (isSacrifice ? 1 + sacrificeEfficiencyMultiplier : 1 + selfSacrificeEfficiencyMultiplier) * amount); - } + bloodAltar.sacrificialDaggerCall(amount, isSacrifice); } @Override @@ -365,103 +56,6 @@ public class TileAltar extends TileInventory implements IBloodAltar, ITickable, return slot == 0; } - public AltarUpgrade getUpgrade() { - return upgrade; - } - - public TileAltar setUpgrade(AltarUpgrade upgrade) { - this.upgrade = upgrade; - return this; - } - - @Override - public int getCapacity() { - return capacity; - } - - @Override - public int getCurrentBlood() { - return getFluidAmount(); - } - - @Override - public EnumAltarTier getTier() { - return altarTier; - } - - public TileAltar setTier(EnumAltarTier tier) { - this.altarTier = tier; - return this; - } - - @Override - public int getProgress() { - return progress; - } - - @Override - public float getSacrificeMultiplier() { - return sacrificeEfficiencyMultiplier; - } - - @Override - public float getSelfSacrificeMultiplier() { - return selfSacrificeEfficiencyMultiplier; - } - - @Override - public float getOrbMultiplier() { - return orbCapacityMultiplier; - } - - @Override - public float getDislocationMultiplier() { - return dislocationMultiplier; - } - - @Override - public int getBufferCapacity() { - return bufferCapacity; - } - - public void addToDemonBloodDuration(int dur) { - this.demonBloodDuration += dur; - } - - public boolean hasDemonBlood() { - return this.demonBloodDuration > 0; - } - - public void decrementDemonBlood() { - this.demonBloodDuration = Math.max(0, this.demonBloodDuration - 1); - } - - public void setActive() { - isActive = false; - } - - public boolean isActive() { - return isActive; - } - - @Override - public void requestPauseAfterCrafting(int amount) { - if (this.isActive) { - this.cooldownAfterCrafting = amount; - } - } - - public void setMainFluid(FluidStack fluid) { - this.fluid = fluid; - } - - public void setOutputFluid(FluidStack fluid) { - this.fluidOutput = fluid; - } - - public void setInputFluid(FluidStack fluid) { - this.fluidInput = fluid; - } // IFluidHandler @@ -499,12 +93,12 @@ public class TileAltar extends TileInventory implements IBloodAltar, ITickable, @Override public FluidStack getFluid() { - return fluid; + return bloodAltar.getFluid(); } @Override public int getFluidAmount() { - return fluid.amount; + return bloodAltar.getFluidAmount(); } @Override @@ -521,4 +115,79 @@ public class TileAltar extends TileInventory implements IBloodAltar, ITickable, public FluidStack drain(int maxDrain, boolean doDrain) { return null; } + + @Override + public int getCapacity() { + return bloodAltar.getCapacity(); + } + + @Override + public int getCurrentBlood() { + return bloodAltar.getCurrentBlood(); + } + + @Override + public EnumAltarTier getTier() { + return bloodAltar.getTier(); + } + + @Override + public int getProgress() { + return bloodAltar.getProgress(); + } + + @Override + public float getSacrificeMultiplier() { + return bloodAltar.getSacrificeMultiplier(); + } + + @Override + public float getSelfSacrificeMultiplier() { + return bloodAltar.getSelfSacrificeMultiplier(); + } + + @Override + public float getOrbMultiplier() { + return bloodAltar.getOrbMultiplier(); + } + + @Override + public float getDislocationMultiplier() { + return bloodAltar.getDislocationMultiplier(); + } + + @Override + public int getBufferCapacity() { + return bloodAltar.getBufferCapacity(); + } + + @Override + public void startCycle() { + bloodAltar.startCycle(); + } + + @Override + public void checkTier() { + bloodAltar.checkTier(); + } + + @Override + public void requestPauseAfterCrafting(int cooldown) { + bloodAltar.requestPauseAfterCrafting(cooldown); + } + + @Override + public boolean isActive() { + return bloodAltar.isActive(); + } + + @Override + public int fillMainTank(int amount) { + return bloodAltar.fillMainTank(amount); + } + + @Override + public void setActive(){ + bloodAltar.setActive(); + } } \ No newline at end of file