コード例 #1
0
        public bool Apply(MonoBehaviour sender, ReagentMix reagentMix)
        {
            bool changing;
            var  changed = false;

            do
            {
                changing = false;
                foreach (var parent in parents)
                {
                    if (parent.Apply(sender, reagentMix))
                    {
                        changing = true;
                        changed  = true;
                    }
                }

                foreach (var reaction in reactions)
                {
                    if (reaction.Apply(sender, reagentMix))
                    {
                        changing = true;
                        changed  = true;
                    }
                }
            } while (changing);

            return(changed);
        }
コード例 #2
0
ファイル: Reaction.cs プロジェクト: PetMudstone/unitystation
        public bool CanReactionHappen(ReagentMix reagentMix, float reactionAmount = 1)
        {
            //correct temperature?
            tempMin = hasMinTemp ? (float?)serializableTempMin : null;
            tempMax = hasMaxTemp ? (float?)serializableTempMax : null;
            if (tempMin != null && reagentMix.Temperature <= tempMin ||
                tempMax != null && reagentMix.Temperature >= tempMax)
            {
                return(false);
            }

            //are all catalysts present?
            foreach (var catalyst in catalysts.m_dict)
            {
                if (reagentMix[catalyst.Key] < catalyst.Value * reactionAmount)
                {
                    return(false);
                }
            }

            //is a single inhibitor present?
            foreach (var inhibitor in inhibitors.m_dict)
            {
                if (reagentMix[inhibitor.Key] > inhibitor.Value * reactionAmount)
                {
                    return(false);
                }
            }
            return(true);
        }
コード例 #3
0
        /// <summary>
        /// Overrides Buffer with incoming ReagentMix.
        /// Used with GetBufferMix() to return reagents from temporary ReagentMix
        /// </summary>
        /// <param name="overridingMix">ReagentMix to override Buffer with</param>
        private void TransferMixToBuffer(ReagentMix overridingMix)
        {
            //seperate back to slots
            if (BufferslotOne)
            {
                BufferslotOne.CurrentReagentMix.Clear();
                if (overridingMix.Total <= BufferslotOne.MaxCapacity)
                {
                    overridingMix.TransferTo(BufferslotOne.CurrentReagentMix, overridingMix.Total);
                }
                else
                {
                    overridingMix.TransferTo(BufferslotOne.CurrentReagentMix, BufferslotOne.MaxCapacity);
                }

                Logger.LogTrace($"ChemMaster: {gameObject} " +
                                $"Reagentmix buffer one after: {BufferslotOne.CurrentReagentMix}", Category.Chemistry);
            }

            if (BufferslotTwo)
            {
                BufferslotTwo.CurrentReagentMix.Clear();
                //Only two containers, and previous math confirms
                // that tempTransfer amount won't be larger than last buffer
                overridingMix.TransferTo(BufferslotTwo.CurrentReagentMix, overridingMix.Total);
                Logger.LogTrace($"ChemMaster: {gameObject} " +
                                $"reagentmix buffer two after: {BufferslotTwo.CurrentReagentMix}", Category.Chemistry);
            }
        }
コード例 #4
0
ファイル: Reaction.cs プロジェクト: unitystation/unitystation
        public bool HasIngredients(ReagentMix reagentMix)
        {
            //has all ingredients?
            if (ingredients.m_dict.Count == 0)
            {
                return(false);
            }

            if (ingredients.m_dict.Count > reagentMix.reagents.m_dict.Count)
            {
                return(false);
            }

            foreach (var ingredient in ingredients.m_dict)
            {
                if (reagentMix.reagents.m_dict.ContainsKey(ingredient.Key) == false)
                {
                    return(false);
                }
                if (ingredient.Value <= 0)
                {
                    return(false);
                }
            }
            return(true);
        }
コード例 #5
0
        public bool Apply(MonoBehaviour sender, ReagentMix reagentMix)
        {
            if ((tempMin != null || reagentMix.Temperature >= tempMin) &&
                (tempMax != null || reagentMix.Temperature <= tempMax))
            {
                return(false);
            }

            if (!ingredients.All(reagent => reagentMix[reagent.Key] > 0))
            {
                return(false);
            }

            if (!ingredients.Any())
            {
                return(false);
            }
            var reactionAmount = ingredients.Min(i => reagentMix[i.Key] / i.Value);

            if (useExactAmounts == true)
            {
                reactionAmount = (float)Math.Floor(reactionAmount);
                if (reactionAmount == 0)
                {
                    return(false);
                }
            }

            if (!catalysts.All(catalyst =>
                               reagentMix[catalyst.Key] > catalyst.Value * reactionAmount))
            {
                return(false);
            }

            if (inhibitors.All(inhibitor => reagentMix[inhibitor.Key] > inhibitor.Value * reactionAmount))
            {
                return(false);
            }

            foreach (var ingredient in ingredients)
            {
                reagentMix.Subtract(ingredient.Key, reactionAmount * ingredient.Value);
            }

            foreach (var result in results)
            {
                var reactionResult = reactionAmount * result.Value;
                reagentMix.Add(result.Key, reactionResult);
            }

            foreach (var effect in effects)
            {
                effect.Apply(sender, reactionAmount);
            }

            return(true);
        }
コード例 #6
0
        public void RemoveFromBuffer(Reagent reagent, float amount)
        {
            ReagentMix tempTransfer = GetBufferMix();

            //one removal, no math
            tempTransfer.Remove(reagent, amount);

            //part two of transfer: fill Buffer from tempTransfer Mix
            TransferMixToBuffer(tempTransfer);

            UpdateGui();
        }
コード例 #7
0
        public void TransferBufferToContainer(Reagent reagent, float amount)
        {
            ReagentMix tempTransfer = GetBufferMix();

            //Container never gets swapped without clearing buffer, so we can assume there's space in container
            tempTransfer.Remove(reagent, amount);
            Container.CurrentReagentMix.Add(reagent, amount);

            TransferMixToBuffer(tempTransfer);

            UpdateGui();
        }
コード例 #8
0
        public bool Apply(MonoBehaviour sender, ReagentMix reagentMix)
        {
            if ((tempMin != null || reagentMix.Temperature >= tempMin) &&
                (tempMax != null || reagentMix.Temperature <= tempMax))
            {
                return(false);
            }

            var reagents = reagentMix.reagents;

            if (!ingredients.All(reagent => reagents.TryGetValue(reagent.Key, out var amount) ? amount > 0 : false))
            {
                return(false);
            }

            if (!ingredients.Any())
            {
                return(false);
            }
            var reactionAmount = ingredients.Min(i => reagents[i.Key] / i.Value);

            if (!catalysts.All(catalyst =>
                               reagents.TryGetValue(catalyst.Key, out var amount) && amount > catalyst.Value * reactionAmount))
            {
                return(false);
            }

            foreach (var ingredient in ingredients)
            {
                reagents[ingredient.Key] -= reactionAmount * ingredient.Value;
            }

            foreach (var result in results)
            {
                var reactionResult = reactionAmount * result.Value;
                if (reagents.Contains(result.Key))
                {
                    reagents[result.Key] += reactionResult;
                }
                else
                {
                    reagents[result.Key] = reactionAmount;
                }
            }

            foreach (var effect in effects)
            {
                effect.Apply(sender, reactionAmount);
            }

            return(true);
        }
コード例 #9
0
ファイル: Reaction.cs プロジェクト: PetMudstone/unitystation
        public float GetReactionAmount(ReagentMix reagentMix)
        {
            var reactionAmount = Mathf.Infinity;

            foreach (var ingredient in ingredients.m_dict)
            {
                var value = reagentMix.reagents.m_dict[ingredient.Key] / ingredient.Value;
                if (value < reactionAmount)
                {
                    reactionAmount = value;
                }
            }
            return(reactionAmount);
        }
コード例 #10
0
ファイル: ChemMaster.cs プロジェクト: ktndrnl/unitystation
        public void RemoveFromBuffer(Reagent reagent, float amount)
        {
            ReagentMix tempTransfer = GetBufferMix();

            //one removal, no math
            tempTransfer.Remove(reagent, amount);
            //remove listing if empty
            if (tempTransfer.reagents[reagent] <= 0)
            {
                tempTransfer.reagentKeys.Remove(reagent);
            }

            //part two of transfer: fill Buffer from tempTransfer Mix
            TransferMixToBuffer(tempTransfer);

            UpdateGui();
        }
コード例 #11
0
        /// <summary>
        /// Retreive Buffer contents as one ReagentMix
        /// </summary>
        /// <returns> Buffer's mix of reagents </returns>
        public ReagentMix GetBufferMix()
        {
            ReagentMix emptyMix = new ReagentMix();

            if (BufferslotOne)
            {
                ReagentMix temp = BufferslotOne.CurrentReagentMix.Clone();
                temp.TransferTo(emptyMix, temp.Total);
            }

            if (BufferslotTwo)
            {
                ReagentMix temp = BufferslotTwo.CurrentReagentMix.Clone();
                temp.TransferTo(emptyMix, temp.Total);
            }

            return(emptyMix);
        }
コード例 #12
0
        public void TransferContainerToBuffer(Reagent reagent, float amount)
        {
            float      capacity     = 0;
            ReagentMix tempTransfer = GetBufferMix();
            float      currentTotal = tempTransfer.Total;

            if (BufferslotOne != null)
            {
                capacity += BufferslotOne.MaxCapacity;
            }

            if (BufferslotTwo != null)
            {
                capacity += BufferslotTwo.MaxCapacity;
            }

            //math
            float space = capacity - currentTotal;

            Logger.LogTrace($"Buffer| capacity:{capacity} total:{currentTotal} space:{space}", Category.Chemistry);

            //part one of transfer: isolate reagents, add to tempTransfer Mix
            if (space > 0)
            {
                Logger.LogTrace($"BEFORE| Mix:{Container.CurrentReagentMix}", Category.Chemistry);
                if (amount < space)
                {
                    Container.CurrentReagentMix.Remove(reagent, amount);
                    tempTransfer.Add(reagent, amount);
                }
                else
                {
                    Container.CurrentReagentMix.Remove(reagent, space);
                    tempTransfer.Add(reagent, space);
                }

                Logger.LogTrace($"AFTER|| Mix:{Container.CurrentReagentMix}", Category.Chemistry);
            }

            //part two of transfer: fill Buffer from tempTransfer Mix
            TransferMixToBuffer(tempTransfer);

            UpdateGui();
        }
コード例 #13
0
ファイル: Reaction.cs プロジェクト: PetMudstone/unitystation
        public virtual bool Apply(MonoBehaviour sender, ReagentMix reagentMix)
        {
            if (HasIngredients(reagentMix) == false)
            {
                return(false);
            }

            var reactionAmount = GetReactionAmount(reagentMix);

            if (useExactAmounts)
            {
                reactionAmount = (float)Math.Floor(reactionAmount);
                if (reactionAmount == 0)
                {
                    return(false);
                }
            }

            if (CanReactionHappen(reagentMix, reactionAmount) == false)
            {
                return(false);
            }

            foreach (var ingredient in ingredients.m_dict)
            {
                reagentMix.Subtract(ingredient.Key, reactionAmount * ingredient.Value);
            }

            foreach (var result in results.m_dict)
            {
                var reactionResult = reactionAmount * result.Value;
                reagentMix.Add(result.Key, reactionResult);
            }

            foreach (var effect in effects)
            {
                if (effect != null)
                {
                    effect.Apply(sender, reactionAmount);
                }
            }

            return(true);
        }
コード例 #14
0
        /// <summary>
        /// Average state of all reagents as a string (liquid, gas, etc)
        /// </summary>
        /// <param name="mix"></param>
        /// <returns></returns>
        public static string GetMixStateDescription(ReagentMix mix)
        {
            var mixState = mix.MixState;

            switch (mixState)
            {
            case ReagentState.Liquid:
                return("liquid");

            case ReagentState.Solid:
                return("powder");

            case ReagentState.Gas:
                return("gas");

            default:
                return("substance");
            }
        }
コード例 #15
0
        public static bool Apply(MonoBehaviour sender, ReagentMix reagentMix, HashSet <Reaction> possibleReactions)
        {
            bool changing;
            var  changed = false;

            do
            {
                changing = false;
                foreach (var reaction in possibleReactions)
                {
                    if (reaction.Apply(sender, reagentMix))
                    {
                        changing = true;
                        changed  = true;
                    }
                }
            } while (changing);

            return(changed);
        }
コード例 #16
0
        public virtual bool Apply(MonoBehaviour sender, ReagentMix reagentMix, List <Reaction> AdditionalReactions = null)
        {
            bool changing;
            var  changed = false;

            do
            {
                changing = false;
                foreach (var parent in parents)
                {
                    if (parent.Apply(sender, reagentMix))
                    {
                        changing = true;
                        changed  = true;
                    }
                }

                foreach (var reaction in reactions)
                {
                    if (reaction.Apply(sender, reagentMix))
                    {
                        changing = true;
                        changed  = true;
                    }
                }

                if (AdditionalReactions != null)
                {
                    foreach (var reaction in AdditionalReactions)
                    {
                        if (reaction.Apply(sender, reagentMix))
                        {
                            changing = true;
                            changed  = true;
                        }
                    }
                }
            } while (changing);

            return(changed);
        }
コード例 #17
0
ファイル: ChemMaster.cs プロジェクト: ktndrnl/unitystation
        public void TransferBufferToContainer(Reagent reagent, float amount)
        {
            ReagentMix tempTransfer = GetBufferMix();

            //Container never gets swapped without clearing buffer, so we can assume there's space in container
            tempTransfer.Remove(reagent, amount);
            Container.CurrentReagentMix.Add(reagent, amount);

            //remove listing if empty
            if (tempTransfer.reagents[reagent] <= 0)
            {
                lock (tempTransfer.reagents)
                {
                    tempTransfer.reagents.m_dict.Remove(reagent);
                }
            }

            TransferMixToBuffer(tempTransfer);

            UpdateGui();
        }
コード例 #18
0
        public void DispenseProduct(int productId, int numberOfProduct, string newName)
        {
            ReagentMix temp = GetBufferMix();
            //Do Math
            float maxProductAmount    = ChemMasterProducts[productId].GetComponent <ReagentContainer>().MaxCapacity;
            float maxTotalAllProducts = maxProductAmount * numberOfProduct;
            float amountPerProduct    = ((maxTotalAllProducts > temp.Total) ? temp.Total : maxTotalAllProducts)
                                        / numberOfProduct;

            for (int i = 0; i < numberOfProduct; i++)
            {
                //Spawn Object
                var product = Spawn.ServerPrefab(ChemMasterProducts[productId], gameObject.WorldPosServer(),
                                                 transform.parent).GameObject;

                //Fill Product
                ReagentContainer productContainer = product.GetComponent <ReagentContainer>();
                if (amountPerProduct <= productContainer.MaxCapacity)
                {
                    temp.TransferTo(productContainer.CurrentReagentMix, amountPerProduct);
                }
                else
                {
                    temp.TransferTo(productContainer.CurrentReagentMix, productContainer.MaxCapacity);
                }

                //Give it some color
                productContainer.OnReagentMixChanged?.Invoke();

                //Give it some love
                product.GetComponent <ItemAttributesV2>().ServerSetArticleName($"{newName}" +
                                                                               $" {product.GetComponent<ItemAttributesV2>().InitialName}");
            }

            ClearBuffer();
            TransferMixToBuffer(temp);
            UpdateGui();
        }
コード例 #19
0
        public virtual bool Apply(MonoBehaviour sender, ReagentMix reagentMix)
        {
            tempMin = hasMinTemp ? (float?)serializableTempMin : null;
            tempMax = hasMaxTemp ? (float?)serializableTempMax : null;

            if (tempMin != null && reagentMix.Temperature <= tempMin ||
                tempMax != null && reagentMix.Temperature >= tempMax)
            {
                return(false);
            }

            if (!ingredients.m_dict.All(reagent => reagentMix[reagent.Key] > 0))
            {
                return(false);
            }

            if (!ingredients.m_dict.Any())
            {
                return(false);
            }

            var reactionAmount = ingredients.m_dict.Min(i => reagentMix[i.Key] / i.Value);

            if (useExactAmounts == true)
            {
                reactionAmount = (float)Math.Floor(reactionAmount);
                if (reactionAmount == 0)
                {
                    return(false);
                }
            }

            if (!catalysts.m_dict.All(catalyst =>
                                      reagentMix[catalyst.Key] >= catalyst.Value * reactionAmount))
            {
                return(false);
            }

            if (inhibitors.m_dict.Count > 0)
            {
                if (inhibitors.m_dict.All(inhibitor => reagentMix[inhibitor.Key] > inhibitor.Value * reactionAmount))
                {
                    return(false);
                }
            }


            foreach (var ingredient in ingredients.m_dict)
            {
                reagentMix.Subtract(ingredient.Key, reactionAmount * ingredient.Value);
            }

            foreach (var result in results.m_dict)
            {
                var reactionResult = reactionAmount * result.Value;
                reagentMix.Add(result.Key, reactionResult);
            }

            foreach (var effect in effects)
            {
                effect.Apply(sender, reactionAmount);
            }

            return(true);
        }