Crafting calculator now supports damageable items, and ore dictionary stuff in primitive form.

This commit is contained in:
AlgorithmX2 2014-06-16 22:36:35 -05:00
parent 1632d2d72e
commit 83d3a3aadb
4 changed files with 134 additions and 29 deletions

View file

@ -1,5 +1,6 @@
package appeng.crafting;
import java.util.HashMap;
import java.util.HashSet;
import java.util.concurrent.TimeUnit;
@ -54,6 +55,13 @@ public class CraftingJob
Stopwatch timer = Stopwatch.createStarted();
tree.request( meci, what.getStackSize(), host.getActionSrc() );
tree.dive( this );
for (String s : opsAndMultiplier.keySet())
{
twoIntegers ti = opsAndMultiplier.get( s );
AELog.info( s + " * " + ti.times + " = " + (ti.perOp * ti.times) );
}
AELog.info( "-------------" + timer.elapsed( TimeUnit.MILLISECONDS ) + "ms" );
// if ( mode == Actionable.MODULATE )
// meci.moveItemsToStorage( storage );
@ -70,7 +78,7 @@ public class CraftingJob
private CraftingTreeNode getCraftingTree(CraftingCache cc, IAEItemStack what)
{
return new CraftingTreeNode( cc, this, what, null, 0 );
return new CraftingTreeNode( cc, this, what, null, -1, 0 );
}
public void writeToNBT(NBTTagCompound out)
@ -78,18 +86,35 @@ public class CraftingJob
}
public void addTask(IAEItemStack what, int crafts, ICraftingPatternDetails details, int depth)
public void addTask(IAEItemStack what, long crafts, ICraftingPatternDetails details, int depth)
{
if ( crafts > 0 )
{
AELog.info( "new task: " + Platform.getItemDisplayName( what ) + " x " + what.getStackSize() + " * " + crafts + " = "
+ (what.getStackSize() * crafts) + " @ " + depth );
postOp( "new task: " + Platform.getItemDisplayName( what ) + " x " + what.getStackSize(), what.getStackSize(), crafts );
}
}
public void addMissing(IAEItemStack what)
{
AELog.info( "required material: " + Platform.getItemDisplayName( what ) + " x " + what.getStackSize() );
postOp( "required material: " + Platform.getItemDisplayName( what ), 1, what.getStackSize() );
}
class twoIntegers
{
public long perOp = 0;
public long times = 0;
};
HashMap<String, twoIntegers> opsAndMultiplier = new HashMap();
private void postOp(String string, long stackSize, long crafts)
{
twoIntegers ti = opsAndMultiplier.get( string );
if ( ti == null )
opsAndMultiplier.put( string, ti = new twoIntegers() );
ti.perOp = stackSize;
ti.times += crafts;
}
}

View file

@ -2,7 +2,9 @@ package appeng.crafting;
import java.util.ArrayList;
import net.minecraft.world.World;
import appeng.api.config.Actionable;
import appeng.api.config.FuzzyMode;
import appeng.api.networking.crafting.ICraftingPatternDetails;
import appeng.api.networking.security.BaseActionSource;
import appeng.api.storage.data.IAEItemStack;
@ -13,6 +15,10 @@ public class CraftingTreeNode
// parent node.
private CraftingTreeProcess parent;
private World world;
// what slot!
int slot;
// what item is this?
private IAEItemStack what;
@ -21,16 +27,18 @@ public class CraftingTreeNode
private ArrayList<CraftingTreeProcess> nodes = new ArrayList();
boolean cannotUse = false;
int missing = 0;
long missing = 0;
public CraftingTreeNode(CraftingCache cc, CraftingJob job, IAEItemStack wat, CraftingTreeProcess par, int depth) {
public CraftingTreeNode(CraftingCache cc, CraftingJob job, IAEItemStack wat, CraftingTreeProcess par, int slot, int depth) {
what = wat;
parent = par;
this.slot = slot;
this.world = job.jobHost.getWorld();
for (ICraftingPatternDetails details : cc.getCraftingFor( what ))// in order.
{
if ( notRecurive( details ) )
nodes.add( new CraftingTreeProcess( cc, job, details, this, depth + 1 ) );
nodes.add( new CraftingTreeProcess( cc, job, details, this, depth + 1, world ) );
}
}
@ -54,21 +62,41 @@ public class CraftingTreeNode
return parent.notRecurive( details );
}
private long getTimes(long remaining, long stackSize)
{
return (remaining / stackSize) + (remaining % stackSize != 0 ? 1 : 0);
}
public void request(MECraftingInventory inv, long l, BaseActionSource src) throws CraftBranchFailure
public IAEItemStack request(MECraftingInventory inv, long l, BaseActionSource src) throws CraftBranchFailure
{
what.setStackSize( l );
IAEItemStack available = inv.extractItems( what, Actionable.MODULATE, src );
if ( slot >= 0 && parent != null && parent.details.isCraftable() )
{
for (IAEItemStack fuzz : inv.getItemList().findFuzzy( what, FuzzyMode.IGNORE_ALL ))
{
if ( parent.details.isValidItemForSlot( slot, fuzz.getItemStack(), world ) )
{
fuzz = fuzz.copy();
fuzz.setStackSize( l );
IAEItemStack available = inv.extractItems( fuzz, Actionable.MODULATE, src );
if ( available != null )
l -= available.getStackSize();
if ( available != null )
{
l -= available.getStackSize();
if ( l == 0 )
return;
if ( l == 0 )
return available;
}
}
}
}
else
{
IAEItemStack available = inv.extractItems( what, Actionable.MODULATE, src );
if ( available != null )
{
l -= available.getStackSize();
if ( l == 0 )
return available;
}
}
if ( nodes.size() == 1 )
{
@ -76,17 +104,17 @@ public class CraftingTreeNode
while (pro.possible && l > 0)
{
pro.request( inv, getTimes( l, pro.getAmountCrafted( what ).getStackSize() ), src );
pro.request( inv, pro.getTimes( l, pro.getAmountCrafted( what ).getStackSize() ), src );
what.setStackSize( l );
available = inv.extractItems( what, Actionable.MODULATE, src );
IAEItemStack available = inv.extractItems( what, Actionable.MODULATE, src );
if ( available != null )
{
l -= available.getStackSize();
if ( l <= 0 )
return;
return available;
}
else
pro.possible = false; // ;P
@ -105,14 +133,14 @@ public class CraftingTreeNode
subInv.commit( src );
what.setStackSize( l );
available = inv.extractItems( what, Actionable.MODULATE, src );
IAEItemStack available = inv.extractItems( what, Actionable.MODULATE, src );
if ( available != null )
{
l -= available.getStackSize();
if ( l <= 0 )
return;
return available;
}
else
pro.possible = false; // ;P
@ -126,6 +154,7 @@ public class CraftingTreeNode
}
missing += l;
return what;
// throw new CraftBranchFailure( what, l );
}

View file

@ -4,6 +4,9 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import appeng.api.AEApi;
import appeng.api.config.Actionable;
import appeng.api.networking.crafting.ICraftingPatternDetails;
import appeng.api.networking.security.BaseActionSource;
@ -17,20 +20,43 @@ public class CraftingTreeProcess
ICraftingPatternDetails details;
CraftingJob job;
int crafts = 0;
long crafts = 0;
boolean damageable;
final private int depth;
Map<CraftingTreeNode, Long> nodes = new HashMap();
public boolean possible = true;
public CraftingTreeProcess(CraftingCache cc, CraftingJob job, ICraftingPatternDetails details, CraftingTreeNode craftingTreeNode, int depth) {
public CraftingTreeProcess(CraftingCache cc, CraftingJob job, ICraftingPatternDetails details, CraftingTreeNode craftingTreeNode, int depth, World world) {
parent = craftingTreeNode;
this.details = details;
this.job = job;
this.depth = depth;
for (IAEItemStack part : details.getCondencedInputs())
nodes.put( new CraftingTreeNode( cc, job, part.copy(), this, depth + 1 ), part.getStackSize() );
if ( details.isCraftable() )
{
IAEItemStack list[] = details.getInputs();
for (int x = 0; x < list.length; x++)
{
IAEItemStack part = list[x];
if ( part != null )
{
ItemStack is = part.getItemStack();
if ( is.getItem().hasContainerItem( is ) )
damageable = true;
nodes.put( new CraftingTreeNode( cc, job, part.copy(), this, x, depth + 1 ), part.getStackSize() );
}
}
}
else
{
for (IAEItemStack part : details.getCondencedInputs())
{
nodes.put( new CraftingTreeNode( cc, job, part.copy(), this, -1, depth + 1 ), part.getStackSize() );
}
}
}
public boolean notRecurive(ICraftingPatternDetails details)
@ -38,6 +64,13 @@ public class CraftingTreeProcess
return parent.notRecurive( details );
}
long getTimes(long remaining, long stackSize)
{
if ( damageable )
return 1;
return (remaining / stackSize) + (remaining % stackSize != 0 ? 1 : 0);
}
IAEItemStack getAmountCrafted(IAEItemStack what2)
{
for (IAEItemStack is : details.getCondencedOutputs())
@ -59,7 +92,22 @@ public class CraftingTreeProcess
for (Entry<CraftingTreeNode, Long> entry : nodes.entrySet())
{
IAEItemStack item = entry.getKey().getStack( entry.getValue() );
entry.getKey().request( inv, item.getStackSize() * i, src );
IAEItemStack stack = entry.getKey().request( inv, item.getStackSize() * i, src );
if ( damageable )
{
ItemStack is = stack.getItemStack();
if ( stack.getItem().hasContainerItem( is ) )
{
is = stack.getItem().getContainerItem( is );
if ( is.isItemStackDamageable() && is.getItemDamage() == is.getMaxDamage() )
is = null;
IAEItemStack o = AEApi.instance().storage().createItemStack( is );
if ( o != null )
inv.injectItems( o, Actionable.MODULATE, src );
}
}
}
// assume its possible.

View file

@ -198,7 +198,10 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
public boolean isValidItemForSlot(int slotIndex, ItemStack i, World w)
{
if ( isCrafting == false )
{
throw new RuntimeException( "Only crafting recipes supported." );
}
TestStatus result = getStatus( slotIndex, i );