public ReagentUnit ReactionEntity(IEntity entity, ReactionMethod method, ReagentUnit reactVolume)
        {
            var removed = ReagentUnit.Zero;

            if (entity == null || entity.Deleted)
            {
                return(removed);
            }

            foreach (var react in entity.GetAllComponents <IReagentReaction>())
            {
                switch (method)
                {
                case ReactionMethod.Touch:
                    removed += react.ReagentReactTouch(this, reactVolume);
                    break;

                case ReactionMethod.Ingestion:
                    removed += react.ReagentReactIngestion(this, reactVolume);
                    break;

                case ReactionMethod.Injection:
                    removed += react.ReagentReactInjection(this, reactVolume);
                    break;
                }

                if (removed > reactVolume)
                {
                    throw new Exception("Removed more than we have!");
                }

                if (removed == reactVolume)
                {
                    break;
                }
            }

            return(removed);
        }
        public void React(ReactionMethod method, IEntity entity, ReagentPrototype reagent, ReagentUnit volume, Solution.Solution? source)
        {
            switch (method)
            {
                case ReactionMethod.Touch:
                    if (!Touch)
                        return;
                    break;
                case ReactionMethod.Injection:
                    if(!Injection)
                        return;
                    break;
                case ReactionMethod.Ingestion:
                    if(!Ingestion)
                        return;
                    break;
                default:
                    throw new ArgumentOutOfRangeException(nameof(method), method, null);
            }

            React(entity, reagent, volume, source);
        }
示例#3
0
        public void ReactionEntity(EntityUid uid, ReactionMethod method, ReagentPrototype reagent,
                                   FixedPoint2 reactVolume, Solution?source)
        {
            if (!EntityManager.TryGetComponent(uid, out ReactiveComponent? reactive))
            {
                return;
            }

            // If we have a source solution, use the reagent quantity we have left. Otherwise, use the reaction volume specified.
            var args = new ReagentEffectArgs(uid, null, source, reagent,
                                             source?.GetReagentQuantity(reagent.ID) ?? reactVolume, EntityManager, method);

            // First, check if the reagent wants to apply any effects.
            if (reagent.ReactiveEffects != null && reactive.ReactiveGroups != null)
            {
                foreach (var(key, val) in reagent.ReactiveEffects)
                {
                    if (!val.Methods.Contains(method))
                    {
                        continue;
                    }

                    if (!reactive.ReactiveGroups.ContainsKey(key))
                    {
                        continue;
                    }

                    if (!reactive.ReactiveGroups[key].Contains(method))
                    {
                        continue;
                    }

                    foreach (var effect in val.Effects)
                    {
                        if (!effect.ShouldApply(args, _robustRandom))
                        {
                            continue;
                        }

                        if (effect.ShouldLog)
                        {
                            var entity = args.SolutionEntity;
                            _adminLogger.Add(LogType.ReagentEffect, effect.LogImpact,
                                             $"Reactive effect {effect.GetType().Name:effect} of reagent {reagent.ID:reagent} with method {method} applied on entity {ToPrettyString(entity):entity} at {Transform(entity).Coordinates:coordinates}");
                        }

                        effect.Effect(args);
                    }
                }
            }

            // Then, check if the prototype has any effects it can apply as well.
            if (reactive.Reactions != null)
            {
                foreach (var entry in reactive.Reactions)
                {
                    if (!entry.Methods.Contains(method))
                    {
                        continue;
                    }

                    if (entry.Reagents != null && !entry.Reagents.Contains(reagent.ID))
                    {
                        continue;
                    }

                    foreach (var effect in entry.Effects)
                    {
                        if (!effect.ShouldApply(args, _robustRandom))
                        {
                            continue;
                        }

                        if (effect.ShouldLog)
                        {
                            var entity = args.SolutionEntity;
                            _adminLogger.Add(LogType.ReagentEffect, effect.LogImpact,
                                             $"Reactive effect {effect.GetType().Name:effect} of {ToPrettyString(entity):entity} using reagent {reagent.ID:reagent} with method {method} at {Transform(entity).Coordinates:coordinates}");
                        }

                        effect.Effect(args);
                    }
                }
            }
        }
示例#4
0
 public void ReactionEntity(EntityUid uid, ReactionMethod method, string reagentId, FixedPoint2 reactVolume, Solution?source)
 {
     // We throw if the reagent specified doesn't exist.
     ReactionEntity(uid, method, _prototypeManager.Index <ReagentPrototype>(reagentId), reactVolume, source);
 }
示例#5
0
 public void ReactionEntity(IEntity?entity, ReactionMethod method, string reagentId, ReagentUnit reactVolume, Solution?source)
 {
     // We throw if the reagent specified doesn't exist.
     ReactionEntity(entity, method, _prototypeManager.Index <ReagentPrototype>(reagentId), reactVolume, source);
 }