Skip to content

Commit

Permalink
Rework AbstractRecipeLogic (#256)
Browse files Browse the repository at this point in the history
* overhaul AbstractRecipeLogic

* finish blast furnace logic

* change how parallel limit is retrieved

* ensure multiblocks call checkRecipe

* make gas collector recipe logic use checkRecipe

* make fusion reactor use checkRecipe

* fix failing test

* documentation, annotations, use overclockPolicy

* missing null check and make getMaxVoltage abstract

* remove second runOverclockingLogic method
  • Loading branch information
TechLord22 authored Nov 26, 2021
1 parent a653bd7 commit ca3b974
Show file tree
Hide file tree
Showing 29 changed files with 357 additions and 289 deletions.
269 changes: 209 additions & 60 deletions src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import gregtech.api.recipes.Recipe;
import net.minecraftforge.items.IItemHandlerModifiable;

import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.List;

Expand Down Expand Up @@ -102,7 +103,7 @@ protected void trySearchNewRecipe() {
return;
}

// Distinct buses only apply to some of the multiblocks, so check the controller against a lower class
// Distinct buses only apply to some multiblocks, so check the controller against a lower class
if (controller instanceof RecipeMapMultiblockController) {
RecipeMapMultiblockController distinctController = (RecipeMapMultiblockController) controller;

Expand Down Expand Up @@ -143,7 +144,7 @@ protected void trySearchNewRecipeDistinct() {

// Our caching implementation
// This guarantees that if we get a recipe cache hit, our efficiency is no different from other machines
if (previousRecipe != null && previousRecipe.matches(false, importInventory.get(lastRecipeIndex), importFluids)) {
if (previousRecipe != null && previousRecipe.matches(false, importInventory.get(lastRecipeIndex), importFluids) && checkRecipe(previousRecipe)) {
currentRecipe = previousRecipe;
currentDistinctInputBus = importInventory.get(lastRecipeIndex);
currentRecipe = findParallelRecipe(
Expand All @@ -153,7 +154,7 @@ protected void trySearchNewRecipeDistinct() {
importFluids,
exportInventory,
exportFluids,
maxVoltage, metaTileEntity.getParallelLimit());
maxVoltage, getParallelLimit());

// If a valid recipe is found, immediately attempt to return it to prevent inventory scanning
if (currentRecipe != null && setupAndConsumeRecipeInputs(currentRecipe, importInventory.get(lastRecipeIndex))) {
Expand All @@ -179,7 +180,7 @@ protected void trySearchNewRecipeDistinct() {
// Look for a new recipe after a cache miss
currentRecipe = findRecipe(maxVoltage, bus, importFluids, MatchingMode.DEFAULT);
// Cache the current recipe, if one is found
if (currentRecipe != null) {
if (currentRecipe != null && checkRecipe(currentRecipe)) {
this.previousRecipe = currentRecipe;
currentDistinctInputBus = bus;
currentRecipe = findParallelRecipe(
Expand All @@ -189,7 +190,7 @@ protected void trySearchNewRecipeDistinct() {
importFluids,
exportInventory,
exportFluids,
maxVoltage, metaTileEntity.getParallelLimit());
maxVoltage,getParallelLimit());

if (currentRecipe != null && setupAndConsumeRecipeInputs(currentRecipe, importInventory.get(i))) {
lastRecipeIndex = i;
Expand All @@ -202,7 +203,7 @@ protected void trySearchNewRecipeDistinct() {
}
}

//If no matching recipes are found, clear the notified inputs so we know when new items are given
//If no matching recipes are found, clear the notified inputs so that we know when new items are given
metaTileEntity.getNotifiedItemInputList().clear();
}

Expand All @@ -218,7 +219,7 @@ public void invalidateInputs() {
}

@Override
protected int[] calculateOverclock(int EUt, long voltage, int duration) {
protected int[] runOverclockingLogic(@Nonnull Recipe recipe, boolean negativeEU, int maxOverclocks) {
// apply maintenance penalties
MultiblockWithDisplayBase displayBase = this.metaTileEntity instanceof MultiblockWithDisplayBase ? (MultiblockWithDisplayBase) metaTileEntity : null;
int numMaintenanceProblems = displayBase == null ? 0 : displayBase.getNumMaintenanceProblems();
Expand All @@ -228,27 +229,32 @@ protected int[] calculateOverclock(int EUt, long voltage, int duration) {
IMaintenanceHatch hatch = displayBase.getAbilities(MultiblockAbility.MAINTENANCE_HATCH).get(0);
double durationMultiplier = hatch.getDurationMultiplier();
if (durationMultiplier != 1.0) {
overclock = super.calculateOverclock(EUt, voltage, (int) Math.round(duration * durationMultiplier));
overclock = standardOverclockingLogic(recipe.getEUt() * (negativeEU ? -1 : 1), getMaxVoltage(), (int) Math.round(recipe.getDuration() * durationMultiplier), getOverclockingDurationDivisor(), getOverclockingVoltageMultiplier(), maxOverclocks);
}
}
if (overclock == null) overclock = super.calculateOverclock(EUt, voltage, duration);
if (overclock == null) overclock = super.runOverclockingLogic(recipe, negativeEU, maxOverclocks);
overclock[1] = (int) (overclock[1] * (1 + 0.1 * numMaintenanceProblems));

return overclock;
}

@Override
protected boolean setupAndConsumeRecipeInputs(Recipe recipe, IItemHandlerModifiable importInventory) {
protected boolean checkRecipe(Recipe recipe) {
RecipeMapMultiblockController controller = (RecipeMapMultiblockController) metaTileEntity;
if (controller.checkRecipe(recipe, false) &&
super.setupAndConsumeRecipeInputs(recipe, importInventory)) {
if (controller.checkRecipe(recipe, false)) {
controller.checkRecipe(recipe, true);
return true;
} else return false;
return super.checkRecipe(recipe);
}
return false;
}

@Override
protected void completeRecipe() {
super.completeRecipe();
performMaintenanceMufflerOperations();
}

protected void performMaintenanceMufflerOperations() {
if (metaTileEntity instanceof MultiblockWithDisplayBase) {
MultiblockWithDisplayBase controller = (MultiblockWithDisplayBase) metaTileEntity;

Expand All @@ -263,7 +269,6 @@ protected void completeRecipe() {
if (controller.hasMaintenanceMechanics())
controller.calculateMaintenance(this.progressTime);
}
super.completeRecipe();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@

import gregtech.api.GTValues;
import gregtech.api.metatileentity.multiblock.RecipeMapPrimitiveMultiblockController;
import gregtech.api.recipes.Recipe;
import gregtech.api.recipes.RecipeMap;

import javax.annotation.Nonnull;

/**
* Recipe Logic for a Multiblock that does not require power.
*/
Expand Down Expand Up @@ -39,13 +42,19 @@ protected long getMaxVoltage() {
}

@Override
protected int[] calculateOverclock(int EUt, long voltage, int duration) {
return new int[]{1, duration};
protected int[] runOverclockingLogic(@Nonnull Recipe recipe, boolean negativeEU, int maxOverclocks) {
return standardOverclockingLogic(1,
getMaxVoltage(),
recipe.getDuration(),
getOverclockingDurationDivisor(),
getOverclockingVoltageMultiplier(),
maxOverclocks
);
}

@Override
protected int getOverclockingTier(long voltage) {
return GTValues.LV; // just return something reasonable
public long getOverclockVoltage() {
return GTValues.V[GTValues.LV];
}

/**
Expand Down
21 changes: 12 additions & 9 deletions src/main/java/gregtech/api/capability/impl/RecipeLogicSteam.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.WorldServer;
import net.minecraftforge.fluids.IFluidTank;
import net.minecraftforge.items.IItemHandlerModifiable;

import javax.annotation.Nonnull;

public class RecipeLogicSteam extends AbstractRecipeLogic {

Expand Down Expand Up @@ -156,8 +157,8 @@ public void update() {
}

@Override
protected boolean setupAndConsumeRecipeInputs(Recipe recipe, IItemHandlerModifiable importInventory) {
return !this.needsVenting && super.setupAndConsumeRecipeInputs(recipe, importInventory);
protected boolean checkRecipe(Recipe recipe) {
return super.checkRecipe(recipe) && !this.needsVenting;
}

@Override
Expand All @@ -167,12 +168,14 @@ protected void completeRecipe() {
}

@Override
protected int[] calculateOverclock(int EUt, long voltage, int duration) {
// double duration for normal Steam machines, double EUt for HP Steam
return new int[]{
isHighPressure ? EUt * 2 : EUt,
isHighPressure ? duration : duration * 2
};
protected int[] runOverclockingLogic(@Nonnull Recipe recipe, boolean negativeEU, int maxOverclocks) {
return standardOverclockingLogic((isHighPressure ? recipe.getEUt() * 2 : recipe.getEUt()) * (negativeEU ? -1 : 1),
getMaxVoltage(),
isHighPressure ? recipe.getDuration() * 2 : recipe.getDuration(),
getOverclockingDurationDivisor(),
getOverclockingVoltageMultiplier(),
maxOverclocks
);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public SteamMultiblockRecipeLogic(RecipeMapSteamMultiblockController tileEntity,
super(tileEntity, recipeMap);
this.steamFluidTank = steamFluidTank;
this.conversionRate = conversionRate;
allowOverclocking = false;
setAllowOverclocking(false);
combineSteamTanks();
}

Expand Down
9 changes: 4 additions & 5 deletions src/main/java/gregtech/api/metatileentity/MetaTileEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,10 @@
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.ICapabilityProvider;
import net.minecraftforge.common.util.Constants.NBT;
import net.minecraftforge.fluids.*;
import net.minecraftforge.fluids.FluidActionResult;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidTank;
import net.minecraftforge.fluids.FluidUtil;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.fml.relauncher.Side;
Expand Down Expand Up @@ -1294,10 +1297,6 @@ public List<IFluidHandler> getNotifiedFluidOutputList() {
return notifiedFluidOutputList;
}

public int getParallelLimit() {
return 1;
}

public boolean isFragile() {
return isFragile;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public SimpleMachineMetaTileEntity(ResourceLocation metaTileEntityId, RecipeMap<

@Override
public MetaTileEntity createMetaTileEntity(MetaTileEntityHolder holder) {
return new SimpleMachineMetaTileEntity(metaTileEntityId, workable.recipeMap, renderer, getTier(), hasFrontFacing, getTankScalingFunction());
return new SimpleMachineMetaTileEntity(metaTileEntityId, workable.getRecipeMap(), renderer, getTier(), hasFrontFacing, getTankScalingFunction());
}

@Override
Expand Down Expand Up @@ -396,7 +396,7 @@ protected RecipeLogicEnergy createWorkable(RecipeMap<?> recipeMap) {
}

protected ModularUI.Builder createGuiTemplate(EntityPlayer player) {
RecipeMap<?> workableRecipeMap = workable.recipeMap;
RecipeMap<?> workableRecipeMap = workable.getRecipeMap();
int yOffset = 0;
if (workableRecipeMap.getMaxInputs() >= 6 || workableRecipeMap.getMaxFluidInputs() >= 6 || workableRecipeMap.getMaxOutputs() >= 6 || workableRecipeMap.getMaxFluidOutputs() >= 6) {
yOffset = FONT_HEIGHT;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,19 +76,19 @@ public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation,
@Override
protected IItemHandlerModifiable createImportItemHandler() {
if (workable == null) return new ItemStackHandler(0);
return new NotifiableItemStackHandler(workable.recipeMap.getMaxInputs(), this, false);
return new NotifiableItemStackHandler(workable.getRecipeMap().getMaxInputs(), this, false);
}

@Override
protected IItemHandlerModifiable createExportItemHandler() {
if (workable == null) return new ItemStackHandler(0);
return new NotifiableItemStackHandler(workable.recipeMap.getMaxOutputs(), this, true);
return new NotifiableItemStackHandler(workable.getRecipeMap().getMaxOutputs(), this, true);
}

@Override
protected FluidTankList createImportFluidHandler() {
if (workable == null) return new FluidTankList(false);
FilteredFluidHandler[] fluidImports = new FilteredFluidHandler[workable.recipeMap.getMaxFluidInputs()];
FilteredFluidHandler[] fluidImports = new FilteredFluidHandler[workable.getRecipeMap().getMaxFluidInputs()];
for (int i = 0; i < fluidImports.length; i++) {
NotifiableFilteredFluidHandler filteredFluidHandler = new NotifiableFilteredFluidHandler(this.tankScalingFunction.apply(this.getTier()), this, false);
filteredFluidHandler.setFillPredicate(this::canInputFluid);
Expand All @@ -100,15 +100,15 @@ protected FluidTankList createImportFluidHandler() {
@Override
protected FluidTankList createExportFluidHandler() {
if (workable == null) return new FluidTankList(false);
FluidTank[] fluidExports = new FluidTank[workable.recipeMap.getMaxFluidOutputs()];
FluidTank[] fluidExports = new FluidTank[workable.getRecipeMap().getMaxFluidOutputs()];
for (int i = 0; i < fluidExports.length; i++) {
fluidExports[i] = new NotifiableFluidTank(this.tankScalingFunction.apply(this.getTier()), this, true);
}
return new FluidTankList(false, fluidExports);
}

protected boolean canInputFluid(FluidStack inputFluid) {
RecipeMap<?> recipeMap = workable.recipeMap;
RecipeMap<?> recipeMap = workable.getRecipeMap();
if (recipeMap.canInputFluidForce(inputFluid.getFluid()))
return true; //if recipe map forces input of given fluid, return true
Set<Recipe> matchingRecipes = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,8 +190,8 @@ protected void addDisplayText(List<ITextComponent> textList) {
} else if (recipeMapWorkable.isActive()) {
textList.add(new TextComponentTranslation("gregtech.multiblock.running"));
int currentProgress = (int) (recipeMapWorkable.getProgressPercent() * 100);
if (this.getParallelLimit() != 1) {
textList.add(new TextComponentTranslation("gregtech.multiblock.parallel", this.getParallelLimit()));
if (this.recipeMapWorkable.getParallelLimit() != 1) {
textList.add(new TextComponentTranslation("gregtech.multiblock.parallel", this.recipeMapWorkable.getParallelLimit()));
}
textList.add(new TextComponentTranslation("gregtech.multiblock.progress", currentProgress));
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ public RecipeMapPrimitiveMultiblockController(ResourceLocation metaTileEntityId,

// just initialize inventories based on RecipeMap values by default
protected void initializeAbilities() {
this.importItems = new NotifiableItemStackHandler(recipeMapWorkable.recipeMap.getMaxInputs(), this, false);
this.importFluids = new FluidTankList(true, makeFluidTanks(recipeMapWorkable.recipeMap.getMaxFluidInputs(), false));
this.exportItems = new NotifiableItemStackHandler(recipeMapWorkable.recipeMap.getMaxOutputs(), this, true);
this.exportFluids = new FluidTankList(false, makeFluidTanks(recipeMapWorkable.recipeMap.getMaxFluidOutputs(), true));
this.importItems = new NotifiableItemStackHandler(recipeMapWorkable.getRecipeMap().getMaxInputs(), this, false);
this.importFluids = new FluidTankList(true, makeFluidTanks(recipeMapWorkable.getRecipeMap().getMaxFluidInputs(), false));
this.exportItems = new NotifiableItemStackHandler(recipeMapWorkable.getRecipeMap().getMaxOutputs(), this, true);
this.exportFluids = new FluidTankList(false, makeFluidTanks(recipeMapWorkable.getRecipeMap().getMaxFluidOutputs(), true));

this.itemInventory = new ItemHandlerProxy(this.importItems, this.exportItems);
this.fluidInventory = new FluidHandlerProxy(this.importFluids, this.exportFluids);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,8 @@ protected void addDisplayText(List<ITextComponent> textList) {
} else if (recipeMapWorkable.isActive()) {
textList.add(new TextComponentTranslation("gregtech.multiblock.running"));
int currentProgress = (int) (recipeMapWorkable.getProgressPercent() * 100);
if (this.getParallelLimit() != 1) {
textList.add(new TextComponentTranslation("gregtech.multiblock.parallel", this.getParallelLimit()));
if (this.recipeMapWorkable.getParallelLimit() != 1) {
textList.add(new TextComponentTranslation("gregtech.multiblock.parallel", this.recipeMapWorkable.getParallelLimit()));
}
textList.add(new TextComponentTranslation("gregtech.multiblock.progress", currentProgress));
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import gregtech.api.recipes.RecipeMap;
import net.minecraftforge.items.IItemHandlerModifiable;

import javax.annotation.Nonnull;

public interface IParallelableRecipeLogic {

/**
Expand All @@ -16,7 +18,7 @@ public interface IParallelableRecipeLogic {
*
* @param builder the recipe builder
*/
default void applyParallelBonus(RecipeBuilder<?> builder) {
default void applyParallelBonus(@Nonnull RecipeBuilder<?> builder) {
}

/**
Expand Down Expand Up @@ -66,9 +68,9 @@ default Recipe findParallelRecipe(AbstractRecipeLogic logic, Recipe currentRecip
if (parallelLimit > 1) {
RecipeBuilder<?> parallelBuilder = null;
if (logic.getParallelLogicType() == ParallelLogicType.MULTIPLY) {
parallelBuilder = findMultipliedParallelRecipe(logic.recipeMap, currentRecipe, inputs, fluidInputs, outputs, fluidOutputs, parallelLimit);
parallelBuilder = findMultipliedParallelRecipe(logic.getRecipeMap(), currentRecipe, inputs, fluidInputs, outputs, fluidOutputs, parallelLimit);
} else if (logic.getParallelLogicType() == ParallelLogicType.APPEND_ITEMS) {
parallelBuilder = findAppendedParallelItemRecipe(logic.recipeMap, inputs, outputs, parallelLimit, maxVoltage);
parallelBuilder = findAppendedParallelItemRecipe(logic.getRecipeMap(), inputs, outputs, parallelLimit, maxVoltage);
}
// if the builder returned is null, no recipe was found.
if (parallelBuilder == null) {
Expand Down
Loading

0 comments on commit ca3b974

Please sign in to comment.