示例#1
0
        private bool TryUseDrink(IEntity target, bool forced = false)
        {
            if (target == null || !_contents.CanRemoveSolutions)
            {
                return(false);
            }

            if (!Opened)
            {
                target.PopupMessage(Loc.GetString("Open {0:theName} first!", Owner));
                return(false);
            }

            if (_contents.CurrentVolume.Float() <= 0)
            {
                if (!forced)
                {
                    target.PopupMessage(Loc.GetString("{0:theName} is empty!", Owner));
                }

                return(false);
            }

            if (!target.TryGetComponent(out IBody body) ||
                !body.TryGetMechanismBehaviors <StomachBehavior>(out var stomachs))
            {
                return(false);
            }

            var transferAmount = ReagentUnit.Min(TransferAmount, _contents.CurrentVolume);
            var split          = _contents.SplitSolution(transferAmount);
            var firstStomach   = stomachs.FirstOrDefault(stomach => stomach.CanTransferSolution(split));


            // All stomach are full or can't handle whatever solution we have.
            if (firstStomach == null)
            {
                _contents.TryAddSolution(split);
                target.PopupMessage(Loc.GetString("You've had enough {0:theName}!", Owner));
                return(false);
            }

            if (_useSound != null)
            {
                EntitySystem.Get <AudioSystem>().PlayFromEntity(_useSound, target, AudioParams.Default.WithVolume(-2f));
            }

            target.PopupMessage(Loc.GetString("Slurp"));
            UpdateAppearance();

            // TODO: Account for partial transfer.

            split.DoEntityReaction(target, ReactionMethod.Ingestion);

            firstStomach.TryTransferSolution(split);

            return(true);
        }
        /// <summary>
        ///     Attempt to transfer provided solution to internal solution.
        ///     Only supports complete transfers
        /// </summary>
        /// <param name="solution">Solution to be transferred</param>
        /// <returns>Whether or not transfer was a success</returns>
        public override bool TryTransferSolution(Solution solution)
        {
            // For now doesn't support partial transfers
            if (solution.TotalVolume + _internalSolution.CurrentVolume > _internalSolution.MaxVolume)
            {
                return(false);
            }

            _internalSolution.TryAddSolution(solution);
            return(true);
        }
        private bool TryUseDrink(IEntity target, bool forced = false)
        {
            if (target == null || !_contents.CanRemoveSolutions)
            {
                return(false);
            }

            if (!Opened)
            {
                target.PopupMessage(Loc.GetString("Open {0:theName} first!", Owner));
                return(false);
            }

            if (_contents.CurrentVolume.Float() <= 0)
            {
                if (!forced)
                {
                    target.PopupMessage(Loc.GetString("{0:theName} is empty!", Owner));
                }

                return(false);
            }

            if (!target.TryGetComponent(out StomachComponent stomachComponent))
            {
                return(false);
            }

            var transferAmount = ReagentUnit.Min(TransferAmount, _contents.CurrentVolume);
            var split          = _contents.SplitSolution(transferAmount);

            if (stomachComponent.TryTransferSolution(split))
            {
                if (_useSound == null)
                {
                    return(false);
                }

                EntitySystem.Get <AudioSystem>().PlayFromEntity(_useSound, target, AudioParams.Default.WithVolume(-2f));
                target.PopupMessage(Loc.GetString("Slurp"));
                UpdateAppearance();
                return(true);
            }

            // Stomach was full or can't handle whatever solution we have.
            _contents.TryAddSolution(split);
            target.PopupMessage(Loc.GetString("You've had enough {0:theName}!", Owner));
            return(false);
        }
示例#4
0
        public override bool TryUseFood(IEntity?user, IEntity?target, UtensilComponent?utensilUsed = null)
        {
            if (user == null)
            {
                return(false);
            }

            var trueTarget = target ?? user;

            if (!trueTarget.TryGetComponent(out SharedBodyComponent? body) ||
                !body.TryGetMechanismBehaviors <StomachBehavior>(out var stomachs))
            {
                return(false);
            }

            if (!user.InRangeUnobstructed(trueTarget, popup: true))
            {
                return(false);
            }

            var transferAmount = ReagentUnit.Min(TransferAmount, _contents.CurrentVolume);
            var split          = _contents.SplitSolution(transferAmount);

            var firstStomach = stomachs.FirstOrDefault(stomach => stomach.CanTransferSolution(split));

            if (firstStomach == null)
            {
                _contents.TryAddSolution(split);
                trueTarget.PopupMessage(user, Loc.GetString("pill-component-cannot-eat-more-message"));
                return(false);
            }

            // TODO: Account for partial transfer.

            split.DoEntityReaction(trueTarget, ReactionMethod.Ingestion);

            firstStomach.TryTransferSolution(split);

            if (UseSound != null)
            {
                SoundSystem.Play(Filter.Pvs(trueTarget), UseSound, trueTarget, AudioParams.Default.WithVolume(-1f));
            }

            trueTarget.PopupMessage(user, Loc.GetString("pill-component-swallow-success-message"));

            Owner.QueueDelete();
            return(true);
        }
示例#5
0
        async Task <bool> IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
        {
            var user      = eventArgs.User;
            var usingItem = eventArgs.Using;

            if (usingItem == null || usingItem.Deleted || !ActionBlockerSystem.CanInteract(user))
            {
                return(false);
            }

            if (usingItem.TryGetComponent(out SeedComponent? seeds))
            {
                if (Seed == null)
                {
                    if (seeds.Seed == null)
                    {
                        user.PopupMessageCursor(Loc.GetString("The packet seems to be empty. You throw it away."));
                        usingItem.Delete();
                        return(false);
                    }

                    user.PopupMessageCursor(Loc.GetString("You plant the {0} {1}.", seeds.Seed.SeedName, seeds.Seed.SeedNoun));

                    Seed       = seeds.Seed;
                    Dead       = false;
                    Age        = 1;
                    Health     = Seed.Endurance;
                    _lastCycle = _gameTiming.CurTime;

                    usingItem.Delete();

                    CheckLevelSanity();
                    UpdateSprite();

                    return(true);
                }

                user.PopupMessageCursor(Loc.GetString("The {0} already has seeds in it!", Owner.Name));
                return(false);
            }

            if (usingItem.HasTag("Hoe"))
            {
                if (WeedLevel > 0)
                {
                    user.PopupMessageCursor(Loc.GetString("You remove the weeds from the {0}.", Owner.Name));
                    user.PopupMessageOtherClients(Loc.GetString("{0} starts uprooting the weeds.", user.Name));
                    WeedLevel = 0;
                    UpdateSprite();
                }
                else
                {
                    user.PopupMessageCursor(Loc.GetString("This plot is devoid of weeds! It doesn't need uprooting."));
                }

                return(true);
            }

            if (usingItem.HasTag("Shovel"))
            {
                if (Seed != null)
                {
                    user.PopupMessageCursor(Loc.GetString("You remove the plant from the {0}.", Owner.Name));
                    user.PopupMessageOtherClients(Loc.GetString("{0} removes the plant.", user.Name));
                    RemovePlant();
                }
                else
                {
                    user.PopupMessageCursor(Loc.GetString("There is no plant to remove."));
                }

                return(true);
            }

            if (usingItem.TryGetComponent(out ISolutionInteractionsComponent? solution) && solution.CanDrain)
            {
                var amount  = ReagentUnit.New(5);
                var sprayed = false;

                if (usingItem.TryGetComponent(out SprayComponent? spray))
                {
                    sprayed = true;
                    amount  = ReagentUnit.New(1);

                    if (!string.IsNullOrEmpty(spray.SpraySound))
                    {
                        SoundSystem.Play(Filter.Pvs(usingItem), spray.SpraySound, usingItem, AudioHelpers.WithVariation(0.125f));
                    }
                }

                var split = solution.Drain(amount);
                if (split.TotalVolume == 0)
                {
                    user.PopupMessageCursor(Loc.GetString("{0:TheName} is empty!", usingItem));
                    return(true);
                }

                user.PopupMessageCursor(Loc.GetString(
                                            sprayed ? "You spray {0:TheName}" : "You transfer {1}u to {0:TheName}",
                                            Owner, split.TotalVolume));

                _solutionContainer?.TryAddSolution(split);

                ForceUpdateByExternalCause();

                return(true);
            }

            if (usingItem.HasTag("PlantSampleTaker"))
            {
                if (Seed == null)
                {
                    user.PopupMessageCursor(Loc.GetString("There is nothing to take a sample of!"));
                    return(false);
                }

                if (Sampled)
                {
                    user.PopupMessageCursor(Loc.GetString("This plant has already been sampled."));
                    return(false);
                }

                if (Dead)
                {
                    user.PopupMessageCursor(Loc.GetString("This plant is dead."));
                    return(false);
                }

                var seed = Seed.SpawnSeedPacket(user.Transform.Coordinates);
                seed.RandomOffset(0.25f);
                user.PopupMessageCursor(Loc.GetString($"You take a sample from the {Seed.DisplayName}."));
                Health -= (_random.Next(3, 5) * 10);

                if (_random.Prob(0.3f))
                {
                    Sampled = true;
                }

                // Just in case.
                CheckLevelSanity();
                ForceUpdateByExternalCause();

                return(true);
            }

            if (usingItem.HasTag("BotanySharp"))
            {
                return(DoHarvest(user));
            }

            if (usingItem.HasComponent <ProduceComponent>())
            {
                user.PopupMessageCursor(Loc.GetString("You compost {1:theName} into {0:theName}.", Owner, usingItem));
                user.PopupMessageOtherClients(Loc.GetString("{0:TheName} composts {1:theName} into {2:theName}.", user, usingItem, Owner));

                if (usingItem.TryGetComponent(out SolutionContainerComponent? solution2))
                {
                    // This deliberately discards overfill.
                    _solutionContainer?.TryAddSolution(solution2.SplitSolution(solution2.Solution.TotalVolume));

                    ForceUpdateByExternalCause();
                }

                usingItem.Delete();

                return(true);
            }

            return(false);
        }
示例#6
0
        async Task <bool> IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
        {
            var user      = eventArgs.User;
            var usingItem = eventArgs.Using;

            if (usingItem == null || usingItem.Deleted || !EntitySystem.Get <ActionBlockerSystem>().CanInteract(user))
            {
                return(false);
            }

            if (usingItem.TryGetComponent(out SeedComponent? seeds))
            {
                if (Seed == null)
                {
                    if (seeds.Seed == null)
                    {
                        user.PopupMessageCursor(Loc.GetString("plant-holder-component-empty-seed-packet-message"));
                        usingItem.QueueDelete();
                        return(false);
                    }

                    user.PopupMessageCursor(Loc.GetString("plant-holder-component-plant-success-message",
                                                          ("seedName", seeds.Seed.SeedName),
                                                          ("seedNoun", seeds.Seed.SeedNoun)));

                    Seed       = seeds.Seed;
                    Dead       = false;
                    Age        = 1;
                    Health     = Seed.Endurance;
                    _lastCycle = _gameTiming.CurTime;

                    usingItem.QueueDelete();

                    CheckLevelSanity();
                    UpdateSprite();

                    return(true);
                }

                user.PopupMessageCursor(Loc.GetString("plant-holder-component-already-seeded-message", ("name", Owner.Name)));
                return(false);
            }

            if (usingItem.HasTag("Hoe"))
            {
                if (WeedLevel > 0)
                {
                    user.PopupMessageCursor(Loc.GetString("plant-holder-component-remove-weeds-message", ("name", Owner.Name)));
                    user.PopupMessageOtherClients(Loc.GetString("plant-holder-component-remove-weeds-others-message", ("otherName", user.Name)));
                    WeedLevel = 0;
                    UpdateSprite();
                }
                else
                {
                    user.PopupMessageCursor(Loc.GetString("plant-holder-component-no-weeds-message"));
                }

                return(true);
            }

            if (usingItem.HasTag("Shovel"))
            {
                if (Seed != null)
                {
                    user.PopupMessageCursor(Loc.GetString("plant-holder-component-remove-plant-message", ("name", Owner.Name)));
                    user.PopupMessageOtherClients(Loc.GetString("plant-holder-component-remove-plant-others-message", ("name", user.Name)));
                    RemovePlant();
                }
                else
                {
                    user.PopupMessageCursor(Loc.GetString("plant-holder-component-no-plant-message"));
                }

                return(true);
            }

            if (usingItem.TryGetComponent(out ISolutionInteractionsComponent? solution) && solution.CanDrain)
            {
                var amount  = ReagentUnit.New(5);
                var sprayed = false;

                if (usingItem.TryGetComponent(out SprayComponent? spray))
                {
                    sprayed = true;
                    amount  = ReagentUnit.New(1);

                    if (!string.IsNullOrEmpty(spray.SpraySound))
                    {
                        SoundSystem.Play(Filter.Pvs(usingItem), spray.SpraySound, usingItem, AudioHelpers.WithVariation(0.125f));
                    }
                }

                var split = solution.Drain(amount);
                if (split.TotalVolume == 0)
                {
                    user.PopupMessageCursor(Loc.GetString("plant-holder-component-empty-message", ("owner", usingItem)));
                    return(true);
                }

                user.PopupMessageCursor(Loc.GetString(sprayed ? "plant-holder-component-spray-message" : "plant-holder-component-transfer-message",
                                                      ("owner", Owner),
                                                      ("amount", split.TotalVolume)));

                _solutionContainer?.TryAddSolution(split);

                ForceUpdateByExternalCause();

                return(true);
            }

            if (usingItem.HasTag("PlantSampleTaker"))
            {
                if (Seed == null)
                {
                    user.PopupMessageCursor(Loc.GetString("plant-holder-component-nothing-to-sample-message"));
                    return(false);
                }

                if (Sampled)
                {
                    user.PopupMessageCursor(Loc.GetString("plant-holder-component-already-sampled-message"));
                    return(false);
                }

                if (Dead)
                {
                    user.PopupMessageCursor(Loc.GetString("plant-holder-component-dead-plant-message"));
                    return(false);
                }

                var seed = Seed.SpawnSeedPacket(user.Transform.Coordinates);
                seed.RandomOffset(0.25f);
                user.PopupMessageCursor(Loc.GetString("plant-holder-component-take-sample-message", ("seedName", Seed.DisplayName)));
                Health -= (_random.Next(3, 5) * 10);

                if (_random.Prob(0.3f))
                {
                    Sampled = true;
                }

                // Just in case.
                CheckLevelSanity();
                ForceUpdateByExternalCause();

                return(true);
            }

            if (usingItem.HasTag("BotanySharp"))
            {
                return(DoHarvest(user));
            }

            if (usingItem.HasComponent <ProduceComponent>())
            {
                user.PopupMessageCursor(Loc.GetString("plant-holder-component-compost-message",
                                                      ("owner", Owner),
                                                      ("usingItem", usingItem)));
                user.PopupMessageOtherClients(Loc.GetString("plant-holder-component-compost-others-message",
                                                            ("user", user),
                                                            ("usingItem", usingItem),
                                                            ("owner", Owner)));

                if (usingItem.TryGetComponent(out SolutionContainerComponent? solution2))
                {
                    // This deliberately discards overfill.
                    _solutionContainer?.TryAddSolution(solution2.SplitSolution(solution2.Solution.TotalVolume));

                    ForceUpdateByExternalCause();
                }

                usingItem.QueueDelete();

                return(true);
            }

            return(false);
        }
        public async Task <bool> InteractUsing(InteractUsingEventArgs eventArgs)
        {
            var user      = eventArgs.User;
            var usingItem = eventArgs.Using;

            if (usingItem == null || usingItem.Deleted || !ActionBlockerSystem.CanInteract(user))
            {
                return(false);
            }

            if (usingItem.TryGetComponent(out SeedComponent? seeds))
            {
                if (Seed == null)
                {
                    if (seeds.Seed == null)
                    {
                        user.PopupMessageCursor(Loc.GetString("The packet seems to be empty. You throw it away."));
                        usingItem.Delete();
                        return(false);
                    }

                    user.PopupMessageCursor(Loc.GetString("You plant the {0} {1}.", seeds.Seed.SeedName, seeds.Seed.SeedNoun));

                    Seed       = seeds.Seed;
                    Dead       = false;
                    Age        = 1;
                    Health     = Seed.Endurance;
                    _lastCycle = _gameTiming.CurTime;

                    usingItem.Delete();

                    CheckLevelSanity();
                    UpdateSprite();

                    return(true);
                }

                user.PopupMessageCursor(Loc.GetString("The {0} already has seeds in it!", Owner.Name));
                return(false);
            }

            if (usingItem.HasComponent <HoeComponent>())
            {
                if (WeedLevel > 0)
                {
                    user.PopupMessageCursor(Loc.GetString("You remove the weeds from the {0}.", Owner.Name));
                    user.PopupMessageOtherClients(Loc.GetString("{0} starts uprooting the weeds.", user.Name));
                    WeedLevel = 0;
                    UpdateSprite();
                }
                else
                {
                    user.PopupMessageCursor(Loc.GetString("This plot is devoid of weeds! It doesn't need uprooting."));
                }

                return(true);
            }

            if (usingItem.TryGetComponent(out SolutionContainerComponent? solution) && solution.CanRemoveSolutions)
            {
                var amount  = 5f;
                var sprayed = false;

                if (usingItem.TryGetComponent(out SprayComponent? spray))
                {
                    sprayed = true;
                    amount  = 1f;
                    EntitySystem.Get <AudioSystem>().PlayFromEntity(spray.SpraySound, usingItem, AudioHelpers.WithVariation(0.125f));
                }

                var chemAmount = ReagentUnit.New(amount);

                var split = solution.Solution.SplitSolution(chemAmount <= solution.Solution.TotalVolume ? chemAmount : solution.Solution.TotalVolume);

                user.PopupMessageCursor(Loc.GetString(sprayed ? $"You spray {Owner.Name} with {usingItem.Name}." : $"You transfer {split.TotalVolume.ToString()}u to {Owner.Name}"));

                _solutionContainer?.TryAddSolution(split);

                SkipAging++; // We're forcing an update cycle, so one age hasn't passed.
                ForceUpdate = true;
                Update();

                return(true);
            }

            if (usingItem.HasComponent <PlantSampleTakerComponent>())
            {
                if (Seed == null)
                {
                    user.PopupMessageCursor(Loc.GetString("There is nothing to take a sample of!"));
                    return(false);
                }

                if (Sampled)
                {
                    user.PopupMessageCursor(Loc.GetString("This plant has already been sampled."));
                    return(false);
                }

                if (Dead)
                {
                    user.PopupMessageCursor(Loc.GetString("This plant is dead."));
                    return(false);
                }

                var seed = Seed.SpawnSeedPacket(user.Transform.Coordinates);
                seed.RandomOffset(0.25f);
                user.PopupMessageCursor(Loc.GetString($"You take a sample from the {Seed.DisplayName}."));
                Health -= (_random.Next(3, 5) * 10);

                if (_random.Prob(0.3f))
                {
                    Sampled = true;
                }

                // Just in case.
                CheckLevelSanity();
                SkipAging++; // We're forcing an update cycle, so one age hasn't passed.
                ForceUpdate = true;
                Update();

                return(true);
            }

            if (usingItem.HasComponent <BotanySharpComponent>())
            {
                return(DoHarvest(user));
            }

            return(false);
        }
        private bool TryUseDrink(IEntity target, bool forced = false)
        {
            if (target == null || !_contents.CanRemoveSolutions)
            {
                return(false);
            }

            if (!Opened)
            {
                target.PopupMessage(Loc.GetString("Open {0:theName} first!", Owner));
                return(false);
            }

            if (_contents.CurrentVolume.Float() <= 0)
            {
                if (!forced)
                {
                    target.PopupMessage(Loc.GetString("{0:theName} is empty!", Owner));
                }

                return(false);
            }

            if (!target.TryGetComponent(out StomachComponent stomachComponent))
            {
                return(false);
            }

            var transferAmount = ReagentUnit.Min(TransferAmount, _contents.CurrentVolume);
            var split          = _contents.SplitSolution(transferAmount);

            if (stomachComponent.CanTransferSolution(split))
            {
                if (_useSound == null)
                {
                    return(false);
                }

                EntitySystem.Get <AudioSystem>().PlayFromEntity(_useSound, target, AudioParams.Default.WithVolume(-2f));
                target.PopupMessage(Loc.GetString("Slurp"));
                UpdateAppearance();

                // TODO: Account for partial transfer.

                foreach (var(reagentId, quantity) in split.Contents)
                {
                    if (!_prototypeManager.TryIndex(reagentId, out ReagentPrototype reagent))
                    {
                        continue;
                    }
                    split.RemoveReagent(reagentId, reagent.ReactionEntity(target, ReactionMethod.Ingestion, quantity));
                }

                stomachComponent.TryTransferSolution(split);

                return(true);
            }

            // Stomach was full or can't handle whatever solution we have.
            _contents.TryAddSolution(split);
            target.PopupMessage(Loc.GetString("You've had enough {0:theName}!", Owner));
            return(false);
        }