Feature/fluidreplicator (#1482)

Added Fluid Replicator multiblock machine.
This commit is contained in:
drcrazy 2018-04-12 15:42:12 +03:00 committed by GitHub
parent 7b275bebb1
commit fef10740ba
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
29 changed files with 1202 additions and 121 deletions

View file

@ -68,4 +68,5 @@ public class Reference {
public static String RECYCLER_RECIPE = "RECYCLER_RECIPE";
public static String SCRAPBOX_RECIPE = "SCRAPBOX_RECIPE";
public static String VACUUM_FREEZER_RECIPE = "VACUUM_FREEZER_RECIPE";
public static String FLUID_REPLICATOR_RECIPE = "FLUID_REPLICATOR_RECIPE";
}

View file

@ -0,0 +1,139 @@
/*
* This file is part of TechReborn, licensed under the MIT License (MIT).
*
* Copyright (c) 2018 TechReborn
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package techreborn.api.fluidreplicator;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nonnull;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidRegistry;
import techreborn.init.ModItems;
import techreborn.tiles.multiblock.TileFluidReplicator;
/**
* @author drcrazy
*
*/
public class FluidReplicatorRecipe implements Cloneable {
/**
* This is the UU matter amount that is required as input
* <p>
* This cannot be null
*/
@Nonnull
private final int input;
/**
* This is the fluid we will produce
* <p>
* This cannot be null
*/
@Nonnull
private final Fluid output;
/**
* This is the time in ticks that the recipe takes to complete
*/
private final int tickTime;
/**
* This is the EU that charges every tick to replicate fluid.
*/
private final int euPerTick;
/**
* @param input int Amount of UU-matter per bucket
* @param output Fluid Fluid to replicate
* @param tickTime int Production time for recipe
* @param euPerTick int EU amount per tick
*/
public FluidReplicatorRecipe(int input, Fluid output, int tickTime, int euPerTick) {
this.input = input;
this.output = output;
this.tickTime = tickTime;
this.euPerTick = euPerTick;
}
public int getInput() {
return input;
}
public Fluid getFluid() {
return output;
}
public int getTickTime() {
return tickTime;
}
public int getEuTick() {
return euPerTick;
}
public List<Object> getInputs() {
ArrayList<Object> inputs = new ArrayList<>();
inputs.add(new ItemStack(ModItems.UU_MATTER, input));
return inputs;
}
public boolean useOreDic() {
return false;
}
public boolean canCraft(TileFluidReplicator tile) {
if (!tile.getMultiBlock()) {
return false;
}
final BlockPos hole = tile.getPos().offset(tile.getFacing().getOpposite(), 2);
final Fluid fluid = FluidRegistry.lookupFluidForBlock(tile.getWorld().getBlockState(hole).getBlock());
if (fluid == null) {
return false;
}
if (!fluid.equals(output)) {
return false;
}
final Fluid tankFluid = tile.tank.getFluidType();
if (tankFluid != null && !tankFluid.equals(output)) {
return false;
}
return true;
}
public boolean onCraft(TileFluidReplicator tile) {
return true;
}
// Cloneable
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}

View file

@ -0,0 +1,204 @@
/*
* This file is part of TechReborn, licensed under the MIT License (MIT).
*
* Copyright (c) 2018 TechReborn
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package techreborn.api.fluidreplicator;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack;
import reborncore.common.recipes.RecipeCrafter;
import reborncore.common.util.Inventory;
import reborncore.common.util.Tank;
import techreborn.api.Reference;
import techreborn.init.ModItems;
import techreborn.tiles.multiblock.TileFluidReplicator;
/**
* @author drcrazy
*
*/
public class FluidReplicatorRecipeCrafter extends RecipeCrafter {
public FluidReplicatorRecipe currentRecipe;
int ticksSinceLastChange;
/**
* RecipeCrafter for Fluid Replicator
*
* @param parentTile TileEntity Reference to the tile having this crafter
* @param inventory Inventory reference to inventory used for crafting
* @param inputSlots This is the list of the slots that the crafting logic should look for the input UU-Matter.
* @param outputSlots This is the list of slots that the crafting logic should look for output fluid
*/
public FluidReplicatorRecipeCrafter(TileEntity parentTile, Inventory inventory, int[] inputSlots, int[] outputSlots) {
super(Reference.FLUID_REPLICATOR_RECIPE, parentTile, 1, 1, inventory, inputSlots, outputSlots);
}
/**
* FluidReplicatorRecipe version of hasAllInputs
*/
private boolean hasAllInputs(FluidReplicatorRecipe recipe) {
if (recipe == null) {
return false;
}
ItemStack inputStack = inventory.getStackInSlot(inputSlots[0]);
if (!inputStack.isItemEqual(new ItemStack(ModItems.UU_MATTER))) {
return false;
}
if (inputStack.getCount() < recipe.getInput()) {
return false;
}
return true;
}
private boolean canFit(Fluid fluid, Tank tank) {
if (tank.fill(new FluidStack(fluid, Fluid.BUCKET_VOLUME), false) != Fluid.BUCKET_VOLUME) {
return false;
}
return true;
}
public void setCurrentRecipe(FluidReplicatorRecipe recipe) {
try {
this.currentRecipe = (FluidReplicatorRecipe) recipe.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
// RecipeCrafter
@Override
public void updateEntity() {
if (parentTile.getWorld().isRemote) {
return;
}
ticksSinceLastChange++;
// Force a has changed every second
if (ticksSinceLastChange >= 20) {
setInvDirty(true);
ticksSinceLastChange = 0;
}
// It will now look for new recipes.
if (currentRecipe == null && isInvDirty()) {
updateCurrentRecipe();
}
if(currentRecipe != null) {
// If it doesn't have all the inputs reset
if (isInvDirty() && !hasAllInputs()) {
currentRecipe = null;
currentTickTime = 0;
setIsActive();
}
// If it has reached the recipe tick time
if (currentRecipe != null && currentTickTime >= currentNeededTicks && hasAllInputs()) {
TileFluidReplicator tileFluidReplicator = (TileFluidReplicator) parentTile;
// Checks to see if it can fit the output
// And fill tank with replicated fluid
if (canFit(currentRecipe.getFluid(), tileFluidReplicator.tank) && currentRecipe.onCraft(tileFluidReplicator)) {
tileFluidReplicator.tank.fill(new FluidStack(currentRecipe.getFluid(), Fluid.BUCKET_VOLUME), true);
// This uses all the inputs
useAllInputs();
// Reset
currentRecipe = null;
currentTickTime = 0;
updateCurrentRecipe();
//Update active state if the tile isnt going to start crafting again
if(currentRecipe == null){
setIsActive();
}
}
} else if (currentRecipe != null && currentTickTime < currentNeededTicks) {
// This uses the power
if (energy.canUseEnergy(getEuPerTick(currentRecipe.getEuTick()))) {
energy.useEnergy(getEuPerTick(currentRecipe.getEuTick()));
// Increase the ticktime
currentTickTime ++;
if(currentTickTime == 1 || currentTickTime % 20 == 0 && soundHanlder != null){
soundHanlder.playSound(false, parentTile);
}
}
}
}
setInvDirty(false);
}
@Override
public void updateCurrentRecipe() {
TileFluidReplicator tileFluidReplicator = (TileFluidReplicator) parentTile;
for (FluidReplicatorRecipe recipe : FluidReplicatorRecipeList.recipes) {
if (recipe.canCraft(tileFluidReplicator) && hasAllInputs(recipe)) {
if (!canFit(recipe.getFluid(), tileFluidReplicator.tank)) {
this.currentRecipe = null;
currentTickTime = 0;
setIsActive();
return;
}
setCurrentRecipe(recipe);
currentNeededTicks = Math.max((int) (currentRecipe.getTickTime()* (1.0 - getSpeedMultiplier())), 1);
currentTickTime = 0;
setIsActive();
return;
}
}
}
@Override
public boolean hasAllInputs() {
if (this.currentRecipe == null) {
return false;
}
else {
return hasAllInputs(this.currentRecipe);
}
}
@Override
public void useAllInputs() {
if (currentRecipe == null) {
return;
}
if (hasAllInputs(currentRecipe)) {
inventory.decrStackSize(inputSlots[0], currentRecipe.getInput());
}
}
@Override
public boolean canCraftAgain() {
TileFluidReplicator tileFluidReplicator = (TileFluidReplicator) parentTile;
for (FluidReplicatorRecipe recipe : FluidReplicatorRecipeList.recipes) {
if (recipe.canCraft(tileFluidReplicator) && hasAllInputs(recipe)) {
if (!canFit(recipe.getFluid(), tileFluidReplicator.tank)) {
return false;
}
if (energy.getEnergy() < recipe.getEuTick()) {
return false;
}
return true;
}
}
return false;
}
}

View file

@ -0,0 +1,78 @@
/*
* This file is part of TechReborn, licensed under the MIT License (MIT).
*
* Copyright (c) 2018 TechReborn
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package techreborn.api.fluidreplicator;
import java.util.ArrayList;
import java.util.Optional;
import org.apache.commons.lang3.Validate;
import net.minecraftforge.fluids.Fluid;
/**
* @author drcrazy
*
*/
public class FluidReplicatorRecipeList {
/**
* This is the list of all the recipes
*/
public static ArrayList<FluidReplicatorRecipe> recipes = new ArrayList<>();
/**
* Register your Fluid Replicator recipe
*
* @param recipe FluidReplicatorRecipe The recipe you want to add
*/
public static void addRecipe(FluidReplicatorRecipe recipe) {
Validate.notNull(recipe);
Validate.isTrue(!recipes.contains(recipe));
Validate.validState(recipe.getInput() >= 1);
Validate.validState(!getRecipeForFluid(recipe.getFluid()).isPresent());
recipes.add(recipe);
}
/**
* Fluid Replicator recipe you want to remove
*
* @param recipe FluidReplicatorRecipe Recipe to remove
* @return boolean true if recipe was removed from list of recipes
*/
public static boolean removeRecipe(FluidReplicatorRecipe recipe) {
return recipes.remove(recipe);
}
/**
* Check if there is a Fluid Replicator recipe for that fluid
*
* @param fluid Fluid Fluid to search for
* @return FluidReplicatorRecipe Recipe for fluid provided
*/
public static Optional<FluidReplicatorRecipe> getRecipeForFluid(Fluid fluid) {
return recipes.stream().filter(recipe -> recipe.getFluid().equals(fluid)).findAny();
}
}