public override void DoSmelt(IWorldAccessor world, ISlotProvider cookingSlotsProvider, IItemSlot inputSlot, IItemSlot outputSlot)
        {
            ItemStack[] stacks = GetCookingStacks(cookingSlotsProvider);

            CookingRecipe recipe = GetMatchingCookingRecipe(world, stacks);

            Block     block       = world.GetBlock(CodeWithPath(FirstCodePart() + "-cooked"));
            ItemStack outputStack = new ItemStack(block);

            if (recipe != null)
            {
                int quantityServings = recipe.GetQuantityServings(stacks);
                for (int i = 0; i < stacks.Length; i++)
                {
                    stacks[i].StackSize /= quantityServings;
                }
                // Not active. Let's sacrifice mergability for letting players select how meals should look and named like
                //stacks = stacks.OrderBy(stack => stack.Collectible.Code.ToShortString()).ToArray(); // Required so that different arrangments of ingredients still create mergable meal bowls

                ((BlockCookedContainer)block).SetContents(recipe.Code, quantityServings, outputStack, stacks);

                outputStack.Collectible.SetTemperature(world, outputStack, GetIngredientsTemperature(world, stacks));
                outputSlot.Itemstack = outputStack;
                inputSlot.Itemstack  = null;

                for (int i = 0; i < cookingSlotsProvider.Slots.Length; i++)
                {
                    cookingSlotsProvider.Slots[i].Itemstack = null;
                }
                return;
            }
        }
예제 #2
0
        public override void DoSmelt(IWorldAccessor world, ISlotProvider cookingSlotsProvider, ItemSlot inputSlot, ItemSlot outputSlot)
        {
            ItemStack[] stacks = GetCookingStacks(cookingSlotsProvider);

            CookingRecipe recipe = GetMatchingCookingRecipe(world, stacks);

            Block     block       = world.GetBlock(CodeWithPath(CodeWithoutParts(1) + "-cooked"));
            ItemStack outputStack = new ItemStack(block);

            if (recipe != null)
            {
                int quantityServings = recipe.GetQuantityServings(stacks);
                for (int i = 0; i < stacks.Length; i++)
                {
                    stacks[i].StackSize /= quantityServings;
                }

                ((BlockCookedContainer)block).SetContents(recipe.Code, quantityServings, outputStack, stacks);

                outputStack.Collectible.SetTemperature(world, outputStack, GetIngredientsTemperature(world, stacks));
                outputSlot.Itemstack = outputStack;
                inputSlot.Itemstack  = null;

                for (int i = 0; i < cookingSlotsProvider.Slots.Length; i++)
                {
                    cookingSlotsProvider.Slots[i].Itemstack = null;
                }
                return;
            }
        }
예제 #3
0
        public override float GetMeltingDuration(IWorldAccessor world, ISlotProvider cookingSlotsProvider, ItemSlot inputSlot)
        {
            float duration = 0;

            ItemStack[] stacks = GetCookingStacks(cookingSlotsProvider, false);
            for (int i = 0; i < stacks.Length; i++)
            {
                var stack       = stacks[i];
                int portionSize = stack.StackSize;

                if (stack.Collectible?.CombustibleProps == null)
                {
                    if (stack.Collectible.Attributes?["waterTightContainerProps"].Exists == true)
                    {
                        var props = BlockLiquidContainerBase.GetContainableProps(stack);
                        portionSize = (int)(stack.StackSize / props.ItemsPerLitre);
                    }

                    duration += 20 * portionSize;
                    continue;
                }

                float singleDuration = stack.Collectible.GetMeltingDuration(world, cookingSlotsProvider, inputSlot);
                duration += singleDuration * portionSize / stack.Collectible.CombustibleProps.SmeltedRatio;
            }

            duration = Math.Max(40, duration / 3);

            return(duration);
        }
예제 #4
0
        public string GetOutputText(IWorldAccessor world, ISlotProvider cookingSlotsProvider, ItemSlot inputSlot)
        {
            if (inputSlot.Itemstack == null)
            {
                return(null);
            }
            if (!(inputSlot.Itemstack.Collectible is BlockCookingContainer))
            {
                return(null);
            }

            ItemStack[] stacks = GetCookingStacks(cookingSlotsProvider);

            CookingRecipe recipe = GetMatchingCookingRecipe(world, stacks);

            if (recipe != null)
            {
                double quantity = recipe.GetQuantityServings(stacks);
                if (quantity != 1)
                {
                    return(Lang.Get("mealcreation-makeplural", (int)quantity, recipe.GetOutputName(world, stacks).ToLowerInvariant()));
                }
                else
                {
                    return(Lang.Get("mealcreation-makesingular", (int)quantity, recipe.GetOutputName(world, stacks).ToLowerInvariant()));
                }
            }

            return(null);
        }
예제 #5
0
        public ItemStack[] GetIngredients(IWorldAccessor world, ISlotProvider cookingSlotsProvider)
        {
            ItemStack[] stacks = new ItemStack[cookingSlotsProvider.Slots.Length];

            for (int i = 0; i < stacks.Length; i++)
            {
                stacks[i] = cookingSlotsProvider.Slots[i].Itemstack;
            }

            return(stacks);
        }
예제 #6
0
        public override float GetMeltingPoint(IWorldAccessor world, ISlotProvider cookingSlotsProvider, ItemSlot inputSlot)
        {
            float meltpoint = 0;

            ItemStack[] stacks = GetCookingStacks(cookingSlotsProvider, false);
            for (int i = 0; i < stacks.Length; i++)
            {
                meltpoint = Math.Max(meltpoint, stacks[i].Collectible.GetMeltingPoint(world, cookingSlotsProvider, inputSlot));
            }

            return(Math.Max(100, meltpoint));
        }
예제 #7
0
        public override bool CanSmelt(IWorldAccessor world, ISlotProvider cookingSlotsProvider, ItemStack inputStack, ItemStack outputStack)
        {
            ItemStack[] stacks = GetCookingStacks(cookingSlotsProvider, false);

            // Got recipe?
            if (GetMatchingCookingRecipe(world, stacks) != null)
            {
                return(true);
            }

            return(false);
        }
예제 #8
0
        public void CalculateSelectedGameObject()
        {
            // Tells the CompositeItemSelector that we want to render the meshes in OnPostRender, so
            // that we can use that texture to determine the examinable.
            setPostRender = true;

            // Identify if mouse is over the user interface, or over objects in the game world.
            if (EventSystem.current.IsPointerOverGameObject())
            {
                // The cursor is over the UI. If the UI is examinable, this will override objects in the game world.
                mouseOverUI       = true;
                currentExaminable = null;

                // Get a list of all the UI elements under the cursor
                var pointerEventData = new PointerEventData(EventSystem.current)
                {
                    position = Input.mousePosition
                };
                List <RaycastResult> UIhits = new List <RaycastResult>();
                EventSystem.current.RaycastAll(pointerEventData, UIhits);

                // Get the UI to give us the GameObject that a slot is displaying.
                foreach (var hit in UIhits)
                {
                    ISlotProvider slot = hit.gameObject.GetComponent <ISlotProvider>();
                    if (slot != null)
                    {
                        currentExaminable = slot.GetCurrentGameObjectInSlot();
                    }
                }
            }
            else
            {
                mouseOverUI = false;
            }

            // Raycast to cursor position. Need to get all possible hits, because the initial hit may have gaps through which we can see other Examinables
            Ray ray = cam.ScreenPointToRay(new Vector2(Input.mousePosition.x, Input.mousePosition.y));

            RaycastHit[] hits = Physics.RaycastAll(ray, 200f);

            // Convert the RaycastHits to GameObjects
            GameObject[] gameObjects = new GameObject[hits.Length];
            for (int i = 0; i < hits.Length; i++)
            {
                gameObjects[i] = hits[i].transform.gameObject;
            }

            // Store the meshes of these GameObjects in our data structure, so that they can be rendered off-screen later.
            AddMeshesToLists(gameObjects);
        }
예제 #9
0
        public override void DoSmelt(IWorldAccessor world, ISlotProvider cookingSlotsProvider, ItemSlot inputSlot, ItemSlot outputSlot)
        {
            ItemStack[]   stacks = GetCookingStacks(cookingSlotsProvider);
            CookingRecipe recipe = GetMatchingCookingRecipe(world, stacks);

            Block     block       = world.GetBlock(CodeWithVariant("type", "cooked"));
            ItemStack outputStack = new ItemStack(block);

            if (recipe != null)
            {
                int quantityServings = recipe.GetQuantityServings(stacks);

                for (int i = 0; i < stacks.Length; i++)
                {
                    CookingRecipeIngredient ingred = recipe.GetIngrendientFor(stacks[i]);
                    ItemStack cookedStack          = ingred.GetMatchingStack(stacks[i])?.CookedStack?.ResolvedItemstack.Clone();
                    if (cookedStack != null)
                    {
                        stacks[i] = cookedStack;
                    }
                }

                // Carry over and set perishable properties
                TransitionableProperties cookedPerishProps = recipe.PerishableProps.Clone();
                cookedPerishProps.TransitionedStack.Resolve(world, "cooking container perished stack");

                CarryOverFreshness(api, cookingSlotsProvider.Slots, stacks, cookedPerishProps);

                for (int i = 0; i < stacks.Length; i++)
                {
                    stacks[i].StackSize /= quantityServings; // whats this good for? Probably doesn't do anything meaningful
                }



                // Disabled. Let's sacrifice mergability for letting players select how meals should look and be named like
                //stacks = stacks.OrderBy(stack => stack.Collectible.Code.ToShortString()).ToArray(); // Required so that different arrangments of ingredients still create mergable meal bowls

                ((BlockCookedContainer)block).SetContents(recipe.Code, quantityServings, outputStack, stacks);

                outputStack.Collectible.SetTemperature(world, outputStack, GetIngredientsTemperature(world, stacks));
                outputSlot.Itemstack = outputStack;
                inputSlot.Itemstack  = null;

                for (int i = 0; i < cookingSlotsProvider.Slots.Length; i++)
                {
                    cookingSlotsProvider.Slots[i].Itemstack = null;
                }
                return;
            }
        }
예제 #10
0
        public ItemStack[] GetCookingStacks(ISlotProvider cookingSlotsProvider, bool clone = true)
        {
            List <ItemStack> stacks = new List <ItemStack>(4);

            for (int i = 0; i < cookingSlotsProvider.Slots.Length; i++)
            {
                ItemStack stack = cookingSlotsProvider.Slots[i].Itemstack;
                if (stack == null)
                {
                    continue;
                }
                stacks.Add(clone ? stack.Clone() : stack);
            }

            return(stacks.ToArray());
        }
예제 #11
0
        public override float GetMeltingPoint(IWorldAccessor world, ISlotProvider cookingSlotsProvider, ItemSlot inputSlot)
        {
            float meltpoint = 0;

            ItemStack[] stacks = GetIngredients(world, cookingSlotsProvider);
            for (int i = 0; i < stacks.Length; i++)
            {
                if (stacks[i] == null)
                {
                    continue;
                }

                meltpoint = Math.Max(meltpoint, stacks[i].Collectible.GetMeltingPoint(world, cookingSlotsProvider, inputSlot));
            }

            return(meltpoint);
        }
예제 #12
0
        public override void DoSmelt(IWorldAccessor world, ISlotProvider cookingSlotsProvider, ItemSlot inputSlot, ItemSlot outputSlot)
        {
            ItemStack[] stacks = GetIngredients(world, cookingSlotsProvider);

            AlloyRecipe alloy = GetMatchingAlloy(world, stacks);

            Block     block       = world.GetBlock(CodeWithPath(FirstCodePart() + "-smelted"));
            ItemStack outputStack = new ItemStack(block);

            if (alloy != null)
            {
                ItemStack smeltedStack = alloy.Output.ResolvedItemstack.Clone();
                int       units        = (int)Math.Round(alloy.GetTotalOutputQuantity(stacks) * 100, 4);

                ((BlockSmeltedContainer)block).SetContents(outputStack, smeltedStack, units);
                outputStack.Collectible.SetTemperature(world, outputStack, GetIngredientsTemperature(world, stacks));
                outputSlot.Itemstack = outputStack;
                inputSlot.Itemstack  = null;

                for (int i = 0; i < cookingSlotsProvider.Slots.Length; i++)
                {
                    cookingSlotsProvider.Slots[i].Itemstack = null;
                }


                return;
            }


            MatchedSmeltableStack match = GetSingleSmeltableStack(stacks);

            if (match != null)
            {
                ((BlockSmeltedContainer)block).SetContents(outputStack, match.output, (int)(match.stackSize * 100));
                outputStack.Collectible.SetTemperature(world, outputStack, GetIngredientsTemperature(world, stacks));
                outputSlot.Itemstack = outputStack;
                inputSlot.Itemstack  = null;

                for (int i = 0; i < cookingSlotsProvider.Slots.Length; i++)
                {
                    cookingSlotsProvider.Slots[i].Itemstack = null;
                }
            }
        }
예제 #13
0
        public override float GetMeltingDuration(IWorldAccessor world, ISlotProvider cookingSlotsProvider, ItemSlot inputSlot)
        {
            float duration = 0;

            ItemStack[] stacks = GetIngredients(world, cookingSlotsProvider);
            for (int i = 0; i < stacks.Length; i++)
            {
                if (stacks[i]?.Collectible?.CombustibleProps == null)
                {
                    continue;
                }

                float singleDuration = stacks[i].Collectible.GetMeltingDuration(world, cookingSlotsProvider, inputSlot);

                duration += singleDuration * stacks[i].StackSize / stacks[i].Collectible.CombustibleProps.SmeltedRatio;
            }

            return(duration);
        }
예제 #14
0
    private void Awake()
    {
        //glowAnimator = glow.GetComponent<Animator>();

        foreach (MonoBehaviour mono in GetComponents <MonoBehaviour>())
        {
            if (mono is ISlotProvider)
            {
                if (slotProvider == null)
                {
                    slotProvider = mono as ISlotProvider;
                }
                else
                {
                    Debug.Log("Multiple slot providers found on object " + name + ". Keeping first.");
                }
            }
        }
    }
예제 #15
0
        public string GetOutputText(IWorldAccessor world, ISlotProvider cookingSlotsProvider, ItemSlot inputSlot)
        {
            if (inputSlot.Itemstack == null)
            {
                return(null);
            }

            if (inputSlot.Itemstack.Collectible is BlockSmeltingContainer)
            {
                BlockSmeltingContainer bsc = (BlockSmeltingContainer)inputSlot.Itemstack.Collectible;

                ItemStack[] stacks = bsc.GetIngredients(world, cookingSlotsProvider);

                for (int i = 0; i < stacks.Length; i++)
                {
                    CombustibleProperties props = stacks[i]?.Collectible.CombustibleProps;
                    if (props != null && !props.RequiresContainer)
                    {
                        return(null);
                    }
                }

                AlloyRecipe alloy = bsc.GetMatchingAlloy(world, stacks);

                if (alloy != null)
                {
                    double quantity = alloy.GetTotalOutputQuantity(stacks);
                    return(string.Format("Will create {0} units of {1}", (int)Math.Round(quantity * 100, 4), CheapMetalNameHax(alloy.Output.ResolvedItemstack)));
                }

                MatchedSmeltableStack match = GetSingleSmeltableStack(stacks);
                if (match != null)
                {
                    return(string.Format("Will create {0} units of {1}", (int)Math.Round(match.stackSize * 100, 4), CheapMetalNameHax(match.output)));
                }

                return(null);
            }

            return(null);
        }
예제 #16
0
        public override float GetMeltingDuration(IWorldAccessor world, ISlotProvider cookingSlotsProvider, ItemSlot inputSlot)
        {
            float duration = 0;

            ItemStack[] stacks = GetCookingStacks(cookingSlotsProvider, false);
            for (int i = 0; i < stacks.Length; i++)
            {
                if (stacks[i].Collectible?.CombustibleProps == null)
                {
                    duration += 20 * stacks[i].StackSize;
                    continue;
                }

                float singleDuration = stacks[i].Collectible.GetMeltingDuration(world, cookingSlotsProvider, inputSlot);
                duration += singleDuration * stacks[i].StackSize / stacks[i].Collectible.CombustibleProps.SmeltedRatio;
            }

            duration = Math.Max(40, duration / 3);

            return(duration);
        }
예제 #17
0
        public override bool CanSmelt(IWorldAccessor world, ISlotProvider cookingSlotsProvider, ItemStack inputStack, ItemStack outputStack)
        {
            ItemStack[] stacks = GetIngredients(world, cookingSlotsProvider);

            // Got alloy?
            if (GetMatchingAlloy(world, stacks) != null)
            {
                return(true);
            }

            for (int i = 0; i < stacks.Length; i++)
            {
                CombustibleProperties props = stacks[i]?.Collectible.CombustibleProps;
                if (props != null && !props.RequiresContainer)
                {
                    return(false);
                }
            }

            MatchedSmeltableStack match = GetSingleSmeltableStack(stacks);

            return(match != null);
        }