public UnfulfilledNode(int item, int stack, int ChildNumber, CraftPathNode parent, CraftPath craftPath) : base(ChildNumber, parent, craftPath) { this.stack = stack; this.item = new List <int>() { item }; }
internal virtual CraftPathNode Clone() { CraftPathNode clone = (CraftPathNode)this.MemberwiseClone(); clone.parent = null; clone.craftPath = null; clone.children = children?.Select(x => x?.Clone()).ToArray(); return(clone); }
// internal static CraftPath public CraftPath(Recipe root, Dictionary <int, int> haveItems) { this.haveItems = haveItems; // 1 for now. current = null; this.root = new RecipeNode(root, 1, -1, null, this); // current = (UnfulfilledNode)this.root.children[0]; ConsumeResources(this.root); }
internal void Push(UnfulfilledNode current, CraftPathNode buyItemNode) { this.current = null; current.parent = null; current.ChildNumber = -1; // Consume ConsumeResources(buyItemNode); // consumes money from savings }
public CraftPathNode(int childNumber, CraftPathNode parent, CraftPath craftPath) { ChildNumber = childNumber; this.parent = parent; this.craftPath = craftPath; if (parent != null) { parent.children[ChildNumber] = this; } }
internal void Pop(UnfulfilledNode current, CraftPathNode recipeNode) { // Swap out Edges this.current = current; current.parent = recipeNode.parent; current.ChildNumber = recipeNode.ChildNumber; current.parent.children[current.ChildNumber] = current; //Utils.Swap(ref ) recipeNode.parent = null; recipeNode.ChildNumber = -1; // invalid, should be GCed. // UnConsume UnConsumeResources(recipeNode); // unconsumes items from haveItems }
private void UnConsumeResources(CraftPathNode craftPathNode) { craftPathNode.UnConsumeResources(this); //BuyItemNode buyItemNode = recipeNode as BuyItemNode; //if (buyItemNode != null) //{ // buyItemNode.ConsumeMoney(this); //} //if (recipeNode.children != null) // foreach (var item in recipeNode.children) // { // HaveItemNode haveItemNode = item as HaveItemNode; // if (haveItemNode != null) // { // haveItemNode.UnConsumeItems(this); // } // } }
public RecipeNode(Recipe recipe, int multiplier, int ChildNumber, CraftPathNode parent, CraftPath craftPath) : base(ChildNumber, parent, craftPath) { this.recipe = recipe; this.multiplier = multiplier; children = new CraftPathNode[recipe.requiredItem.Count(x => !x.IsAir)]; List <int> groups = RecipePath.GetAcceptedGroups(recipe); for (int i = 0; i < children.Length; i++) // For Each Ingredient. { bool itemIsRecipeGroupItem = false; foreach (var groupid in groups) { // 6 wood, 4 shadewood works for 10 any wood. // multiplier assumes all same Item in ItemGroup used for all Recipes. if (recipe.requiredItem[i].type == RecipeGroup.recipeGroups[groupid].ValidItems[RecipeGroup.recipeGroups[groupid].IconicItemIndex]) { bool foundValidItem = false; bool foundPartialItem = false; foreach (var validItemID in RecipeGroup.recipeGroups[groupid].ValidItems) { if (craftPath.haveItems.ContainsKey(validItemID) && craftPath.haveItems[validItemID] >= recipe.requiredItem[i].stack * multiplier) { // Any Wood on left, Wood on Right problem. Wood could be consumed before Wood node, when ShadeWood would be better option. children[i] = new HaveItemNode(validItemID, recipe.requiredItem[i].stack * multiplier, i, this, craftPath); foundValidItem = true; break; } else if (craftPath.haveItems.ContainsKey(validItemID)) { foundPartialItem = true; } } if (!foundValidItem && foundPartialItem) { List <Tuple <int, int> > listOfItems = new List <Tuple <int, int> >(); int remaining = recipe.requiredItem[i].stack * multiplier; foreach (var validItemID in RecipeGroup.recipeGroups[groupid].ValidItems) { if (remaining > 0 && craftPath.haveItems.ContainsKey(validItemID)) { int taken = Math.Min(remaining, craftPath.haveItems[validItemID]); listOfItems.Add(new Tuple <int, int>(validItemID, taken)); remaining -= taken; } } children[i] = new HaveItemsNode(RecipeGroup.recipeGroups[groupid], listOfItems, i, this, craftPath); if (remaining > 0) { children[i].children = new CraftPathNode[1]; children[i].children[0] = new UnfulfilledNode(RecipeGroup.recipeGroups[groupid], remaining, 0, children[i], craftPath); } } else if (!foundValidItem) { children[i] = new UnfulfilledNode(RecipeGroup.recipeGroups[groupid], recipe.requiredItem[i].stack * multiplier, i, this, craftPath); } itemIsRecipeGroupItem = true; break; } } // Does it make more sense to nest these, or add more children slots? Hm, Children match up to recipe ingredient index.... Make a BranchNode? if (!itemIsRecipeGroupItem) { // Recipe Groups can have stacks-size different inputs if needed. Ignore for now and handle: 10 wood needed, 9 wood held and 2 platforms held. if (craftPath.haveItems.ContainsKey(recipe.requiredItem[i].type) && craftPath.haveItems[recipe.requiredItem[i].type] >= recipe.requiredItem[i].stack * multiplier) { // Potential problem: Recipe with multiple of same item. Or Item and ItemGroup that share. // Could implement consumed flag and attempt to consume immediately. children[i] = new HaveItemNode(recipe.requiredItem[i].type, recipe.requiredItem[i].stack * multiplier, i, this, craftPath); } else { if (craftPath.haveItems.ContainsKey(recipe.requiredItem[i].type)) { int remainder = recipe.requiredItem[i].stack * multiplier - craftPath.haveItems[recipe.requiredItem[i].type]; children[i] = new HaveItemNode(recipe.requiredItem[i].type, craftPath.haveItems[recipe.requiredItem[i].type], i, this, craftPath); children[i].children = new CraftPathNode[1]; children[i].children[0] = new UnfulfilledNode(recipe.requiredItem[i].type, remainder, 0, children[i], craftPath); } else { children[i] = new UnfulfilledNode(recipe.requiredItem[i].type, recipe.requiredItem[i].stack * multiplier, i, this, craftPath); // assign current? } } } // TODO: Assign CraftPath.Current to 1st or last unfulfilled // TODO: If Loot and Shop and Missing disabled, check // if (RecipePath.isCraftableOptimization && !ItemCatalogueUI.instance.craftResults[item.Key]) } }
public UnfulfilledNode(RecipeGroup recipeGroup, int stack, int ChildNumber, CraftPathNode parent, CraftPath craftPath) : base(ChildNumber, parent, craftPath) { this.recipeGroup = recipeGroup; this.item = recipeGroup.ValidItems; this.stack = stack; // recipeGroup.ContainsItem probably faster than iterating over item? }
public LootItemNode(int itemid, int stack, int ChildNumber, CraftPathNode parent, CraftPath craftPath) : base(ChildNumber, parent, craftPath) { this.itemid = itemid; this.stack = stack; }
public HaveItemsNode(RecipeGroup recipeGroup, List <Tuple <int, int> > listOfItems, int ChildNumber, CraftPathNode parent, CraftPath craftPath) : base(ChildNumber, parent, craftPath) { this.recipeGroup = recipeGroup; this.listOfItems = listOfItems; }