Compare commits

...
10 Commits
11 changed files with 112 additions and 13 deletions

No files matched your search

+4
View File
@@ -257,3 +257,7 @@ def getBuildNumber() {
return "$System.env.BUILD_NUMBER" != "null" ? "$System.env.BUILD_NUMBER" : "0"
}
sourceSets {
main { output.resourcesDir = output.classesDir }
}
+1 -1
View File
@@ -2,4 +2,4 @@ mcversion=1.7.10
forgeversion=10.13.4.1614-1.7.10
version_major=4
version_minor=2
version_patch=20
version_patch=22
@@ -77,6 +77,12 @@ public class Config {
// Performance
public static boolean enableBackpackResupply = true;
// Optimization
public static boolean enableCraftingTimeout = true;
public static int craftingTimeout = 200; // Time given in ms
public static boolean cacheWorktableRecipes = true;
public static boolean promoteWorktableRecipesToFrontOfGlobalRecipemap = true;
// Customization
private static boolean craftingBronzeEnabled = true;
@@ -215,6 +221,11 @@ public class Config {
enableBackpackResupply = configCommon.getBooleanLocalized("performance", "backpacks.resupply", enableBackpackResupply);
enableCraftingTimeout = configCommon.getBooleanLocalized("optimization","enable.crafting.timeout", enableCraftingTimeout);
craftingTimeout = configCommon.getIntLocalized("optimization","crafting.timeout",craftingTimeout, 50, 2000 ); // min 50ms, default 200ms, max 2000 ms. Integer.MAX_VALUE is ~ 2100 ms because of multiplication by 1,000,000
cacheWorktableRecipes = configCommon.getBooleanLocalized("optimization","cache.worktable.recipes", cacheWorktableRecipes);
promoteWorktableRecipesToFrontOfGlobalRecipemap = configCommon.getBooleanLocalized("optimization","promote.worktable.recipes",promoteWorktableRecipesToFrontOfGlobalRecipemap);
// move legacy mail property
configCommon.moveProperty("tweaks.gui", "mail.alert", "tweaks.gui.mail.alert");
configCommon.renameProperty("tweaks.gui.mail.alert", "mail.alert", "enabled");
@@ -30,13 +30,14 @@ import cpw.mods.fml.common.registry.GameRegistry;
import forestry.api.recipes.IDescriptiveRecipe;
import forestry.api.recipes.RecipeManagers;
import forestry.core.config.Config;
import forestry.core.fluids.Fluids;
import forestry.core.utils.ItemStackUtil;
import forestry.core.utils.Log;
import forestry.factory.inventory.InventoryCraftingForestry;
public abstract class RecipeUtil {
static List<Object> cachedRecipes = new ArrayList<Object>();
public static void addFermenterRecipes(ItemStack resource, int fermentationValue, Fluids output) {
if (RecipeManagers.fermenterManager == null) {
return;
@@ -99,7 +100,6 @@ public abstract class RecipeUtil {
if (ItemStackUtil.containsSets(recipeItems, availableItems, true, true) == 0) {
return null;
}
// Check that it doesn't make a different recipe.
// For example:
// Wood Logs are all ore dictionary equivalent with each other,
@@ -140,7 +140,6 @@ public abstract class RecipeUtil {
}
}
}
List<ItemStack> outputs = findMatchingRecipes(crafting, world);
if (!ItemStackUtil.containsItemStack(outputs, recipeOutput)) {
return null;
@@ -155,7 +154,29 @@ public abstract class RecipeUtil {
}
List<ItemStack> matchingRecipes = new ArrayList<>();
List<Integer> matchingIndex=new ArrayList();
List<Object> matchingRecipeMap = new ArrayList();
int index = 0;
if(Config.cacheWorktableRecipes) {
// Check across the whole cached recipe map
// Add each recipe to the matchingRecipes list
for (Object recipe : cachedRecipes) {
IRecipe irecipe = (IRecipe) recipe;
if (irecipe.matches(inventory, world)) {
ItemStack result = irecipe.getCraftingResult(inventory);
if (!ItemStackUtil.containsItemStack(matchingRecipes, result)) {
matchingRecipes.add(result);
}
}
}
if( matchingRecipes.size() > 0 ) {
// If we found recipes here, we found all the potential recipes, so we can just return immediately.
return matchingRecipes;
}
}
// Only do this if there were no cached recipes hit
for (Object recipe : CraftingManager.getInstance().getRecipeList()) {
IRecipe irecipe = (IRecipe) recipe;
@@ -163,10 +184,39 @@ public abstract class RecipeUtil {
ItemStack result = irecipe.getCraftingResult(inventory);
if (!ItemStackUtil.containsItemStack(matchingRecipes, result)) {
matchingRecipes.add(result);
if(Config.promoteWorktableRecipesToFrontOfGlobalRecipemap || Config.cacheWorktableRecipes) {
// Add to the back of the list. That way when we cycle through the list
// moving items to the front, the index locations for the following items doesn't change
matchingRecipeMap.add(recipe);
matchingIndex.add(new Integer(index));
}
}
}
index++;
}
if (matchingRecipeMap.size() > 0 )
{
if (Config.promoteWorktableRecipesToFrontOfGlobalRecipemap) {
// Only move the recipes if the last one was beyond 500 in the recipeMap (in GTNH about 57k recipes)
if (matchingIndex.get(matchingIndex.size()-1) > 500) {
List recipeMap = CraftingManager.getInstance().getRecipeList();
System.out.println( "Highest recipe found at " + matchingIndex.get(matchingIndex.size()-1) + ", moving " + matchingIndex.size() + " to front" );
System.out.println( "Size of recipe map " + recipeMap.size() );
for (index = 0; index < matchingIndex.size(); index++) { // index is reused here, it goes through the matching groups.
// Remove recipe and add back at the front
int target = matchingIndex.get(index); // remove requires int
System.out.println("Removing recipe at " + target);
recipeMap.remove(target);
recipeMap.add(0,matchingRecipeMap.get(index));
}
}
}
if(Config.cacheWorktableRecipes) {
// However, we should always add found recipes the cached recipe map
// Location doesn't matter since we have to scan the whole cached recipe map anyways.
cachedRecipes.addAll(matchingRecipeMap);
}
}
return matchingRecipes;
}
@@ -265,6 +265,7 @@ public abstract class SlotUtil {
// if mergeOnly = true, don't shift into empty slots.
private static boolean shiftToMachineInventory(List inventorySlots, ItemStack stackToShift, int numSlots, boolean mergeOnly) {
for (int machineIndex = playerInventorySize; machineIndex < numSlots; machineIndex++) {
// System.out.println("SlotUtil::shiftToMachineinventory");
Slot slot = (Slot) inventorySlots.get(machineIndex);
if (mergeOnly && slot.getStack() == null) {
continue;
@@ -21,6 +21,7 @@ import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.entity.player.PlayerDestroyItemEvent;
import forestry.core.config.Config;
import forestry.core.inventory.InventoryAdapterTile;
import forestry.core.inventory.wrappers.InventoryMapper;
import forestry.core.network.DataInputStreamForestry;
@@ -41,7 +42,9 @@ public class TileWorktable extends TileBase implements ICrafterWorktable {
private final RecipeMemory recipeMemory;
private final InventoryAdapterTile craftingDisplay;
private MemorizedRecipe currentRecipe;
private long savedTick = 0;
private long savedSystemTimeExpiration = 0;
public TileWorktable() {
super("worktable");
setInternalInventory(new InventoryWorktable(this));
@@ -121,10 +124,27 @@ public class TileWorktable extends TileBase implements ICrafterWorktable {
return false;
}
if( Config.enableCraftingTimeout ) {
long currentTick = worldObj.getTotalWorldTime();
if (currentTick == savedTick){
// Processing in the same tick, second call, check expiration timer
long currentTime = System.nanoTime();
if(currentTime > savedSystemTimeExpiration) {
// Time to craft has expired, stop crafting loop
return false;
}
} else {
// New tick has arrived, so reset timer data
savedTick=currentTick;
savedSystemTimeExpiration = System.nanoTime() + Config.craftingTimeout * 1000000;
}
}
ItemStack[] recipeItems = InventoryUtil.getStacks(currentRecipe.getCraftMatrix());
ItemStack[] inventory = InventoryUtil.getStacks(this);
InventoryCraftingForestry crafting = RecipeUtil.getCraftRecipe(recipeItems, inventory, worldObj, currentRecipe.getRecipeOutput());
return crafting != null;
return crafting != null;
}
@Override
@@ -147,7 +167,6 @@ public class TileWorktable extends TileBase implements ICrafterWorktable {
if (removed == null) {
return false;
}
// update crafting display to match the ingredients that were actually used
setCraftingDisplay(crafting);
return true;
@@ -28,7 +28,7 @@ public class ButterflySpawner implements ILeafTickHandler {
if (world.rand.nextFloat() >= tree.getGenome().getSappiness() * tree.getGenome().getYield()) {
return false;
}
IButterfly spawn = ButterflyManager.butterflyRoot.getIndividualTemplates().get(world.rand.nextInt(ButterflyManager.butterflyRoot.getIndividualTemplates().size()));
if (world.rand.nextFloat() >= spawn.getGenome().getPrimary().getRarity() * 0.5f) {
return false;
@@ -23,6 +23,7 @@ import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.ChunkCoordinates;
import net.minecraft.util.DamageSource;
import net.minecraft.util.MathHelper;
import net.minecraft.util.MovingObjectPosition;
@@ -69,6 +70,7 @@ public class EntityButterfly extends EntityCreature implements IEntityButterfly
public static final int EXHAUSTION_REST = 1000;
public static final int EXHAUSTION_CONSUMPTION = 100 * EXHAUSTION_REST;
public static final int MAX_LIFESPAN = 24000 * 7; // one minecraft week in ticks
private int maximumHomeDistance = 64;
private Vec3 flightTarget;
private int exhaustion;
@@ -89,10 +91,11 @@ public class EntityButterfly extends EntityCreature implements IEntityButterfly
setDefaults();
}
public EntityButterfly(World world, IButterfly butterfly) {
public EntityButterfly(World world, IButterfly butterfly, int x, int y, int z) {
super(world);
setDefaults();
setIndividual(butterfly);
setHomeArea(x, y, z, maximumHomeDistance);
}
@Override
@@ -194,6 +197,13 @@ public class EntityButterfly extends EntityCreature implements IEntityButterfly
@Override
public float getBlockPathWeight(int x, int y, int z) {
float weight = 0.0f;
final ChunkCoordinates home = getHomePosition();
double distanceToHome = home.getDistanceSquared(x, y, z);
if(!isWithinHomeDistanceFromPosition(distanceToHome)){
weight -= 7.5f + 0.005 * (distanceToHome / 4);
}
if (!getButterfly().isAcceptedEnvironment(worldObj, x, y, z)) {
weight -= 15.0f;
@@ -232,6 +242,10 @@ public class EntityButterfly extends EntityCreature implements IEntityButterfly
return weight;
}
private boolean isWithinHomeDistanceFromPosition(double distanceToHome) {
return distanceToHome < (maximumHomeDistance * maximumHomeDistance);
}
private int getFluidDepth(int x, int z) {
Chunk chunk = worldObj.getChunkFromBlockCoords(x, z);
int xx = x & 15;
@@ -149,7 +149,7 @@ public class ButterflyHelper extends SpeciesRoot implements IButterflyRoot {
@Override
public EntityButterfly spawnButterflyInWorld(World world, IButterfly butterfly, double x, double y, double z) {
return EntityUtil.spawnEntity(world, new EntityButterfly(world, butterfly), x, y, z);
return EntityUtil.spawnEntity(world, new EntityButterfly(world, butterfly, (int)x, (int)y, (int)z), x, y, z);
}
@Override
@@ -133,7 +133,7 @@ public class ItemButterflyGE extends ItemGE {
return false;
}
if (EntityUtil.spawnEntity(entityItem.worldObj, new EntityButterfly(entityItem.worldObj, butterfly), entityItem.posX, entityItem.posY, entityItem.posZ) != null) {
if (EntityUtil.spawnEntity(entityItem.worldObj, new EntityButterfly(entityItem.worldObj, butterfly, (int)entityItem.posX, (int)entityItem.posY, (int)entityItem.posZ), entityItem.posX, entityItem.posY, entityItem.posZ) != null) {
if (entityItem.getEntityItem().stackSize > 1) {
entityItem.getEntityItem().stackSize--;
} else {
@@ -81,7 +81,7 @@ public class RenderButterflyItem implements IItemRenderer {
}
if (entity == null) {
entity = new EntityButterfly(Proxies.common.getRenderWorld(), butterfly);
entity = new EntityButterfly(Proxies.common.getRenderWorld(), butterfly, 0, 0, 0);
} else {
entity.setIndividual(butterfly);
}