Пример #1
0
        public bool TurnOn(IEntity user)
        {
            if (Activated)
            {
                return(false);
            }

            if (Cell == null)
            {
                SoundSystem.Play(Filter.Pvs(Owner), TurnOnFailSound.GetSound(), Owner);
                Owner.PopupMessage(user, Loc.GetString("handheld-light-component-cell-missing-message"));
                UpdateLightAction();
                return(false);
            }

            // To prevent having to worry about frame time in here.
            // Let's just say you need a whole second of charge before you can turn it on.
            // Simple enough.
            if (Wattage > Cell.CurrentCharge)
            {
                SoundSystem.Play(Filter.Pvs(Owner), TurnOnFailSound.GetSound(), Owner);
                Owner.PopupMessage(user, Loc.GetString("handheld-light-component-cell-dead-message"));
                UpdateLightAction();
                return(false);
            }

            Activated = true;
            UpdateLightAction();
            SetState(true);
            Owner.EntityManager.EventBus.QueueEvent(EventSource.Local, new ActivateHandheldLightMessage(this));

            SoundSystem.Play(Filter.Pvs(Owner), TurnOnSound.GetSound(), Owner);
            return(true);
        }
        async Task <bool> IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs)
        {
            if (eventArgs.Target == null || !eventArgs.CanReach)
            {
                return(false);
            }

            if (eventArgs.Target.TryGetComponent(out ReagentTankComponent? tank) &&
                eventArgs.Target.TryGetComponent(out ISolutionInteractionsComponent? targetSolution) &&
                targetSolution.CanDrain &&
                Owner.TryGetComponent(out SolutionContainerComponent? container))
            {
                var trans = ReagentUnit.Min(container.EmptyVolume, targetSolution.DrainAvailable);
                if (trans > 0)
                {
                    var drained = targetSolution.Drain(trans);
                    container.TryAddSolution(drained);

                    SoundSystem.Play(Filter.Pvs(Owner), _refillSound.GetSound(), Owner);
                    eventArgs.Target.PopupMessage(eventArgs.User, Loc.GetString("fire-extinguisher-component-after-interact-refilled-message", ("owner", Owner)));
                }

                return(true);
            }

            return(false);
        }
Пример #3
0
    private bool TrySetupFTL(ShuttleComponent shuttle, [NotNullWhen(true)] out FTLComponent?component)
    {
        var uid = shuttle.Owner;

        component = null;

        if (HasComp <FTLComponent>(uid))
        {
            _sawmill.Warning($"Tried queuing {ToPrettyString(uid)} which already has HyperspaceComponent?");
            return(false);
        }

        if (TryComp <FTLDestinationComponent>(uid, out var dest))
        {
            dest.Enabled = false;
        }

        _thruster.DisableLinearThrusters(shuttle);
        _thruster.EnableLinearThrustDirection(shuttle, DirectionFlag.North);
        _thruster.SetAngularThrust(shuttle, false);
        // TODO: Maybe move this to docking instead?
        SetDocks(uid, false);

        component = AddComp <FTLComponent>(uid);
        // TODO: Need BroadcastGrid to not be bad.
        SoundSystem.Play(_startupSound.GetSound(), Filter.Empty().AddInRange(Transform(uid).MapPosition, GetSoundRange(component.Owner)), _startupSound.Params);
        // Make sure the map is setup before we leave to avoid pop-in (e.g. parallax).
        SetupHyperspace();
        return(true);
    }
Пример #4
0
    /// <summary>
    /// Dispatches an announcement on a specific station
    /// </summary>
    /// <param name="source">The entity making the announcement (used to determine the station)</param>
    /// <param name="message">The contents of the message</param>
    /// <param name="sender">The sender (Communications Console in Communications Console Announcement)</param>
    /// <param name="playDefaultSound">Play the announcement sound</param>
    /// <param name="colorOverride">Optional color for the announcement message</param>
    public void DispatchStationAnnouncement(EntityUid source, string message, string sender = "Central Command",
                                            bool playDefaultSound = true, SoundSpecifier?announcementSound = null, Color?colorOverride = null)
    {
        var messageWrap = Loc.GetString("chat-manager-sender-announcement-wrap-message", ("sender", sender));
        var station     = _stationSystem.GetOwningStation(source);

        if (station == null)
        {
            // you can't make a station announcement without a station
            return;
        }

        if (!EntityManager.TryGetComponent <StationDataComponent>(station, out var stationDataComp))
        {
            return;
        }

        var filter = _stationSystem.GetInStation(stationDataComp);

        _chatManager.ChatMessageToManyFiltered(filter, ChatChannel.Radio, message, messageWrap, source, false, colorOverride);

        if (playDefaultSound)
        {
            SoundSystem.Play(announcementSound?.GetSound() ?? DefaultAnnouncementSound, filter, AudioParams.Default.WithVolume(-2f));
        }

        _adminLogger.Add(LogType.Chat, LogImpact.Low, $"Station Announcement on {station} from {sender}: {message}");
    }
Пример #5
0
        public bool TryInsertBullet(EntityUid user, EntityUid entity)
        {
            if (!Entities.TryGetComponent(entity, out AmmoComponent? ammoComponent))
            {
                return(false);
            }

            if (ammoComponent.Caliber != _caliber)
            {
                Owner.PopupMessage(user, Loc.GetString("revolver-barrel-component-try-inser-bullet-wrong-caliber"));
                return(false);
            }

            // Functions like a stack
            // These are inserted in reverse order but then when fired Cycle will go through in order
            // The reason we don't just use an actual stack is because spin can select a random slot to point at
            for (var i = _ammoSlots.Length - 1; i >= 0; i--)
            {
                var slot = _ammoSlots[i];
                if (slot == default)
                {
                    _currentSlot  = i;
                    _ammoSlots[i] = entity;
                    _ammoContainer.Insert(entity);
                    SoundSystem.Play(Filter.Pvs(Owner), _soundInsert.GetSound(), Owner, AudioParams.Default.WithVolume(-2));

                    Dirty();
                    UpdateAppearance();
                    return(true);
                }
            }

            Owner.PopupMessage(user, Loc.GetString("revolver-barrel-component-try-inser-bullet-ammo-full"));
            return(false);
        }
        private void PlaceAt(IMapGrid mapGrid, EntityCoordinates location, ushort tileId, float offset = 0)
        {
            var variant = _random.Pick(((ContentTileDefinition)_tileDefinitionManager[tileId]).PlacementVariants);

            mapGrid.SetTile(location.Offset(new Vector2(offset, offset)), new Tile(tileId, 0, variant));
            SoundSystem.Play(Filter.Pvs(location), _placeTileSound.GetSound(), location, AudioHelpers.WithVariation(0.125f));
        }
        public void ToggleToiletSeat()
        {
            IsSeatUp = !IsSeatUp;
            SoundSystem.Play(Filter.Pvs(Owner), _toggleSound.GetSound(), Owner, AudioHelpers.WithVariation(0.05f));

            UpdateSprite();
        }
        async Task <bool> IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs)
        {
            var solutionContainerSystem = EntitySystem.Get <SolutionContainerSystem>();

            if (eventArgs.Target == null || !eventArgs.CanReach)
            {
                return(false);
            }

            var targetEntity = eventArgs.Target;

            if (eventArgs.Target.HasComponent <ReagentTankComponent>() &&
                solutionContainerSystem.TryGetDrainableSolution(targetEntity.Uid, out var targetSolution) &&
                solutionContainerSystem.TryGetDrainableSolution(Owner.Uid, out var container))
            {
                var transfer = ReagentUnit.Min(container.AvailableVolume, targetSolution.DrainAvailable);
                if (transfer > 0)
                {
                    var drained = solutionContainerSystem.Drain(targetEntity.Uid, targetSolution, transfer);
                    solutionContainerSystem.TryAddSolution(Owner.Uid, container, drained);

                    SoundSystem.Play(Filter.Pvs(Owner), _refillSound.GetSound(), Owner);
                    eventArgs.Target.PopupMessage(eventArgs.User,
                                                  Loc.GetString("fire-extinguisher-component-after-interact-refilled-message", ("owner", Owner)));
                }

                return(true);
            }

            return(false);
        }
 private void TeleportLoop()
 {
     if (_currentState == CargoTelepadState.Idle && _teleportQueue.Count > 0)
     {
         _currentState = CargoTelepadState.Charging;
         if (Owner.TryGetComponent <SpriteComponent>(out var spriteComponent) && spriteComponent.LayerCount > 0)
         {
             spriteComponent.LayerSetState(0, "idle");
         }
         Owner.SpawnTimer((int)(TeleportDelay * 1000), () =>
         {
             if (!Deleted && !Owner.Deleted && _currentState == CargoTelepadState.Charging && _teleportQueue.Count > 0)
             {
                 _currentState = CargoTelepadState.Teleporting;
                 if (Owner.TryGetComponent <SpriteComponent>(out var spriteComponent) && spriteComponent.LayerCount > 0)
                 {
                     spriteComponent.LayerSetState(0, "beam");
                 }
                 Owner.SpawnTimer((int)(TeleportDuration * 1000), () =>
                 {
                     if (!Deleted && !Owner.Deleted && _currentState == CargoTelepadState.Teleporting && _teleportQueue.Count > 0)
                     {
                         SoundSystem.Play(Filter.Pvs(Owner), _teleportSound.GetSound(), Owner, AudioParams.Default.WithVolume(-8f));
                         Owner.EntityManager.SpawnEntity(_teleportQueue[0].Product, Owner.Transform.Coordinates);
                         _teleportQueue.RemoveAt(0);
                         if (Owner.TryGetComponent <SpriteComponent>(out var spriteComponent) && spriteComponent.LayerCount > 0)
                         {
                             spriteComponent.LayerSetState(0, "idle");
                         }
                         _currentState = CargoTelepadState.Idle;
                         TeleportLoop();
                     }
                 });
        async Task <bool> IInteractUsing.InteractUsing(InteractUsingEventArgs args)
        {
            if (!args.User.TryGetComponent <IHandsComponent>(out var hands))
            {
                Owner.PopupMessage(args.User, Loc.GetString("ame-part-component-interact-using-no-hands"));
                return(false);
            }

            if (!args.Using.TryGetComponent <ToolComponent>(out var tool) || !tool.Qualities.Contains(_qualityNeeded))
            {
                return(false);
            }

            if (!_mapManager.TryGetGrid(args.ClickLocation.GetGridId(_serverEntityManager), out var mapGrid))
            {
                return(false); // No AME in space.
            }
            var snapPos = mapGrid.TileIndicesFor(args.ClickLocation);

            if (mapGrid.GetAnchoredEntities(snapPos).Any(sc => _serverEntityManager.HasComponent <AMEShieldComponent>(sc)))
            {
                Owner.PopupMessage(args.User, Loc.GetString("ame-part-component-shielding-already-present"));
                return(true);
            }

            var ent = _serverEntityManager.SpawnEntity("AMEShielding", mapGrid.GridTileToLocal(snapPos));

            ent.Transform.LocalRotation = Owner.Transform.LocalRotation;

            SoundSystem.Play(Filter.Pvs(Owner), _unwrapSound.GetSound(), Owner);

            Owner.QueueDelete();

            return(true);
        }
        public bool TryEjectCell(IEntity user)
        {
            if (PowerCell == null || !PowerCellRemovable)
            {
                return(false);
            }

            if (!user.TryGetComponent(out HandsComponent? hands))
            {
                return(false);
            }

            var cell = PowerCell;

            if (!_powerCellContainer.Remove(cell.Owner))
            {
                return(false);
            }

            Dirty();
            UpdateAppearance();

            if (!hands.PutInHand(cell.Owner.GetComponent <ItemComponent>()))
            {
                cell.Owner.Transform.Coordinates = user.Transform.Coordinates;
            }

            SoundSystem.Play(Filter.Pvs(Owner), _soundPowerCellEject.GetSound(), Owner, AudioParams.Default.WithVolume(-2));
            return(true);
        }
Пример #12
0
        public override HashSet <EntityUid> Gib(bool gibParts = false)
        {
            var gibs = base.Gib(gibParts);

            var xform       = _entMan.GetComponent <TransformComponent>(Owner);
            var coordinates = xform.Coordinates;

            // These have already been forcefully removed from containers so run it here.
            foreach (var part in gibs)
            {
                _entMan.EventBus.RaiseLocalEvent(part, new PartGibbedEvent(Owner, gibs), true);
            }

            SoundSystem.Play(_gibSound.GetSound(), Filter.Pvs(Owner, entityManager: _entMan), coordinates, AudioHelpers.WithVariation(0.025f));

            if (_entMan.TryGetComponent(Owner, out ContainerManagerComponent? container))
            {
                foreach (var cont in container.GetAllContainers())
                {
                    foreach (var ent in cont.ContainedEntities)
                    {
                        cont.ForceRemove(ent);
                        _entMan.GetComponent <TransformComponent>(ent).Coordinates = coordinates;
                        ent.RandomOffset(0.25f);
                    }
                }
            }

            _entMan.EventBus.RaiseLocalEvent(Owner, new BeingGibbedEvent(gibs), false);
            _entMan.QueueDeleteEntity(Owner);

            return(gibs);
        }
Пример #13
0
        /// <summary>
        /// Russian Roulette
        /// </summary>
        public void Spin()
        {
            var random = _random.Next(_ammoSlots.Length - 1);

            _currentSlot = random;
            SoundSystem.Play(Filter.Pvs(Owner), _soundSpin.GetSound(), Owner, AudioParams.Default.WithVolume(-2));
            Dirty();
        }
Пример #14
0
        public bool TryDoInject(IEntity?target, IEntity user)
        {
            if (target == null || !EligibleEntity(target))
            {
                return(false);
            }

            string?msgFormat = null;

            if (target == user)
            {
                msgFormat = "hypospray-component-inject-self-message";
            }
            else if (EligibleEntity(user) && ClumsyComponent.TryRollClumsy(user, ClumsyFailChance))
            {
                msgFormat = "hypospray-component-inject-self-clumsy-message";
                target    = user;
            }

            if (_solution == null || _solution.CurrentVolume == 0)
            {
                user.PopupMessageCursor(Loc.GetString("hypospray-component-empty-message"));
                return(true);
            }

            user.PopupMessage(Loc.GetString(msgFormat ?? "hypospray-component-inject-other-message", ("other", target)));
            if (target != user)
            {
                target.PopupMessage(Loc.GetString("hypospray-component-feel-prick-message"));
                var meleeSys = EntitySystem.Get <MeleeWeaponSystem>();
                var angle    = Angle.FromWorldVec(target.Transform.WorldPosition - user.Transform.WorldPosition);
                meleeSys.SendLunge(angle, user);
            }

            SoundSystem.Play(Filter.Pvs(user), _injectSound.GetSound(), user);

            var targetSolution = target.GetComponent <SolutionContainerComponent>();

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

            if (realTransferAmount <= 0)
            {
                user.PopupMessage(user, Loc.GetString("hypospray-component-transfer-already-full-message ", ("owner", targetSolution.Owner)));
                return(true);
            }

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

            if (!targetSolution.CanAddSolution(removedSolution))
            {
                return(true);
            }

            removedSolution.DoEntityReaction(target, ReactionMethod.Injection);

            targetSolution.TryAddSolution(removedSolution);
Пример #15
0
        public override void Added()
        {
            _chatManager.DispatchServerAnnouncement(Loc.GetString("rule-traitor-added-announcement"));

            var filter = Filter.Empty()
                         .AddWhere(session => ((IPlayerSession)session).ContentData()?.Mind?.HasRole <TraitorRole>() ?? false);

            SoundSystem.Play(filter, _addedSound.GetSound(), AudioParams.Default);
        }
Пример #16
0
        public void FireEffects(EntityUid user, float distance, Angle angle, EntityUid?hitEntity = null)
        {
            var effectSystem = EntitySystem.Get <EffectSystem>();

            _startTime = _gameTiming.CurTime;
            _deathTime = _startTime + TimeSpan.FromSeconds(1);

            var mapManager = IoCManager.Resolve <IMapManager>();

            // We'll get the effects relative to the grid / map of the firer
            var gridOrMap = _entMan.GetComponent <TransformComponent>(user).GridID == GridId.Invalid ? mapManager.GetMapEntityId(_entMan.GetComponent <TransformComponent>(user).MapID) :
                            mapManager.GetGrid(_entMan.GetComponent <TransformComponent>(user).GridID).GridEntityId;

            var parentXform = _entMan.GetComponent <TransformComponent>(gridOrMap);

            var localCoordinates = new EntityCoordinates(gridOrMap, parentXform.InvWorldMatrix.Transform(_entMan.GetComponent <TransformComponent>(user).WorldPosition));
            var localAngle       = angle - parentXform.WorldRotation;

            var afterEffect = AfterEffects(localCoordinates, localAngle, distance, 1.0f);

            if (afterEffect != null)
            {
                effectSystem.CreateParticle(afterEffect);
            }

            // if we're too close we'll stop the impact and muzzle / impact sprites from clipping
            if (distance > 1.0f)
            {
                var impactEffect = ImpactFlash(distance, localAngle);
                if (impactEffect != null)
                {
                    effectSystem.CreateParticle(impactEffect);
                }

                var muzzleEffect = MuzzleFlash(localCoordinates, localAngle);
                if (muzzleEffect != null)
                {
                    effectSystem.CreateParticle(muzzleEffect);
                }
            }

            if (hitEntity != null && _soundHitWall != null)
            {
                // TODO: No wall component so ?
                var offset      = localAngle.ToVec().Normalized / 2;
                var coordinates = localCoordinates.Offset(offset);
                SoundSystem.Play(Filter.Pvs(coordinates), _soundHitWall.GetSound(), coordinates);
            }

            Owner.SpawnTimer((int)_deathTime.TotalMilliseconds, () =>
            {
                if (!_entMan.Deleted(Owner))
                {
                    _entMan.DeleteEntity(Owner);
                }
            });
        }
        //Called every 10 seconds
        public void Update()
        {
            CheckContents();

            if (DoSoulBeep && Appearance != null && Appearance.TryGetData(MorgueVisuals.HasSoul, out bool hasSoul) && hasSoul)
            {
                SoundSystem.Play(Filter.Pvs(Owner), _occupantHasSoulAlarmSound.GetSound(), Owner);
            }
        }
Пример #18
0
        public void React(IEntity solutionEntity, double intensity)
        {
            if (!solutionEntity.TryGetComponent(out SolutionContainerComponent? contents))
            {
                return;
            }

            var solution = contents.SplitSolution(contents.MaxVolume);
            // We take the square root so it becomes harder to reach higher amount values
            var amount = (int)Math.Round(_rangeConstant + _rangeMultiplier * Math.Sqrt(intensity));

            amount = Math.Min(amount, _maxRange);

            if (_diluteReagents)
            {
                // The maximum value of solutionFraction is _reagentMaxConcentrationFactor, achieved when amount = 0
                // The infimum of solutionFraction is 0, which is approached when amount tends to infinity
                // solutionFraction is equal to 1 only when amount equals _reagentDilutionStart
                float solutionFraction;
                if (amount >= _reagentDilutionStart)
                {
                    // Weird formulas here but basically when amount increases, solutionFraction gets closer to 0 in a reciprocal manner
                    // _reagentDilutionFactor defines how fast solutionFraction gets closer to 0
                    solutionFraction = 1 / (_reagentDilutionFactor * (amount - _reagentDilutionStart) + 1);
                }
                else
                {
                    // Here when amount decreases, solutionFraction gets closer to _reagentMaxConcentrationFactor in a linear manner
                    solutionFraction = amount * (1 - _reagentMaxConcentrationFactor) / _reagentDilutionStart +
                                       _reagentMaxConcentrationFactor;
                }
                solution.RemoveSolution(solution.TotalVolume * solutionFraction);
            }

            if (!_mapManager.TryFindGridAt(solutionEntity.Transform.MapPosition, out var grid))
            {
                return;
            }

            var coords = grid.MapToGrid(solutionEntity.Transform.MapPosition);

            var ent = solutionEntity.EntityManager.SpawnEntity(_prototypeId, coords.SnapToGrid());

            var areaEffectComponent = GetAreaEffectComponent(ent);

            if (areaEffectComponent == null)
            {
                Logger.Error("Couldn't get AreaEffectComponent from " + _prototypeId);
                ent.QueueDelete();
                return;
            }

            areaEffectComponent.TryAddSolution(solution);
            areaEffectComponent.Start(amount, _duration, _spreadDelay, _removeDelay);

            SoundSystem.Play(Filter.Pvs(solutionEntity), _sound.GetSound(), solutionEntity, AudioHelpers.WithVariation(0.125f));
        }
Пример #19
0
        //Called every 10 seconds
        public void Update()
        {
            CheckContents();

            if (DoSoulBeep && _entMan.TryGetComponent <AppearanceComponent>(Owner, out var appearance) &&
                appearance.TryGetData(MorgueVisuals.HasSoul, out bool hasSoul) && hasSoul)
            {
                SoundSystem.Play(Filter.Pvs(Owner), _occupantHasSoulAlarmSound.GetSound(), Owner);
            }
        }
Пример #20
0
    public void DispatchStationEventMusic(EntityUid source, SoundSpecifier sound, StationEventMusicType type)
    {
        var audio     = AudioParams.Default.WithVolume(-8);
        var soundFile = sound.GetSound();
        var msg       = new StationEventMusicEvent(soundFile, type, audio);

        var filter = GetStationAndPvs(source);

        RaiseNetworkEvent(msg, filter);
    }
Пример #21
0
        void IBodyPartAdded.BodyPartAdded(BodyPartAddedEventArgs args)
        {
            if (args.Part.PartType != BodyPartType.Hand)
            {
                return;
            }

            // If this annoys you, which it should.
            // Ping Smugleaf.
            var location = args.Part.Symmetry switch
            {
                BodyPartSymmetry.None => HandLocation.Middle,
                BodyPartSymmetry.Left => HandLocation.Left,
                BodyPartSymmetry.Right => HandLocation.Right,
                _ => throw new ArgumentOutOfRangeException()
            };

            AddHand(args.Slot, location);
        }

        void IBodyPartRemoved.BodyPartRemoved(BodyPartRemovedEventArgs args)
        {
            if (args.Part.PartType != BodyPartType.Hand)
            {
                return;
            }

            RemoveHand(args.Slot);
        }

        bool IDisarmedAct.Disarmed(DisarmedActEvent @event)
        {
            if (BreakPulls())
            {
                return(false);
            }

            var source = @event.Source;
            var target = @event.Target;

            SoundSystem.Play(Filter.Pvs(source), _disarmedSound.GetSound(), source, AudioHelpers.WithVariation(0.025f));

            if (ActiveHand != null && Drop(ActiveHand, false))
            {
                source.PopupMessageOtherClients(Loc.GetString("hands-component-disarm-success-others-message", ("disarmer", Name: _entities.GetComponent <MetaDataComponent>(source).EntityName), ("disarmed", Name: _entities.GetComponent <MetaDataComponent>(target).EntityName)));
                source.PopupMessageCursor(Loc.GetString("hands-component-disarm-success-message", ("disarmed", Name: _entities.GetComponent <MetaDataComponent>(target).EntityName)));
            }
            else
            {
                source.PopupMessageOtherClients(Loc.GetString("hands-component-shove-success-others-message", ("shover", Name: _entities.GetComponent <MetaDataComponent>(source).EntityName), ("shoved", Name: _entities.GetComponent <MetaDataComponent>(target).EntityName)));
                source.PopupMessageCursor(Loc.GetString("hands-component-shove-success-message", ("shoved", Name: _entities.GetComponent <MetaDataComponent>(target).EntityName)));
            }

            return(true);
        }
Пример #22
0
        private void PlaySound(EntityUid uid, SoundSpecifier sound, float varyPitch = 0f,
                               NukeComponent?component = null)
        {
            if (!Resolve(uid, ref component))
            {
                return;
            }

            SoundSystem.Play(Filter.Pvs(uid), sound.GetSound(),
                             uid, AudioHelpers.WithVariation(varyPitch).WithVolume(-5f));
        }
        async Task <bool> IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
        {
            if (string.IsNullOrEmpty(_slice))
            {
                return(false);
            }

            var scs = EntitySystem.Get <SolutionContainerSystem>();

            if (!Owner.TryGetComponent <FoodComponent>(out var foodComp) || !scs.TryGetSolution(Owner, foodComp.SolutionName, out var solution))
            {
                return(false);
            }

            if (!eventArgs.Using.TryGetComponent(out UtensilComponent? utensil) || !utensil.HasType(UtensilType.Knife))
            {
                return(false);
            }

            var itemToSpawn = Owner.EntityManager.SpawnEntity(_slice, Owner.Transform.Coordinates);
            // This is done this way so that... food additives (read: poisons) remain in the system.
            // Basically, we want to:
            // 1. Split off a representative chunk
            var lostSolution = scs.SplitSolution(Owner.Uid, solution,
                                                 solution.CurrentVolume / ReagentUnit.New(Count));

            // 2. Delete the Nutriment (it's already in the target) so we just have additives
            // It might be an idea to remove the removal of Nutriment & clear the food
            lostSolution.RemoveReagent("Nutriment", lostSolution.GetReagentQuantity("Nutriment"));
            // 3. Dump whatever we can into the slice
            if (itemToSpawn.TryGetComponent <FoodComponent>(out var itsFoodComp) && scs.TryGetSolution(itemToSpawn, itsFoodComp.SolutionName, out var itsSolution))
            {
                var lostSolutionPart = lostSolution.SplitSolution(itsSolution.AvailableVolume);
                scs.TryAddSolution(itemToSpawn.Uid, itsSolution, lostSolutionPart);
            }
            if (eventArgs.User.TryGetComponent(out HandsComponent? handsComponent))
            {
                if (ContainerHelpers.IsInContainer(Owner))
                {
                    handsComponent.PutInHandOrDrop(itemToSpawn.GetComponent <ItemComponent>());
                }
            }

            SoundSystem.Play(Filter.Pvs(Owner), _sound.GetSound(), Owner.Transform.Coordinates,
                             AudioParams.Default.WithVolume(-2));

            Count--;
            if (Count < 1)
            {
                Owner.Delete();
            }
            return(true);
        }
Пример #24
0
        private void Deny()
        {
            SoundSystem.Play(Filter.Pvs(Owner), _soundDeny.GetSound(), Owner, AudioParams.Default.WithVolume(-2f));

            // Play the Deny animation
            TrySetVisualState(VendingMachineVisualState.Deny);
            //TODO: This duration should be a distinct value specific to the deny animation
            Owner.SpawnTimer(_animationDuration, () =>
            {
                TrySetVisualState(VendingMachineVisualState.Normal);
            });
        }
Пример #25
0
        private void ToggleLight()
        {
            if (!Owner.TryGetComponent(out PointLightComponent? light))
            {
                return;
            }

            _lightOn      = !_lightOn;
            light.Enabled = _lightOn;
            SoundSystem.Play(Filter.Pvs(Owner), _toggleFlashlightSound.GetSound(), Owner);
            UpdatePDAUserInterface();
        }
Пример #26
0
    /// <summary>
    /// Dispatches an announcement to all.
    /// </summary>
    /// <param name="message">The contents of the message</param>
    /// <param name="sender">The sender (Communications Console in Communications Console Announcement)</param>
    /// <param name="playSound">Play the announcement sound</param>
    /// <param name="colorOverride">Optional color for the announcement message</param>
    public void DispatchGlobalAnnouncement(string message, string sender = "Central Command",
                                           bool playSound = true, SoundSpecifier?announcementSound = null, Color?colorOverride = null)
    {
        var messageWrap = Loc.GetString("chat-manager-sender-announcement-wrap-message", ("sender", sender));

        _chatManager.ChatMessageToAll(ChatChannel.Radio, message, messageWrap, colorOverride);
        if (playSound)
        {
            SoundSystem.Play(announcementSound?.GetSound() ?? DefaultAnnouncementSound, Filter.Broadcast(), AudioParams.Default.WithVolume(-2f));
        }
        _adminLogger.Add(LogType.Chat, LogImpact.Low, $"Global station announcement from {sender}: {message}");
    }
Пример #27
0
        ///<summary>
        ///Method to allow the user to swap the mode of the RCD by clicking it in hand, the actual in hand clicking bit is done over on UseEntity()
        ///@param UseEntityEventArgs = The entity which triggered this method call, used to know where to play the "click" sound.
        ///</summary>

        public void SwapMode(UseEntityEventArgs eventArgs)
        {
            SoundSystem.Play(Filter.Pvs(Owner), _swapModeSound.GetSound(), Owner);
            var mode = (int)_mode;            //Firstly, cast our RCDmode mode to an int (enums are backed by ints anyway by default)

            mode  = (++mode) % _modes.Length; //Then, do a rollover on the value so it doesnt hit an invalid state
            _mode = (RcdMode)mode;            //Finally, cast the newly acquired int mode to an RCDmode so we can use it.
            Owner.PopupMessage(eventArgs.User,
                               Loc.GetString(
                                   "rcd-component-change-mode",
                                   ("mode", _mode.ToString())
                                   )
                               ); //Prints an overhead message above the RCD
        }
Пример #28
0
        public override void Effect(ReagentEffectArgs args)
        {
            if (args.Source == null)
            {
                return;
            }

            var splitSolution = EntitySystem.Get <SolutionContainerSystem>().SplitSolution(args.SolutionEntity, args.Source, args.Source.MaxVolume);
            // We take the square root so it becomes harder to reach higher amount values
            var amount = (int)Math.Round(_rangeConstant + _rangeMultiplier * Math.Sqrt(args.Quantity.Float()));

            amount = Math.Min(amount, _maxRange);

            if (_diluteReagents)
            {
                // The maximum value of solutionFraction is _reagentMaxConcentrationFactor, achieved when amount = 0
                // The infimum of solutionFraction is 0, which is approached when amount tends to infinity
                // solutionFraction is equal to 1 only when amount equals _reagentDilutionStart
                // Weird formulas here but basically when amount increases, solutionFraction gets closer to 0 in a reciprocal manner
                // _reagentDilutionFactor defines how fast solutionFraction gets closer to 0
                float solutionFraction = 1 / (_reagentDilutionFactor * (amount) + 1);
                splitSolution.RemoveSolution(splitSolution.TotalVolume * (1 - solutionFraction));
            }

            var transform = args.EntityManager.GetComponent <TransformComponent>(args.SolutionEntity);

            if (!_mapManager.TryFindGridAt(transform.MapPosition, out var grid))
            {
                return;
            }

            var coords = grid.MapToGrid(transform.MapPosition);

            var ent = args.EntityManager.SpawnEntity(_prototypeId, coords.SnapToGrid());

            var areaEffectComponent = GetAreaEffectComponent(ent);

            if (areaEffectComponent == null)
            {
                Logger.Error("Couldn't get AreaEffectComponent from " + _prototypeId);
                IoCManager.Resolve <IEntityManager>().QueueDeleteEntity(ent);
                return;
            }

            areaEffectComponent.TryAddSolution(splitSolution);
            areaEffectComponent.Start(amount, _duration, _spreadDelay, _removeDelay);

            SoundSystem.Play(Filter.Pvs(args.SolutionEntity), _sound.GetSound(), args.SolutionEntity, AudioHelpers.WithVariation(0.125f));
        }
        public void TryCremate()
        {
            if (Cooking)
            {
                return;
            }
            if (Open)
            {
                return;
            }

            SoundSystem.Play(Filter.Pvs(Owner), _cremateStartSound.GetSound(), Owner);

            Cremate();
        }
        public void Cremate()
        {
            if (Open)
            {
                CloseStorage();
            }

            if (_entities.TryGetComponent(Owner, out AppearanceComponent appearanceComponent))
            {
                appearanceComponent.SetData(CrematoriumVisuals.Burning, true);
            }
            Cooking = true;

            SoundSystem.Play(Filter.Pvs(Owner), _crematingSound.GetSound(), Owner);

            _cremateCancelToken?.Cancel();

            _cremateCancelToken = new CancellationTokenSource();
            Owner.SpawnTimer(_burnMilis, () =>
            {
                if (_entities.Deleted(Owner))
                {
                    return;
                }
                if (_entities.TryGetComponent(Owner, out appearanceComponent))
                {
                    appearanceComponent.SetData(CrematoriumVisuals.Burning, false);
                }
                Cooking = false;

                if (Contents.ContainedEntities.Count > 0)
                {
                    for (var i = Contents.ContainedEntities.Count - 1; i >= 0; i--)
                    {
                        var item = Contents.ContainedEntities[i];
                        Contents.Remove(item);
                        _entities.DeleteEntity(item);
                    }

                    var ash = _entities.SpawnEntity("Ash", _entities.GetComponent <TransformComponent>(Owner).Coordinates);
                    Contents.Insert(ash);
                }

                TryOpenStorage(Owner);

                SoundSystem.Play(Filter.Pvs(Owner), _cremateFinishSound.GetSound(), Owner);
            }, _cremateCancelToken.Token);
        }