private void OnStartup(EntityUid uid, SharedCombatModeComponent component, ComponentStartup args)
        {
            if (component.CombatToggleAction == null &&
                _protoMan.TryIndex(component.CombatToggleActionId, out InstantActionPrototype? toggleProto))
            {
                component.CombatToggleAction = new(toggleProto);
            }

            if (component.CombatToggleAction != null)
            {
                _actionsSystem.AddAction(uid, component.CombatToggleAction, null);
            }

            if (component.DisarmAction == null &&
                component.CanDisarm &&
                _protoMan.TryIndex(component.DisarmActionId, out EntityTargetActionPrototype? disarmProto))
            {
                component.DisarmAction = new(disarmProto);
            }

            if (component.DisarmAction != null && component.CanDisarm)
            {
                _actionsSystem.AddAction(uid, component.DisarmAction, null);
            }
        }
Ejemplo n.º 2
0
        /////////
        /////////  Server-specific stuff
        /////////

        public override void ExposeData(ObjectSerializer serializer)
        {
            base.ExposeData(serializer);

            serializer.DataReadWriteFunction(
                "BaseTemplate",
                "bodyTemplate.Humanoid",
                template =>
            {
                if (!_prototypeManager.TryIndex(template, out BodyTemplatePrototype templateData))
                {
                    throw new InvalidOperationException("No BodyTemplatePrototype was found with the name " + template + " while loading a BodyTemplate!");     //Should never happen unless you f**k up the prototype.
                }

                _template = new BodyTemplate(templateData);
            },
                () => _template.Name);

            serializer.DataReadWriteFunction(
                "BasePreset",
                "bodyPreset.BasicHuman",
                preset =>
            {
                if (!_prototypeManager.TryIndex(preset, out BodyPresetPrototype presetData))
                {
                    throw new InvalidOperationException("No BodyPresetPrototype was found with the name " + preset + " while loading a BodyPreset!");     //Should never happen unless you f**k up the prototype.
                }

                LoadBodyPreset(new BodyPreset(presetData));
            },
                () => _presetName);
        }
        /// <summary>
        /// Update the button grid of reagents which can be dispensed.
        /// <para>The actions for these buttons are set in <see cref="ReagentDispenserBoundUserInterface.UpdateReagentsList"/>.</para>
        /// </summary>
        /// <param name="inventory">Reagents which can be dispensed by this dispenser</param>
        public void UpdateReagentsList(List <ReagentDispenserInventoryEntry> inventory)
        {
            if (ChemicalList == null)
            {
                return;
            }
            if (inventory == null)
            {
                return;
            }

            ChemicalList.Children.Clear();

            foreach (var entry in inventory)
            {
                if (_prototypeManager.TryIndex(entry.ID, out ReagentPrototype? proto))
                {
                    ChemicalList.AddChild(new Button {
                        Text = proto.LocalizedName
                    });
                }
                else
                {
                    ChemicalList.AddChild(new Button {
                        Text = Loc.GetString("reagent-dispenser-window-reagent-name-not-found-text")
                    });
                }
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// when sleeping component is added or removed, we do some stuff with other components.
        /// </summary>
        private void OnSleepStateChanged(EntityUid uid, MobStateComponent component, SleepStateChangedEvent args)
        {
            _prototypeManager.TryIndex <InstantActionPrototype>("Wake", out var wakeAction);
            if (args.FellAsleep)
            {
                EnsureComp <StunnedComponent>(uid);
                EnsureComp <KnockedDownComponent>(uid);

                var emitSound = EnsureComp <SpamEmitSoundComponent>(uid);
                emitSound.Sound          = new SoundCollectionSpecifier("Snores");
                emitSound.PlayChance     = 0.33f;
                emitSound.RollInterval   = 5f;
                emitSound.PopUp          = "sleep-onomatopoeia";
                emitSound.PitchVariation = 0.2f;

                if (wakeAction != null)
                {
                    var wakeInstance = new InstantAction(wakeAction);
                    wakeInstance.Cooldown = (_gameTiming.CurTime, _gameTiming.CurTime + TimeSpan.FromSeconds(15));
                    _actionsSystem.AddAction(uid, wakeInstance, null);
                }
                return;
            }
            if (wakeAction != null)
            {
                _actionsSystem.RemoveAction(uid, wakeAction);
            }

            RemComp <StunnedComponent>(uid);
            RemComp <KnockedDownComponent>(uid);
            RemComp <SpamEmitSoundComponent>(uid);
        }
Ejemplo n.º 5
0
        protected void RecalculateColor()
        {
            if (Solution.TotalVolume == 0)
            {
                SubstanceColor = Color.Transparent;
                return;
            }

            Color mixColor             = default;
            var   runningTotalQuantity = ReagentUnit.New(0);

            foreach (var reagent in Solution)
            {
                runningTotalQuantity += reagent.Quantity;

                if (!_prototypeManager.TryIndex(reagent.ReagentId, out ReagentPrototype proto))
                {
                    continue;
                }

                if (mixColor == default)
                {
                    mixColor = proto.SubstanceColor;
                    continue;
                }

                var interpolateValue = (1 / runningTotalQuantity.Float()) * reagent.Quantity.Float();
                mixColor = Color.InterpolateBetween(mixColor, proto.SubstanceColor, interpolateValue);
            }

            SubstanceColor = mixColor;
        }
        protected override void ReceiveMessage(BoundUserInterfaceMessage message)
        {
            switch (message)
            {
            case SharedLatheComponent.LatheProducingRecipeMessage msg:
                if (!_prototypeManager.TryIndex(msg.ID, out LatheRecipePrototype recipe))
                {
                    break;
                }
                _queueMenu?.SetInfo(recipe);
                break;

            case SharedLatheComponent.LatheStoppedProducingRecipeMessage _:
                _queueMenu?.ClearInfo();
                break;

            case SharedLatheComponent.LatheFullQueueMessage msg:
                _queuedRecipes.Clear();
                foreach (var id in msg.Recipes)
                {
                    if (!_prototypeManager.TryIndex(id, out LatheRecipePrototype recipePrototype))
                    {
                        break;
                    }
                    _queuedRecipes.Enqueue(recipePrototype);
                }
                _queueMenu?.PopulateList();
                break;
            }
        }
        /// <summary>
        ///     Initialize a damageable component
        /// </summary>
        private void DamageableInit(EntityUid uid, DamageableComponent component, ComponentInit _)
        {
            if (component.DamageContainerID != null &&
                _prototypeManager.TryIndex <DamageContainerPrototype>(component.DamageContainerID,
                                                                      out var damageContainerPrototype))
            {
                // Initialize damage dictionary, using the types and groups from the damage
                // container prototype
                foreach (var type in damageContainerPrototype.SupportedTypes)
                {
                    component.Damage.DamageDict.TryAdd(type, FixedPoint2.Zero);
                }

                foreach (var groupID in damageContainerPrototype.SupportedGroups)
                {
                    var group = _prototypeManager.Index <DamageGroupPrototype>(groupID);
                    foreach (var type in group.DamageTypes)
                    {
                        component.Damage.DamageDict.TryAdd(type, FixedPoint2.Zero);
                    }
                }
            }
            else
            {
                // No DamageContainerPrototype was given. So we will allow the container to support all damage types
                foreach (var type in _prototypeManager.EnumeratePrototypes <DamageTypePrototype>())
                {
                    component.Damage.DamageDict.TryAdd(type.ID, FixedPoint2.Zero);
                }
            }

            component.DamagePerGroup = component.Damage.GetDamagePerGroup(_prototypeManager);
            component.TotalDamage    = component.Damage.Total;
        }
        /// <summary>
        /// Polymorphs the target entity into the specific polymorph prototype
        /// </summary>
        /// <param name="target">The entity that will be transformed</param>
        /// <param name="id">The id of the polymorph prototype</param>
        public EntityUid?PolymorphEntity(EntityUid target, string id)
        {
            if (!_proto.TryIndex <PolymorphPrototype>(id, out var proto))
            {
                _saw.Error("Invalid polymorph prototype");
                return(null);
            }

            return(PolymorphEntity(target, proto));
        }
Ejemplo n.º 9
0
    private void OnInitialize(EntityUid uid, SurveillanceCameraRouterComponent router, ComponentInit args)
    {
        if (router.SubnetFrequencyId == null ||
            !_prototypeManager.TryIndex(router.SubnetFrequencyId, out DeviceFrequencyPrototype? subnetFrequency))
        {
            return;
        }

        router.SubnetFrequency = subnetFrequency.Frequency;
        router.Active          = true;
    }
Ejemplo n.º 10
0
        private void OnAccessInit(EntityUid uid, AccessComponent component, ComponentInit args)
        {
            // Add all tags in groups to the list of tags.
            foreach (var group in component.Groups)
            {
                if (!_prototypeManager.TryIndex<AccessGroupPrototype>(group, out var proto))
                    continue;

                component.Tags.UnionWith(proto.Tags);
            }
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Randomly run a valid event <b>immediately</b>, ignoring earlieststart or whether the event is enabled
        /// </summary>
        /// <returns></returns>
        public string RunRandomEvent()
        {
            var randomEvent = PickRandomEvent();

            if (randomEvent == null ||
                !_prototype.TryIndex <GameRulePrototype>(randomEvent.Id, out var proto))
            {
                return(Loc.GetString("station-event-system-run-random-event-no-valid-events"));
            }

            GameTicker.AddGameRule(proto);
            return(Loc.GetString("station-event-system-run-event", ("eventName", randomEvent.Id)));
        }
Ejemplo n.º 12
0
        private bool TryParseDamageArgs(
            IConsoleShell shell,
            EntityUid target,
            string[] args,
            [NotNullWhen(true)] out Damage?func)
        {
            var entMan = IoCManager.Resolve <IEntityManager>();

            if (!int.TryParse(args[1], out var amount))
            {
                shell.WriteLine($"{args[1]} is not a valid damage integer.");

                func = null;
                return(false);
            }

            if (_prototypeManager.TryIndex <DamageGroupPrototype>(args[0], out var damageGroup))
            {
                func = (entity, ignoreResistances) =>
                {
                    var damage = new DamageSpecifier(damageGroup, amount);
                    EntitySystem.Get <DamageableSystem>().TryChangeDamage(entity, damage, ignoreResistances);

                    shell.WriteLine($"Damaged entity {entMan.GetComponent<MetaDataComponent>(entity).EntityName} with id {entity} for {amount} {damageGroup} damage{(ignoreResistances ? ", ignoring resistances." : ".")}");
                };

                return(true);
            }
            // Fall back to DamageType
            else if (_prototypeManager.TryIndex <DamageTypePrototype>(args[0], out var damageType))
            {
                func = (entity, ignoreResistances) =>
                {
                    var damage = new DamageSpecifier(damageType, amount);
                    EntitySystem.Get <DamageableSystem>().TryChangeDamage(entity, damage, ignoreResistances);

                    shell.WriteLine($"Damaged entity {entMan.GetComponent<MetaDataComponent>(entity).EntityName} with id {entity} for {amount} {damageType} damage{(ignoreResistances ? ", ignoring resistances." : ".")}");
                };
                return(true);
            }
            else
            {
                shell.WriteLine($"{args[0]} is not a valid damage class or type.");

                var types = DamageTypes();
                shell.WriteLine(types);

                func = null;
                return(false);
            }
        }
Ejemplo n.º 13
0
        private void TryInjectIntoBloodstream(BloodstreamComponent targetBloodstream, IEntity user)
        {
            if (!Owner.TryGetComponent(out SolutionContainerComponent? solution) || solution.CurrentVolume == 0)
            {
                return;
            }

            // Get transfer amount. May be smaller than _transferAmount if not enough room
            var realTransferAmount = ReagentUnit.Min(_transferAmount, targetBloodstream.EmptyVolume);

            if (realTransferAmount <= 0)
            {
                Owner.PopupMessage(user, Loc.GetString("You aren't able to inject {0:theName}!", targetBloodstream.Owner));
                return;
            }

            // Move units from attackSolution to targetSolution
            var removedSolution = solution.SplitSolution(realTransferAmount);

            if (!solution.CanAddSolution(removedSolution))
            {
                return;
            }

            // TODO: Account for partial transfer.

            foreach (var(reagentId, quantity) in removedSolution.Contents)
            {
                if (!_prototypeManager.TryIndex(reagentId, out ReagentPrototype reagent))
                {
                    continue;
                }
                removedSolution.RemoveReagent(reagentId, reagent.ReactionEntity(solution.Owner, ReactionMethod.Injection, quantity));
            }

            solution.TryAddSolution(removedSolution);

            foreach (var(reagentId, quantity) in removedSolution.Contents)
            {
                if (!_prototypeManager.TryIndex(reagentId, out ReagentPrototype reagent))
                {
                    continue;
                }
                reagent.ReactionEntity(targetBloodstream.Owner, ReactionMethod.Injection, quantity);
            }

            Owner.PopupMessage(user, Loc.GetString("You inject {0}u into {1:theName}!", removedSolution.TotalVolume, targetBloodstream.Owner));
            Dirty();
        }
        /// <summary>
        ///     Attempts to remove a status effect from an entity.
        /// </summary>
        /// <param name="uid">The entity to remove an effect from.</param>
        /// <param name="key">The effect ID to remove.</param>
        /// <param name="status">The status effects component to change, if you already have it.</param>
        /// <returns>False if the effect could not be removed, true otherwise.</returns>
        /// <remarks>
        ///     Obviously this doesn't automatically clear any effects a status effect might have.
        ///     That's up to the removed component to handle itself when it's removed.
        /// </remarks>
        public bool TryRemoveStatusEffect(EntityUid uid, string key,
                                          StatusEffectsComponent?status = null)
        {
            if (!Resolve(uid, ref status, false))
            {
                return(false);
            }
            if (!status.ActiveEffects.ContainsKey(key))
            {
                return(false);
            }
            if (!_prototypeManager.TryIndex <StatusEffectPrototype>(key, out var proto))
            {
                return(false);
            }

            var state = status.ActiveEffects[key];

            // There are cases where a status effect component might be server-only, so TryGetRegistration...
            if (state.RelevantComponent != null && _componentFactory.TryGetRegistration(state.RelevantComponent, out var registration))
            {
                var type = registration.Type;

                // Make sure the component is actually there first.
                // Maybe a badmin badminned the component away,
                // or perhaps, on the client, the component deletion sync
                // was faster than prediction could predict. Either way, let's not assume the component exists.
                if (EntityManager.HasComponent(uid, type))
                {
                    EntityManager.RemoveComponent(uid, type);
                }
            }

            if (proto.Alert != null)
            {
                _alertsSystem.ClearAlert(uid, proto.Alert.Value);
            }

            status.ActiveEffects.Remove(key);
            if (status.ActiveEffects.Count == 0)
            {
                RemComp <ActiveStatusEffectsComponent>(uid);
            }

            Dirty(status);
            // event?
            return(true);
        }
Ejemplo n.º 15
0
    private void OnInteractUsing(EntityUid uid, SeedExtractorComponent component, InteractUsingEvent args)
    {
        if (!TryComp <ApcPowerReceiverComponent>(uid, out var powerReceiverComponent) || !powerReceiverComponent.Powered)
        {
            return;
        }

        if (TryComp(args.Used, out ProduceComponent? produce))
        {
            if (!_prototypeManager.TryIndex <SeedPrototype>(produce.SeedName, out var seed))
            {
                return;
            }

            _popupSystem.PopupCursor(Loc.GetString("seed-extractor-component-interact-message", ("name", args.Used)),
                                     Filter.Entities(args.User));

            QueueDel(args.Used);

            var random = _random.Next(component.MinSeeds, component.MaxSeeds);
            var coords = Transform(uid).Coordinates;

            for (var i = 0; i < random; i++)
            {
                _botanySystem.SpawnSeedPacket(seed, coords);
            }
        }
    }
Ejemplo n.º 16
0
        private void InitializeFromPrototype()
        {
            if (string.IsNullOrEmpty(_packPrototypeId))
            {
                return;
            }
            if (!_prototypeManager.TryIndex(_packPrototypeId, out VendingMachineInventoryPrototype? packPrototype))
            {
                return;
            }

            _entMan.GetComponent <MetaDataComponent>(Owner).EntityName = packPrototype.Name;
            _animationDuration = TimeSpan.FromSeconds(packPrototype.AnimationDuration);
            _spriteName        = packPrototype.SpriteName;
            if (!string.IsNullOrEmpty(_spriteName))
            {
                var          spriteComponent       = _entMan.GetComponent <SpriteComponent>(Owner);
                const string vendingMachineRSIPath = "Structures/Machines/VendingMachines/{0}.rsi";
                spriteComponent.BaseRSIPath = string.Format(vendingMachineRSIPath, _spriteName);
            }

            var inventory = new List <VendingMachineInventoryEntry>();

            foreach (var(id, amount) in packPrototype.StartingInventory)
            {
                inventory.Add(new VendingMachineInventoryEntry(id, amount));
            }
            Inventory = inventory;
        }
Ejemplo n.º 17
0
        /// <summary>
        ///     Try to split this stack into two. Returns a non-null <see cref="IEntity"/> if successful.
        /// </summary>
        public IEntity?Split(EntityUid uid, int amount, EntityCoordinates spawnPosition, SharedStackComponent?stack = null)
        {
            if (!Resolve(uid, ref stack))
            {
                return(null);
            }

            // Get a prototype ID to spawn the new entity. Null is also valid, although it should rarely be picked...
            var prototype = _prototypeManager.TryIndex <StackPrototype>(stack.StackTypeId, out var stackType)
                ? stackType.Spawn
                : stack.Owner.Prototype?.ID ?? null;

            // Try to remove the amount of things we want to split from the original stack...
            if (!Use(uid, amount, stack))
            {
                return(null);
            }

            // Set the output parameter in the event instance to the newly split stack.
            var entity = EntityManager.SpawnEntity(prototype, spawnPosition);

            if (EntityManager.TryGetComponent(entity.Uid, out SharedStackComponent? stackComp))
            {
                // Set the split stack's count.
                SetCount(entity.Uid, amount, stackComp);
            }

            return(entity);
        }
        public void InitializeFromPrototype(EntityUid uid, VendingMachineComponent?vendComponent = null)
        {
            if (!Resolve(uid, ref vendComponent))
            {
                return;
            }

            if (string.IsNullOrEmpty(vendComponent.PackPrototypeId))
            {
                return;
            }

            if (!_prototypeManager.TryIndex(vendComponent.PackPrototypeId, out VendingMachineInventoryPrototype? packPrototype))
            {
                return;
            }

            MetaData(uid).EntityName        = packPrototype.Name;
            vendComponent.AnimationDuration = TimeSpan.FromSeconds(packPrototype.AnimationDuration);
            vendComponent.SpriteName        = packPrototype.SpriteName;
            if (!string.IsNullOrEmpty(vendComponent.SpriteName))
            {
                if (TryComp <SpriteComponent>(vendComponent.Owner, out var spriteComp))
                {
                    const string vendingMachineRSIPath = "Structures/Machines/VendingMachines/{0}.rsi";
                    spriteComp.BaseRSIPath = string.Format(vendingMachineRSIPath, vendComponent.SpriteName);
                }
            }

            AddInventoryFromPrototype(uid, packPrototype.StartingInventory, InventoryType.Regular, vendComponent);
            AddInventoryFromPrototype(uid, packPrototype.EmaggedInventory, InventoryType.Emagged, vendComponent);
            AddInventoryFromPrototype(uid, packPrototype.ContrabandInventory, InventoryType.Contraband, vendComponent);
        }
Ejemplo n.º 19
0
        /// <summary>
        /// play emote and return a string of text describing the emote
        /// </summary>
        public string PlayEmote(string emote)
        {
            var output = emote;

            if (!string.IsNullOrWhiteSpace(emote))
            {
                var soundToPlay = emote;

                if (_prototypeManager.TryIndex(emote, out EmotePrototype proto))
                {
                    output      = _emoteRandom.Pick(proto.Output);
                    soundToPlay = proto.SoundCollectionID;

                    foreach (var e in proto.Effect)
                    {
                        output = e.PlayEffect(Owner, output);
                    }

                    var soundCollection = _prototypeManager.Index <SoundCollectionPrototype>(soundToPlay);
                    if (soundCollection != null)
                    {
                        var file = _emoteRandom.Pick(soundCollection.PickFiles);
                        Owner.GetComponent <SoundComponent>().Play(file, AudioParams.Default.WithVolume(4f));
                    }
                }
            }

            return(output);
        }
Ejemplo n.º 20
0
        /// <summary>
        ///    Loads the given BodyPartPrototype - current data on this BodyPart will be overwritten!
        /// </summary>
        public virtual void LoadFromPrototype(BodyPartPrototype data)
        {
            Name           = data.Name;
            Plural         = data.Plural;
            PartType       = data.PartType;
            RSIPath        = data.RSIPath;
            RSIState       = data.RSIState;
            MaxDurability  = data.Durability;
            CurrentDamages = new BiologicalDamageContainer();
            Resistance     = data.Resistance;
            Size           = data.Size;
            Compatibility  = data.Compatibility;
            Properties     = data.Properties;
            //_surgeryData = (ISurgeryData) Activator.CreateInstance(null, data.SurgeryDataName);
            //TODO: figure out a way to convert a string name in the YAML to the proper class (reflection won't work for reasons)
            _surgeryData = new BiologicalSurgeryData(this);
            IPrototypeManager prototypeManager = IoCManager.Resolve <IPrototypeManager>();

            foreach (string mechanismPrototypeID in data.Mechanisms)
            {
                if (!prototypeManager.TryIndex(mechanismPrototypeID, out MechanismPrototype mechanismData))
                {
                    throw new InvalidOperationException("No MechanismPrototype was found with the name " + mechanismPrototypeID + " while loading a BodyPartPrototype!");
                }
                _mechanisms.Add(new Mechanism(mechanismData));
            }
        }
 public void UpdateList(Label number, double numberVal, ItemList list, PowerMonitoringConsoleEntry[] listVal)
 {
     number.Text = Loc.GetString("power-monitoring-window-value", ("value", numberVal));
     // This magic is important to prevent scrolling issues.
     while (list.Count > listVal.Length)
     {
         list.RemoveAt(list.Count - 1);
     }
     while (list.Count < listVal.Length)
     {
         list.AddItem("YOU SHOULD NEVER SEE THIS (REALLY!)", null, false);
     }
     // Now overwrite the items properly...
     for (var i = 0; i < listVal.Length; i++)
     {
         var ent = listVal[i];
         _prototypeManager.TryIndex(ent.IconEntityPrototypeId, out EntityPrototype? entityPrototype);
         IRsiStateLike?iconState = null;
         if (entityPrototype != null)
         {
             iconState = SpriteComponent.GetPrototypeIcon(entityPrototype, StaticIoC.ResC);
         }
         var icon = iconState?.GetFrame(RSI.State.Direction.South, 0);
         var item = list[i];
         item.Text = $"{ent.NameLocalized} {Loc.GetString("power-monitoring-window-value", ("value", ent.Size))}";
         item.Icon = icon;
     }
 }
Ejemplo n.º 22
0
        /// <summary>
        ///     Try to split this stack into two.
        ///     See <see cref="StackSplitEvent"/>
        /// </summary>
        private void OnStackSplit(EntityUid uid, StackComponent stack, StackSplitEvent args)
        {
            // If the stack doesn't have enough things as specified in the parameters, we do nothing.
            if (stack.Count < args.Amount)
            {
                return;
            }

            // Get a prototype ID to spawn the new entity. Null is also valid, although it should rarely be picked...
            var prototype = _prototypeManager.TryIndex <StackPrototype>(stack.StackTypeId, out var stackType)
                ? stackType.Spawn
                : stack.Owner.Prototype?.ID ?? null;

            // Remove the amount of things we want to split from the original stack...
            RaiseLocalEvent(uid, new StackChangeCountEvent(stack.Count - args.Amount), false);

            // Set the output parameter in the event instance to the newly split stack.
            args.Result = EntityManager.SpawnEntity(prototype, args.SpawnPosition);

            if (args.Result.TryGetComponent(out StackComponent? stackComp))
            {
                // Set the split stack's count.
                RaiseLocalEvent(args.Result.Uid, new StackChangeCountEvent(args.Amount), false);
            }
        }
Ejemplo n.º 23
0
        /// <summary>
        ///     Try to split this stack into two. Returns a non-null <see cref="Robust.Shared.GameObjects.EntityUid"/> if successful.
        /// </summary>
        public EntityUid?Split(EntityUid uid, int amount, EntityCoordinates spawnPosition, SharedStackComponent?stack = null)
        {
            if (!Resolve(uid, ref stack))
            {
                return(null);
            }

            // Get a prototype ID to spawn the new entity. Null is also valid, although it should rarely be picked...
            var prototype = _prototypeManager.TryIndex <StackPrototype>(stack.StackTypeId, out var stackType)
                ? stackType.Spawn
                : Prototype(stack.Owner)?.ID;

            // Try to remove the amount of things we want to split from the original stack...
            if (!Use(uid, amount, stack))
            {
                return(null);
            }

            // Set the output parameter in the event instance to the newly split stack.
            var entity = Spawn(prototype, spawnPosition);

            if (TryComp(entity, out SharedStackComponent? stackComp))
            {
                // Set the split stack's count.
                SetCount(entity, amount, stackComp);
                // Don't let people dupe unlimited stacks
                stackComp.Unlimited = false;
            }

            return(entity);
        }
Ejemplo n.º 24
0
    /// <summary>
    ///     Queue an explosion, with a specified epicenter and set of starting tiles.
    /// </summary>
    public void QueueExplosion(MapCoordinates epicenter,
                               string typeId,
                               float totalIntensity,
                               float slope,
                               float maxTileIntensity,
                               float tileBreakScale = 1f,
                               int maxTileBreak     = int.MaxValue,
                               bool canCreateVacuum = true,
                               bool addLog          = false)
    {
        if (totalIntensity <= 0 || slope <= 0)
        {
            return;
        }

        if (!_prototypeManager.TryIndex <ExplosionPrototype>(typeId, out var type))
        {
            Logger.Error($"Attempted to spawn unknown explosion prototype: {type}");
            return;
        }

        if (addLog) // dont log if already created a separate, more detailed, log.
        {
            _adminLogger.Add(LogType.Explosion, LogImpact.High, $"Explosion spawned at {epicenter:coordinates} with intensity {totalIntensity} slope {slope}");
        }

        _explosionQueue.Enqueue(() => SpawnExplosion(epicenter, type, totalIntensity,
                                                     slope, maxTileIntensity, tileBreakScale, maxTileBreak, canCreateVacuum));
    }
Ejemplo n.º 25
0
        private void RefreshContentsDisplay(IReadOnlyList <Solution.ReagentQuantity> reagents, List <EntityUid> solids)
        {
            _reagents.Clear();
            _menu.IngredientsListReagents.Clear();
            foreach (var reagent in reagents)
            {
                _prototypeManager.TryIndex(reagent.ReagentId, out ReagentPrototype proto);
                var reagentAdded = _menu.IngredientsListReagents.AddItem($"{reagent.Quantity} {proto.Name}");
                var reagentIndex = _menu.IngredientsListReagents.IndexOf(reagentAdded);
                _reagents.Add(reagentIndex, reagent);
            }

            _solids.Clear();
            _menu.IngredientsList.Clear();
            foreach (var entityID in solids)
            {
                if (!_entityManager.TryGetEntity(entityID, out var entity))
                {
                    return;
                }

                if (!entity.Deleted && entity.TryGetComponent(out IconComponent icon))
                {
                    var solidItem = _menu.IngredientsList.AddItem(entity.Name, icon.Icon.Default);

                    var solidIndex = _menu.IngredientsList.IndexOf(solidItem);
                    _solids.Add(solidIndex, entityID);
                }
            }
        }
Ejemplo n.º 26
0
        private void OnExamineSolution(EntityUid uid, ExaminableSolutionComponent examinableComponent,
                                       ExaminedEvent args)
        {
            if (!args.Examined.TryGetComponent(out SolutionContainerManagerComponent? solutionsManager) ||
                !solutionsManager.Solutions.TryGetValue(examinableComponent.Solution, out var solutionHolder))
            {
                return;
            }

            if (solutionHolder.Contents.Count == 0)
            {
                args.PushText(Loc.GetString("shared-solution-container-component-on-examine-empty-container"));
                return;
            }

            var primaryReagent = solutionHolder.GetPrimaryReagentId();

            if (!_prototypeManager.TryIndex(primaryReagent, out ReagentPrototype? proto))
            {
                Logger.Error(
                    $"{nameof(Solution)} could not find the prototype associated with {primaryReagent}.");
                return;
            }

            var colorHex = solutionHolder.Color
                           .ToHexNoAlpha(); //TODO: If the chem has a dark color, the examine text becomes black on a black background, which is unreadable.
            var messageString = "shared-solution-container-component-on-examine-main-text";

            args.PushMarkup(Loc.GetString(messageString,
                                          ("color", colorHex),
                                          ("wordedAmount", Loc.GetString(solutionHolder.Contents.Count == 1
                    ? "shared-solution-container-component-on-examine-worded-amount-one-reagent"
                    : "shared-solution-container-component-on-examine-worded-amount-multiple-reagents")),
                                          ("desc", Loc.GetString(proto.PhysicalDescription))));
        }
Ejemplo n.º 27
0
        private void UpdateBarSignVisuals(BarSignComponent component)
        {
            if (component.CurrentSign == null)
            {
                return;
            }

            if (!_prototypeManager.TryIndex(component.CurrentSign, out BarSignPrototype? prototype))
            {
                Logger.ErrorS("barSign", $"Invalid bar sign prototype: \"{component.CurrentSign}\"");
                return;
            }

            if (component.Owner.TryGetComponent(out SpriteComponent? sprite))
            {
                if (!component.Owner.TryGetComponent(out ApcPowerReceiverComponent? receiver) || receiver.Powered)
                {
                    sprite.LayerSetState(0, "empty");
                    sprite.LayerSetShader(0, "shaded");
                }
                else
                {
                    sprite.LayerSetState(0, prototype.Icon);
                    sprite.LayerSetShader(0, "unshaded");
                }
            }
Ejemplo n.º 28
0
        /// <summary>
        ///     Loops through each reagent in _internalSolution,
        ///     and calls <see cref="IMetabolizable.Metabolize"/> for each of them.
        /// </summary>
        /// <param name="frameTime">The time since the last metabolism tick in seconds.</param>
        private void ProcessNutrients(float frameTime)
        {
            if (!Owner.TryGetComponent(out BloodstreamComponent bloodstream))
            {
                return;
            }

            if (bloodstream.Solution.CurrentVolume == 0)
            {
                return;
            }

            // Run metabolism for each reagent, remove metabolized reagents
            // Using ToList here lets us edit reagents while iterating
            foreach (var reagent in bloodstream.Solution.ReagentList.ToList())
            {
                if (!_prototypeManager.TryIndex(reagent.ReagentId, out ReagentPrototype prototype))
                {
                    continue;
                }

                // Run metabolism code for each reagent
                foreach (var metabolizable in prototype.Metabolism)
                {
                    var reagentDelta = metabolizable.Metabolize(Owner, reagent.ReagentId, frameTime);
                    bloodstream.Solution.TryRemoveReagent(reagent.ReagentId, reagentDelta);
                }
            }
        }
    private void OnUserDamageModified(EntityUid uid, BlockingUserComponent component, DamageModifyEvent args)
    {
        if (TryComp <BlockingComponent>(component.BlockingItem, out var blockingComponent))
        {
            if (_proto.TryIndex(blockingComponent.PassiveBlockDamageModifer, out DamageModifierSetPrototype? passiveblockModifier) && !blockingComponent.IsBlocking)
            {
                args.Damage = DamageSpecifier.ApplyModifierSet(args.Damage, passiveblockModifier);
            }

            if (_proto.TryIndex(blockingComponent.ActiveBlockDamageModifier, out DamageModifierSetPrototype? activeBlockModifier) && blockingComponent.IsBlocking)
            {
                args.Damage = DamageSpecifier.ApplyModifierSet(args.Damage, activeBlockModifier);
                SoundSystem.Play(blockingComponent.BlockSound.GetSound(), Filter.Pvs(component.Owner, entityManager: EntityManager), component.Owner, AudioHelpers.WithVariation(0.2f));
            }
        }
    }
Ejemplo n.º 30
0
    /// <summary>
    /// Finds 2-5 random, alive entities that can host diseases
    /// and gives them a randomly selected disease.
    /// They all get the same disease.
    /// </summary>
    public override void Startup()
    {
        base.Startup();
        HashSet <EntityUid>            stationsToNotify = new();
        List <DiseaseCarrierComponent> aliveList        = new();

        foreach (var(carrier, mobState) in _entityManager.EntityQuery <DiseaseCarrierComponent, MobStateComponent>())
        {
            if (!mobState.IsDead())
            {
                aliveList.Add(carrier);
            }
        }
        _random.Shuffle(aliveList);
        /// We're going to filter the above out to only alive mobs. Might change after future mobstate rework

        var toInfect = _random.Next(2, 5);

        var diseaseName = _random.Pick(NotTooSeriousDiseases);

        if (!_prototypeManager.TryIndex(diseaseName, out DiseasePrototype? disease))
        {
            return;
        }

        var diseaseSystem = EntitySystem.Get <DiseaseSystem>();
        var entSysMgr     = IoCManager.Resolve <IEntitySystemManager>();
        var stationSystem = entSysMgr.GetEntitySystem <StationSystem>();
        var chatSystem    = entSysMgr.GetEntitySystem <ChatSystem>();

        // Now we give it to people in the list of living disease carriers earlier
        foreach (var target in aliveList)
        {
            if (toInfect-- == 0)
            {
                break;
            }

            diseaseSystem.TryAddDisease(target.Owner, disease, target);

            var station = stationSystem.GetOwningStation(target.Owner);
            if (station == null)
            {
                continue;
            }
            stationsToNotify.Add((EntityUid)station);
        }

        if (!AnnounceEvent)
        {
            return;
        }
        foreach (var station in stationsToNotify)
        {
            chatSystem.DispatchStationAnnouncement(station, Loc.GetString("station-event-disease-outbreak-announcement"),
                                                   playDefaultSound: false, colorOverride: Color.YellowGreen);
        }
    }