Skip to content

Commit

Permalink
Merge branch 'master' into FixPumpCoverNPE
Browse files Browse the repository at this point in the history
  • Loading branch information
PrototypeTrousers authored Dec 18, 2020
2 parents 34f67b3 + 22a594d commit 01bffe1
Show file tree
Hide file tree
Showing 35 changed files with 877 additions and 222 deletions.
40 changes: 39 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,47 @@
## Changelog

### 1.10.8
* Added Sifter to Smart Item FIlter options (#1345) - LAGIdiot
* Fixed shouldCheckWeakPower not working correctly because of Vanilla MC bug (#1331) - solidDoWant
* Fixed wrong localization key for empty hand (#1327) - Pierre Zhang
* Fixed wrong translation of Rubber nuget in ZH (#1327) - Pierre Zhang
* Fixed Multiblocks voiding partial recipe outputs when output bus is mostly full (#1337) - ALongStringOfNumbers

### 1.10.7 (Hotfix)
* Fixed Brewery and Forming Press recipe finder not working properly - LAGIdiot
* Fixed Fluid Canner and Electric Furnace recipe finder not working properly (#1326) - ALongStringOfNumbers

### 1.10.6
* Added Oredicts to granite variants, marble, basalt (#1306) - ALongStringOfNumbers
* Added Matching Mode to API for possible recipe filtering (#1308) - galyfray
* Added Smart Matching Mode to Smart Item Filter allowing it ignoring fluids in recipes (#1308) - galyfray
* Updated Crafting Station to show only extractable items from connected inventories (#1290) - Frederic Marceau
* Updated zh_cn localization (#1307) - Pierre Zhang
* Updated Ore Byproduct JEI page to include data for Chemical Bath byproducts (#1310) - ALongStringOfNumbers
* Fixed a missing command warning for hand (#1307) - Pierre Zhang
* Fixed Smart Item Filter tooltip on Filter Mode (#1308) - galyfray
* Fixed Ore Byproduct JEI page showing some unobtainable resources (#1310) - ALongStringOfNumbers
* Fixed multiblock fluid tank forming on load not respecting blocked sides (#1313) - PrototypeTrousers
* Fixed multiblock fluid tank incorrectly providing capabilities on load (#1313) - PrototypeTrousers
* Fixed Ice broken by Saw still creating water block (#1317) - Eutro
* Fixed drained Fluid Cells not stacking due to NBT (#1319) - ALongStringOfNumbers

### 1.10.5
* Added LargeStackSizeItemStackHandler to API (#1284) - LAGIdiot
* Added a JEI Info Tab for the Fluid Canner Machines for Buckets and Fluid Cells (#1288) - Frederic Marceau
* Added recipe for turning Block of Quartz (Vanilla MC) to 4 Nether Quartz (Vanilla MC) (#1293) - LAGIdiot
* Updated Granite to be its own material (#1287) - LAGIdiot
* Macerating recipe changed
* Fixed Item Filter not persisting items with size > 127 (#1284) - LAGIdiot
* Fixed recipe validation logging data from builder chance instead of recipe chance (#1297) - galyfray
* Fixed Machine Controller GUI allowing to set too high redstone signal (#1299) - galyfray
* Fixed Machine Controller incorrectly setting working enabled on cover removal (#1299) - galyfray
* Fixed recipes taking 1 tick less to finish then they should (#1301) - LAGIdiot

### 1.10.4
* Added placing Pump/Conveyor/Robotic Arm on Output side of machine will turn allow input from output side on (#1266) - PrototypeTrousers
* Fixed issue preventing battery from fully charged. (#1267) - Derek.CHAN
* Fixes Crafting Station crash and item dupe (#1274) - PrototypeTrousers
* Fixed Crafting Station crash and item dupe (#1274) - PrototypeTrousers
* Fixed some RU lang entries (#1279) - Bombm

### 1.10.3
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/gregtech/GregTechVersion.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ public final class GregTechVersion {
//This number is incremented every major feature update
public static final int MINOR = 10;
//This number is incremented every time the feature is added, or bug is fixed. resets every major version change
public static final int REVISION = 4;
public static final int REVISION = 8;
//This number is incremented every build, and never reset. Should always be 0 in the repo code.
public static final int BUILD = 0;

Expand Down
4 changes: 3 additions & 1 deletion src/main/java/gregtech/api/block/machines/BlockMachine.java
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,9 @@ public boolean canConnectRedstone(IBlockState state, IBlockAccess world, BlockPo

@Override
public boolean shouldCheckWeakPower(IBlockState state, IBlockAccess world, BlockPos pos, EnumFacing side) {
return true;
// The check in World::getRedstonePower in the vanilla code base is reversed. Setting this to false will
// actually cause getWeakPower to be called, rather than prevent it.
return false;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,8 @@ protected void updateRecipeProgress() {
boolean drawEnergy = drawEnergy(recipeEUt);
if (drawEnergy || (recipeEUt < 0)) {
metaTileEntity.setSituation(WORKING);
if (++progressTime >= maxProgressTime) {
//as recipe starts with progress on 1 this has to be > only not => to compensate for it
if (++progressTime > maxProgressTime) {
completeRecipe();
}
} else if (recipeEUt > 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,25 @@ public boolean canFillFluidType(FluidStack fluid) {
int liquidTemperature = fluid.getFluid().getTemperature();
return liquidTemperature >= minFluidTemperature && liquidTemperature <= maxFluidTemperature;
}


@Override
public FluidStack drain(FluidStack resource, boolean doDrain) {
FluidStack drained = super.drain(resource, doDrain);
this.removeTagWhenEmpty(doDrain);
return drained;
}

@Override
public FluidStack drain(int maxDrain, boolean doDrain) {
FluidStack drained = super.drain(maxDrain, doDrain);
this.removeTagWhenEmpty(doDrain);
return drained;
}

private void removeTagWhenEmpty(Boolean doDrain) {
if(doDrain && this.getFluid() == null) {
this.container.setTagCompound(null);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,24 @@ public boolean canFillFluidType(FluidStack fluid) {
int liquidTemperature = fluid.getFluid().getTemperature();
return liquidTemperature >= minFluidTemperature && liquidTemperature <= maxFluidTemperature;
}

@Override
public FluidStack drain(FluidStack resource, boolean doDrain) {
FluidStack drained = super.drain(resource, doDrain);
this.removeTagWhenEmpty(doDrain);
return drained;
}

@Override
public FluidStack drain(int maxDrain, boolean doDrain) {
FluidStack drained = super.drain(maxDrain, doDrain);
this.removeTagWhenEmpty(doDrain);
return drained;
}

private void removeTagWhenEmpty(Boolean doDrain) {
if(doDrain && this.getFluid() == null) {
this.container.setTagCompound(null);
}
}
}
40 changes: 33 additions & 7 deletions src/main/java/gregtech/api/metatileentity/MetaTileEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
import java.util.function.Consumer;

import static gregtech.api.situation.Situations.*;
import static gregtech.api.util.InventoryUtils.simulateItemStackMerge;

public abstract class MetaTileEntity implements ICoverable {

Expand Down Expand Up @@ -947,13 +948,38 @@ protected void moveInventoryItems(IItemHandler sourceInventory, IItemHandler tar
if (hasItemsToMove && !movedItems) this.failedToMoveItems = true;
}

public static boolean addItemsToItemHandler(IItemHandler handler, boolean simulate, List<ItemStack> items) {
boolean insertedAll = true;
for (ItemStack stack : items) {
insertedAll &= ItemHandlerHelper.insertItemStacked(handler, stack, simulate).isEmpty();
if (!insertedAll && simulate) return false;
}
return insertedAll;
/**
* Simulates the insertion of items into a target inventory, then optionally performs the insertion.
* <br /><br />
* Simulating will not modify any of the input parameters. Insertion will either succeed completely, or fail
* without modifying anything.
*
* @param handler the target inventory
* @param simulate whether to simulate ({@code true}) or actually perform the insertion ({@code false})
* @param items the items to insert into {@code handler}.
* @return {@code true} if the insertion succeeded, {@code false} otherwise.
* @throws IllegalStateException if {@code handler} does not accept all items as expected while performing a
* real insertion. This should not be possible unless the handler is modified in
* another thread, or it does not behave in a manner conforming with the contract
* of {@link gregtech.api.util.InventoryUtils#simulateItemStackMerge simulateItemStackMerge}.
*/
public static boolean addItemsToItemHandler(final IItemHandler handler,
final boolean simulate,
final List<ItemStack> items)
{
// determine if there is sufficient room to insert all items into the target inventory
final boolean canMerge = simulateItemStackMerge(items, handler);

// if we're not simulating and the merge should succeed, perform the merge.
if(!simulate && canMerge)
items.forEach(stack -> {
ItemStack rest = ItemHandlerHelper.insertItemStacked(handler, stack, simulate);
if(!rest.isEmpty())
throw new IllegalStateException(
String.format("Insertion failed, remaining stack contained %d items.", rest.getCount()));
});

return canMerge;
}

public static boolean addFluidsToFluidHandler(IFluidHandler handler, boolean simulate, List<FluidStack> items) {
Expand Down
4 changes: 3 additions & 1 deletion src/main/java/gregtech/api/pipenet/block/BlockPipe.java
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,9 @@ public boolean canConnectRedstone(IBlockState state, IBlockAccess world, BlockPo

@Override
public boolean shouldCheckWeakPower(IBlockState state, IBlockAccess world, BlockPos pos, EnumFacing side) {
return true;
// The check in World::getRedstonePower in the vanilla code base is reversed. Setting this to false will
// actually cause getWeakPower to be called, rather than prevent it.
return false;
}

@Override
Expand Down
13 changes: 13 additions & 0 deletions src/main/java/gregtech/api/recipes/MatchingMode.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package gregtech.api.recipes;

/**
* This enum is used to describe the way {@link Recipe#matches} should determine if the recipe matches the provided input.
* DEFAULT - Both Items and Liquids are checked.
* IGNORE_ITEMS - Items input are ignored, only Liquids input are checked.
* IGNORE_FLUIDS - Liquids input are ignored, only Items input are checked.
*/
public enum MatchingMode {
DEFAULT,
IGNORE_ITEMS,
IGNORE_FLUIDS
}
138 changes: 96 additions & 42 deletions src/main/java/gregtech/api/recipes/Recipe.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.items.IItemHandlerModifiable;
import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.tuple.Pair;

import java.util.*;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -77,41 +78,83 @@ public Recipe(List<CountableIngredient> inputs, List<ItemStack> outputs, List<Ch
this.inputs.sort(Comparator.comparing(CountableIngredient::getCount).reversed());
}

public final boolean matches(boolean consumeIfSuccessful, IItemHandlerModifiable inputs, IMultipleTankHandler fluidInputs, MatchingMode matchingMode) {
return matches(consumeIfSuccessful, GTUtility.itemHandlerToList(inputs), GTUtility.fluidHandlerToList(fluidInputs), matchingMode);
}

public final boolean matches(boolean consumeIfSuccessful, IItemHandlerModifiable inputs, IMultipleTankHandler fluidInputs) {
return matches(consumeIfSuccessful, GTUtility.itemHandlerToList(inputs), GTUtility.fluidHandlerToList(fluidInputs));
return matches(consumeIfSuccessful, GTUtility.itemHandlerToList(inputs), GTUtility.fluidHandlerToList(fluidInputs), MatchingMode.DEFAULT);
}

public boolean matches(boolean consumeIfSuccessful, List<ItemStack> inputs, List<FluidStack> fluidInputs) {
int[] fluidAmountInTank = new int[fluidInputs.size()];
int[] itemAmountInSlot = new int[inputs.size()];
return matches(consumeIfSuccessful, inputs, fluidInputs, MatchingMode.DEFAULT);
}

for (int i = 0; i < fluidAmountInTank.length; i++) {
FluidStack fluidInTank = fluidInputs.get(i);
fluidAmountInTank[i] = fluidInTank == null ? 0 : fluidInTank.amount;
/**
* This methods aim to verify if the current recipe matches the given inputs according to matchingMode mode.
*
* @param consumeIfSuccessful if true and matchingMode is equal to {@link MatchingMode#DEFAULT} will consume the inputs of the recipe.
* @param inputs Items input or Collections.emptyList() if none.
* @param fluidInputs Fluids input or Collections.emptyList() if none.
* @param matchingMode How this method should check if inputs matches according to {@link MatchingMode} description.
* @return true if the recipe matches the given inputs false otherwise.
*/
public boolean matches(boolean consumeIfSuccessful, List<ItemStack> inputs, List<FluidStack> fluidInputs, MatchingMode matchingMode) {
Pair<Boolean, Integer[]> fluids = null;
Pair<Boolean, Integer[]> items = null;

if (matchingMode == MatchingMode.IGNORE_FLUIDS) {
if (getInputs().isEmpty()) {
return false;
}
} else {
fluids = matchesFluid(fluidInputs);
if (!fluids.getKey()) {
return false;
}
}
for (int i = 0; i < itemAmountInSlot.length; i++) {
ItemStack itemInSlot = inputs.get(i);
itemAmountInSlot[i] = itemInSlot.isEmpty() ? 0 : itemInSlot.getCount();

if (matchingMode == MatchingMode.IGNORE_ITEMS) {
if (getFluidInputs().isEmpty()) {
return false;
}
} else {
items = matchesItems(inputs);
if (!items.getKey()) {
return false;
}
}

for (FluidStack fluid : this.fluidInputs) {
int fluidAmount = fluid.amount;
boolean isNotConsumed = false;
if (fluidAmount == 0) {
fluidAmount = 1;
isNotConsumed = true;
if (consumeIfSuccessful && matchingMode == MatchingMode.DEFAULT) {
Integer[] fluidAmountInTank = fluids.getValue();
Integer[] itemAmountInSlot = items.getValue();
for (int i = 0; i < fluidAmountInTank.length; i++) {
FluidStack fluidStack = fluidInputs.get(i);
int fluidAmount = fluidAmountInTank[i];
if (fluidStack == null || fluidStack.amount == fluidAmount)
continue;
fluidStack.amount = fluidAmount;
if (fluidStack.amount == 0)
fluidInputs.set(i, null);
}
for (int i = 0; i < fluidInputs.size(); i++) {
FluidStack tankFluid = fluidInputs.get(i);
if (tankFluid == null || !tankFluid.isFluidEqual(fluid))
for (int i = 0; i < itemAmountInSlot.length; i++) {
ItemStack itemInSlot = inputs.get(i);
int itemAmount = itemAmountInSlot[i];
if (itemInSlot.isEmpty() || itemInSlot.getCount() == itemAmount)
continue;
int fluidAmountToConsume = Math.min(fluidAmountInTank[i], fluidAmount);
fluidAmount -= fluidAmountToConsume;
if (!isNotConsumed) fluidAmountInTank[i] -= fluidAmountToConsume;
if (fluidAmount == 0) break;
itemInSlot.setCount(itemAmountInSlot[i]);
}
if (fluidAmount > 0)
return false;
}

return true;
}

private Pair<Boolean, Integer[]> matchesItems(List<ItemStack> inputs) {
Integer[] itemAmountInSlot = new Integer[inputs.size()];

for (int i = 0; i < itemAmountInSlot.length; i++) {
ItemStack itemInSlot = inputs.get(i);
itemAmountInSlot[i] = itemInSlot.isEmpty() ? 0 : itemInSlot.getCount();
}

for (CountableIngredient ingredient : this.inputs) {
Expand All @@ -131,29 +174,40 @@ public boolean matches(boolean consumeIfSuccessful, List<ItemStack> inputs, List
if (ingredientAmount == 0) break;
}
if (ingredientAmount > 0)
return false;
return Pair.of(false, itemAmountInSlot);
}

if (consumeIfSuccessful) {
for (int i = 0; i < fluidAmountInTank.length; i++) {
FluidStack fluidStack = fluidInputs.get(i);
int fluidAmount = fluidAmountInTank[i];
if (fluidStack == null || fluidStack.amount == fluidAmount)
continue;
fluidStack.amount = fluidAmount;
if (fluidStack.amount == 0)
fluidInputs.set(i, null);
return Pair.of(true, itemAmountInSlot);
}

private Pair<Boolean, Integer[]> matchesFluid(List<FluidStack> fluidInputs) {
Integer[] fluidAmountInTank = new Integer[fluidInputs.size()];

for (int i = 0; i < fluidAmountInTank.length; i++) {
FluidStack fluidInTank = fluidInputs.get(i);
fluidAmountInTank[i] = fluidInTank == null ? 0 : fluidInTank.amount;
}

for (FluidStack fluid : this.fluidInputs) {
int fluidAmount = fluid.amount;
boolean isNotConsumed = false;
if (fluidAmount == 0) {
fluidAmount = 1;
isNotConsumed = true;
}
for (int i = 0; i < itemAmountInSlot.length; i++) {
ItemStack itemInSlot = inputs.get(i);
int itemAmount = itemAmountInSlot[i];
if (itemInSlot.isEmpty() || itemInSlot.getCount() == itemAmount)
for (int i = 0; i < fluidInputs.size(); i++) {
FluidStack tankFluid = fluidInputs.get(i);
if (tankFluid == null || !tankFluid.isFluidEqual(fluid))
continue;
itemInSlot.setCount(itemAmountInSlot[i]);
int fluidAmountToConsume = Math.min(fluidAmountInTank[i], fluidAmount);
fluidAmount -= fluidAmountToConsume;
if (!isNotConsumed) fluidAmountInTank[i] -= fluidAmountToConsume;
if (fluidAmount == 0) break;
}
if (fluidAmount > 0)
return Pair.of(false, fluidAmountInTank);
}

return true;
return Pair.of(true, fluidAmountInTank);
}

///////////////////
Expand All @@ -176,7 +230,7 @@ public List<ItemStack> getResultItemOutputs(int maxOutputSlots, Random random, i
chancedOutputsList = chancedOutputsList.subList(0, Math.max(0, maxChancedSlots));
}
for (ChanceEntry chancedOutput : chancedOutputsList) {
int outputChance = RecipeMap.getChanceFunction().chanceFor(chancedOutput.getChance(),chancedOutput.getBoostPerTier(), tier);
int outputChance = RecipeMap.getChanceFunction().chanceFor(chancedOutput.getChance(), chancedOutput.getBoostPerTier(), tier);
if (random.nextInt(Recipe.getMaxChancedValue()) <= outputChance) {
outputs.add(chancedOutput.getItemStack().copy());
}
Expand Down
Loading

0 comments on commit 01bffe1

Please sign in to comment.