Remove all autocrafting logic. Improve the ICraftingPattern interface. Remove blocking mode.
This commit is contained in:
@@ -1,36 +0,0 @@
|
||||
package com.raoulvdberge.refinedstorage.api.autocrafting;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.api.network.INetwork;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.fml.common.eventhandler.Event;
|
||||
import net.minecraftforge.items.ItemHandlerHelper;
|
||||
|
||||
/**
|
||||
* Event fired upon completion of an auto crafting task.
|
||||
*/
|
||||
public class EventAutocraftingComplete extends Event {
|
||||
private ItemStack crafted;
|
||||
private INetwork network;
|
||||
|
||||
private EventAutocraftingComplete(INetwork network, ItemStack crafted) {
|
||||
this.crafted = crafted;
|
||||
this.network = network;
|
||||
}
|
||||
|
||||
public ItemStack getCrafted() {
|
||||
return crafted;
|
||||
}
|
||||
|
||||
public INetwork getNetwork() {
|
||||
return network;
|
||||
}
|
||||
|
||||
public static void fire(INetwork network, ItemStack crafted) {
|
||||
MinecraftForge.EVENT_BUS.post(new EventAutocraftingComplete(network, crafted));
|
||||
}
|
||||
|
||||
public static void fire(INetwork network, ItemStack crafted, int quantity) {
|
||||
fire(network, ItemHandlerHelper.copyStackWithSize(crafted, quantity));
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,6 @@ package com.raoulvdberge.refinedstorage.api.autocrafting;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTask;
|
||||
import com.raoulvdberge.refinedstorage.api.util.IComparer;
|
||||
import com.raoulvdberge.refinedstorage.api.util.IStackList;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
@@ -12,7 +11,6 @@ import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* The crafting manager handles the storing, updating, adding and deleting of crafting tasks in a network.
|
||||
@@ -23,39 +21,11 @@ public interface ICraftingManager {
|
||||
*/
|
||||
List<ICraftingTask> getTasks();
|
||||
|
||||
/**
|
||||
* @return all the crafting pattern containers
|
||||
*/
|
||||
List<ICraftingPatternContainer> getContainers();
|
||||
|
||||
/**
|
||||
* @return named crafting pattern containers
|
||||
*/
|
||||
Map<String, List<IItemHandlerModifiable>> getNamedContainers();
|
||||
|
||||
/**
|
||||
* @param blocker the container that is blocking another container
|
||||
* @param blockee the container being blocked, may be the same as blocker
|
||||
*/
|
||||
void addContainerBlock(UUID blocker, UUID blockee);
|
||||
|
||||
/**
|
||||
* @param blocker the container that is blocking another container
|
||||
*/
|
||||
void removeContainerBlock(UUID blocker);
|
||||
|
||||
/**
|
||||
* @param blockee the container to check
|
||||
* @return whether the container is blocked
|
||||
*/
|
||||
boolean isContainerBlocked(UUID blockee);
|
||||
|
||||
/**
|
||||
* @param container the container to set the blocking state for
|
||||
* @param blocked whether the container should be blocked
|
||||
*/
|
||||
void setContainerBlocked(ICraftingPatternContainer container, boolean blocked);
|
||||
|
||||
/**
|
||||
* Adds a crafting task.
|
||||
*
|
||||
@@ -70,27 +40,8 @@ public interface ICraftingManager {
|
||||
*/
|
||||
void cancel(@Nonnull ICraftingTask task);
|
||||
|
||||
/**
|
||||
* Creates a crafting task.
|
||||
*
|
||||
* @param stack the stack to create a task for
|
||||
* @param pattern the pattern
|
||||
* @param quantity the quantity
|
||||
* @param automated whether this crafting task is created in an automated way
|
||||
* @return the crafting task
|
||||
*/
|
||||
ICraftingTask create(@Nullable ItemStack stack, ICraftingPattern pattern, int quantity, boolean automated);
|
||||
|
||||
/**
|
||||
* Creates a crafting task.
|
||||
*
|
||||
* @param stack the stack to create a task for
|
||||
* @param patternChain the pattern
|
||||
* @param quantity the quantity
|
||||
* @param automated whether this crafting task is created in an automated way
|
||||
* @return the crafting task
|
||||
*/
|
||||
ICraftingTask create(@Nullable ItemStack stack, ICraftingPatternChain patternChain, int quantity, boolean automated);
|
||||
@Nullable
|
||||
ICraftingTask create(ItemStack stack, int quantity);
|
||||
|
||||
/**
|
||||
* Schedules a crafting task if the task isn't scheduled yet.
|
||||
@@ -121,122 +72,14 @@ public interface ICraftingManager {
|
||||
void rebuild();
|
||||
|
||||
/**
|
||||
* Returns crafting patterns from an item stack.
|
||||
* Return a crafting pattern from an item stack.
|
||||
*
|
||||
* @param pattern the stack to get a pattern for
|
||||
* @param flags the flags to compare on, see {@link IComparer}
|
||||
* @return a list of crafting patterns where the given pattern is one of the outputs
|
||||
*/
|
||||
List<ICraftingPattern> getPatterns(ItemStack pattern, int flags);
|
||||
|
||||
/**
|
||||
* Returns a crafting pattern for an item stack.
|
||||
* This returns a single crafting pattern, as opposed to {@link ICraftingManager#getPatterns(ItemStack, int)}.
|
||||
* Internally, this makes a selection out of the available patterns.
|
||||
* It makes this selection based on the item count of the pattern outputs in the system.
|
||||
*
|
||||
* @param pattern the stack to get a pattern for
|
||||
* @param flags the flags to compare on, see {@link IComparer}
|
||||
* @return the pattern, or null if the pattern is not found
|
||||
* @return the crafting pattern, or null if none is found
|
||||
*/
|
||||
@Nullable
|
||||
default ICraftingPattern getPattern(ItemStack pattern, int flags) {
|
||||
ICraftingPatternChain chain = getPatternChain(pattern, flags);
|
||||
|
||||
return chain == null ? null : chain.cycle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a crafting pattern for an item stack.
|
||||
* This returns a single crafting pattern, as opposed to {@link ICraftingManager#getPatterns(ItemStack, int)}.
|
||||
* Internally, this makes a selection out of the available patterns.
|
||||
* It makes this selection based on the item count of the pattern outputs in the {@link IStackList<ItemStack>} provided.
|
||||
*
|
||||
* @param pattern the stack to get a pattern for
|
||||
* @param flags the flags to compare on, see {@link IComparer}
|
||||
* @param itemList the {@link IStackList<ItemStack>} used to calculate the best fitting pattern
|
||||
* @return the pattern, or null if the pattern is not found
|
||||
*/
|
||||
@Nullable
|
||||
default ICraftingPattern getPattern(ItemStack pattern, int flags, IStackList<ItemStack> itemList) {
|
||||
ICraftingPatternChain chain = getPatternChain(pattern, flags, itemList);
|
||||
|
||||
return chain == null ? null : chain.cycle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a crafting pattern for an item stack.
|
||||
* This returns a single crafting pattern, as opposed to {@link ICraftingManager#getPatterns(ItemStack, int)}.
|
||||
* Internally, this makes a selection out of the available patterns.
|
||||
* It makes this selection based on the item count of the pattern outputs in the system.
|
||||
*
|
||||
* @param pattern the stack to get a pattern for
|
||||
* @return the pattern, or null if the pattern is not found
|
||||
*/
|
||||
@Nullable
|
||||
default ICraftingPattern getPattern(ItemStack pattern) {
|
||||
return getPattern(pattern, IComparer.COMPARE_DAMAGE | IComparer.COMPARE_NBT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a crafting pattern chain for an item stack.
|
||||
* This returns a single crafting pattern, as opposed to {@link ICraftingManager#getPatterns(ItemStack, int)}.
|
||||
* Internally, this makes a selection out of the available patterns.
|
||||
* It makes this selection based on the item count of the pattern outputs in the system.
|
||||
*
|
||||
* @param pattern the stack to get a pattern for
|
||||
* @param flags the flags to compare on, see {@link IComparer}
|
||||
* @return the pattern chain, or null if the pattern chain is not found
|
||||
*/
|
||||
@Nullable
|
||||
ICraftingPatternChain getPatternChain(ItemStack pattern, int flags);
|
||||
|
||||
/**
|
||||
* Returns a crafting pattern chain for an item stack.
|
||||
* This returns a single crafting pattern, as opposed to {@link ICraftingManager#getPatterns(ItemStack, int)}.
|
||||
* Internally, this makes a selection out of the available patterns.
|
||||
* It makes this selection based on the item count of the pattern outputs in the {@link IStackList<ItemStack>} provided.
|
||||
*
|
||||
* @param pattern the stack to get a pattern for
|
||||
* @param flags the flags to compare on, see {@link IComparer}
|
||||
* @param itemList the {@link IStackList<ItemStack>} used to calculate the best fitting pattern
|
||||
* @return the pattern chain, or null if the pattern chain is not found
|
||||
*/
|
||||
@Nullable
|
||||
ICraftingPatternChain getPatternChain(ItemStack pattern, int flags, IStackList<ItemStack> itemList);
|
||||
|
||||
/**
|
||||
* Returns a crafting pattern for an item stack.
|
||||
* This returns a single crafting pattern, as opposed to {@link ICraftingManager#getPatterns(ItemStack, int)}.
|
||||
* Internally, this makes a selection out of the available patterns.
|
||||
* It makes this selection based on the item count of the pattern outputs in the system.
|
||||
*
|
||||
* @param pattern the stack to get a pattern for
|
||||
* @return the pattern chain, or null if the pattern chain is not found
|
||||
*/
|
||||
@Nullable
|
||||
default ICraftingPatternChain getPatternChain(ItemStack pattern) {
|
||||
return getPatternChain(pattern, IComparer.COMPARE_DAMAGE | IComparer.COMPARE_NBT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if there is a pattern with a given stack as output.
|
||||
*
|
||||
* @param stack the stack
|
||||
* @return true if there is a pattern, false otherwise
|
||||
*/
|
||||
default boolean hasPattern(ItemStack stack) {
|
||||
return hasPattern(stack, IComparer.COMPARE_DAMAGE | IComparer.COMPARE_NBT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if there is a pattern with a given stack as output.
|
||||
*
|
||||
* @param stack the stack
|
||||
* @param flags the flags to compare on, see {@link IComparer}
|
||||
* @return true if there is a pattern, false otherwise
|
||||
*/
|
||||
boolean hasPattern(ItemStack stack, int flags);
|
||||
ICraftingPattern getPattern(ItemStack pattern, int flags);
|
||||
|
||||
/**
|
||||
* Updates the tasks in this manager.
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
package com.raoulvdberge.refinedstorage.api.autocrafting;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.api.util.IComparer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.NonNullList;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -36,82 +35,34 @@ public interface ICraftingPattern {
|
||||
boolean isOredict();
|
||||
|
||||
/**
|
||||
* @return true if the crafting pattern may block other crafting tasks that are the same, false otherwise
|
||||
* @return the inputs per slot
|
||||
*/
|
||||
boolean isBlocking();
|
||||
|
||||
/**
|
||||
* @return the inputs, can contain nulls
|
||||
*/
|
||||
List<ItemStack> getInputs();
|
||||
|
||||
/**
|
||||
* @return the possible inputs per slot, empty list means null slot
|
||||
*/
|
||||
List<List<ItemStack>> getOreInputs();
|
||||
|
||||
/**
|
||||
* @param took the items took
|
||||
* @return the outputs based on the items took, null when failed
|
||||
*/
|
||||
@Nullable
|
||||
List<ItemStack> getOutputs(ItemStack[] took);
|
||||
List<NonNullList<ItemStack>> getInputs();
|
||||
|
||||
/**
|
||||
* @return the outputs
|
||||
*/
|
||||
List<ItemStack> getOutputs();
|
||||
NonNullList<ItemStack> getOutputs();
|
||||
|
||||
/**
|
||||
* @param took the items took
|
||||
* @param took the items took per slot
|
||||
* @return the outputs based on the items took
|
||||
*/
|
||||
List<ItemStack> getByproducts(ItemStack[] took);
|
||||
NonNullList<ItemStack> getOutputs(NonNullList<ItemStack> took);
|
||||
|
||||
/**
|
||||
* @return the byproducts
|
||||
* @return the outputs
|
||||
*/
|
||||
List<ItemStack> getByproducts();
|
||||
NonNullList<ItemStack> getByproducts();
|
||||
|
||||
/**
|
||||
* @param took the items took per slot
|
||||
* @return the outputs based on the items took
|
||||
*/
|
||||
NonNullList<ItemStack> getByproducts(NonNullList<ItemStack> took);
|
||||
|
||||
/**
|
||||
* @return the id of the factory that creates a crafting task for this pattern, as defined in the {@link com.raoulvdberge.refinedstorage.api.autocrafting.registry.ICraftingTaskRegistry}
|
||||
*/
|
||||
String getId();
|
||||
|
||||
/**
|
||||
* Returns the quantity of items that this crafting task yields per request.
|
||||
*
|
||||
* @param requested the item requested
|
||||
* @return the quantity
|
||||
*/
|
||||
default int getQuantityPerRequest(ItemStack requested) {
|
||||
return getQuantityPerRequest(requested, IComparer.COMPARE_DAMAGE | IComparer.COMPARE_NBT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the quantity of items that this crafting task yields per request.
|
||||
*
|
||||
* @param requested the item requested
|
||||
* @param compare the {@link IComparer} flags
|
||||
* @return the quantity
|
||||
*/
|
||||
int getQuantityPerRequest(ItemStack requested, int compare);
|
||||
|
||||
/**
|
||||
* Returns the actual outputted {@link ItemStack}
|
||||
*
|
||||
* @param requested an item requested
|
||||
* @param compare the {@link IComparer} flags
|
||||
* @return the actual {@link ItemStack} with quantity
|
||||
*/
|
||||
ItemStack getActualOutput(ItemStack requested, int compare);
|
||||
|
||||
/**
|
||||
* Compares with an other pattern if it is alike
|
||||
* Used to balance out {@link com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingStep}s over alike {@link ICraftingPattern}s
|
||||
*
|
||||
* @param pattern the {@link ICraftingPattern} to compare against
|
||||
* @return true if the patterns are alike, false otherwise
|
||||
*/
|
||||
boolean alike(ICraftingPattern pattern);
|
||||
}
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
package com.raoulvdberge.refinedstorage.api.autocrafting;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Represents a chain of {@link ICraftingPattern}s, used to balance crafts over those patterns.
|
||||
*/
|
||||
public interface ICraftingPatternChain extends Collection<ICraftingPattern> {
|
||||
/**
|
||||
* Check whether a pattern belongs in the chain.
|
||||
*
|
||||
* @param compare the {@link ICraftingPattern} to check
|
||||
* @return true if the chains {@link #getPrototype()} is {@link ICraftingPattern#alike(ICraftingPattern)}, false otherwise
|
||||
*/
|
||||
default boolean isValidForChain(ICraftingPattern compare) {
|
||||
return getPrototype() == compare || getPrototype().alike(compare);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cycles the list and returns use you the pattern that was used the longest time ago.
|
||||
*
|
||||
* @return an {@link ICraftingPattern}
|
||||
*/
|
||||
ICraftingPattern cycle();
|
||||
|
||||
/**
|
||||
* The prototype used for this {@link ICraftingPatternChain}.
|
||||
*
|
||||
* @return an {@link ICraftingPattern} that represents all patterns in the chain
|
||||
*/
|
||||
ICraftingPattern getPrototype();
|
||||
}
|
||||
@@ -7,7 +7,6 @@ import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.IItemHandlerModifiable;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
@@ -76,11 +75,6 @@ public interface ICraftingPatternContainer {
|
||||
@Nullable
|
||||
ICraftingPatternContainer getRootContainer();
|
||||
|
||||
/**
|
||||
* @return true if this container or its proxy is blocked, false otherwise
|
||||
*/
|
||||
boolean isBlocked();
|
||||
|
||||
/**
|
||||
* @return the UUID of this container
|
||||
*/
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.raoulvdberge.refinedstorage.api.autocrafting.registry;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPatternChain;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTask;
|
||||
import com.raoulvdberge.refinedstorage.api.network.INetwork;
|
||||
import net.minecraft.item.ItemStack;
|
||||
@@ -22,23 +21,9 @@ public interface ICraftingTaskFactory {
|
||||
* @param stack the stack to create a task for
|
||||
* @param pattern the pattern
|
||||
* @param quantity the quantity
|
||||
* @param automated whether this crafting task is created in an automated way
|
||||
* @param tag the NBT tag, if this is null it isn't reading from disk but is used for making a task on demand
|
||||
* @return the crafting task
|
||||
*/
|
||||
@Nonnull
|
||||
ICraftingTask create(INetwork network, @Nullable ItemStack stack, ICraftingPattern pattern, int quantity, boolean automated, @Nullable NBTTagCompound tag);
|
||||
|
||||
/**
|
||||
* Returns a crafting task for a given NBT tag and pattern.
|
||||
*
|
||||
* @param network the network
|
||||
* @param stack the stack to create a task for
|
||||
* @param patternChain the pattern chain
|
||||
* @param quantity the quantity
|
||||
* @param automated whether this crafting task is created in an automated way
|
||||
* @return the crafting task
|
||||
*/
|
||||
@Nonnull
|
||||
ICraftingTask create(INetwork network, @Nullable ItemStack stack, ICraftingPatternChain patternChain, int quantity, boolean automated);
|
||||
ICraftingTask create(INetwork network, ItemStack stack, int quantity, ICraftingPattern pattern, @Nullable NBTTagCompound tag);
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ public interface ICraftingTaskRegistry {
|
||||
* Returns the crafting task factory by factory id.
|
||||
*
|
||||
* @param id the factory id
|
||||
* @return the factory
|
||||
* @return the factory, or null if there is no factory
|
||||
*/
|
||||
@Nullable
|
||||
ICraftingTaskFactory get(String id);
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
package com.raoulvdberge.refinedstorage.api.autocrafting.task;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern;
|
||||
import com.raoulvdberge.refinedstorage.api.util.IStackList;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
|
||||
import java.util.Deque;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents a step in a crafting task.
|
||||
*/
|
||||
public interface ICraftingStep {
|
||||
/**
|
||||
* @return the pattern
|
||||
*/
|
||||
ICraftingPattern getPattern();
|
||||
|
||||
/**
|
||||
* @return the input stacks
|
||||
*/
|
||||
List<ItemStack> getInputs();
|
||||
|
||||
/**
|
||||
* @return a list of steps the have to be done before this one can be started
|
||||
*/
|
||||
List<ICraftingStep> getPreliminarySteps();
|
||||
|
||||
/**
|
||||
* Check if the processing can start.
|
||||
*
|
||||
* @param items a list to compare the needed {@link ItemStack} inputs against
|
||||
* @param fluids a list to compare the needed {@link FluidStack} inputs against (eg. a bucket, machine insert)
|
||||
* @return true if processing can start, false otherwise
|
||||
*/
|
||||
boolean canStartProcessing(IStackList<ItemStack> items, IStackList<FluidStack> fluids);
|
||||
|
||||
/**
|
||||
* Check if the processing can start.
|
||||
* Assuming you have all needed {@link ItemStack}s and {@link FluidStack}s
|
||||
*
|
||||
* @return true if processing can start, false otherwise
|
||||
*/
|
||||
boolean canStartProcessing();
|
||||
|
||||
/**
|
||||
* When called, this step will be marked as started processing.
|
||||
*/
|
||||
void setStartedProcessing();
|
||||
|
||||
/**
|
||||
* @return whether this step has started processing
|
||||
*/
|
||||
boolean hasStartedProcessing();
|
||||
|
||||
/**
|
||||
* Execute this step.
|
||||
* Any items to be added to the network should be inserting into these queues and they'll be managed by the {@link ICraftingTask}.
|
||||
*
|
||||
* @param toInsertItems a queue of items to be inserted into the network
|
||||
* @param toInsertFluids a queue of fluids to be inserted into the network
|
||||
*/
|
||||
void execute(Deque<ItemStack> toInsertItems, Deque<FluidStack> toInsertFluids);
|
||||
|
||||
/**
|
||||
* @return true if we received all outputs, false otherwise
|
||||
*/
|
||||
boolean hasReceivedOutputs();
|
||||
|
||||
/**
|
||||
* @param stack the output to check
|
||||
* @return true if we received the given output (based upon item and count), false otherwise
|
||||
*/
|
||||
boolean hasReceivedOutput(ItemStack stack);
|
||||
|
||||
/**
|
||||
* @param stack the output to check
|
||||
* @return amount of times this {@link ItemStack} has been received
|
||||
*/
|
||||
int getReceivedOutput(ItemStack stack);
|
||||
|
||||
/**
|
||||
* The {@link ItemStack} given to it will be changed and contain the remainder.
|
||||
* The return value will only be true if the stack size is zero.
|
||||
*
|
||||
* @param stack the stack that was inserted in the storage system
|
||||
* @return true if this item belonged to the processable item and was fully used, false otherwise
|
||||
*/
|
||||
boolean onReceiveOutput(ItemStack stack);
|
||||
|
||||
/**
|
||||
* Writes the crafting step to NBT.
|
||||
*
|
||||
* @param tag the tag
|
||||
* @return the written tag
|
||||
*/
|
||||
NBTTagCompound writeToNBT(NBTTagCompound tag);
|
||||
}
|
||||
@@ -1,28 +1,17 @@
|
||||
package com.raoulvdberge.refinedstorage.api.autocrafting.task;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPatternContainer;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.craftingmonitor.ICraftingMonitorElement;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.preview.ICraftingPreviewElement;
|
||||
import com.raoulvdberge.refinedstorage.api.util.IStackList;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Represents a crafting task.
|
||||
*/
|
||||
public interface ICraftingTask {
|
||||
String NBT_QUANTITY = "Quantity";
|
||||
String NBT_PATTERN_ID = "PatternID";
|
||||
String NBT_PATTERN_STACK = "PatternStack";
|
||||
String NBT_PATTERN_CONTAINER = "PatternContainer";
|
||||
String NBT_REQUESTED = "Requested";
|
||||
String NBT_AUTOMATED = "Automated";
|
||||
|
||||
/**
|
||||
* Calculates what this task will do, but doesn't run the task yet.
|
||||
*/
|
||||
@@ -32,30 +21,23 @@ public interface ICraftingTask {
|
||||
* Updates this task. Gets called every few ticks, depending on the speed of the pattern container.
|
||||
* {@link ICraftingTask#calculate()} must be run before this!
|
||||
*
|
||||
* @param usedContainers a map keeping track of used containers and how many times
|
||||
* @return true if this crafting task is finished and can be deleted from the list, false otherwise
|
||||
*/
|
||||
boolean update(Map<ICraftingPatternContainer, Integer> usedContainers);
|
||||
boolean update();
|
||||
|
||||
/**
|
||||
* Called when this task is cancelled.
|
||||
*/
|
||||
void onCancelled();
|
||||
|
||||
/**
|
||||
* Reschedule the task. This does a recalculation and restart of the task.
|
||||
*/
|
||||
void reschedule();
|
||||
|
||||
/**
|
||||
* @return the amount of items that have to be crafted
|
||||
*/
|
||||
int getQuantity();
|
||||
|
||||
/**
|
||||
* @return the stack requested, or null if no specific stack is associated with this task
|
||||
* @return the stack requested
|
||||
*/
|
||||
@Nullable
|
||||
ItemStack getRequested();
|
||||
|
||||
/**
|
||||
@@ -66,26 +48,6 @@ public interface ICraftingTask {
|
||||
*/
|
||||
NBTTagCompound writeToNBT(NBTTagCompound tag);
|
||||
|
||||
/**
|
||||
* Helper method to write default necessary elements to NBT.
|
||||
*
|
||||
* @param tag the tag
|
||||
* @return the written tag
|
||||
*/
|
||||
default NBTTagCompound writeDefaultsToNBT(NBTTagCompound tag) {
|
||||
tag.setInteger(NBT_QUANTITY, getQuantity());
|
||||
tag.setString(NBT_PATTERN_ID, getPattern().getId());
|
||||
tag.setTag(NBT_PATTERN_STACK, getPattern().getStack().serializeNBT());
|
||||
tag.setLong(NBT_PATTERN_CONTAINER, getPattern().getContainer().getPosition().toLong());
|
||||
tag.setBoolean(NBT_AUTOMATED, isAutomated());
|
||||
|
||||
if (getRequested() != null) {
|
||||
tag.setTag(NBT_REQUESTED, getRequested().serializeNBT());
|
||||
}
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link ICraftingTask#calculate()} must be run before this!
|
||||
*
|
||||
@@ -100,13 +62,6 @@ public interface ICraftingTask {
|
||||
*/
|
||||
List<ICraftingPreviewElement> getPreviewStacks();
|
||||
|
||||
/**
|
||||
* {@link ICraftingTask#calculate()} must be run before this!
|
||||
*
|
||||
* @return the steps for this task
|
||||
*/
|
||||
List<ICraftingStep> getSteps();
|
||||
|
||||
/**
|
||||
* @return the crafting pattern corresponding to this task
|
||||
*/
|
||||
@@ -119,22 +74,4 @@ public interface ICraftingTask {
|
||||
* @return true if no recursion was found, false otherwise
|
||||
*/
|
||||
boolean isValid();
|
||||
|
||||
/**
|
||||
* @return true if the task is finished, false otherwise
|
||||
*/
|
||||
boolean isFinished();
|
||||
|
||||
/**
|
||||
* @return the missing items
|
||||
*/
|
||||
IStackList<ItemStack> getMissing();
|
||||
|
||||
/**
|
||||
* Returns whether the crafting task is created in an automated way.
|
||||
* For example: through the Crafting Upgrade or the "Trigger task with redstone signal" option in the crafter.
|
||||
*
|
||||
* @return true if this crafting task is created in an automated way, false otherwise
|
||||
*/
|
||||
boolean isAutomated();
|
||||
}
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
package com.raoulvdberge.refinedstorage.apiimpl.autocrafting;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.RS;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.*;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingManager;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPatternContainer;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.registry.ICraftingTaskFactory;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingStep;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTask;
|
||||
import com.raoulvdberge.refinedstorage.api.network.INetwork;
|
||||
import com.raoulvdberge.refinedstorage.api.network.node.INetworkNode;
|
||||
import com.raoulvdberge.refinedstorage.api.network.node.INetworkNodeProxy;
|
||||
import com.raoulvdberge.refinedstorage.api.util.IComparer;
|
||||
import com.raoulvdberge.refinedstorage.api.util.IStackList;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
||||
import com.raoulvdberge.refinedstorage.container.ContainerCraftingMonitor;
|
||||
import com.raoulvdberge.refinedstorage.network.MessageCraftingMonitorElements;
|
||||
@@ -17,45 +15,27 @@ import com.raoulvdberge.refinedstorage.tile.TileController;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraftforge.common.util.Constants;
|
||||
import net.minecraftforge.items.IItemHandlerModifiable;
|
||||
import net.minecraftforge.items.ItemHandlerHelper;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class CraftingManager implements ICraftingManager {
|
||||
private static final String NBT_CRAFTING_TASKS = "CraftingTasks";
|
||||
private static final String NBT_BLOCKED_CONTAINERS = "BlockedContainers";
|
||||
private static final String NBT_BLOCKER_UUID = "BlockerUuid";
|
||||
private static final String NBT_BLOCKEE_UUID = "BlockeeUuid";
|
||||
|
||||
private TileController network;
|
||||
|
||||
private List<ICraftingPatternContainer> containers = new ArrayList<>();
|
||||
private Map<String, List<IItemHandlerModifiable>> containerInventories = new LinkedHashMap<>();
|
||||
private CraftingPatternChainList patterns = new CraftingPatternChainList();
|
||||
|
||||
// A map of blockers to blockees.
|
||||
private Map<UUID, UUID> blockingContainers = new HashMap<>();
|
||||
// A set of blockees.
|
||||
private Set<UUID> blockedContainers = new HashSet<>();
|
||||
private List<ICraftingPattern> patterns = new ArrayList<>();
|
||||
|
||||
private List<ICraftingTask> craftingTasks = new ArrayList<>();
|
||||
private List<ICraftingTask> craftingTasksToAdd = new ArrayList<>();
|
||||
private List<ICraftingTask> craftingTasksToCancel = new ArrayList<>();
|
||||
private List<NBTTagCompound> craftingTasksToRead = new ArrayList<>();
|
||||
private List<ICraftingStep> runningSteps = new ArrayList<>();
|
||||
private List<ICraftingTask> tasks = new ArrayList<>();
|
||||
private List<ICraftingTask> tasksToAdd = new ArrayList<>();
|
||||
private List<ICraftingTask> tasksToCancel = new ArrayList<>();
|
||||
|
||||
private boolean craftingMonitorUpdateRequested;
|
||||
|
||||
private int ticks;
|
||||
private boolean updateRequested;
|
||||
|
||||
public CraftingManager(TileController network) {
|
||||
this.network = network;
|
||||
@@ -63,12 +43,7 @@ public class CraftingManager implements ICraftingManager {
|
||||
|
||||
@Override
|
||||
public List<ICraftingTask> getTasks() {
|
||||
return craftingTasks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ICraftingPatternContainer> getContainers() {
|
||||
return containers;
|
||||
return tasks;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -76,189 +51,51 @@ public class CraftingManager implements ICraftingManager {
|
||||
return containerInventories;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addContainerBlock(UUID blocker, UUID blockee) {
|
||||
blockedContainers.add(blockee);
|
||||
blockingContainers.put(blocker, blockee);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeContainerBlock(UUID blocker) {
|
||||
blockedContainers.remove(blockingContainers.get(blocker));
|
||||
blockingContainers.remove(blocker);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isContainerBlocked(UUID blockee) {
|
||||
return blockedContainers.contains(blockee);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContainerBlocked(ICraftingPatternContainer container, boolean blocked) {
|
||||
if (blocked) {
|
||||
ICraftingPatternContainer proxy = container.getRootContainer();
|
||||
if (proxy != null) {
|
||||
addContainerBlock(container.getUuid(), proxy.getUuid());
|
||||
}
|
||||
} else {
|
||||
removeContainerBlock(container.getUuid());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(@Nonnull ICraftingTask task) {
|
||||
craftingTasksToAdd.add(task);
|
||||
tasksToAdd.add(task);
|
||||
|
||||
network.markDirty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel(@Nonnull ICraftingTask task) {
|
||||
craftingTasksToCancel.add(task);
|
||||
tasksToCancel.add(task);
|
||||
|
||||
network.markDirty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICraftingTask create(@Nullable ItemStack stack, ICraftingPattern pattern, int quantity, boolean automated) {
|
||||
return API.instance().getCraftingTaskRegistry().get(pattern.getId()).create(network, stack, pattern, quantity, automated, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICraftingTask create(@Nullable ItemStack stack, ICraftingPatternChain patternChain, int quantity, boolean automated) {
|
||||
return API.instance().getCraftingTaskRegistry().get(patternChain.getPrototype().getId()).create(network, stack, patternChain, quantity, automated);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ICraftingPattern> getPatterns() {
|
||||
return patterns.asList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ICraftingPattern> getPatterns(ItemStack pattern, int flags) {
|
||||
return getPatternChains(pattern, flags).stream().flatMap(Collection::stream).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private List<ICraftingPatternChain> getPatternChains(ItemStack pattern, int flags) {
|
||||
List<ICraftingPatternChain> patternChains = new LinkedList<>();
|
||||
|
||||
for (CraftingPatternChainList.CraftingPatternChain chain : this.patterns) {
|
||||
for (ItemStack output : chain.getPrototype().getOutputs()) {
|
||||
if (API.instance().getComparer().isEqual(output, pattern, flags)) {
|
||||
patternChains.add(chain);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return patternChains;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPattern(ItemStack stack, int flags) {
|
||||
for (CraftingPatternChainList.CraftingPatternChain chain : this.patterns) {
|
||||
for (ItemStack output : chain.getPrototype().getOutputs()) {
|
||||
if (API.instance().getComparer().isEqual(output, stack, flags)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICraftingPatternChain getPatternChain(ItemStack pattern, int flags) {
|
||||
return getPatternChain(pattern, flags, network.getItemStorageCache().getList().getOredicted());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICraftingPatternChain getPatternChain(ItemStack pattern, int flags, IStackList<ItemStack> itemList) {
|
||||
List<ICraftingPatternChain> patternChains = getPatternChains(pattern, flags);
|
||||
|
||||
if (patternChains.isEmpty()) {
|
||||
@Nullable
|
||||
public ICraftingTask create(ItemStack stack, int quantity) {
|
||||
ICraftingPattern pattern = getPattern(stack, IComparer.COMPARE_DAMAGE | IComparer.COMPARE_NBT);
|
||||
if (pattern == null) {
|
||||
return null;
|
||||
} else if (patternChains.size() == 1) {
|
||||
return patternChains.get(0);
|
||||
}
|
||||
|
||||
int highestScore = 0;
|
||||
int highestPattern = 0;
|
||||
|
||||
for (int i = 0; i < patternChains.size(); ++i) {
|
||||
int score = 0;
|
||||
|
||||
for (ItemStack input : patternChains.get(i).getPrototype().getInputs()) {
|
||||
if (input != null) {
|
||||
ItemStack stored = itemList.get(input, IComparer.COMPARE_DAMAGE | IComparer.COMPARE_NBT | (patternChains.get(i).getPrototype().isOredict() ? IComparer.COMPARE_OREDICT : 0));
|
||||
|
||||
score += stored != null ? stored.getCount() : 0;
|
||||
}
|
||||
ICraftingTaskFactory factory = API.instance().getCraftingTaskRegistry().get(pattern.getId());
|
||||
if (factory == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (score > highestScore) {
|
||||
highestScore = score;
|
||||
highestPattern = i;
|
||||
}
|
||||
}
|
||||
|
||||
return patternChains.get(highestPattern);
|
||||
return factory.create(network, stack, quantity, pattern, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
if (!craftingTasksToRead.isEmpty()) {
|
||||
for (NBTTagCompound tag : craftingTasksToRead) {
|
||||
ICraftingTask task = readCraftingTask(network, tag);
|
||||
|
||||
if (task != null) {
|
||||
add(task);
|
||||
}
|
||||
}
|
||||
|
||||
craftingTasksToRead.clear();
|
||||
}
|
||||
|
||||
if (network.canRun()) {
|
||||
boolean craftingTasksChanged = !craftingTasksToAdd.isEmpty() || !craftingTasksToCancel.isEmpty();
|
||||
tasksToCancel.forEach(ICraftingTask::onCancelled);
|
||||
tasks.removeAll(tasksToCancel);
|
||||
tasksToCancel.clear();
|
||||
|
||||
craftingTasksToCancel.forEach(ICraftingTask::onCancelled);
|
||||
craftingTasks.removeAll(craftingTasksToCancel);
|
||||
craftingTasksToCancel.clear();
|
||||
tasksToAdd.stream().filter(ICraftingTask::isValid).forEach(tasks::add);
|
||||
tasksToAdd.clear();
|
||||
|
||||
craftingTasksToAdd.stream().filter(ICraftingTask::isValid).forEach(craftingTasks::add);
|
||||
craftingTasksToAdd.clear();
|
||||
|
||||
// Only run task updates every 5 ticks
|
||||
if (ticks++ % 5 == 0) {
|
||||
Iterator<ICraftingTask> craftingTaskIterator = craftingTasks.iterator();
|
||||
Map<ICraftingPatternContainer, Integer> usedCrafters = new HashMap<>();
|
||||
|
||||
while (craftingTaskIterator.hasNext()) {
|
||||
ICraftingTask task = craftingTaskIterator.next();
|
||||
|
||||
if (task.update(usedCrafters)) {
|
||||
EventAutocraftingComplete.fire(network, task.getRequested(), task.getQuantity());
|
||||
craftingTaskIterator.remove();
|
||||
|
||||
craftingTasksChanged = true;
|
||||
} else if (!task.getMissing().isEmpty() && ticks % 100 == 0 && Math.random() > 0.5) {
|
||||
task.getMissing().clear();
|
||||
}
|
||||
tasks.removeIf(ICraftingTask::update);
|
||||
}
|
||||
|
||||
runningSteps = craftingTasks.stream()
|
||||
.map(ICraftingTask::getSteps)
|
||||
.flatMap(List::stream)
|
||||
.filter(ICraftingStep::hasStartedProcessing)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (craftingTasksChanged) {
|
||||
markCraftingMonitorForUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (craftingMonitorUpdateRequested) {
|
||||
craftingMonitorUpdateRequested = false;
|
||||
if (updateRequested) {
|
||||
updateRequested = false;
|
||||
|
||||
sendCraftingMonitorUpdate();
|
||||
}
|
||||
@@ -266,43 +103,17 @@ public class CraftingManager implements ICraftingManager {
|
||||
|
||||
@Override
|
||||
public void readFromNBT(NBTTagCompound tag) {
|
||||
if (tag.hasKey(NBT_CRAFTING_TASKS)) {
|
||||
NBTTagList taskList = tag.getTagList(NBT_CRAFTING_TASKS, Constants.NBT.TAG_COMPOUND);
|
||||
for (int i = 0; i < taskList.tagCount(); ++i) {
|
||||
craftingTasksToRead.add(taskList.getCompoundTagAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
if (tag.hasKey(NBT_BLOCKED_CONTAINERS)) {
|
||||
NBTTagList containerList = tag.getTagList(NBT_BLOCKED_CONTAINERS, Constants.NBT.TAG_COMPOUND);
|
||||
for (int i = 0; i < containerList.tagCount(); ++i) {
|
||||
NBTTagCompound compound = containerList.getCompoundTagAt(i);
|
||||
addContainerBlock(compound.getUniqueId(NBT_BLOCKER_UUID), compound.getUniqueId(NBT_BLOCKEE_UUID));
|
||||
}
|
||||
}
|
||||
// TODO
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTTagCompound writeToNBT(NBTTagCompound tag) {
|
||||
NBTTagList craftingTaskList = new NBTTagList();
|
||||
for (ICraftingTask task : craftingTasks) {
|
||||
craftingTaskList.appendTag(task.writeToNBT(new NBTTagCompound()));
|
||||
}
|
||||
tag.setTag(NBT_CRAFTING_TASKS, craftingTaskList);
|
||||
|
||||
NBTTagList blockingContainersList = new NBTTagList();
|
||||
for (Entry<UUID, UUID> pair : blockingContainers.entrySet()) {
|
||||
NBTTagCompound compound = new NBTTagCompound();
|
||||
compound.setUniqueId(NBT_BLOCKER_UUID, pair.getKey());
|
||||
compound.setUniqueId(NBT_BLOCKEE_UUID, pair.getValue());
|
||||
blockingContainersList.appendTag(compound);
|
||||
}
|
||||
tag.setTag(NBT_BLOCKED_CONTAINERS, blockingContainersList);
|
||||
|
||||
// TODO
|
||||
return tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public ICraftingTask schedule(ItemStack stack, int toSchedule, int compare) {
|
||||
for (ICraftingTask task : getTasks()) {
|
||||
for (ItemStack output : task.getPattern().getOutputs()) {
|
||||
@@ -313,13 +124,10 @@ public class CraftingManager implements ICraftingManager {
|
||||
}
|
||||
|
||||
if (toSchedule > 0) {
|
||||
ICraftingPatternChain patternChain = getPatternChain(stack, compare);
|
||||
|
||||
if (patternChain != null) {
|
||||
ICraftingTask task = create(stack, patternChain, toSchedule, true);
|
||||
ICraftingTask task = create(stack, toSchedule);
|
||||
|
||||
if (task != null) {
|
||||
task.calculate();
|
||||
task.getMissing().clear();
|
||||
|
||||
add(task);
|
||||
|
||||
@@ -334,13 +142,12 @@ public class CraftingManager implements ICraftingManager {
|
||||
|
||||
@Override
|
||||
public void track(ItemStack stack, int size) {
|
||||
ItemStack inserted = ItemHandlerHelper.copyStackWithSize(stack, size);
|
||||
// TODO
|
||||
}
|
||||
|
||||
for (ICraftingStep step : runningSteps) {
|
||||
if (step.onReceiveOutput(inserted)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public List<ICraftingPattern> getPatterns() {
|
||||
return patterns;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -355,20 +162,30 @@ public class CraftingManager implements ICraftingManager {
|
||||
patterns.addAll(container.getPatterns());
|
||||
|
||||
IItemHandlerModifiable handler = container.getPatternInventory();
|
||||
|
||||
if (handler != null) {
|
||||
containerInventories.computeIfAbsent(container.getName(), k -> new ArrayList<>()).add(handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Auto reschedules stuck tasks after a pattern rebuild
|
||||
craftingTasks.forEach(t -> t.getMissing().clear());
|
||||
@Nullable
|
||||
@Override
|
||||
public ICraftingPattern getPattern(ItemStack pattern, int flags) {
|
||||
for (ICraftingPattern patternInList : patterns) {
|
||||
for (ItemStack output : patternInList.getOutputs()) {
|
||||
if (API.instance().getComparer().isEqual(output, pattern, flags)) {
|
||||
return patternInList;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markCraftingMonitorForUpdate() {
|
||||
craftingMonitorUpdateRequested = true;
|
||||
this.updateRequested = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -382,26 +199,4 @@ public class CraftingManager implements ICraftingManager {
|
||||
public void sendCraftingMonitorUpdate(EntityPlayerMP player) {
|
||||
RS.INSTANCE.network.sendTo(new MessageCraftingMonitorElements(((ContainerCraftingMonitor) player.openContainer).getCraftingMonitor()), player);
|
||||
}
|
||||
|
||||
private static ICraftingTask readCraftingTask(INetwork network, NBTTagCompound tag) {
|
||||
ItemStack stack = new ItemStack(tag.getCompoundTag(ICraftingTask.NBT_PATTERN_STACK));
|
||||
|
||||
if (!stack.isEmpty() && stack.getItem() instanceof ICraftingPatternProvider) {
|
||||
TileEntity container = network.world().getTileEntity(BlockPos.fromLong(tag.getLong(ICraftingTask.NBT_PATTERN_CONTAINER)));
|
||||
|
||||
if (container instanceof INetworkNodeProxy) {
|
||||
INetworkNodeProxy proxy = (INetworkNodeProxy) container;
|
||||
if (proxy.getNode() instanceof ICraftingPatternContainer) {
|
||||
ICraftingPattern pattern = ((ICraftingPatternProvider) stack.getItem()).create(network.world(), stack, (ICraftingPatternContainer) proxy.getNode());
|
||||
|
||||
ICraftingTaskFactory factory = API.instance().getCraftingTaskRegistry().get(tag.getString(ICraftingTask.NBT_PATTERN_ID));
|
||||
if (factory != null) {
|
||||
return factory.create(network, tag.hasKey(ICraftingTask.NBT_REQUESTED) ? new ItemStack(tag.getCompoundTag(ICraftingTask.NBT_REQUESTED)) : null, pattern, tag.getInteger(ICraftingTask.NBT_QUANTITY), false, tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,128 +2,76 @@ package com.raoulvdberge.refinedstorage.apiimpl.autocrafting;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPatternContainer;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.registry.CraftingTaskFactory;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.util.Comparer;
|
||||
import com.raoulvdberge.refinedstorage.item.ItemPattern;
|
||||
import com.raoulvdberge.refinedstorage.util.StackUtils;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.inventory.Container;
|
||||
import net.minecraft.inventory.InventoryCrafting;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.crafting.CraftingManager;
|
||||
import net.minecraft.item.crafting.IRecipe;
|
||||
import net.minecraft.item.crafting.Ingredient;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.oredict.OreDictionary;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class CraftingPattern implements ICraftingPattern {
|
||||
private ICraftingPatternContainer container;
|
||||
private ItemStack stack;
|
||||
private boolean processing;
|
||||
private boolean oredict;
|
||||
private boolean valid;
|
||||
private IRecipe recipe;
|
||||
private List<ItemStack> inputs = new ArrayList<>();
|
||||
private List<List<ItemStack>> oreInputs = new ArrayList<>();
|
||||
private List<ItemStack> outputs = new ArrayList<>();
|
||||
private List<ItemStack> byproducts = new ArrayList<>();
|
||||
private Integer hashCodeCached = null;
|
||||
private List<NonNullList<ItemStack>> inputs = new ArrayList<>();
|
||||
private NonNullList<ItemStack> outputs = NonNullList.create();
|
||||
private NonNullList<ItemStack> byproducts = NonNullList.create();
|
||||
|
||||
public CraftingPattern(World world, ICraftingPatternContainer container, ItemStack stack) {
|
||||
this.container = container;
|
||||
this.stack = Comparer.stripTags(stack);
|
||||
this.stack = stack;
|
||||
this.processing = ItemPattern.isProcessing(stack);
|
||||
this.oredict = ItemPattern.isOredict(stack);
|
||||
|
||||
InventoryCrafting inv = new InventoryCrafting(new Container() {
|
||||
@Override
|
||||
public boolean canInteractWith(EntityPlayer player) {
|
||||
return false;
|
||||
}
|
||||
}, 3, 3);
|
||||
if (processing) {
|
||||
this.valid = true;
|
||||
|
||||
for (int i = 0; i < 9; ++i) {
|
||||
ItemStack slot = ItemPattern.getSlot(stack, i);
|
||||
ItemStack input = ItemPattern.getSlot(stack, i);
|
||||
|
||||
inputs.add(Comparer.stripTags(slot));
|
||||
inputs.add(input == null ? NonNullList.create() : NonNullList.from(ItemStack.EMPTY, input));
|
||||
}
|
||||
|
||||
if (slot != null) {
|
||||
inv.setInventorySlotContents(i, slot);
|
||||
this.outputs = ItemPattern.getOutputs(stack);
|
||||
} else {
|
||||
InventoryCrafting inv = new InventoryCraftingDummy();
|
||||
|
||||
for (int i = 0; i < 9; ++i) {
|
||||
ItemStack input = ItemPattern.getSlot(stack, i);
|
||||
|
||||
inputs.add(input == null ? NonNullList.create() : NonNullList.from(ItemStack.EMPTY, input));
|
||||
|
||||
if (input != null) {
|
||||
inv.setInventorySlotContents(i, input);
|
||||
}
|
||||
}
|
||||
|
||||
if (!ItemPattern.isProcessing(stack)) {
|
||||
for (IRecipe r : CraftingManager.REGISTRY) {
|
||||
if (r.matches(inv, world)) {
|
||||
recipe = r;
|
||||
this.recipe = r;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.byproducts = recipe.getRemainingItems(inv);
|
||||
|
||||
if (recipe != null) {
|
||||
ItemStack output = recipe.getCraftingResult(inv);
|
||||
|
||||
if (!output.isEmpty()) {
|
||||
outputs.add(Comparer.stripTags(output.copy()));
|
||||
this.valid = true;
|
||||
|
||||
if (isOredict()) {
|
||||
List<List<ItemStack>> inputs = new LinkedList<>();
|
||||
|
||||
for (Ingredient ingredient : recipe.getIngredients()) {
|
||||
inputs.add(Arrays.asList(ingredient.getMatchingStacks()));
|
||||
outputs.add(output);
|
||||
}
|
||||
|
||||
for (List<ItemStack> input : inputs) {
|
||||
if (input.isEmpty()) {
|
||||
oreInputs.add(Collections.emptyList());
|
||||
} else {
|
||||
List<ItemStack> cleaned = new LinkedList<>();
|
||||
for (ItemStack in : input) {
|
||||
cleaned.add(Comparer.stripTags(in.copy()));
|
||||
}
|
||||
oreInputs.add(cleaned);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (ItemStack remaining : recipe.getRemainingItems(inv)) {
|
||||
if (!remaining.isEmpty()) {
|
||||
ItemStack cleaned = Comparer.stripTags(remaining.copy());
|
||||
byproducts.add(cleaned);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
outputs = ItemPattern.getOutputs(stack);
|
||||
}
|
||||
|
||||
if (oreInputs.isEmpty()) {
|
||||
for (ItemStack input : inputs) {
|
||||
if (input == null || input.isEmpty()) {
|
||||
oreInputs.add(Collections.emptyList());
|
||||
} else {
|
||||
int[] ids = OreDictionary.getOreIDs(input);
|
||||
|
||||
if (ids.length == 0) {
|
||||
oreInputs.add(Collections.singletonList(Comparer.stripTags(input)));
|
||||
} else if (isOredict()) {
|
||||
List<ItemStack> oredictInputs = Arrays.stream(ids)
|
||||
.mapToObj(OreDictionary::getOreName)
|
||||
.map(OreDictionary::getOres)
|
||||
.flatMap(List::stream)
|
||||
.map(ItemStack::copy)
|
||||
.map(Comparer::stripTags)
|
||||
.peek(s -> s.setCount(input.getCount()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// Add original stack as first, should prevent some issues
|
||||
oredictInputs.add(0, Comparer.stripTags(input.copy()));
|
||||
|
||||
oreInputs.add(oredictInputs);
|
||||
} else {
|
||||
oreInputs.add(Collections.singletonList(Comparer.stripTags(input)));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -141,95 +89,42 @@ public class CraftingPattern implements ICraftingPattern {
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
return !inputs.isEmpty() && inputs.stream().filter(Objects::nonNull).count() > 0 && !outputs.isEmpty();
|
||||
return valid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isProcessing() {
|
||||
return ItemPattern.isProcessing(stack);
|
||||
return processing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOredict() {
|
||||
return ItemPattern.isOredict(stack);
|
||||
return oredict;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBlocking() {
|
||||
return ItemPattern.isBlocking(stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ItemStack> getInputs() {
|
||||
public List<NonNullList<ItemStack>> getInputs() {
|
||||
return inputs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<List<ItemStack>> getOreInputs() {
|
||||
return oreInputs;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public List<ItemStack> getOutputs(ItemStack[] took) {
|
||||
List<ItemStack> outputs = new ArrayList<>();
|
||||
|
||||
InventoryCrafting inv = new InventoryCrafting(new Container() {
|
||||
@Override
|
||||
public boolean canInteractWith(EntityPlayer player) {
|
||||
return false;
|
||||
}
|
||||
}, 3, 3);
|
||||
|
||||
for (int i = 0; i < 9; ++i) {
|
||||
if (took[i] != null) {
|
||||
inv.setInventorySlotContents(i, took[i]);
|
||||
}
|
||||
}
|
||||
|
||||
ItemStack cleaned = recipe.getCraftingResult(inv);
|
||||
if (cleaned.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
outputs.add(cleaned.copy());
|
||||
|
||||
public NonNullList<ItemStack> getOutputs() {
|
||||
return outputs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ItemStack> getOutputs() {
|
||||
return outputs;
|
||||
public NonNullList<ItemStack> getOutputs(NonNullList<ItemStack> took) {
|
||||
return StackUtils.emptyNonNullList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ItemStack> getByproducts(ItemStack[] took) {
|
||||
List<ItemStack> byproducts = new ArrayList<>();
|
||||
|
||||
InventoryCrafting inv = new InventoryCrafting(new Container() {
|
||||
@Override
|
||||
public boolean canInteractWith(EntityPlayer player) {
|
||||
return false;
|
||||
}
|
||||
}, 3, 3);
|
||||
|
||||
for (int i = 0; i < 9; ++i) {
|
||||
if (took[i] != null) {
|
||||
inv.setInventorySlotContents(i, took[i]);
|
||||
}
|
||||
}
|
||||
|
||||
for (ItemStack remaining : recipe.getRemainingItems(inv)) {
|
||||
if (!remaining.isEmpty()) {
|
||||
byproducts.add(remaining.copy());
|
||||
}
|
||||
}
|
||||
|
||||
public NonNullList<ItemStack> getByproducts() {
|
||||
return byproducts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ItemStack> getByproducts() {
|
||||
return byproducts;
|
||||
public NonNullList<ItemStack> getByproducts(NonNullList<ItemStack> took) {
|
||||
return StackUtils.emptyNonNullList();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -237,100 +132,14 @@ public class CraftingPattern implements ICraftingPattern {
|
||||
return CraftingTaskFactory.ID;
|
||||
}
|
||||
|
||||
private class InventoryCraftingDummy extends InventoryCrafting {
|
||||
public InventoryCraftingDummy() {
|
||||
super(new Container() {
|
||||
@Override
|
||||
public int getQuantityPerRequest(ItemStack requested, int compare) {
|
||||
int quantity = 0;
|
||||
requested = Comparer.stripTags(requested.copy());
|
||||
for (ItemStack output : outputs) {
|
||||
if (API.instance().getComparer().isEqual(requested, output, compare)) {
|
||||
quantity += output.getCount();
|
||||
|
||||
if (!ItemPattern.isProcessing(stack)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return quantity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getActualOutput(ItemStack requested, int compare) {
|
||||
requested = Comparer.stripTags(requested.copy());
|
||||
for (ItemStack output : outputs) {
|
||||
if (API.instance().getComparer().isEqual(requested, output, compare)) {
|
||||
return output.copy();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CraftingPattern{" +
|
||||
"container=" + container +
|
||||
", inputs=" + inputs +
|
||||
", outputs=" + outputs +
|
||||
", byproducts=" + byproducts +
|
||||
'}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return this == obj || (obj instanceof ICraftingPattern && this.alike((ICraftingPattern) obj));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
if (hashCodeCached == null) {
|
||||
hashCodeCached = 0;
|
||||
for (ItemStack outputItemStack : this.getOutputs()) {
|
||||
int itemHashCode = 0;
|
||||
itemHashCode = outputItemStack.getCount();
|
||||
itemHashCode = itemHashCode * 31 + outputItemStack.getItem().hashCode();
|
||||
itemHashCode = itemHashCode * 31 + outputItemStack.getItemDamage();
|
||||
itemHashCode = itemHashCode * 31 + Objects.hashCode(outputItemStack.getTagCompound());
|
||||
hashCodeCached = hashCodeCached * 31 + itemHashCode;
|
||||
}
|
||||
}
|
||||
return hashCodeCached;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean alike(ICraftingPattern other) {
|
||||
if (other == this) {
|
||||
public boolean canInteractWith(EntityPlayer player) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (other.getId().equals(this.getId())
|
||||
&& other.isOredict() == this.isOredict()
|
||||
&& other.isBlocking() == this.isBlocking()
|
||||
&& other.isProcessing() == this.isProcessing()
|
||||
&& other.getOreInputs().size() == this.getOreInputs().size()
|
||||
&& other.getOutputs().size() == this.getOutputs().size()) {
|
||||
boolean same = true;
|
||||
for (int i = 0; i < other.getOreInputs().size(); i++) {
|
||||
same &= other.getOreInputs().get(i).size() == this.getOreInputs().get(i).size();
|
||||
}
|
||||
int j = 0;
|
||||
while (same && j < other.getOutputs().size()) {
|
||||
same = ItemStack.areItemStacksEqual(other.getOutputs().get(j), this.getOutputs().get(j));
|
||||
j++;
|
||||
}
|
||||
int i = 0;
|
||||
while (same && i < other.getOreInputs().size()) {
|
||||
List<ItemStack> otherList = other.getOreInputs().get(i);
|
||||
List<ItemStack> thisList = this.getOreInputs().get(i);
|
||||
j = 0;
|
||||
while (same && j < otherList.size()) {
|
||||
same = ItemStack.areItemStacksEqual(otherList.get(j), thisList.get(j));
|
||||
j++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return same;
|
||||
}
|
||||
return false;
|
||||
}, 3, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,133 +0,0 @@
|
||||
package com.raoulvdberge.refinedstorage.apiimpl.autocrafting;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPatternChain;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class CraftingPatternChainList implements Iterable<CraftingPatternChainList.CraftingPatternChain> {
|
||||
LinkedList<CraftingPatternChain> innerChain = new LinkedList<>();
|
||||
Map<ICraftingPattern, CraftingPatternChain> innerChainMap = new HashMap<>();
|
||||
|
||||
public void add(ICraftingPattern pattern) {
|
||||
CraftingPatternChain chain = innerChainMap.get(pattern);
|
||||
if (chain == null) {
|
||||
chain = new CraftingPatternChain(pattern);
|
||||
innerChain.add(chain);
|
||||
innerChainMap.put(pattern, chain);
|
||||
} else {
|
||||
if (!chain.add(pattern)) {
|
||||
chain = new CraftingPatternChain(pattern);
|
||||
innerChain.add(chain);
|
||||
innerChainMap.put(pattern, chain);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addAll(Collection<ICraftingPattern> patterns) {
|
||||
patterns.forEach(this::add);
|
||||
}
|
||||
|
||||
public List<ICraftingPattern> asList() {
|
||||
return innerChain.stream().flatMap(Collection::stream).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<CraftingPatternChain> iterator() {
|
||||
return innerChain.iterator();
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
innerChain.clear();
|
||||
innerChainMap.clear();
|
||||
}
|
||||
|
||||
public static class CraftingPatternChain implements ICraftingPatternChain {
|
||||
private LinkedList<ICraftingPattern> innerList;
|
||||
private ICraftingPattern prototype;
|
||||
|
||||
public CraftingPatternChain(ICraftingPattern prototype) {
|
||||
this.prototype = prototype;
|
||||
this.innerList = new LinkedList<>();
|
||||
this.innerList.add(prototype);
|
||||
}
|
||||
|
||||
public ICraftingPattern cycle() {
|
||||
ICraftingPattern front = innerList.poll();
|
||||
innerList.addLast(front);
|
||||
return front;
|
||||
}
|
||||
|
||||
public ICraftingPattern getPrototype() {
|
||||
return prototype;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return innerList.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return innerList.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Object o) {
|
||||
return innerList.contains(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<ICraftingPattern> iterator() {
|
||||
return innerList.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] toArray() {
|
||||
return innerList.toArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T[] toArray(T[] a) {
|
||||
return innerList.toArray(a);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(ICraftingPattern pattern) {
|
||||
return isValidForChain(pattern) && innerList.add(pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(Object o) {
|
||||
return innerList.remove(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsAll(Collection<?> c) {
|
||||
return innerList.containsAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addAll(Collection<? extends ICraftingPattern> c) {
|
||||
c.removeIf(p -> !isValidForChain(p));
|
||||
|
||||
return innerList.addAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeAll(Collection<?> c) {
|
||||
return innerList.removeAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean retainAll(Collection<?> c) {
|
||||
return innerList.retainAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
innerList.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,84 +1,23 @@
|
||||
package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.registry;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPatternChain;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.registry.ICraftingTaskFactory;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingStep;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTask;
|
||||
import com.raoulvdberge.refinedstorage.api.network.INetwork;
|
||||
import com.raoulvdberge.refinedstorage.api.util.IStackList;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.CraftingStep;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.CraftingTask;
|
||||
import com.raoulvdberge.refinedstorage.util.StackUtils;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import net.minecraftforge.common.util.Constants;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Deque;
|
||||
import java.util.List;
|
||||
|
||||
public class CraftingTaskFactory implements ICraftingTaskFactory {
|
||||
public static final String ID = "normal";
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public ICraftingTask create(INetwork network, @Nullable ItemStack stack, ICraftingPattern pattern, int quantity, boolean automated, @Nullable NBTTagCompound tag) {
|
||||
if (tag != null) {
|
||||
NBTTagList stepsList = tag.getTagList(CraftingTask.NBT_STEPS, Constants.NBT.TAG_COMPOUND);
|
||||
|
||||
List<ICraftingStep> steps = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < stepsList.tagCount(); ++i) {
|
||||
NBTTagCompound stepTag = stepsList.getCompoundTagAt(i);
|
||||
|
||||
ICraftingStep step = CraftingStep.toCraftingStep(stepTag, network);
|
||||
|
||||
if (step != null) {
|
||||
steps.add(step);
|
||||
}
|
||||
}
|
||||
|
||||
NBTTagList toInsertList = tag.getTagList(CraftingTask.NBT_TO_INSERT_ITEMS, Constants.NBT.TAG_COMPOUND);
|
||||
|
||||
Deque<ItemStack> toInsert = new ArrayDeque<>();
|
||||
|
||||
for (int i = 0; i < toInsertList.tagCount(); ++i) {
|
||||
ItemStack insertStack = new ItemStack(toInsertList.getCompoundTagAt(i));
|
||||
|
||||
if (!insertStack.isEmpty()) {
|
||||
toInsert.add(insertStack);
|
||||
}
|
||||
}
|
||||
|
||||
IStackList<FluidStack> toTakeFluids = StackUtils.readFluidStackList(tag.getTagList(CraftingTask.NBT_TO_TAKE_FLUIDS, Constants.NBT.TAG_COMPOUND));
|
||||
|
||||
NBTTagList toInsertFluidsList = tag.getTagList(CraftingTask.NBT_TO_INSERT_FLUIDS, Constants.NBT.TAG_COMPOUND);
|
||||
|
||||
Deque<FluidStack> toInsertFluids = new ArrayDeque<>();
|
||||
|
||||
for (int i = 0; i < toInsertFluidsList.tagCount(); ++i) {
|
||||
FluidStack tookStack = FluidStack.loadFluidStackFromNBT(toInsertFluidsList.getCompoundTagAt(i));
|
||||
|
||||
if (tookStack != null) {
|
||||
toInsertFluids.add(tookStack);
|
||||
}
|
||||
}
|
||||
|
||||
return new CraftingTask(network, stack, pattern, quantity, steps, toInsert, toTakeFluids, toInsertFluids, tag.hasKey(CraftingTask.NBT_AUTOMATED) && tag.getBoolean(CraftingTask.NBT_AUTOMATED));
|
||||
}
|
||||
|
||||
return new CraftingTask(network, stack, pattern, quantity, automated);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public ICraftingTask create(INetwork network, @Nullable ItemStack stack, ICraftingPatternChain patternChain, int quantity, boolean automated) {
|
||||
return new CraftingTask(network, stack, patternChain, quantity, automated);
|
||||
// TODO: handle tag?
|
||||
public ICraftingTask create(INetwork network, ItemStack stack, int quantity, ICraftingPattern pattern, @Nullable NBTTagCompound tag) {
|
||||
return new CraftingTask(network, stack, quantity, pattern);
|
||||
}
|
||||
}
|
||||
@@ -1,321 +0,0 @@
|
||||
package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPatternContainer;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPatternProvider;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingStep;
|
||||
import com.raoulvdberge.refinedstorage.api.network.INetwork;
|
||||
import com.raoulvdberge.refinedstorage.api.network.node.INetworkNodeProxy;
|
||||
import com.raoulvdberge.refinedstorage.api.util.IComparer;
|
||||
import com.raoulvdberge.refinedstorage.api.util.IStackList;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.util.Comparer;
|
||||
import com.raoulvdberge.refinedstorage.util.StackUtils;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraftforge.common.util.Constants;
|
||||
import net.minecraftforge.fluids.Fluid;
|
||||
import net.minecraftforge.fluids.FluidRegistry;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public abstract class CraftingStep implements ICraftingStep {
|
||||
public static final String NBT_CRAFTING_STEP_TYPE = "CraftingStepType";
|
||||
private static final String NBT_SATISFIED = "Satisfied_%d";
|
||||
private static final String NBT_PATTERN = "Pattern";
|
||||
private static final String NBT_PATTERN_CONTAINER = "PatternContainer";
|
||||
private static final String NBT_STARTED_PROCESSING = "StartedProcessing";
|
||||
private static final String NBT_PRELIMINARY_STEPS = "PreliminarySteps";
|
||||
|
||||
protected INetwork network;
|
||||
protected ICraftingPattern pattern;
|
||||
|
||||
protected Map<Integer, Integer> satisfied;
|
||||
|
||||
protected boolean startedProcessing;
|
||||
protected List<ICraftingStep> preliminarySteps;
|
||||
|
||||
public CraftingStep(INetwork network, ICraftingPattern pattern, List<ICraftingStep> preliminarySteps) {
|
||||
this.network = network;
|
||||
this.pattern = pattern;
|
||||
this.satisfied = new HashMap<>(getPattern().getOutputs().size());
|
||||
this.preliminarySteps = new ArrayList<>(preliminarySteps);
|
||||
}
|
||||
|
||||
public CraftingStep(INetwork network) {
|
||||
this.network = network;
|
||||
}
|
||||
|
||||
public boolean readFromNBT(NBTTagCompound tag) {
|
||||
ItemStack patternStack = new ItemStack(tag.getCompoundTag(NBT_PATTERN));
|
||||
|
||||
if (!patternStack.isEmpty()) {
|
||||
TileEntity container = network.world().getTileEntity(BlockPos.fromLong(tag.getLong(NBT_PATTERN_CONTAINER)));
|
||||
|
||||
if (container instanceof INetworkNodeProxy) {
|
||||
INetworkNodeProxy proxy = (INetworkNodeProxy) container;
|
||||
|
||||
if (proxy.getNode() instanceof ICraftingPatternContainer) {
|
||||
this.pattern = ((ICraftingPatternProvider) patternStack.getItem()).create(network.world(), patternStack, (ICraftingPatternContainer) proxy.getNode());
|
||||
this.satisfied = new HashMap<>(pattern.getOutputs().size());
|
||||
|
||||
for (ItemStack stack : pattern.getOutputs()) {
|
||||
int hashcode = API.instance().getItemStackHashCode(stack);
|
||||
|
||||
String id = String.format(NBT_SATISFIED, hashcode);
|
||||
|
||||
if (tag.hasKey(id)) {
|
||||
this.satisfied.put(hashcode, tag.getInteger(id));
|
||||
}
|
||||
}
|
||||
|
||||
this.startedProcessing = tag.getBoolean(NBT_STARTED_PROCESSING);
|
||||
|
||||
NBTTagList preliminaryTagList = tag.getTagList(NBT_PRELIMINARY_STEPS, Constants.NBT.TAG_COMPOUND);
|
||||
|
||||
this.preliminarySteps = new LinkedList<>();
|
||||
|
||||
for (int i = 0; i < preliminaryTagList.tagCount(); i++) {
|
||||
NBTTagCompound stepTag = preliminaryTagList.getCompoundTagAt(i);
|
||||
|
||||
ICraftingStep step = CraftingStep.toCraftingStep(stepTag, network);
|
||||
|
||||
if (step != null) {
|
||||
this.preliminarySteps.add(step);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICraftingPattern getPattern() {
|
||||
return pattern;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ItemStack> getInputs() {
|
||||
return pattern.getInputs().stream().filter(Objects::nonNull).filter(s -> !s.isEmpty()).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ICraftingStep> getPreliminarySteps() {
|
||||
return preliminarySteps != null ? preliminarySteps : Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canStartProcessing() {
|
||||
return getPreliminarySteps().size() == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStartedProcessing() {
|
||||
if (getPattern().isBlocking()) {
|
||||
network.getCraftingManager().setContainerBlocked(getPattern().getContainer(), true);
|
||||
}
|
||||
|
||||
startedProcessing = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasStartedProcessing() {
|
||||
return startedProcessing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasReceivedOutputs() {
|
||||
for (ItemStack stack : pattern.getOutputs()) {
|
||||
Integer received = satisfied.get(API.instance().getItemStackHashCode(stack));
|
||||
|
||||
if (received == null || stack.getCount() > received) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (getPattern().isBlocking()) {
|
||||
network.getCraftingManager().setContainerBlocked(getPattern().getContainer(), false);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasReceivedOutput(ItemStack stack) {
|
||||
return getReceivedOutput(stack) >= stack.getCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getReceivedOutput(ItemStack stack) {
|
||||
Integer received = satisfied.get(API.instance().getItemStackHashCode(stack));
|
||||
|
||||
return received == null ? 0 : received;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onReceiveOutput(ItemStack stack) {
|
||||
ItemStack compareStack = Comparer.stripTags(stack.copy());
|
||||
|
||||
for (ItemStack output : pattern.getOutputs()) {
|
||||
int hash = API.instance().getItemStackHashCode(output);
|
||||
|
||||
Integer received = satisfied.get(hash);
|
||||
|
||||
if (received == null) {
|
||||
received = 0;
|
||||
}
|
||||
|
||||
if (API.instance().getComparer().isEqual(compareStack, output, CraftingTask.DEFAULT_COMPARE | (getPattern().isOredict() ? IComparer.COMPARE_OREDICT : 0))) {
|
||||
if (received < output.getCount()) {
|
||||
int toReceive = Math.min(output.getCount() - received, stack.getCount());
|
||||
|
||||
satisfied.put(hash, received + toReceive);
|
||||
|
||||
stack.shrink(toReceive);
|
||||
|
||||
network.getCraftingManager().markCraftingMonitorForUpdate();
|
||||
|
||||
if (stack.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTTagCompound writeToNBT(NBTTagCompound tag) {
|
||||
for (Map.Entry<Integer, Integer> entry : satisfied.entrySet()) {
|
||||
tag.setInteger(String.format(NBT_SATISFIED, entry.getKey()), entry.getValue());
|
||||
}
|
||||
|
||||
tag.setTag(NBT_PATTERN, pattern.getStack().serializeNBT());
|
||||
tag.setLong(NBT_PATTERN_CONTAINER, pattern.getContainer().getPosition().toLong());
|
||||
tag.setBoolean(NBT_STARTED_PROCESSING, startedProcessing);
|
||||
|
||||
|
||||
NBTTagList preliminaryTagList = new NBTTagList();
|
||||
for (ICraftingStep step : preliminarySteps) {
|
||||
preliminaryTagList.appendTag(step.writeToNBT(new NBTTagCompound()));
|
||||
}
|
||||
|
||||
tag.setTag(NBT_PRELIMINARY_STEPS, preliminaryTagList);
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
enum AvailableType {
|
||||
ITEM, FLUID
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected AvailableType isItemAvailable(IStackList<ItemStack> items, IStackList<FluidStack> fluids, ItemStack stack, ItemStack actualStack, int compare) {
|
||||
if (actualStack == null || actualStack.isEmpty() || !items.trackedRemove(actualStack, stack.getCount())) {
|
||||
FluidStack fluidInItem;
|
||||
|
||||
if (API.instance().getComparer().isEqual(stack, StackUtils.WATER_BOTTLE)) {
|
||||
FluidStack fluidStack = fluids.get(new FluidStack(FluidRegistry.WATER, Fluid.BUCKET_VOLUME), compare);
|
||||
ItemStack emptyBottle = items.get(StackUtils.EMPTY_BOTTLE, compare);
|
||||
|
||||
if (emptyBottle != null && fluidStack != null && !emptyBottle.isEmpty() && items.trackedRemove(StackUtils.EMPTY_BOTTLE, 1)) {
|
||||
return AvailableType.FLUID;
|
||||
}
|
||||
} else if ((fluidInItem = StackUtils.getFluid(stack, true).getValue()) != null && StackUtils.hasFluidBucket(fluidInItem)) {
|
||||
FluidStack fluidStack = fluids.get(fluidInItem, compare);
|
||||
ItemStack bucket = items.get(StackUtils.EMPTY_BUCKET, compare);
|
||||
|
||||
if (bucket != null && fluidStack != null && !bucket.isEmpty() && fluids.trackedRemove(fluidStack, fluidInItem.amount) && items.trackedRemove(bucket, 1)) {
|
||||
return AvailableType.FLUID;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return AvailableType.ITEM;
|
||||
}
|
||||
|
||||
protected boolean extractItems(List<ItemStack> extractedItems, int compare, Deque<ItemStack> toInsertItems) {
|
||||
for (ItemStack input : getInputs()) {
|
||||
// This will be a tool, like a hammer
|
||||
if (input.isItemStackDamageable()) {
|
||||
compare &= ~IComparer.COMPARE_DAMAGE;
|
||||
} else {
|
||||
compare |= IComparer.COMPARE_DAMAGE;
|
||||
}
|
||||
|
||||
ItemStack extracted = network.extractItem(input, input.getCount(), compare, false);
|
||||
|
||||
if (extracted != null) {
|
||||
extractedItems.add(extracted);
|
||||
} else {
|
||||
boolean abort = true;
|
||||
|
||||
FluidStack fluidInItem;
|
||||
|
||||
if (API.instance().getComparer().isEqual(input, StackUtils.WATER_BOTTLE)) {
|
||||
FluidStack fluidStack = network.extractFluid(new FluidStack(FluidRegistry.WATER, Fluid.BUCKET_VOLUME), Fluid.BUCKET_VOLUME, compare, true); // Simulate is true because we won't actually get the fluid out of the storage for bottles!
|
||||
ItemStack emptyBottleStack = network.extractItem(StackUtils.EMPTY_BOTTLE, 1, compare, false);
|
||||
|
||||
if (fluidStack != null && fluidStack.amount == Fluid.BUCKET_VOLUME && emptyBottleStack != null) {
|
||||
abort = false;
|
||||
|
||||
extractedItems.add(input.copy());
|
||||
}
|
||||
} else if ((fluidInItem = StackUtils.getFluid(input, true).getValue()) != null) {
|
||||
FluidStack fluidStack = network.extractFluid(fluidInItem, fluidInItem.amount, compare, false);
|
||||
ItemStack bucketStack = network.extractItem(StackUtils.EMPTY_BUCKET, 1, compare, false);
|
||||
|
||||
if (fluidStack != null && fluidStack.amount == fluidInItem.amount && bucketStack != null) {
|
||||
abort = false;
|
||||
|
||||
extractedItems.add(input.copy());
|
||||
}
|
||||
}
|
||||
|
||||
if (abort) {
|
||||
// Abort task re-insert taken stacks and reset state
|
||||
toInsertItems.addAll(extractedItems);
|
||||
|
||||
startedProcessing = false;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static ICraftingStep toCraftingStep(NBTTagCompound tag, INetwork network) {
|
||||
CraftingStep step = null;
|
||||
|
||||
switch (tag.getString(CraftingStep.NBT_CRAFTING_STEP_TYPE)) {
|
||||
case CraftingStepCraft.ID:
|
||||
step = new CraftingStepCraft(network);
|
||||
break;
|
||||
case CraftingStepProcess.ID:
|
||||
step = new CraftingStepProcess(network);
|
||||
break;
|
||||
}
|
||||
|
||||
if (step != null && step.readFromNBT(tag)) {
|
||||
return step;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,151 +0,0 @@
|
||||
package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingStep;
|
||||
import com.raoulvdberge.refinedstorage.api.network.INetwork;
|
||||
import com.raoulvdberge.refinedstorage.api.util.IComparer;
|
||||
import com.raoulvdberge.refinedstorage.api.util.IStackList;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.util.StackListItem;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import net.minecraftforge.common.util.Constants;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class CraftingStepCraft extends CraftingStep {
|
||||
public static final String ID = "craft";
|
||||
private static final String NBT_TO_INSERT = "ToInsert";
|
||||
|
||||
private List<ItemStack> inputs;
|
||||
|
||||
public CraftingStepCraft(INetwork network, ICraftingPattern pattern, List<ItemStack> inputs, List<ICraftingStep> preliminarySteps) {
|
||||
super(network, pattern, preliminarySteps);
|
||||
|
||||
this.inputs = new LinkedList<>();
|
||||
|
||||
for (ItemStack input : inputs) {
|
||||
this.inputs.add(input == null ? null : input.copy());
|
||||
}
|
||||
}
|
||||
|
||||
public CraftingStepCraft(INetwork network) {
|
||||
super(network);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ItemStack> getInputs() {
|
||||
return inputs == null ? super.getInputs() : inputs.stream().filter(Objects::nonNull).filter(s -> !s.isEmpty()).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canStartProcessing(IStackList<ItemStack> items, IStackList<FluidStack> fluids) {
|
||||
if (!super.canStartProcessing()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int compare = CraftingTask.DEFAULT_COMPARE;
|
||||
|
||||
for (ItemStack stack : getInputs()) {
|
||||
// This will be a tool, like a hammer
|
||||
if (stack.isItemStackDamageable()) {
|
||||
compare &= ~IComparer.COMPARE_DAMAGE;
|
||||
} else {
|
||||
compare |= IComparer.COMPARE_DAMAGE;
|
||||
}
|
||||
|
||||
ItemStack actualStack = items.get(stack, compare);
|
||||
|
||||
if (isItemAvailable(items, fluids, stack, actualStack, compare) == null) {
|
||||
items.undo();
|
||||
fluids.undo();
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
items.undo();
|
||||
fluids.undo();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Deque<ItemStack> toInsertItems, Deque<FluidStack> toInsertFluids) {
|
||||
List<ItemStack> extracted = new LinkedList<>();
|
||||
|
||||
if (extractItems(extracted, CraftingTask.DEFAULT_COMPARE, toInsertItems)) {
|
||||
IStackList<ItemStack> extractedStacks = API.instance().createItemStackList();
|
||||
|
||||
extracted.forEach(extractedStacks::add);
|
||||
|
||||
ItemStack[] took = StackListItem.toCraftingGrid(extractedStacks, inputs, CraftingTask.DEFAULT_COMPARE | (pattern.isOredict() ? IComparer.COMPARE_OREDICT : 0));
|
||||
|
||||
List<ItemStack> outputs = pattern.isOredict() ? pattern.getOutputs(took) : pattern.getOutputs();
|
||||
if (outputs == null) {
|
||||
toInsertItems.addAll(extracted);
|
||||
|
||||
startedProcessing = false;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (ItemStack output : outputs) {
|
||||
if (output != null && !output.isEmpty()) {
|
||||
toInsertItems.add(output.copy());
|
||||
}
|
||||
}
|
||||
|
||||
for (ItemStack byproduct : (pattern.isOredict() ? pattern.getByproducts(took) : pattern.getByproducts())) {
|
||||
toInsertItems.add(byproduct.copy());
|
||||
}
|
||||
} else {
|
||||
// Couldn't extract items
|
||||
startedProcessing = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTTagCompound writeToNBT(NBTTagCompound tag) {
|
||||
tag.setString(NBT_CRAFTING_STEP_TYPE, ID);
|
||||
super.writeToNBT(tag);
|
||||
|
||||
NBTTagList toInsertList = new NBTTagList();
|
||||
|
||||
for (ItemStack insert : inputs) {
|
||||
toInsertList.appendTag(insert == null ? new NBTTagCompound() : insert.serializeNBT());
|
||||
}
|
||||
|
||||
tag.setTag(NBT_TO_INSERT, toInsertList);
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean readFromNBT(NBTTagCompound tag) {
|
||||
if (super.readFromNBT(tag)) {
|
||||
if (tag.hasKey(NBT_TO_INSERT)) {
|
||||
NBTTagList toInsertList = tag.getTagList(NBT_TO_INSERT, Constants.NBT.TAG_COMPOUND);
|
||||
|
||||
inputs = new ArrayList<>(toInsertList.tagCount());
|
||||
|
||||
for (int i = 0; i < toInsertList.tagCount(); ++i) {
|
||||
ItemStack stack = new ItemStack(toInsertList.getCompoundTagAt(i));
|
||||
|
||||
if (stack.isEmpty()) {
|
||||
inputs.add(null);
|
||||
} else {
|
||||
inputs.add(stack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,142 +0,0 @@
|
||||
package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingStep;
|
||||
import com.raoulvdberge.refinedstorage.api.network.INetwork;
|
||||
import com.raoulvdberge.refinedstorage.api.util.IComparer;
|
||||
import com.raoulvdberge.refinedstorage.api.util.IStackList;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.ItemHandlerHelper;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class CraftingStepProcess extends CraftingStep {
|
||||
public static final String ID = "process";
|
||||
|
||||
public CraftingStepProcess(INetwork network, ICraftingPattern pattern, List<ICraftingStep> preliminarySteps) {
|
||||
super(network, pattern, preliminarySteps);
|
||||
}
|
||||
|
||||
public CraftingStepProcess(INetwork network) {
|
||||
super(network);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canStartProcessing(IStackList<ItemStack> items, IStackList<FluidStack> fluids) {
|
||||
if (!super.canStartProcessing()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
IItemHandler inventory = getPattern().getContainer().getConnectedInventory();
|
||||
|
||||
int compare = CraftingTask.DEFAULT_COMPARE | (pattern.isOredict() ? IComparer.COMPARE_OREDICT : 0);
|
||||
|
||||
if (inventory != null) {
|
||||
Deque<ItemStack> toInsert = new LinkedList<>();
|
||||
|
||||
for (ItemStack stack : getInputs()) {
|
||||
// This will be a tool, like a hammer
|
||||
if (stack.isItemStackDamageable()) {
|
||||
compare &= ~IComparer.COMPARE_DAMAGE;
|
||||
} else {
|
||||
compare |= IComparer.COMPARE_DAMAGE;
|
||||
}
|
||||
|
||||
ItemStack actualStack = items.get(stack, compare);
|
||||
AvailableType type = isItemAvailable(items, fluids, stack, actualStack, compare);
|
||||
|
||||
if (type == AvailableType.ITEM) {
|
||||
toInsert.add(ItemHandlerHelper.copyStackWithSize(actualStack, stack.getCount()));
|
||||
} else if (type == AvailableType.FLUID) {
|
||||
toInsert.add(ItemHandlerHelper.copyStackWithSize(stack, stack.getCount()));
|
||||
} else {
|
||||
items.undo();
|
||||
fluids.undo();
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
items.undo();
|
||||
fluids.undo();
|
||||
|
||||
return insertItems(inventory, toInsert, true);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canStartProcessing() {
|
||||
if (!super.canStartProcessing()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
IItemHandler inventory = getPattern().getContainer().getConnectedInventory();
|
||||
|
||||
return inventory != null && insertItems(inventory, new LinkedList<>(getInputs()), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Deque<ItemStack> toInsertItems, Deque<FluidStack> toInsertFluids) {
|
||||
LinkedList<ItemStack> extracted = new LinkedList<>();
|
||||
|
||||
int compare = CraftingTask.DEFAULT_COMPARE | (getPattern().isOredict() ? IComparer.COMPARE_OREDICT : 0);
|
||||
|
||||
if (extractItems(extracted, compare, toInsertItems)) {
|
||||
IItemHandler inventory = getPattern().getContainer().getConnectedInventory();
|
||||
|
||||
if (insertItems(inventory, new ArrayDeque<>(extracted), true)) {
|
||||
insertItems(inventory, extracted, false);
|
||||
} else {
|
||||
// Something went wrong here, redo!
|
||||
toInsertItems.addAll(extracted);
|
||||
startedProcessing = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTTagCompound writeToNBT(NBTTagCompound tag) {
|
||||
tag.setString(NBT_CRAFTING_STEP_TYPE, ID);
|
||||
|
||||
return super.writeToNBT(tag);
|
||||
}
|
||||
|
||||
private static boolean insertItems(IItemHandler inventory, Deque<ItemStack> stacks, boolean simulate) {
|
||||
ItemStack current = stacks.poll();
|
||||
|
||||
List<Integer> availableSlots = IntStream.range(0, inventory.getSlots()).boxed().collect(Collectors.toList());
|
||||
|
||||
while (current != null && !availableSlots.isEmpty()) {
|
||||
ItemStack remainder = null;
|
||||
|
||||
for (Integer slot : availableSlots) {
|
||||
remainder = inventory.insertItem(slot, current, simulate);
|
||||
|
||||
if (remainder.isEmpty() || current.getCount() != remainder.getCount()) {
|
||||
availableSlots.remove(slot);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (remainder == null || remainder.isEmpty()) {
|
||||
current = stacks.poll();
|
||||
} else if (current.getCount() == remainder.getCount()) {
|
||||
break; // Can't be inserted
|
||||
} else {
|
||||
current = remainder;
|
||||
}
|
||||
}
|
||||
|
||||
return current == null && stacks.isEmpty();
|
||||
}
|
||||
}
|
||||
@@ -1,549 +1,41 @@
|
||||
package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPatternChain;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPatternContainer;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.craftingmonitor.ICraftingMonitorElement;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.craftingmonitor.ICraftingMonitorElementList;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.preview.ICraftingPreviewElement;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingStep;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTask;
|
||||
import com.raoulvdberge.refinedstorage.api.network.INetwork;
|
||||
import com.raoulvdberge.refinedstorage.api.util.IComparer;
|
||||
import com.raoulvdberge.refinedstorage.api.util.IStackList;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.craftingmonitor.CraftingMonitorElementError;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.craftingmonitor.CraftingMonitorElementInfo;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.craftingmonitor.CraftingMonitorElementItemRender;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.craftingmonitor.CraftingMonitorElementText;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.preview.CraftingPreviewElementError;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.preview.CraftingPreviewElementFluidStack;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.preview.CraftingPreviewElementItemStack;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.util.StackListItem;
|
||||
import com.raoulvdberge.refinedstorage.util.StackUtils;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import net.minecraftforge.fluids.Fluid;
|
||||
import net.minecraftforge.fluids.FluidRegistry;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.items.ItemHandlerHelper;
|
||||
import net.minecraftforge.oredict.OreDictionary;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class CraftingTask implements ICraftingTask {
|
||||
protected static final int DEFAULT_COMPARE = IComparer.COMPARE_DAMAGE | IComparer.COMPARE_NBT | IComparer.COMPARE_STRIP_NBT;
|
||||
|
||||
public static final String NBT_STEPS = "Steps";
|
||||
public static final String NBT_TO_TAKE_FLUIDS = "ToTakeFluids";
|
||||
public static final String NBT_TO_INSERT_ITEMS = "ToInsertItems";
|
||||
public static final String NBT_TO_INSERT_FLUIDS = "ToInsertFluids";
|
||||
|
||||
private INetwork network;
|
||||
@Nullable
|
||||
private ItemStack requested;
|
||||
private ICraftingPattern pattern;
|
||||
private ICraftingPatternChain chain;
|
||||
|
||||
private ItemStack stack;
|
||||
private int quantity;
|
||||
private boolean automated;
|
||||
private ICraftingPattern pattern;
|
||||
|
||||
private List<ICraftingStep> mainSteps = new LinkedList<>();
|
||||
|
||||
private IStackList<ItemStack> toTake = API.instance().createItemStackList();
|
||||
private IStackList<ItemStack> toCraft = API.instance().createItemStackList();
|
||||
private IStackList<ItemStack> missing = API.instance().createItemStackList();
|
||||
|
||||
private Set<ICraftingPattern> usedPatterns = new HashSet<>();
|
||||
private ICraftingPattern recursedPattern = null;
|
||||
|
||||
private Deque<ItemStack> toInsertItems = new ArrayDeque<>();
|
||||
private Deque<FluidStack> toInsertFluids = new ArrayDeque<>();
|
||||
private IStackList<FluidStack> toTakeFluids = API.instance().createFluidStackList();
|
||||
|
||||
public CraftingTask(INetwork network, @Nullable ItemStack requested, ICraftingPattern pattern, int quantity, boolean automated) {
|
||||
public CraftingTask(INetwork network, ItemStack stack, int quantity, ICraftingPattern pattern) {
|
||||
this.network = network;
|
||||
this.requested = requested;
|
||||
this.pattern = pattern;
|
||||
this.stack = stack;
|
||||
this.quantity = quantity;
|
||||
this.automated = automated;
|
||||
}
|
||||
|
||||
public CraftingTask(INetwork network, @Nullable ItemStack requested, ICraftingPatternChain chain, int quantity, boolean automated) {
|
||||
this(network, requested, chain.getPrototype(), quantity, automated);
|
||||
|
||||
this.chain = chain;
|
||||
}
|
||||
|
||||
public CraftingTask(INetwork network, @Nullable ItemStack requested, ICraftingPattern pattern, int quantity, List<ICraftingStep> mainSteps, Deque<ItemStack> toInsertItems, IStackList<FluidStack> toTakeFluids, Deque<FluidStack> toInsertFluids, boolean automated) {
|
||||
this(network, requested, pattern, quantity, automated);
|
||||
|
||||
this.mainSteps = mainSteps;
|
||||
this.toInsertItems = toInsertItems;
|
||||
this.toTakeFluids = toTakeFluids;
|
||||
this.toInsertFluids = toInsertFluids;
|
||||
this.pattern = pattern;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void calculate() {
|
||||
// Copy here might be expensive but since it is only executed once it isn't a big impact
|
||||
IStackList<ItemStack> networkList = network.getItemStorageCache().getList().copy().getOredicted();
|
||||
|
||||
IStackList<FluidStack> networkFluidList = network.getFluidStorageCache().getList().copy();
|
||||
|
||||
IStackList<ItemStack> toInsert = API.instance().createItemStackList();
|
||||
|
||||
ItemStack requested = this.requested != null ? this.requested : pattern.getOutputs().get(0);
|
||||
|
||||
toCraft.add(requested, quantity);
|
||||
|
||||
int quantity = this.quantity;
|
||||
|
||||
ICraftingPattern currentPattern;
|
||||
while (quantity > 0 && recursedPattern == null) {
|
||||
currentPattern = this.chain == null ? this.pattern : this.chain.cycle();
|
||||
|
||||
mainSteps.add(calculate(networkList, networkFluidList, currentPattern, toInsert));
|
||||
|
||||
quantity -= currentPattern.getQuantityPerRequest(requested);
|
||||
}
|
||||
|
||||
usedPatterns.clear();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private ICraftingStep calculate(IStackList<ItemStack> networkItems, IStackList<FluidStack> networkFluids, ICraftingPattern pattern, IStackList<ItemStack> toInsert) {
|
||||
if (!usedPatterns.add(pattern)) {
|
||||
recursedPattern = pattern;
|
||||
return null;
|
||||
}
|
||||
|
||||
int compare = DEFAULT_COMPARE;
|
||||
|
||||
IStackList<ItemStack> actualInputs = API.instance().createItemStackList();
|
||||
List<ItemStack> usedStacks = new LinkedList<>();
|
||||
List<ICraftingStep> previousSteps = new LinkedList<>();
|
||||
|
||||
IStackList<ItemStack> byproductList = API.instance().createItemStackList();
|
||||
pattern.getByproducts().forEach(byproductList::add);
|
||||
|
||||
for (List<ItemStack> inputs : pattern.getOreInputs()) {
|
||||
if (inputs == null || inputs.isEmpty()) {
|
||||
usedStacks.add(null);
|
||||
continue;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
ItemStack input, extraStack, networkStack;
|
||||
do {
|
||||
input = inputs.get(i).copy();
|
||||
|
||||
// This will be a tool, like a hammer
|
||||
if (input.isItemStackDamageable()) {
|
||||
compare &= ~IComparer.COMPARE_DAMAGE;
|
||||
} else {
|
||||
compare |= IComparer.COMPARE_DAMAGE;
|
||||
}
|
||||
|
||||
extraStack = toInsert.get(input, compare);
|
||||
networkStack = networkItems.get(input, compare);
|
||||
}
|
||||
while (extraStack == null && networkStack == null && ++i < inputs.size() && !network.getCraftingManager().hasPattern(input, compare));
|
||||
|
||||
// Stack not found, just take first
|
||||
if (i == inputs.size()) {
|
||||
input = inputs.get(0).copy();
|
||||
}
|
||||
|
||||
usedStacks.add(input.copy());
|
||||
|
||||
// This will be a tool, like a hammer
|
||||
if (input.isItemStackDamageable()) {
|
||||
compare &= ~IComparer.COMPARE_DAMAGE;
|
||||
} else {
|
||||
compare |= IComparer.COMPARE_DAMAGE;
|
||||
}
|
||||
|
||||
// This handles recipes that use the output as input for the sub recipe
|
||||
final int lambdaCompare = compare;
|
||||
final ItemStack lambdaInput = input;
|
||||
ICraftingPattern inputPattern = null;
|
||||
|
||||
int available = (extraStack == null ? 0 : extraStack.getCount()) + (networkStack == null ? 0 : networkStack.getCount());
|
||||
|
||||
if (available < input.getCount()) {
|
||||
inputPattern = network.getCraftingManager().getPattern(input, compare, networkItems);
|
||||
|
||||
if (inputPattern != null) {
|
||||
if (inputPattern.getInputs().stream().anyMatch(s -> API.instance().getComparer().isEqual(s, lambdaInput, lambdaCompare))) {
|
||||
int craftQuantity = inputPattern.getQuantityPerRequest(input, compare);
|
||||
// The needed amount is the actual needed amount of extraStacks + the needed input (twice so you can keep repeating it)
|
||||
long needed = (networkStack == null ? 0 : -networkStack.getCount()) + input.getCount() + inputPattern.getInputs().stream().filter(s -> API.instance().getComparer().isEqual(s, lambdaInput, lambdaCompare)).count() * 2;
|
||||
|
||||
do {
|
||||
previousSteps.add(calculate(networkItems, networkFluids, inputPattern, toInsert));
|
||||
toCraft.add(input, craftQuantity);
|
||||
extraStack = toInsert.get(input, compare);
|
||||
} while (extraStack != null && extraStack.getCount() < needed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (input.getCount() > 0) {
|
||||
if (extraStack != null && !extraStack.isEmpty()) {
|
||||
int takeQuantity = Math.min(extraStack.getCount(), input.getCount());
|
||||
|
||||
ItemStack inputStack = ItemHandlerHelper.copyStackWithSize(extraStack, takeQuantity);
|
||||
|
||||
actualInputs.add(inputStack);
|
||||
|
||||
input.shrink(takeQuantity);
|
||||
|
||||
if (byproductList.get(inputStack, compare) == null) {
|
||||
toCraft.add(inputStack);
|
||||
}
|
||||
|
||||
toInsert.remove(inputStack);
|
||||
|
||||
if (input.getCount() > 0) {
|
||||
i = 0;
|
||||
do {
|
||||
extraStack = toInsert.get(inputs.get(i), compare);
|
||||
} while ((extraStack == null || extraStack.isEmpty()) && ++i < inputs.size());
|
||||
}
|
||||
} else if (networkStack != null && networkStack.getCount() > 0) {
|
||||
int takeQuantity = Math.min(networkStack.getCount(), input.getCount());
|
||||
|
||||
ItemStack inputStack = ItemHandlerHelper.copyStackWithSize(networkStack, takeQuantity);
|
||||
|
||||
toTake.add(inputStack);
|
||||
actualInputs.add(inputStack);
|
||||
|
||||
input.shrink(takeQuantity);
|
||||
|
||||
networkItems.remove(inputStack);
|
||||
|
||||
if (input.getCount() > 0) {
|
||||
i = 0;
|
||||
do {
|
||||
networkStack = networkItems.get(inputs.get(i), compare);
|
||||
} while ((extraStack == null || extraStack.getCount() == 0) && ++i < inputs.size());
|
||||
}
|
||||
} else {
|
||||
int oreDictedCompare = compare | (pattern.isOredict() ? IComparer.COMPARE_OREDICT : 0);
|
||||
|
||||
if (inputPattern == null) {
|
||||
inputPattern = network.getCraftingManager().getPattern(input, oreDictedCompare, networkItems);
|
||||
}
|
||||
|
||||
if (inputPattern != null) {
|
||||
ItemStack actualCraft = inputPattern.getActualOutput(input, oreDictedCompare);
|
||||
|
||||
int craftQuantity = Math.min(inputPattern.getQuantityPerRequest(input, oreDictedCompare), input.getCount());
|
||||
|
||||
ItemStack inputCrafted = ItemHandlerHelper.copyStackWithSize(actualCraft, craftQuantity);
|
||||
|
||||
toCraft.add(inputCrafted);
|
||||
actualInputs.add(inputCrafted);
|
||||
|
||||
ICraftingStep step = calculate(networkItems, networkFluids, inputPattern, toInsert);
|
||||
|
||||
input.shrink(craftQuantity);
|
||||
|
||||
if (step != null) {
|
||||
previousSteps.add(step);
|
||||
|
||||
if (recursedPattern == null) {
|
||||
// Calculate added all the crafted outputs toInsert
|
||||
// So we remove the ones we use from toInsert
|
||||
ItemStack inserted = toInsert.get(inputCrafted, compare);
|
||||
toInsert.remove(inserted, craftQuantity);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Fluid checks are with a stack size of one
|
||||
ItemStack fluidCheck = ItemHandlerHelper.copyStackWithSize(input, 1);
|
||||
|
||||
while (!input.isEmpty() && doFluidCalculation(networkItems, networkFluids, fluidCheck, toInsert, previousSteps)) {
|
||||
actualInputs.add(fluidCheck);
|
||||
input.shrink(1);
|
||||
}
|
||||
|
||||
// When it isn't a fluid or just doesn't have the needed fluids
|
||||
if (input.getCount() > 0) {
|
||||
ItemStack copy = input.copy();
|
||||
|
||||
if (copy.getItemDamage() == OreDictionary.WILDCARD_VALUE) {
|
||||
copy.setItemDamage(0);
|
||||
}
|
||||
|
||||
missing.add(copy);
|
||||
|
||||
input.setCount(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ItemStack[] took = null;
|
||||
if (missing.isEmpty() && !pattern.isProcessing()) {
|
||||
took = StackListItem.toCraftingGrid(actualInputs, usedStacks, compare | (pattern.isOredict() ? IComparer.COMPARE_OREDICT : 0));
|
||||
}
|
||||
|
||||
List<ItemStack> outputs = (!pattern.isProcessing() && pattern.isOredict() && missing.isEmpty()) ? pattern.getOutputs(took) : pattern.getOutputs();
|
||||
if (outputs == null) {
|
||||
outputs = pattern.getOutputs();
|
||||
}
|
||||
|
||||
for (ItemStack output : outputs) {
|
||||
if (output != null && !output.isEmpty()) {
|
||||
toInsert.add(output);
|
||||
}
|
||||
}
|
||||
|
||||
for (ItemStack byproduct : (!pattern.isProcessing() && pattern.isOredict() && missing.isEmpty()) ? pattern.getByproducts(took) : pattern.getByproducts()) {
|
||||
toInsert.add(byproduct);
|
||||
}
|
||||
|
||||
usedPatterns.remove(pattern);
|
||||
|
||||
return pattern.isProcessing() ? new CraftingStepProcess(network, pattern, previousSteps) : new CraftingStepCraft(network, pattern, usedStacks, previousSteps);
|
||||
}
|
||||
|
||||
private boolean doFluidCalculation(IStackList<ItemStack> networkList, IStackList<FluidStack> networkFluidList, ItemStack input, IStackList<ItemStack> toInsert, List<ICraftingStep> previousSteps) {
|
||||
FluidStack fluidInItem;
|
||||
|
||||
if (API.instance().getComparer().isEqual(input, StackUtils.WATER_BOTTLE)) {
|
||||
FluidStack fluidInStorage = networkFluidList.get(new FluidStack(FluidRegistry.WATER, Fluid.BUCKET_VOLUME));
|
||||
|
||||
if (fluidInStorage == null || fluidInStorage.amount < Fluid.BUCKET_VOLUME) {
|
||||
missing.add(input);
|
||||
} else {
|
||||
ItemStack emptyBottle = toInsert.get(StackUtils.EMPTY_BOTTLE);
|
||||
boolean hasBottle = false;
|
||||
if (emptyBottle != null && emptyBottle.getCount() > 0) {
|
||||
hasBottle = toInsert.remove(StackUtils.EMPTY_BOTTLE, 1);
|
||||
}
|
||||
if (!hasBottle) {
|
||||
emptyBottle = networkList.get(StackUtils.EMPTY_BOTTLE);
|
||||
if (emptyBottle != null && emptyBottle.getCount() > 0) {
|
||||
hasBottle = networkList.remove(StackUtils.EMPTY_BOTTLE);
|
||||
}
|
||||
}
|
||||
|
||||
ICraftingPattern emptyBottlePattern = network.getCraftingManager().getPattern(StackUtils.EMPTY_BOTTLE);
|
||||
|
||||
if (!hasBottle) {
|
||||
if (emptyBottlePattern == null) {
|
||||
missing.add(StackUtils.EMPTY_BOTTLE);
|
||||
} else {
|
||||
toCraft.add(StackUtils.EMPTY_BOTTLE);
|
||||
previousSteps.add(calculate(networkList, networkFluidList, emptyBottlePattern, toInsert));
|
||||
toInsert.remove(StackUtils.EMPTY_BOTTLE, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (hasBottle || emptyBottlePattern != null) {
|
||||
toTake.add(StackUtils.EMPTY_BOTTLE);
|
||||
networkList.remove(StackUtils.EMPTY_BOTTLE);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
} else if ((fluidInItem = StackUtils.getFluid(input, true).getValue()) != null && StackUtils.hasFluidBucket(fluidInItem)) {
|
||||
FluidStack fluidInStorage = networkFluidList.get(fluidInItem);
|
||||
|
||||
if (fluidInStorage == null || fluidInStorage.amount < fluidInItem.amount) {
|
||||
missing.add(input);
|
||||
} else {
|
||||
ItemStack bucket = toInsert.get(StackUtils.EMPTY_BUCKET);
|
||||
boolean hasBucket = false;
|
||||
if (bucket != null && bucket.getCount() > 0) {
|
||||
hasBucket = toInsert.remove(StackUtils.EMPTY_BUCKET, 1);
|
||||
}
|
||||
if (!hasBucket) {
|
||||
bucket = networkList.get(StackUtils.EMPTY_BUCKET);
|
||||
if (bucket != null && bucket.getCount() > 0) {
|
||||
hasBucket = networkList.remove(StackUtils.EMPTY_BUCKET, 1);
|
||||
}
|
||||
}
|
||||
|
||||
ICraftingPattern bucketPattern = network.getCraftingManager().getPattern(StackUtils.EMPTY_BUCKET);
|
||||
|
||||
if (!hasBucket) {
|
||||
if (bucketPattern == null) {
|
||||
missing.add(StackUtils.EMPTY_BUCKET);
|
||||
} else {
|
||||
toCraft.add(StackUtils.EMPTY_BUCKET);
|
||||
previousSteps.add(calculate(networkList, networkFluidList, bucketPattern, toInsert));
|
||||
toInsert.remove(StackUtils.EMPTY_BUCKET, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (hasBucket || bucketPattern != null) {
|
||||
toTakeFluids.add(fluidInItem);
|
||||
networkFluidList.remove(fluidInItem);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean update() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancelled() {
|
||||
for (ItemStack stack : toInsertItems) {
|
||||
network.insertItemTracked(stack, stack.getCount());
|
||||
}
|
||||
|
||||
for (ICraftingStep step : getSteps()) {
|
||||
if (step.getPattern().isBlocking()) {
|
||||
network.getCraftingManager().setContainerBlocked(step.getPattern().getContainer(), false);
|
||||
}
|
||||
}
|
||||
|
||||
network.getCraftingManager().markCraftingMonitorForUpdate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "\nCraftingTask{quantity=" + quantity +
|
||||
"\n, automated=" + automated +
|
||||
"\n, toTake=" + toTake +
|
||||
"\n, toTakeFluids=" + toTakeFluids +
|
||||
"\n, toCraft=" + toCraft +
|
||||
"\n, toInsertItems=" + toInsertItems +
|
||||
"\n, toInsertFluids=" + toInsertFluids +
|
||||
"\n, mainSteps=" + mainSteps +
|
||||
'}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean update(Map<ICraftingPatternContainer, Integer> usedContainers) {
|
||||
IStackList<ItemStack> networkItems = network.getItemStorageCache().getList().getOredicted();
|
||||
IStackList<FluidStack> networkFluids = network.getFluidStorageCache().getList();
|
||||
|
||||
if (!missing.isEmpty()) {
|
||||
for (ItemStack missing : this.missing.getStacks()) {
|
||||
if (!networkItems.trackedRemove(missing)) {
|
||||
networkItems.undo();
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
networkItems.undo();
|
||||
reschedule();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// We need to copy the size cause we'll re-add unadded stacks to the queue
|
||||
// Do inserting on the next tick, reliefs CPU time during insertion
|
||||
// See TileController#runningSteps
|
||||
int times = toInsertItems.size();
|
||||
for (int i = 0; i < times; i++) {
|
||||
ItemStack insert = toInsertItems.poll();
|
||||
if (insert != null) {
|
||||
ItemStack remainder = network.insertItemTracked(insert, insert.getCount());
|
||||
|
||||
if (remainder != null) {
|
||||
toInsertItems.add(remainder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Collect all leaf steps
|
||||
List<ICraftingStep> leafSteps = new LinkedList<>();
|
||||
Queue<ICraftingStep> steps = new LinkedList<>();
|
||||
|
||||
steps.addAll(mainSteps);
|
||||
|
||||
while (steps.size() > 0) {
|
||||
ICraftingStep step = steps.poll();
|
||||
|
||||
if (step.getPreliminarySteps().size() > 0) {
|
||||
steps.addAll(step.getPreliminarySteps());
|
||||
} else {
|
||||
leafSteps.add(step);
|
||||
}
|
||||
}
|
||||
|
||||
for (ICraftingStep step : leafSteps) {
|
||||
if (!step.hasStartedProcessing()) {
|
||||
ICraftingPatternContainer container = step.getPattern().getContainer();
|
||||
Integer timesUsed = usedContainers.get(container);
|
||||
|
||||
if (timesUsed == null) {
|
||||
timesUsed = 0;
|
||||
}
|
||||
|
||||
if (timesUsed++ <= container.getSpeedUpdateCount()) {
|
||||
if (!step.getPattern().isProcessing() || !container.isBlocked()) {
|
||||
if (step.canStartProcessing(networkItems, networkFluids)) {
|
||||
step.setStartedProcessing();
|
||||
|
||||
step.execute(toInsertItems, toInsertFluids);
|
||||
|
||||
usedContainers.put(container, timesUsed);
|
||||
|
||||
network.getCraftingManager().markCraftingMonitorForUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (getSteps().stream().filter(ICraftingStep::hasStartedProcessing).count() == 0) {
|
||||
// When there is no started processes, restart the task.
|
||||
reschedule();
|
||||
}
|
||||
|
||||
// Remove finished tasks
|
||||
steps.clear(); // Re use Queue from earlier
|
||||
|
||||
mainSteps.removeIf(ICraftingStep::hasReceivedOutputs);
|
||||
|
||||
steps.addAll(mainSteps);
|
||||
|
||||
while (steps.size() > 0) {
|
||||
ICraftingStep step = steps.poll();
|
||||
step.getPreliminarySteps().removeIf(ICraftingStep::hasReceivedOutputs);
|
||||
steps.addAll(step.getPreliminarySteps());
|
||||
}
|
||||
|
||||
return isFinished();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reschedule() {
|
||||
List<ICraftingStep> mainSteps = this.mainSteps.stream().filter(s -> s.getPattern().alike(pattern)).collect(Collectors.toList());
|
||||
|
||||
missing.clear();
|
||||
this.mainSteps.clear();
|
||||
|
||||
// if the list of main mainSteps is empty there is no point in rescheduling
|
||||
if (!mainSteps.isEmpty()) {
|
||||
quantity = 0;
|
||||
|
||||
int quantityPerRequest = pattern.getQuantityPerRequest(requested);
|
||||
|
||||
for (ICraftingStep step : mainSteps) {
|
||||
quantity += quantityPerRequest - step.getReceivedOutput(requested);
|
||||
}
|
||||
|
||||
if (quantity > 0) {
|
||||
calculate();
|
||||
}
|
||||
|
||||
network.getCraftingManager().markCraftingMonitorForUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -551,142 +43,24 @@ public class CraftingTask implements ICraftingTask {
|
||||
return quantity;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public ItemStack getRequested() {
|
||||
return requested;
|
||||
return stack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTTagCompound writeToNBT(NBTTagCompound tag) {
|
||||
writeDefaultsToNBT(tag);
|
||||
|
||||
NBTTagList stepsList = new NBTTagList();
|
||||
|
||||
for (ICraftingStep step : mainSteps) {
|
||||
stepsList.appendTag(step.writeToNBT(new NBTTagCompound()));
|
||||
}
|
||||
|
||||
tag.setTag(NBT_STEPS, stepsList);
|
||||
|
||||
NBTTagList toInsertItemsList = new NBTTagList();
|
||||
|
||||
for (ItemStack insert : toInsertItems) {
|
||||
toInsertItemsList.appendTag(insert.serializeNBT());
|
||||
}
|
||||
|
||||
tag.setTag(NBT_TO_INSERT_ITEMS, toInsertItemsList);
|
||||
|
||||
tag.setTag(NBT_TO_TAKE_FLUIDS, StackUtils.serializeFluidStackList(toTakeFluids));
|
||||
|
||||
NBTTagList toInsertFluidsList = new NBTTagList();
|
||||
|
||||
for (FluidStack insert : toInsertFluids) {
|
||||
toInsertFluidsList.appendTag(insert.writeToNBT(new NBTTagCompound()));
|
||||
}
|
||||
|
||||
tag.setTag(NBT_TO_INSERT_FLUIDS, toInsertFluidsList);
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ICraftingMonitorElement> getCraftingMonitorElements() {
|
||||
ICraftingMonitorElementList elements = API.instance().createCraftingMonitorElementList();
|
||||
|
||||
elements.directAdd(new CraftingMonitorElementItemRender(
|
||||
network.getCraftingManager().getTasks().indexOf(this),
|
||||
requested != null ? requested : pattern.getOutputs().get(0),
|
||||
quantity,
|
||||
0
|
||||
));
|
||||
|
||||
if (!missing.isEmpty()) {
|
||||
elements.directAdd(new CraftingMonitorElementText("gui.refinedstorage:crafting_monitor.items_missing", 16));
|
||||
|
||||
missing.getStacks().stream()
|
||||
.map(stack -> new CraftingMonitorElementError(new CraftingMonitorElementItemRender(
|
||||
-1,
|
||||
stack,
|
||||
stack.getCount(),
|
||||
32
|
||||
), ""))
|
||||
.forEach(elements::add);
|
||||
|
||||
elements.commit();
|
||||
return Collections.singletonList(new CraftingMonitorElementItemRender(network.getCraftingManager().getTasks().indexOf(this), stack, quantity, 0));
|
||||
}
|
||||
|
||||
if (!toInsertItems.isEmpty()) {
|
||||
elements.directAdd(new CraftingMonitorElementText("gui.refinedstorage:crafting_monitor.items_inserting", 16));
|
||||
|
||||
toInsertItems.stream()
|
||||
.map(stack -> new CraftingMonitorElementItemRender(
|
||||
-1,
|
||||
stack,
|
||||
stack.getCount(),
|
||||
32
|
||||
))
|
||||
.forEach(elements::add);
|
||||
|
||||
elements.commit();
|
||||
}
|
||||
|
||||
if (!isFinished()) {
|
||||
if (getSteps().stream().filter(s -> !s.getPattern().isProcessing()).count() > 0) {
|
||||
elements.directAdd(new CraftingMonitorElementText("gui.refinedstorage:crafting_monitor.items_crafting", 16));
|
||||
|
||||
IStackList<ItemStack> oreDictPrepped = network.getItemStorageCache().getList().getOredicted();
|
||||
IStackList<FluidStack> networkFluids = network.getFluidStorageCache().getList();
|
||||
|
||||
for (ICraftingStep step : getSteps().stream().filter(s -> !s.getPattern().isProcessing()).collect(Collectors.toList())) {
|
||||
for (int i = 0; i < step.getPattern().getOutputs().size(); ++i) {
|
||||
ICraftingMonitorElement element = new CraftingMonitorElementItemRender(
|
||||
-1,
|
||||
step.getPattern().getOutputs().get(i),
|
||||
step.getPattern().getOutputs().get(i).getCount(),
|
||||
32
|
||||
);
|
||||
|
||||
if (!step.hasStartedProcessing() && !step.canStartProcessing(oreDictPrepped, networkFluids)) {
|
||||
element = new CraftingMonitorElementInfo(element, "gui.refinedstorage:crafting_monitor.waiting_for_items");
|
||||
}
|
||||
|
||||
elements.add(element);
|
||||
}
|
||||
}
|
||||
|
||||
elements.commit();
|
||||
}
|
||||
|
||||
if (getSteps().stream().filter(s -> s.getPattern().isProcessing()).count() > 0) {
|
||||
elements.directAdd(new CraftingMonitorElementText("gui.refinedstorage:crafting_monitor.items_processing", 16));
|
||||
|
||||
for (ICraftingStep step : getSteps().stream().filter(s -> s.getPattern().isProcessing()).collect(Collectors.toList())) {
|
||||
for (int i = 0; i < step.getPattern().getOutputs().size(); ++i) {
|
||||
ICraftingMonitorElement element = new CraftingMonitorElementItemRender(
|
||||
-1,
|
||||
step.getPattern().getOutputs().get(i),
|
||||
step.getPattern().getOutputs().get(i).getCount(),
|
||||
32
|
||||
);
|
||||
|
||||
if (step.getPattern().getContainer().getConnectedTile() == null) {
|
||||
element = new CraftingMonitorElementError(element, "gui.refinedstorage:crafting_monitor.machine_none");
|
||||
} else if (!step.hasStartedProcessing() && !step.canStartProcessing()) {
|
||||
element = new CraftingMonitorElementError(element, "gui.refinedstorage:crafting_monitor.machine_in_use");
|
||||
} else if (!step.hasStartedProcessing() && step.getPattern().getContainer().isBlocked()) {
|
||||
element = new CraftingMonitorElementError(element, "gui.refinedstorage:crafting_monitor.blocked");
|
||||
}
|
||||
|
||||
elements.add(element);
|
||||
}
|
||||
}
|
||||
|
||||
elements.commit();
|
||||
}
|
||||
}
|
||||
|
||||
return elements.getElements();
|
||||
@Override
|
||||
public List<ICraftingPreviewElement> getPreviewStacks() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -694,98 +68,8 @@ public class CraftingTask implements ICraftingTask {
|
||||
return pattern;
|
||||
}
|
||||
|
||||
public List<ICraftingStep> getSteps() {
|
||||
List<ICraftingStep> allSteps = new LinkedList<>();
|
||||
Queue<ICraftingStep> steps = new LinkedList<>();
|
||||
|
||||
steps.addAll(mainSteps);
|
||||
|
||||
while (steps.size() > 0) {
|
||||
ICraftingStep step = steps.poll();
|
||||
|
||||
allSteps.add(step);
|
||||
|
||||
steps.addAll(step.getPreliminarySteps());
|
||||
}
|
||||
|
||||
return allSteps;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
return recursedPattern == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStackList<ItemStack> getMissing() {
|
||||
return missing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ICraftingPreviewElement> getPreviewStacks() {
|
||||
if (!isValid()) {
|
||||
return Collections.singletonList(new CraftingPreviewElementError(recursedPattern.getStack()));
|
||||
}
|
||||
|
||||
Map<Integer, CraftingPreviewElementItemStack> map = new LinkedHashMap<>();
|
||||
|
||||
for (ItemStack stack : toCraft.getStacks()) {
|
||||
int hash = API.instance().getItemStackHashCode(stack);
|
||||
|
||||
CraftingPreviewElementItemStack previewStack = map.get(hash);
|
||||
|
||||
if (previewStack == null) {
|
||||
previewStack = new CraftingPreviewElementItemStack(stack);
|
||||
}
|
||||
|
||||
previewStack.addToCraft(stack.getCount());
|
||||
|
||||
map.put(hash, previewStack);
|
||||
}
|
||||
|
||||
for (ItemStack stack : missing.getStacks()) {
|
||||
int hash = API.instance().getItemStackHashCode(stack);
|
||||
|
||||
CraftingPreviewElementItemStack previewStack = map.get(hash);
|
||||
|
||||
if (previewStack == null) {
|
||||
previewStack = new CraftingPreviewElementItemStack(stack);
|
||||
}
|
||||
|
||||
previewStack.setMissing(true);
|
||||
previewStack.addToCraft(stack.getCount());
|
||||
|
||||
map.put(hash, previewStack);
|
||||
}
|
||||
|
||||
for (ItemStack stack : toTake.getStacks()) {
|
||||
int hash = API.instance().getItemStackHashCode(stack);
|
||||
|
||||
CraftingPreviewElementItemStack previewStack = map.get(hash);
|
||||
|
||||
if (previewStack == null) {
|
||||
previewStack = new CraftingPreviewElementItemStack(stack);
|
||||
}
|
||||
|
||||
previewStack.addAvailable(stack.getCount());
|
||||
|
||||
map.put(hash, previewStack);
|
||||
}
|
||||
|
||||
List<ICraftingPreviewElement> elements = new ArrayList<>(map.values());
|
||||
|
||||
toTakeFluids.getStacks().stream().map(CraftingPreviewElementFluidStack::new).forEach(elements::add);
|
||||
|
||||
return elements;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAutomated() {
|
||||
return automated;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFinished() {
|
||||
return mainSteps.stream().allMatch(ICraftingStep::hasReceivedOutputs);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ import com.raoulvdberge.refinedstorage.api.network.item.NetworkItemAction;
|
||||
import com.raoulvdberge.refinedstorage.api.network.security.Permission;
|
||||
import com.raoulvdberge.refinedstorage.api.util.IStackList;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.CraftingTask;
|
||||
import com.raoulvdberge.refinedstorage.network.MessageGridCraftingPreviewResponse;
|
||||
import com.raoulvdberge.refinedstorage.network.MessageGridCraftingStartResponse;
|
||||
import com.raoulvdberge.refinedstorage.util.StackUtils;
|
||||
@@ -171,25 +170,27 @@ public class ItemGridHandler implements IItemGridHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO why?
|
||||
IStackList<ItemStack> cache = API.instance().createItemStackList();
|
||||
|
||||
for (ICraftingPattern pattern : network.getCraftingManager().getPatterns()) {
|
||||
for (ItemStack output : pattern.getOutputs()) {
|
||||
if (output != null) {
|
||||
cache.add(output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ItemStack stack = cache.get(hash);
|
||||
|
||||
if (stack != null) {
|
||||
Thread calculationThread = new Thread(() -> {
|
||||
ICraftingTask task = new CraftingTask(network, stack, network.getCraftingManager().getPatternChain(stack), quantity, false);
|
||||
ICraftingTask task = network.getCraftingManager().create(stack, quantity);
|
||||
if (task == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
task.calculate();
|
||||
|
||||
if (noPreview && task.getMissing().isEmpty()) {
|
||||
if (noPreview /*&& task.getMissing().isEmpty()*/) { // TODO
|
||||
network.getCraftingManager().add(task);
|
||||
|
||||
RS.INSTANCE.network.sendTo(new MessageGridCraftingStartResponse(), player);
|
||||
@@ -212,7 +213,7 @@ public class ItemGridHandler implements IItemGridHandler {
|
||||
|
||||
for (ICraftingPattern pattern : network.getCraftingManager().getPatterns()) {
|
||||
for (ItemStack output : pattern.getOutputs()) {
|
||||
if (output != null && API.instance().getItemStackHashCode(output) == hash) {
|
||||
if (API.instance().getItemStackHashCode(output) == hash) {
|
||||
stack = output;
|
||||
|
||||
break;
|
||||
@@ -225,12 +226,13 @@ public class ItemGridHandler implements IItemGridHandler {
|
||||
}
|
||||
|
||||
if (stack != null) {
|
||||
ICraftingTask task = new CraftingTask(network, stack, network.getCraftingManager().getPatternChain(stack), quantity, false);
|
||||
ICraftingTask task = network.getCraftingManager().create(stack, quantity);
|
||||
if (task == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
task.calculate();
|
||||
|
||||
task.getMissing().clear();
|
||||
|
||||
network.getCraftingManager().add(task);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,7 +116,6 @@ public class NetworkNodeCrafter extends NetworkNode implements ICraftingPatternC
|
||||
network.getCraftingManager().getTasks().stream()
|
||||
.filter(task -> task.getPattern().getContainer().getPosition().equals(pos))
|
||||
.forEach(task -> network.getCraftingManager().cancel(task));
|
||||
network.getCraftingManager().setContainerBlocked(this, false);
|
||||
}
|
||||
|
||||
network.getCraftingManager().rebuild();
|
||||
@@ -268,13 +267,8 @@ public class NetworkNodeCrafter extends NetworkNode implements ICraftingPatternC
|
||||
visited = true;
|
||||
ICraftingPatternContainer facingContainer = ((ICraftingPatternContainer)facing).getRootContainer();
|
||||
visited = false;
|
||||
return facingContainer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBlocked() {
|
||||
ICraftingPatternContainer proxy = getRootContainer();
|
||||
return proxy != null && network != null && network.getCraftingManager().isContainerBlocked(proxy.getUuid());
|
||||
return facingContainer;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -283,6 +277,7 @@ public class NetworkNodeCrafter extends NetworkNode implements ICraftingPatternC
|
||||
uuid = UUID.randomUUID();
|
||||
markDirty();
|
||||
}
|
||||
|
||||
return uuid;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import com.raoulvdberge.refinedstorage.inventory.ItemHandlerFilter;
|
||||
import com.raoulvdberge.refinedstorage.inventory.ItemHandlerListenerNetworkNode;
|
||||
import com.raoulvdberge.refinedstorage.tile.craftingmonitor.ICraftingMonitor;
|
||||
import com.raoulvdberge.refinedstorage.tile.craftingmonitor.TileCraftingMonitor;
|
||||
import com.raoulvdberge.refinedstorage.tile.data.TileDataManager;
|
||||
import com.raoulvdberge.refinedstorage.tile.data.TileDataParameter;
|
||||
import com.raoulvdberge.refinedstorage.util.StackUtils;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
@@ -25,9 +24,6 @@ import java.util.List;
|
||||
public class NetworkNodeCraftingMonitor extends NetworkNode implements ICraftingMonitor {
|
||||
public static final String ID = "crafting_monitor";
|
||||
|
||||
private static final String NBT_VIEW_AUTOMATED = "ViewAutomated";
|
||||
|
||||
private boolean viewAutomated = true;
|
||||
private List<IFilter> filters = new ArrayList<>();
|
||||
private ItemHandlerListenerNetworkNode filterListener = new ItemHandlerListenerNetworkNode(this);
|
||||
private ItemHandlerFilter filter = new ItemHandlerFilter(filters, new ArrayList<>(), slot -> {
|
||||
@@ -102,8 +98,6 @@ public class NetworkNodeCraftingMonitor extends NetworkNode implements ICrafting
|
||||
|
||||
StackUtils.writeItems(filter, 0, tag);
|
||||
|
||||
tag.setBoolean(NBT_VIEW_AUTOMATED, viewAutomated);
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
@@ -112,20 +106,6 @@ public class NetworkNodeCraftingMonitor extends NetworkNode implements ICrafting
|
||||
super.read(tag);
|
||||
|
||||
StackUtils.readItems(filter, 0, tag);
|
||||
|
||||
if (tag.hasKey(NBT_VIEW_AUTOMATED)) {
|
||||
viewAutomated = tag.getBoolean(NBT_VIEW_AUTOMATED);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canViewAutomated() {
|
||||
return world.isRemote ? TileCraftingMonitor.VIEW_AUTOMATED.getValue() : viewAutomated;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewAutomatedChanged(boolean viewAutomated) {
|
||||
TileDataManager.setParameter(TileCraftingMonitor.VIEW_AUTOMATED, viewAutomated);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -133,10 +113,6 @@ public class NetworkNodeCraftingMonitor extends NetworkNode implements ICrafting
|
||||
// NO OP
|
||||
}
|
||||
|
||||
public void setViewAutomated(boolean viewAutomated) {
|
||||
this.viewAutomated = viewAutomated;
|
||||
}
|
||||
|
||||
public ItemHandlerFilter getFilter() {
|
||||
return filter;
|
||||
}
|
||||
|
||||
@@ -63,7 +63,6 @@ public class NetworkNodeGrid extends NetworkNode implements IGridNetworkAware {
|
||||
public static final String NBT_TAB_PAGE = "TabPage";
|
||||
public static final String NBT_SIZE = "Size";
|
||||
public static final String NBT_PROCESSING_PATTERN = "ProcessingPattern";
|
||||
public static final String NBT_BLOCKING_PATTERN = "BlockingPattern";
|
||||
|
||||
private Container craftingContainer = new Container() {
|
||||
@Override
|
||||
@@ -130,7 +129,6 @@ public class NetworkNodeGrid extends NetworkNode implements IGridNetworkAware {
|
||||
|
||||
private boolean oredictPattern = false;
|
||||
private boolean processingPattern = false;
|
||||
private boolean blockingPattern = false;
|
||||
|
||||
public NetworkNodeGrid(World world, BlockPos pos) {
|
||||
super(world, pos);
|
||||
@@ -196,14 +194,6 @@ public class NetworkNodeGrid extends NetworkNode implements IGridNetworkAware {
|
||||
this.processingPattern = processingPattern;
|
||||
}
|
||||
|
||||
public boolean isBlockingPattern() {
|
||||
return blockingPattern;
|
||||
}
|
||||
|
||||
public void setBlockingPattern(boolean blockingPattern) {
|
||||
this.blockingPattern = blockingPattern;
|
||||
}
|
||||
|
||||
public GridType getType() {
|
||||
if (type == null && world.getBlockState(pos).getBlock() == RSBlocks.GRID) {
|
||||
type = (GridType) world.getBlockState(pos).getValue(BlockGrid.TYPE);
|
||||
@@ -499,10 +489,6 @@ public class NetworkNodeGrid extends NetworkNode implements IGridNetworkAware {
|
||||
|
||||
ItemStack pattern = new ItemStack(RSItems.PATTERN);
|
||||
|
||||
if (processingPattern) {
|
||||
ItemPattern.setBlocking(pattern, blockingPattern);
|
||||
}
|
||||
|
||||
ItemPattern.setOredict(pattern, oredictPattern);
|
||||
|
||||
if (processingPattern) {
|
||||
@@ -692,7 +678,6 @@ public class NetworkNodeGrid extends NetworkNode implements IGridNetworkAware {
|
||||
|
||||
tag.setBoolean(NBT_OREDICT_PATTERN, oredictPattern);
|
||||
tag.setBoolean(NBT_PROCESSING_PATTERN, processingPattern);
|
||||
tag.setBoolean(NBT_BLOCKING_PATTERN, blockingPattern);
|
||||
|
||||
return tag;
|
||||
}
|
||||
@@ -728,10 +713,6 @@ public class NetworkNodeGrid extends NetworkNode implements IGridNetworkAware {
|
||||
if (tag.hasKey(NBT_PROCESSING_PATTERN)) {
|
||||
processingPattern = tag.getBoolean(NBT_PROCESSING_PATTERN);
|
||||
}
|
||||
|
||||
if (tag.hasKey(NBT_BLOCKING_PATTERN)) {
|
||||
blockingPattern = tag.getBoolean(NBT_BLOCKING_PATTERN);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -6,7 +6,6 @@ import com.raoulvdberge.refinedstorage.api.render.IElementDrawer;
|
||||
import com.raoulvdberge.refinedstorage.api.render.IElementDrawers;
|
||||
import com.raoulvdberge.refinedstorage.container.ContainerCraftingMonitor;
|
||||
import com.raoulvdberge.refinedstorage.gui.control.Scrollbar;
|
||||
import com.raoulvdberge.refinedstorage.gui.control.SideButtonCraftingMonitorViewAutomated;
|
||||
import com.raoulvdberge.refinedstorage.gui.control.SideButtonRedstoneMode;
|
||||
import com.raoulvdberge.refinedstorage.network.MessageCraftingMonitorCancel;
|
||||
import com.raoulvdberge.refinedstorage.tile.craftingmonitor.ICraftingMonitor;
|
||||
@@ -71,8 +70,6 @@ public class GuiCraftingMonitor extends GuiBase {
|
||||
addSideButton(new SideButtonRedstoneMode(this, craftingMonitor.getRedstoneModeParameter()));
|
||||
}
|
||||
|
||||
addSideButton(new SideButtonCraftingMonitorViewAutomated(this, craftingMonitor));
|
||||
|
||||
String cancel = t("gui.cancel");
|
||||
String cancelAll = t("misc.refinedstorage:cancel_all");
|
||||
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
package com.raoulvdberge.refinedstorage.gui.control;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.gui.GuiBase;
|
||||
import com.raoulvdberge.refinedstorage.tile.craftingmonitor.ICraftingMonitor;
|
||||
import net.minecraft.util.text.TextFormatting;
|
||||
|
||||
public class SideButtonCraftingMonitorViewAutomated extends SideButton {
|
||||
private ICraftingMonitor craftingMonitor;
|
||||
|
||||
public SideButtonCraftingMonitorViewAutomated(GuiBase gui, ICraftingMonitor craftingMonitor) {
|
||||
super(gui);
|
||||
|
||||
this.craftingMonitor = craftingMonitor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTooltip() {
|
||||
return GuiBase.t("sidebutton.refinedstorage:crafting_monitor.view_automated") + "\n" + TextFormatting.GRAY + GuiBase.t("gui." + (craftingMonitor.canViewAutomated() ? "yes" : "no"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawButtonIcon(int x, int y) {
|
||||
gui.drawTexture(x, y, craftingMonitor.canViewAutomated() ? 0 : 16, 144, 16, 16);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed() {
|
||||
craftingMonitor.onViewAutomatedChanged(!craftingMonitor.canViewAutomated());
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,6 @@ public class GuiGrid extends GuiBase implements IResizableDisplay {
|
||||
private TextFieldSearch searchField;
|
||||
private GuiCheckBox oredictPattern;
|
||||
private GuiCheckBox processingPattern;
|
||||
private GuiCheckBox blockingPattern;
|
||||
private GuiButton tabPageLeft;
|
||||
private GuiButton tabPageRight;
|
||||
|
||||
@@ -129,10 +128,6 @@ public class GuiGrid extends GuiBase implements IResizableDisplay {
|
||||
if (grid.getType() == GridType.PATTERN) {
|
||||
processingPattern = addCheckBox(x + 7, y + getTabHeight() + getTopHeight() + (getVisibleRows() * 18) + 60, t("misc.refinedstorage:processing"), TileGrid.PROCESSING_PATTERN.getValue());
|
||||
oredictPattern = addCheckBox(processingPattern.x + processingPattern.width + 5, y + getTabHeight() + getTopHeight() + (getVisibleRows() * 18) + 60, t("misc.refinedstorage:oredict"), TileGrid.OREDICT_PATTERN.getValue());
|
||||
|
||||
if (((NetworkNodeGrid) grid).isProcessingPattern()) {
|
||||
blockingPattern = addCheckBox(oredictPattern.x + oredictPattern.width + 5, y + getTabHeight() + getTopHeight() + (getVisibleRows() * 18) + 60, t("misc.refinedstorage:blocking"), TileGrid.BLOCKING_PATTERN.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
if (grid.getType() != GridType.FLUID && grid.getViewType() != -1) {
|
||||
@@ -620,8 +615,6 @@ public class GuiGrid extends GuiBase implements IResizableDisplay {
|
||||
|
||||
if (button == oredictPattern) {
|
||||
TileDataManager.setParameter(TileGrid.OREDICT_PATTERN, oredictPattern.isChecked());
|
||||
} else if (button == blockingPattern) {
|
||||
TileDataManager.setParameter(TileGrid.BLOCKING_PATTERN, blockingPattern.isChecked());
|
||||
} else if (button == processingPattern) {
|
||||
// Rebuild the inventory slots before the slot change packet arrives
|
||||
TileGrid.PROCESSING_PATTERN.setValue(false, processingPattern.isChecked());
|
||||
@@ -743,12 +736,6 @@ public class GuiGrid extends GuiBase implements IResizableDisplay {
|
||||
}
|
||||
}
|
||||
|
||||
public void updateBlockingPattern(boolean checked) {
|
||||
if (blockingPattern != null) {
|
||||
blockingPattern.setIsChecked(checked);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateScrollbarAndTabs() {
|
||||
if (scrollbar != null) {
|
||||
scrollbar.setEnabled(getRows() > getVisibleRows());
|
||||
|
||||
@@ -13,10 +13,8 @@ public class ConverterCraftingPattern implements Converter {
|
||||
|
||||
output.put("outputs", pattern.getOutputs());
|
||||
output.put("inputs", pattern.getInputs());
|
||||
output.put("oreInputs", pattern.getOreInputs());
|
||||
output.put("byproducts", pattern.getByproducts());
|
||||
output.put("processing", pattern.isProcessing());
|
||||
output.put("blocking", pattern.isBlocking());
|
||||
output.put("oredict", pattern.isOredict());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ public class ConverterCraftingTask implements Converter {
|
||||
ICraftingTask task = (ICraftingTask) value;
|
||||
|
||||
output.put("stack", task.getRequested());
|
||||
output.put("missing", task.getMissing().getStacks());
|
||||
// TODO: output.put("missing", task.getMissing().getStacks());
|
||||
output.put("pattern", task.getPattern());
|
||||
output.put("quantity", task.getQuantity());
|
||||
}
|
||||
|
||||
@@ -22,9 +22,9 @@ import net.minecraftforge.items.CapabilityItemHandler;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.ItemHandlerHelper;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.List;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.raoulvdberge.refinedstorage.api.util.IComparer.COMPARE_DAMAGE;
|
||||
import static com.raoulvdberge.refinedstorage.api.util.IComparer.COMPARE_NBT;
|
||||
@@ -68,7 +68,7 @@ public class EnvironmentNetwork extends AbstractManagedEnvironment {
|
||||
}
|
||||
|
||||
ItemStack stack = args.checkItemStack(0);
|
||||
return new Object[]{node.getNetwork().getCraftingManager().getPattern(stack)};
|
||||
return new Object[]{node.getNetwork().getCraftingManager().getPattern(stack, IComparer.COMPARE_DAMAGE | IComparer.COMPARE_NBT)};
|
||||
}
|
||||
|
||||
@Callback(doc = "function():table -- Gets the patterns of this network.")
|
||||
@@ -93,7 +93,7 @@ public class EnvironmentNetwork extends AbstractManagedEnvironment {
|
||||
|
||||
ItemStack stack = args.checkItemStack(0);
|
||||
|
||||
return new Object[]{node.getNetwork().getCraftingManager().hasPattern(stack)};
|
||||
return new Object[]{node.getNetwork().getCraftingManager().getPattern(stack, IComparer.COMPARE_DAMAGE | IComparer.COMPARE_NBT) != null};
|
||||
}
|
||||
|
||||
@Callback(doc = "function(stack:table[, count: number]):table -- Gets a list of missing items for a crafting task.")
|
||||
@@ -103,18 +103,17 @@ public class EnvironmentNetwork extends AbstractManagedEnvironment {
|
||||
}
|
||||
|
||||
ItemStack stack = args.checkItemStack(0);
|
||||
int count = args.optInteger(1, 1);
|
||||
|
||||
if (!node.getNetwork().getCraftingManager().hasPattern(stack)) {
|
||||
throw new IllegalArgumentException("No pattern for this item exists");
|
||||
ICraftingTask task = node.getNetwork().getCraftingManager().create(stack, count);
|
||||
if (task == null) {
|
||||
throw new IllegalArgumentException("Could not create crafting task");
|
||||
}
|
||||
|
||||
int count = args.optInteger(1, 1);
|
||||
ICraftingPattern pattern = node.getNetwork().getCraftingManager().getPattern(stack);
|
||||
|
||||
ICraftingTask task = node.getNetwork().getCraftingManager().create(stack, pattern, count, true);
|
||||
task.calculate();
|
||||
|
||||
return new Object[]{task.getMissing().getStacks()};
|
||||
//TODO return new Object[]{task.getMissing().getStacks()};
|
||||
return new Object[]{};
|
||||
}
|
||||
|
||||
@Callback(doc = "function(stack:table[, count: number]) -- Schedules a crafting task.")
|
||||
@@ -124,15 +123,13 @@ public class EnvironmentNetwork extends AbstractManagedEnvironment {
|
||||
}
|
||||
|
||||
ItemStack stack = args.checkItemStack(0);
|
||||
int amount = args.optInteger(1, 1);
|
||||
|
||||
if (!node.getNetwork().getCraftingManager().hasPattern(stack)) {
|
||||
throw new IllegalArgumentException("No pattern for this item stack exists");
|
||||
ICraftingTask task = node.getNetwork().getCraftingManager().create(stack, amount);
|
||||
if (task == null) {
|
||||
throw new IllegalArgumentException("Could not create crafting task");
|
||||
}
|
||||
|
||||
int amount = args.optInteger(1, 1);
|
||||
ICraftingPattern pattern = node.getNetwork().getCraftingManager().getPattern(stack);
|
||||
|
||||
ICraftingTask task = node.getNetwork().getCraftingManager().create(stack, pattern, amount, true);
|
||||
task.calculate();
|
||||
|
||||
node.getNetwork().getCraftingManager().add(task);
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.raoulvdberge.refinedstorage.RSItems;
|
||||
import com.raoulvdberge.refinedstorage.api.util.IComparer;
|
||||
import com.raoulvdberge.refinedstorage.api.util.IFilter;
|
||||
import com.raoulvdberge.refinedstorage.inventory.ItemHandlerFilterItems;
|
||||
import com.raoulvdberge.refinedstorage.util.RenderUtils;
|
||||
import net.minecraft.client.resources.I18n;
|
||||
import net.minecraft.client.util.ITooltipFlag;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
@@ -73,7 +74,7 @@ public class ItemFilter extends ItemBase {
|
||||
|
||||
ItemHandlerFilterItems items = new ItemHandlerFilterItems(stack);
|
||||
|
||||
ItemPattern.combineItems(tooltip, false, items.getFilteredItems());
|
||||
RenderUtils.addCombinedItemsToTooltip(tooltip, false, items.getFilteredItems());
|
||||
}
|
||||
|
||||
public static int getCompare(ItemStack stack) {
|
||||
|
||||
@@ -4,10 +4,8 @@ import com.raoulvdberge.refinedstorage.RSItems;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPatternContainer;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPatternProvider;
|
||||
import com.raoulvdberge.refinedstorage.api.util.IStackList;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.CraftingPattern;
|
||||
import com.raoulvdberge.refinedstorage.util.StackUtils;
|
||||
import com.raoulvdberge.refinedstorage.util.RenderUtils;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.client.resources.I18n;
|
||||
import net.minecraft.client.util.ITooltipFlag;
|
||||
@@ -25,7 +23,10 @@ import net.minecraftforge.common.util.Constants;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ItemPattern extends ItemBase implements ICraftingPatternProvider {
|
||||
private static Map<ItemStack, CraftingPattern> PATTERN_CACHE = new HashMap<>();
|
||||
@@ -33,7 +34,6 @@ public class ItemPattern extends ItemBase implements ICraftingPatternProvider {
|
||||
private static final String NBT_SLOT = "Slot_%d";
|
||||
private static final String NBT_OUTPUTS = "Outputs";
|
||||
private static final String NBT_OREDICT = "Oredict";
|
||||
private static final String NBT_BLOCKING = "Blocking";
|
||||
|
||||
public ItemPattern() {
|
||||
super("pattern");
|
||||
@@ -61,20 +61,16 @@ public class ItemPattern extends ItemBase implements ICraftingPatternProvider {
|
||||
if (GuiScreen.isShiftKeyDown() || isProcessing(stack)) {
|
||||
tooltip.add(TextFormatting.YELLOW + I18n.format("misc.refinedstorage:pattern.inputs") + TextFormatting.RESET);
|
||||
|
||||
combineItems(tooltip, true, StackUtils.toNonNullList(pattern.getInputs()));
|
||||
RenderUtils.addCombinedItemsToTooltip(tooltip, true, pattern.getInputs().stream().map(i -> i.size() > 0 ? i.get(0) : ItemStack.EMPTY).collect(Collectors.toList()));
|
||||
|
||||
tooltip.add(TextFormatting.YELLOW + I18n.format("misc.refinedstorage:pattern.outputs") + TextFormatting.RESET);
|
||||
}
|
||||
|
||||
combineItems(tooltip, true, StackUtils.toNonNullList(pattern.getOutputs()));
|
||||
RenderUtils.addCombinedItemsToTooltip(tooltip, true, pattern.getOutputs());
|
||||
|
||||
if (isOredict(stack)) {
|
||||
tooltip.add(TextFormatting.BLUE + I18n.format("misc.refinedstorage:pattern.oredict") + TextFormatting.RESET);
|
||||
}
|
||||
|
||||
if (isBlocking(stack)) {
|
||||
tooltip.add(TextFormatting.BLUE + I18n.format("misc.refinedstorage:blocking") + TextFormatting.RESET);
|
||||
}
|
||||
} else {
|
||||
tooltip.add(TextFormatting.RED + I18n.format("misc.refinedstorage:pattern.invalid") + TextFormatting.RESET);
|
||||
}
|
||||
@@ -117,12 +113,8 @@ public class ItemPattern extends ItemBase implements ICraftingPatternProvider {
|
||||
pattern.getTagCompound().setTag(NBT_OUTPUTS, outputs);
|
||||
}
|
||||
|
||||
public static List<ItemStack> getOutputs(ItemStack pattern) {
|
||||
if (!isProcessing(pattern)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
IStackList<ItemStack> outputs = API.instance().createItemStackList();
|
||||
public static NonNullList<ItemStack> getOutputs(ItemStack pattern) {
|
||||
NonNullList<ItemStack> outputs = NonNullList.create();
|
||||
|
||||
NBTTagList outputsTag = pattern.getTagCompound().getTagList(NBT_OUTPUTS, Constants.NBT.TAG_COMPOUND);
|
||||
|
||||
@@ -134,7 +126,7 @@ public class ItemPattern extends ItemBase implements ICraftingPatternProvider {
|
||||
}
|
||||
}
|
||||
|
||||
return new ArrayList<>(outputs.getStacks());
|
||||
return outputs;
|
||||
}
|
||||
|
||||
public static boolean isProcessing(ItemStack pattern) {
|
||||
@@ -145,10 +137,6 @@ public class ItemPattern extends ItemBase implements ICraftingPatternProvider {
|
||||
return pattern.hasTagCompound() && pattern.getTagCompound().hasKey(NBT_OREDICT) && pattern.getTagCompound().getBoolean(NBT_OREDICT);
|
||||
}
|
||||
|
||||
public static boolean isBlocking(ItemStack pattern) {
|
||||
return pattern.hasTagCompound() && pattern.getTagCompound().hasKey(NBT_BLOCKING) && pattern.getTagCompound().getBoolean(NBT_BLOCKING);
|
||||
}
|
||||
|
||||
public static void setOredict(ItemStack pattern, boolean oredict) {
|
||||
if (!pattern.hasTagCompound()) {
|
||||
pattern.setTagCompound(new NBTTagCompound());
|
||||
@@ -157,40 +145,6 @@ public class ItemPattern extends ItemBase implements ICraftingPatternProvider {
|
||||
pattern.getTagCompound().setBoolean(NBT_OREDICT, oredict);
|
||||
}
|
||||
|
||||
public static void setBlocking(ItemStack pattern, boolean blockingTask) {
|
||||
if (!pattern.hasTagCompound()) {
|
||||
pattern.setTagCompound(new NBTTagCompound());
|
||||
}
|
||||
|
||||
pattern.getTagCompound().setBoolean(NBT_BLOCKING, blockingTask);
|
||||
}
|
||||
|
||||
public static void combineItems(List<String> tooltip, boolean displayAmount, NonNullList<ItemStack> stacks) {
|
||||
Set<Integer> combinedIndices = new HashSet<>();
|
||||
|
||||
for (int i = 0; i < stacks.size(); ++i) {
|
||||
if (!stacks.get(i).isEmpty() && !combinedIndices.contains(i)) {
|
||||
ItemStack stack = stacks.get(i);
|
||||
|
||||
String data = stack.getDisplayName();
|
||||
|
||||
int amount = stack.getCount();
|
||||
|
||||
for (int j = i + 1; j < stacks.size(); ++j) {
|
||||
if (API.instance().getComparer().isEqual(stack, stacks.get(j))) {
|
||||
amount += stacks.get(j).getCount();
|
||||
|
||||
combinedIndices.add(j);
|
||||
}
|
||||
}
|
||||
|
||||
data = (displayAmount ? (TextFormatting.WHITE + String.valueOf(amount) + " ") : "") + TextFormatting.GRAY + data;
|
||||
|
||||
tooltip.add(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, EnumHand hand) {
|
||||
if (!world.isRemote && player.isSneaking()) {
|
||||
@@ -203,7 +157,6 @@ public class ItemPattern extends ItemBase implements ICraftingPatternProvider {
|
||||
@Override
|
||||
@Nonnull
|
||||
public ICraftingPattern create(World world, ItemStack stack, ICraftingPatternContainer container) {
|
||||
// We copy the pattern stack because if we remove it from the inventory, the crafting task will use a pattern with an invalid stack...
|
||||
return new CraftingPattern(world, container, stack.copy());
|
||||
return new CraftingPattern(world, container, stack);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,13 +5,10 @@ import com.raoulvdberge.refinedstorage.api.network.item.INetworkItemHandler;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.network.item.NetworkItemWirelessCraftingMonitor;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class ItemWirelessCraftingMonitor extends ItemNetworkItem {
|
||||
private static final String NBT_VIEW_AUTOMATED = "ViewAutomated";
|
||||
|
||||
public ItemWirelessCraftingMonitor() {
|
||||
super("wireless_crafting_monitor");
|
||||
}
|
||||
@@ -21,16 +18,4 @@ public class ItemWirelessCraftingMonitor extends ItemNetworkItem {
|
||||
public INetworkItem provide(INetworkItemHandler handler, EntityPlayer player, ItemStack stack) {
|
||||
return new NetworkItemWirelessCraftingMonitor(handler, player, stack);
|
||||
}
|
||||
|
||||
public static void setViewAutomated(ItemStack stack, boolean viewAutomated) {
|
||||
if (!stack.hasTagCompound()) {
|
||||
stack.setTagCompound(new NBTTagCompound());
|
||||
}
|
||||
|
||||
stack.getTagCompound().setBoolean(NBT_VIEW_AUTOMATED, viewAutomated);
|
||||
}
|
||||
|
||||
public static boolean canViewAutomated(ItemStack stack) {
|
||||
return (stack.hasTagCompound() && stack.getTagCompound().hasKey(NBT_VIEW_AUTOMATED)) ? stack.getTagCompound().getBoolean(NBT_VIEW_AUTOMATED) : true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,10 +51,6 @@ public class MessageCraftingMonitorElements implements IMessage, IMessageHandler
|
||||
for (ICraftingTask task : craftingMonitor.getTasks()) {
|
||||
ItemStack stack = task.getRequested();
|
||||
|
||||
if (!craftingMonitor.canViewAutomated() && task.isAutomated()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (stack == null || GridFilterFilter.accepts(craftingMonitor.getFilters(), stack, Item.REGISTRY.getNameForObject(stack.getItem()).getResourceDomain())) {
|
||||
elements.addAll(task.getCraftingMonitorElements());
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@ import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class MessageGridItemUpdate implements IMessage, IMessageHandler<MessageGridItemUpdate, IMessage> {
|
||||
@@ -33,7 +32,7 @@ public class MessageGridItemUpdate implements IMessage, IMessageHandler<MessageG
|
||||
int size = network.getItemStorageCache().getList().getStacks().size();
|
||||
|
||||
for (ICraftingPattern pattern : network.getCraftingManager().getPatterns()) {
|
||||
size += pattern.getOutputs().stream().filter(Objects::nonNull).count();
|
||||
size += pattern.getOutputs().size();
|
||||
}
|
||||
|
||||
buf.writeInt(size);
|
||||
@@ -51,7 +50,6 @@ public class MessageGridItemUpdate implements IMessage, IMessageHandler<MessageG
|
||||
|
||||
for (ICraftingPattern pattern : network.getCraftingManager().getPatterns()) {
|
||||
for (ItemStack output : pattern.getOutputs()) {
|
||||
if (output != null) {
|
||||
StackUtils.writeItemStack(buf, output, network, true);
|
||||
|
||||
IStorageTracker.IStorageTrackerEntry entry = network.getItemStorageTracker().get(output);
|
||||
@@ -62,7 +60,6 @@ public class MessageGridItemUpdate implements IMessage, IMessageHandler<MessageG
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.canCraft = canCraft;
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
package com.raoulvdberge.refinedstorage.network;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.container.ContainerCraftingMonitor;
|
||||
import com.raoulvdberge.refinedstorage.item.ItemWirelessCraftingMonitor;
|
||||
import com.raoulvdberge.refinedstorage.tile.craftingmonitor.ICraftingMonitor;
|
||||
import com.raoulvdberge.refinedstorage.tile.craftingmonitor.WirelessCraftingMonitor;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
|
||||
|
||||
public class MessageWirelessCraftingMonitorViewAutomated extends MessageHandlerPlayerToServer<MessageWirelessCraftingMonitorViewAutomated> implements IMessage {
|
||||
private boolean viewAutomated;
|
||||
|
||||
public MessageWirelessCraftingMonitorViewAutomated() {
|
||||
}
|
||||
|
||||
public MessageWirelessCraftingMonitorViewAutomated(boolean viewAutomated) {
|
||||
this.viewAutomated = viewAutomated;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fromBytes(ByteBuf buf) {
|
||||
viewAutomated = buf.readBoolean();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toBytes(ByteBuf buf) {
|
||||
buf.writeBoolean(viewAutomated);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(MessageWirelessCraftingMonitorViewAutomated message, EntityPlayerMP player) {
|
||||
if (player.openContainer instanceof ContainerCraftingMonitor) {
|
||||
ICraftingMonitor craftingMonitor = ((ContainerCraftingMonitor) player.openContainer).getCraftingMonitor();
|
||||
|
||||
if (craftingMonitor instanceof WirelessCraftingMonitor) {
|
||||
ItemStack stack = ((WirelessCraftingMonitor) craftingMonitor).getStack();
|
||||
|
||||
ItemWirelessCraftingMonitor.setViewAutomated(stack, message.viewAutomated);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -137,7 +137,6 @@ public class ProxyCommon {
|
||||
RS.INSTANCE.network.registerMessage(MessageReaderWriterChannelRemove.class, MessageReaderWriterChannelRemove.class, id++, Side.SERVER);
|
||||
RS.INSTANCE.network.registerMessage(MessageSecurityManagerUpdate.class, MessageSecurityManagerUpdate.class, id++, Side.SERVER);
|
||||
RS.INSTANCE.network.registerMessage(MessageWirelessFluidGridSettingsUpdate.class, MessageWirelessFluidGridSettingsUpdate.class, id++, Side.SERVER);
|
||||
RS.INSTANCE.network.registerMessage(MessageWirelessCraftingMonitorViewAutomated.class, MessageWirelessCraftingMonitorViewAutomated.class, id++, Side.SERVER);
|
||||
RS.INSTANCE.network.registerMessage(MessageCrafterManagerSlotSizes.class, MessageCrafterManagerSlotSizes.class, id++, Side.CLIENT);
|
||||
RS.INSTANCE.network.registerMessage(MessageCrafterManagerRequestSlotData.class, MessageCrafterManagerRequestSlotData.class, id++, Side.SERVER);
|
||||
|
||||
|
||||
@@ -27,10 +27,6 @@ public interface ICraftingMonitor {
|
||||
|
||||
ItemHandlerBase getFilter();
|
||||
|
||||
boolean canViewAutomated();
|
||||
|
||||
void onViewAutomatedChanged(boolean viewAutomated);
|
||||
|
||||
boolean isActive();
|
||||
|
||||
void onClosed(EntityPlayer player);
|
||||
|
||||
@@ -1,31 +1,13 @@
|
||||
package com.raoulvdberge.refinedstorage.tile.craftingmonitor;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.api.network.INetwork;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.network.node.NetworkNodeCraftingMonitor;
|
||||
import com.raoulvdberge.refinedstorage.tile.TileNode;
|
||||
import com.raoulvdberge.refinedstorage.tile.data.TileDataParameter;
|
||||
import net.minecraft.network.datasync.DataSerializers;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class TileCraftingMonitor extends TileNode<NetworkNodeCraftingMonitor> {
|
||||
public static final TileDataParameter<Boolean, TileCraftingMonitor> VIEW_AUTOMATED = new TileDataParameter<>(DataSerializers.BOOLEAN, true, t -> t.getNode().canViewAutomated(), (t, v) -> {
|
||||
t.getNode().setViewAutomated(v);
|
||||
t.getNode().markDirty();
|
||||
|
||||
INetwork network = t.getNode().getNetwork();
|
||||
|
||||
if (network != null) {
|
||||
network.getCraftingManager().sendCraftingMonitorUpdate();
|
||||
}
|
||||
});
|
||||
|
||||
public TileCraftingMonitor() {
|
||||
dataManager.addWatchedParameter(VIEW_AUTOMATED);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public NetworkNodeCraftingMonitor createNode(World world, BlockPos pos) {
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
package com.raoulvdberge.refinedstorage.tile.craftingmonitor;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.RS;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTask;
|
||||
import com.raoulvdberge.refinedstorage.api.network.INetwork;
|
||||
import com.raoulvdberge.refinedstorage.api.util.IFilter;
|
||||
import com.raoulvdberge.refinedstorage.inventory.ItemHandlerBase;
|
||||
import com.raoulvdberge.refinedstorage.inventory.ItemHandlerFilter;
|
||||
import com.raoulvdberge.refinedstorage.item.ItemWirelessCraftingMonitor;
|
||||
import com.raoulvdberge.refinedstorage.network.MessageWirelessCraftingMonitorViewAutomated;
|
||||
import com.raoulvdberge.refinedstorage.tile.data.TileDataParameter;
|
||||
import com.raoulvdberge.refinedstorage.util.StackUtils;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
@@ -29,8 +27,6 @@ public class WirelessCraftingMonitor implements ICraftingMonitor {
|
||||
private int networkDimension;
|
||||
private BlockPos network;
|
||||
|
||||
private boolean viewAutomated;
|
||||
|
||||
private List<IFilter> filters = new ArrayList<>();
|
||||
private ItemHandlerFilter filter = new ItemHandlerFilter(filters, new ArrayList<>(), null) {
|
||||
@Override
|
||||
@@ -55,7 +51,6 @@ public class WirelessCraftingMonitor implements ICraftingMonitor {
|
||||
this.stack = stack;
|
||||
this.networkDimension = networkDimension;
|
||||
this.network = new BlockPos(ItemWirelessCraftingMonitor.getX(stack), ItemWirelessCraftingMonitor.getY(stack), ItemWirelessCraftingMonitor.getZ(stack));
|
||||
this.viewAutomated = ItemWirelessCraftingMonitor.canViewAutomated(stack);
|
||||
|
||||
if (stack.hasTagCompound()) {
|
||||
StackUtils.readItems(filter, 0, stack.getTagCompound());
|
||||
@@ -107,18 +102,6 @@ public class WirelessCraftingMonitor implements ICraftingMonitor {
|
||||
return filter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canViewAutomated() {
|
||||
return viewAutomated;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewAutomatedChanged(boolean viewAutomated) {
|
||||
RS.INSTANCE.network.sendToServer(new MessageWirelessCraftingMonitorViewAutomated(viewAutomated));
|
||||
|
||||
this.viewAutomated = viewAutomated;
|
||||
}
|
||||
|
||||
private INetwork getNetwork() {
|
||||
World world = DimensionManager.getWorld(networkDimension);
|
||||
|
||||
|
||||
@@ -80,10 +80,6 @@ public class TileGrid extends TileNode<NetworkNodeGrid> {
|
||||
((ContainerGrid) player.openContainer).sendAllSlots();
|
||||
});
|
||||
}, (initial, p) -> GuiBase.executeLater(GuiGrid.class, GuiBase::initGui));
|
||||
public static final TileDataParameter<Boolean, TileGrid> BLOCKING_PATTERN = new TileDataParameter<>(DataSerializers.BOOLEAN, false, t -> t.getNode().isBlockingPattern(), (t, v) -> {
|
||||
t.getNode().setBlockingPattern(v);
|
||||
t.getNode().markDirty();
|
||||
}, (initial, p) -> GuiBase.executeLater(GuiGrid.class, grid -> grid.updateBlockingPattern(p)));
|
||||
|
||||
public static void trySortGrid(boolean initial) {
|
||||
if (!initial) {
|
||||
@@ -101,7 +97,6 @@ public class TileGrid extends TileNode<NetworkNodeGrid> {
|
||||
dataManager.addWatchedParameter(TAB_PAGE);
|
||||
dataManager.addWatchedParameter(OREDICT_PATTERN);
|
||||
dataManager.addWatchedParameter(PROCESSING_PATTERN);
|
||||
dataManager.addWatchedParameter(BLOCKING_PATTERN);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.raoulvdberge.refinedstorage.util;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
@@ -11,11 +12,13 @@ import net.minecraft.client.renderer.texture.TextureMap;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.RayTraceResult;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.util.text.TextFormatting;
|
||||
import net.minecraftforge.common.model.TRSRTransformation;
|
||||
import net.minecraftforge.fluids.Fluid;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
@@ -23,6 +26,9 @@ import net.minecraftforge.fluids.FluidStack;
|
||||
import javax.vecmath.Matrix4f;
|
||||
import javax.vecmath.Vector3f;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public final class RenderUtils {
|
||||
public static final Matrix4f EMPTY_MATRIX_TRANSFORM = getTransform(0, 0, 0, 0, 0, 0, 1.0f).getMatrix();
|
||||
@@ -294,4 +300,30 @@ public final class RenderUtils {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void addCombinedItemsToTooltip(List<String> tooltip, boolean displayAmount, List<ItemStack> stacks) {
|
||||
Set<Integer> combinedIndices = new HashSet<>();
|
||||
|
||||
for (int i = 0; i < stacks.size(); ++i) {
|
||||
if (!stacks.get(i).isEmpty() && !combinedIndices.contains(i)) {
|
||||
ItemStack stack = stacks.get(i);
|
||||
|
||||
String data = stack.getDisplayName();
|
||||
|
||||
int amount = stack.getCount();
|
||||
|
||||
for (int j = i + 1; j < stacks.size(); ++j) {
|
||||
if (API.instance().getComparer().isEqual(stack, stacks.get(j))) {
|
||||
amount += stacks.get(j).getCount();
|
||||
|
||||
combinedIndices.add(j);
|
||||
}
|
||||
}
|
||||
|
||||
data = (displayAmount ? (TextFormatting.WHITE + String.valueOf(amount) + " ") : "") + TextFormatting.GRAY + data;
|
||||
|
||||
tooltip.add(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.raoulvdberge.refinedstorage.util;
|
||||
import com.raoulvdberge.refinedstorage.api.network.INetwork;
|
||||
import com.raoulvdberge.refinedstorage.api.storage.IStorageDisk;
|
||||
import com.raoulvdberge.refinedstorage.api.storage.IStorageDiskProvider;
|
||||
import com.raoulvdberge.refinedstorage.api.util.IComparer;
|
||||
import com.raoulvdberge.refinedstorage.api.util.IStackList;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
@@ -110,7 +111,7 @@ public final class StackUtils {
|
||||
buf.writeInt(API.instance().getItemStackHashCode(stack));
|
||||
|
||||
if (network != null) {
|
||||
buf.writeBoolean(network.getCraftingManager().hasPattern(stack));
|
||||
buf.writeBoolean(network.getCraftingManager().getPattern(stack, IComparer.COMPARE_DAMAGE | IComparer.COMPARE_NBT) != null);
|
||||
buf.writeBoolean(displayCraftText);
|
||||
} else {
|
||||
buf.writeBoolean(false);
|
||||
@@ -160,18 +161,6 @@ public final class StackUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static NonNullList<ItemStack> toNonNullList(List<ItemStack> list) {
|
||||
NonNullList<ItemStack> other = NonNullList.create();
|
||||
|
||||
for (ItemStack item : list) {
|
||||
if (item != null) {
|
||||
other.add(item);
|
||||
}
|
||||
}
|
||||
|
||||
return other;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> NonNullList<T> emptyNonNullList() {
|
||||
return (NonNullList<T>) EMPTY_NON_NULL_LIST;
|
||||
|
||||
@@ -110,7 +110,6 @@ misc.refinedstorage:set=Set
|
||||
misc.refinedstorage:cancel_all=Cancel All
|
||||
misc.refinedstorage:priority=Priority
|
||||
misc.refinedstorage:oredict=Oredict
|
||||
misc.refinedstorage:blocking=Blocking
|
||||
misc.refinedstorage:processing=Processing
|
||||
|
||||
misc.refinedstorage:reader_writer.redstone=Redstone strength: %d
|
||||
@@ -164,8 +163,6 @@ sidebutton.refinedstorage:grid.size.1=Small
|
||||
sidebutton.refinedstorage:grid.size.2=Medium
|
||||
sidebutton.refinedstorage:grid.size.3=Large
|
||||
|
||||
sidebutton.refinedstorage:crafting_monitor.view_automated=View automated tasks
|
||||
|
||||
sidebutton.refinedstorage:mode=Mode
|
||||
sidebutton.refinedstorage:mode.whitelist=Whitelist
|
||||
sidebutton.refinedstorage:mode.blacklist=Blacklist
|
||||
|
||||
@@ -109,7 +109,6 @@ misc.refinedstorage:set=Poner
|
||||
misc.refinedstorage:cancel_all=Cancelar todo
|
||||
misc.refinedstorage:priority=Prioridad
|
||||
misc.refinedstorage:oredict=Diccionario de minerales
|
||||
misc.refinedstorage:blocking=Bloqueo
|
||||
misc.refinedstorage:processing=Procesándose
|
||||
|
||||
misc.refinedstorage:reader_writer.redstone=Fuerza de señal: %d
|
||||
@@ -163,8 +162,6 @@ sidebutton.refinedstorage:grid.size.1=Pequeño
|
||||
sidebutton.refinedstorage:grid.size.2=Mediano
|
||||
sidebutton.refinedstorage:grid.size.3=largo
|
||||
|
||||
sidebutton.refinedstorage:crafting_monitor.view_automated=Ver tareas automatizadas
|
||||
|
||||
sidebutton.refinedstorage:mode=Modo
|
||||
sidebutton.refinedstorage:mode.whitelist=Permitido
|
||||
sidebutton.refinedstorage:mode.blacklist=No permitido
|
||||
|
||||
@@ -104,7 +104,6 @@ misc.refinedstorage:set=Fixer
|
||||
misc.refinedstorage:cancel_all=Tout annuler
|
||||
misc.refinedstorage:priority=Priorité
|
||||
misc.refinedstorage:oredict=Oredict
|
||||
misc.refinedstorage:blocking=Blocker
|
||||
misc.refinedstorage:processing=En Traitement
|
||||
|
||||
misc.refinedstorage:reader_writer.redstone=Redstone strength: %d
|
||||
@@ -140,8 +139,6 @@ sidebutton.refinedstorage:grid.size.1=Petit
|
||||
sidebutton.refinedstorage:grid.size.2=Moyen
|
||||
sidebutton.refinedstorage:grid.size.3=Grand
|
||||
|
||||
sidebutton.refinedstorage:crafting_monitor.view_automated=Vue des tâches automatisées
|
||||
|
||||
sidebutton.refinedstorage:mode=Mode
|
||||
sidebutton.refinedstorage:mode.whitelist=Liste blanche
|
||||
sidebutton.refinedstorage:mode.blacklist=Liste noire
|
||||
|
||||
@@ -103,7 +103,6 @@ misc.refinedstorage:set=설정
|
||||
misc.refinedstorage:cancel_all=모두 취소
|
||||
misc.refinedstorage:priority=우선 순위
|
||||
misc.refinedstorage:oredict=Ore Dictionary
|
||||
misc.refinedstorage:blocking=Blocking
|
||||
|
||||
misc.refinedstorage:reader_writer.redstone=레드스톤 강도: %d
|
||||
|
||||
@@ -138,8 +137,6 @@ sidebutton.refinedstorage:grid.size.1=작음
|
||||
sidebutton.refinedstorage:grid.size.2=중간
|
||||
sidebutton.refinedstorage:grid.size.3=큼
|
||||
|
||||
sidebutton.refinedstorage:crafting_monitor.view_automated=자동으로 시작된 작업 보기
|
||||
|
||||
sidebutton.refinedstorage:mode=모드
|
||||
sidebutton.refinedstorage:mode.whitelist=화이트리스트
|
||||
sidebutton.refinedstorage:mode.blacklist=블랙리스트
|
||||
|
||||
@@ -104,7 +104,6 @@ misc.refinedstorage:set=Definir
|
||||
misc.refinedstorage:cancel_all=Cancelar tudo
|
||||
misc.refinedstorage:priority=Prioridade
|
||||
misc.refinedstorage:oredict=Oredict
|
||||
misc.refinedstorage:blocking=Bloqueio
|
||||
misc.refinedstorage:processing=Processamento
|
||||
|
||||
misc.refinedstorage:reader_writer.redstone=Força de redstone: %d
|
||||
@@ -141,8 +140,6 @@ sidebutton.refinedstorage:grid.size.1=Pequeno
|
||||
sidebutton.refinedstorage:grid.size.2=Médio
|
||||
sidebutton.refinedstorage:grid.size.3=Grande
|
||||
|
||||
sidebutton.refinedstorage:crafting_monitor.view_automated=Ver tarefas automatizadas
|
||||
|
||||
sidebutton.refinedstorage:mode=Modo
|
||||
sidebutton.refinedstorage:mode.whitelist=Lista branca
|
||||
sidebutton.refinedstorage:mode.blacklist=Lista negra
|
||||
|
||||
@@ -110,7 +110,6 @@ misc.refinedstorage:set=Установить
|
||||
misc.refinedstorage:cancel_all=Отменить все
|
||||
misc.refinedstorage:priority=Приоритет
|
||||
misc.refinedstorage:oredict=Словарь руды
|
||||
misc.refinedstorage:blocking=Блокировка
|
||||
misc.refinedstorage:processing=Обработка
|
||||
|
||||
misc.refinedstorage:reader_writer.redstone=Сила красного камня: %d
|
||||
@@ -164,8 +163,6 @@ sidebutton.refinedstorage:grid.size.1=Маленький
|
||||
sidebutton.refinedstorage:grid.size.2=Средний
|
||||
sidebutton.refinedstorage:grid.size.3=Большой
|
||||
|
||||
sidebutton.refinedstorage:crafting_monitor.view_automated=Просмотр автоматизированных задач
|
||||
|
||||
sidebutton.refinedstorage:mode=Режим
|
||||
sidebutton.refinedstorage:mode.whitelist=Белый список
|
||||
sidebutton.refinedstorage:mode.blacklist=Черный список
|
||||
|
||||
@@ -105,7 +105,6 @@ misc.refinedstorage:set=设置
|
||||
misc.refinedstorage:cancel_all=取消所有
|
||||
misc.refinedstorage:priority=优先级
|
||||
misc.refinedstorage:oredict=矿物辞典
|
||||
misc.refinedstorage:blocking=阻塞中
|
||||
misc.refinedstorage:processing=进行中
|
||||
|
||||
misc.refinedstorage:reader_writer.redstone=红石强度:%d
|
||||
@@ -142,8 +141,6 @@ sidebutton.refinedstorage:grid.size.1=小
|
||||
sidebutton.refinedstorage:grid.size.2=中
|
||||
sidebutton.refinedstorage:grid.size.3=大
|
||||
|
||||
sidebutton.refinedstorage:crafting_monitor.view_automated=查看自动化进程
|
||||
|
||||
sidebutton.refinedstorage:mode=模式
|
||||
sidebutton.refinedstorage:mode.whitelist=白名单
|
||||
sidebutton.refinedstorage:mode.blacklist=黑名单
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
Reference in New Issue
Block a user