예제 #1
0
        public void RefreshTimer(EntityUid uid, bool minimumBound = true, AdvertiseComponent?advertise = null)
        {
            if (!Resolve(uid, ref advertise))
            {
                return;
            }

            var minWait = Math.Max(1, advertise.MinimumWait);
            var maxWait = Math.Max(minWait, advertise.MaximumWait);

            var waitSeconds = minimumBound ? _random.Next(minWait, maxWait) : _random.Next(maxWait);

            advertise.NextAdvertisementTime = _gameTiming.CurTime.Add(TimeSpan.FromSeconds(waitSeconds));
        }
예제 #2
0
    private void OnClugUse(EntityUid uid, ClusterGrenadeComponent component, UseInHandEvent args)
    {
        if (component.CountDown || (component.GrenadesContainer.ContainedEntities.Count + component.UnspawnedCount) <= 0)
        {
            return;
        }

        // TODO: Should be an Update loop
        uid.SpawnTimer((int)(component.Delay * 1000), () =>
        {
            if (Deleted(component.Owner))
            {
                return;
            }

            component.CountDown  = true;
            var delay            = 20;
            var grenadesInserted = component.GrenadesContainer.ContainedEntities.Count + component.UnspawnedCount;
            var thrownCount      = 0;
            var segmentAngle     = 360 / grenadesInserted;
            while (TryGetGrenade(component, out var grenade))
            {
                var angleMin = segmentAngle * thrownCount;
                var angleMax = segmentAngle * (thrownCount + 1);
                var angle    = Angle.FromDegrees(_random.Next(angleMin, angleMax));
                // var distance = random.NextFloat() * _throwDistance;

                delay += _random.Next(550, 900);
                thrownCount++;

                // TODO: Suss out throw strength
                grenade.TryThrow(angle.ToVec().Normalized *component.ThrowDistance);

                grenade.SpawnTimer(delay, () =>
                {
                    if ((!EntityManager.EntityExists(grenade) ? EntityLifeStage.Deleted : MetaData(grenade).EntityLifeStage) >= EntityLifeStage.Deleted)
                    {
                        return;
                    }

                    _trigger.Trigger(grenade, args.User);
                });
            }

            EntityManager.DeleteEntity(uid);
        });

        args.Handled = true;
    }
예제 #3
0
        private void DoSpawn(IEntity owner, IRobustRandom random)
        {
            if (Spawn == null)
            {
                return;
            }

            foreach (var(key, value) in Spawn)
            {
                var count = value.Min >= value.Max
                    ? value.Min
                    : random.Next(value.Min, value.Max + 1);

                if (count == 0)
                {
                    continue;
                }

                if (EntityPrototypeHelpers.HasComponent <StackComponent>(key))
                {
                    var spawned = owner.EntityManager.SpawnEntity(key, owner.Transform.Coordinates);
                    var stack   = spawned.GetComponent <StackComponent>();
                    stack.Count = count;
                    spawned.RandomOffset(0.5f);
                }
                else
                {
                    for (var i = 0; i < count; i++)
                    {
                        var spawned = owner.EntityManager.SpawnEntity(key, owner.Transform.Coordinates);
                        spawned.RandomOffset(0.5f);
                    }
                }
            }
        }
예제 #4
0
        async Task <bool> IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
        {
            if (!_powerReceiver?.Powered ?? false)
            {
                return(false);
            }

            if (eventArgs.Using.TryGetComponent(out ProduceComponent? produce) && produce.Seed != null)
            {
                eventArgs.User.PopupMessageCursor(Loc.GetString("seed-extractor-component-interact-message", ("name", eventArgs.Using.Name)));

                eventArgs.Using.QueueDelete();

                var random = _random.Next(_minSeeds, _maxSeeds);

                for (var i = 0; i < random; i++)
                {
                    produce.Seed.SpawnSeedPacket(Owner.Transform.Coordinates, Owner.EntityManager);
                }

                return(true);
            }

            return(false);
        }
        public void Play(ScheduledSound schedule)
        {
            if (!schedule.Play)
            {
                return;
            }

            Timer.Spawn((int)schedule.Delay + (_random.Next((int)schedule.RandomDelay)), () =>
            {
                if (!schedule.Play)
                {
                    return;                     // We make sure this hasn't changed.
                }
                if (_audioSystem == null)
                {
                    _audioSystem = EntitySystem.Get <AudioSystem>();
                }
                _audioStreams.Add(schedule, _audioSystem.Play(schedule.Filename, Owner, schedule.AudioParams));

                if (schedule.Times == 0)
                {
                    return;
                }

                if (schedule.Times > 0)
                {
                    schedule.Times--;
                }

                Play(schedule);
            });
        }
예제 #6
0
    private void OnPlaqueMapInit(EntityUid uid, AtmosPlaqueComponent component, MapInitEvent args)
    {
        var rand = _random.Next(100);

        // Let's not pat ourselves on the back too hard.
        // 1% chance of zumos
        if (rand == 0)
        {
            component.Type = PlaqueType.Zumos;
        }
        // 9% FEA
        else if (rand <= 10)
        {
            component.Type = PlaqueType.Fea;
        }
        // 45% ZAS
        else if (rand <= 55)
        {
            component.Type = PlaqueType.Zas;
        }
        // 45% LINDA
        else
        {
            component.Type = PlaqueType.Linda;
        }

        UpdateSign(component);
    }
        async Task <bool> IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
        {
            if (!_entMan.TryGetComponent <ApcPowerReceiverComponent>(Owner, out var powerReceiverComponent) || !powerReceiverComponent.Powered)
            {
                return(false);
            }

            if (_entMan.TryGetComponent(eventArgs.Using, out ProduceComponent? produce) && produce.Seed != null)
            {
                eventArgs.User.PopupMessageCursor(Loc.GetString("seed-extractor-component-interact-message", ("name", _entMan.GetComponent <MetaDataComponent>(eventArgs.Using).EntityName)));

                _entMan.QueueDeleteEntity(eventArgs.Using);

                var random = _random.Next(_minSeeds, _maxSeeds);

                for (var i = 0; i < random; i++)
                {
                    produce.Seed.SpawnSeedPacket(_entMan.GetComponent <TransformComponent>(Owner).Coordinates, _entMan);
                }

                return(true);
            }

            return(false);
        }
예제 #8
0
        private string?GetRandomPrototype()
        {
            var defaultProto = _prototypes?.Keys.FirstOrDefault();

            if (defaultProto == null)
            {
                return(null);
            }

            DebugTools.AssertNotNull(_prototypes);

            if (_prototypes !.Count == 1)
            {
                return(defaultProto);
            }

            var probResult = _random.Next(0, 100);
            var total      = 0;

            foreach (var item in _prototypes)
            {
                total += item.Value;
                if (probResult < total)
                {
                    return(item.Key);
                }
            }

            return(defaultProto);
        }
예제 #9
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);
            }
        }
    }
예제 #10
0
        public override void Startup()
        {
            base.Startup();
            EntitySystem.Get <AudioSystem>().PlayGlobal("/Audio/Announcements/radiation.ogg");
            IoCManager.InjectDependencies(this);

            _timeElapsed     = 0.0f;
            _pulsesRemaining = _robustRandom.Next(30, 100);

            var componentManager = IoCManager.Resolve <IComponentManager>();

            foreach (var overlay in componentManager.EntityQuery <ServerOverlayEffectsComponent>())
            {
                overlay.AddOverlay(SharedOverlayID.RadiationPulseOverlay);
            }
        }
예제 #11
0
        public void Play(ScheduledSound schedule)
        {
            if (!schedule.Play)
            {
                return;
            }

            Timer.Spawn((int)schedule.Delay + (_random.Next((int)schedule.RandomDelay)), () =>
            {
                if (!schedule.Play)
                {
                    return;                     // We make sure this hasn't changed.
                }
                if (_audioSystem == null)
                {
                    _audioSystem = IoCManager.Resolve <IEntitySystemManager>().GetEntitySystem <AudioSystem>();
                }
                _audioSystem.Play(schedule.Filename, Owner, schedule.AudioParams);

                if (schedule.Times == 0)
                {
                    _schedules.Remove(schedule);
                    return;
                }

                if (schedule.Times > 0)
                {
                    schedule.Times--;
                }

                Play(schedule);
            });
        }
예제 #12
0
        protected override void CycleChamberedBullet(int chamber)
        {
            DebugTools.Assert(chamber == 0);

            // Eject chambered bullet.
            var entity = RemoveFromChamber(chamber);

            entity.Transform.GridPosition  = Owner.Transform.GridPosition;
            entity.Transform.LocalRotation = _bulletDropRandom.Pick(_randomBulletDirs).ToAngle();
            var effect = $"/Audio/Guns/Casings/casingfall{_bulletDropRandom.Next(1, 4)}.ogg";

            Owner.GetComponent <SoundComponent>().Play(effect, AudioParams.Default.WithVolume(-3));

            if (Magazine != null)
            {
                var magComponent = Magazine.GetComponent <BallisticMagazineComponent>();
                var bullet       = magComponent.TakeBullet();
                if (bullet != null)
                {
                    LoadIntoChamber(0, bullet);
                }

                if (magComponent.CountLoaded == 0 && _autoEjectMagazine)
                {
                    EjectMagazine();
                    if (_autoEjectSound != null)
                    {
                        Owner.GetComponent <SoundComponent>().Play(_autoEjectSound, AudioParams.Default.WithVolume(-5));
                    }
                }
            }

            _updateAppearance();
        }
    private void OnInteractUsing(EntityUid uid, SeedExtractorComponent component, InteractUsingEvent args)
    {
        if (!this.IsPowered(uid, EntityManager))
        {
            return;
        }

        if (!TryComp(args.Used, out ProduceComponent? produce))
        {
            return;
        }
        if (!_botanySystem.TryGetSeed(produce, out var seed))
        {
            return;
        }

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

        QueueDel(args.Used);

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

        if (random > 1)
        {
            seed.Unique = false;
        }

        for (var i = 0; i < random; i++)
        {
            _botanySystem.SpawnSeedPacket(seed, coords);
        }
    }
예제 #14
0
 public static float NextFloat(this IRobustRandom random)
 {
     // This is pretty much the CoreFX implementation.
     // So credits to that.
     // Except using float instead of double.
     return(random.Next() * 4.6566128752458E-10f);
 }
예제 #15
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();
        }
예제 #16
0
        public static T PickAndTake <T>(this IRobustRandom random, IList <T> list)
        {
            var index   = random.Next(list.Count);
            var element = list[index];

            list.RemoveAt(index);
            return(element);
        }
예제 #17
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);
        }
    }
예제 #18
0
        private void MoveSingulo(SingularityComponent singularity, PhysicsComponent physics)
        {
            if (singularity.Level <= 1)
            {
                return;
            }
            // TODO: Could try gradual changes instead but for now just try to replicate

            var pushVector = new Vector2(_robustRandom.Next(-10, 10), _robustRandom.Next(-10, 10));

            if (pushVector == Vector2.Zero)
            {
                return;
            }

            physics.LinearVelocity = Vector2.Zero;
            physics.LinearVelocity = pushVector.Normalized * 2;
        }
            public void ExecutePlayerAction(PlayerAction action)
            {
                if (!_running)
                {
                    return;
                }

                switch (action)
                {
                case PlayerAction.Attack:
                    var attackAmount = _random.Next(2, 6);
                    _latestPlayerActionMessage = $"You attack {_enemyName} for {attackAmount}!";
                    EntitySystem.Get <AudioSystem>().PlayFromEntity("/Audio/Effects/Arcade/player_attack.ogg", Owner.Owner, AudioParams.Default.WithVolume(-4f));
                    if (!Owner._enemyInvincibilityFlag)
                    {
                        _enemyHp -= attackAmount;
                    }
                    _turtleTracker -= _turtleTracker > 0 ? 1 : 0;
                    break;

                case PlayerAction.Heal:
                    var pointAmount = _random.Next(1, 3);
                    var healAmount  = _random.Next(6, 8);
                    _latestPlayerActionMessage = $"You use {pointAmount} magic to heal for {healAmount} damage!";
                    EntitySystem.Get <AudioSystem>().PlayFromEntity("/Audio/Effects/Arcade/player_heal.ogg", Owner.Owner, AudioParams.Default.WithVolume(-4f));
                    if (!Owner._playerInvincibilityFlag)
                    {
                        _playerMp -= pointAmount;
                    }
                    _playerHp += healAmount;
                    _turtleTracker++;
                    break;

                case PlayerAction.Recharge:
                    var charge_amount = _random.Next(4, 7);
                    _latestPlayerActionMessage = $"You regain {charge_amount} points";
                    EntitySystem.Get <AudioSystem>().PlayFromEntity("/Audio/Effects/Arcade/player_charge.ogg", Owner.Owner, AudioParams.Default.WithVolume(-4f));
                    _playerMp      += charge_amount;
                    _turtleTracker -= _turtleTracker > 0 ? 1 : 0;
                    break;
                }

                if (!CheckGameConditions())
                {
                    _running = false;
                    return;
                }

                ValidateVars();
                ExecuteAiAction();

                if (!CheckGameConditions())
                {
                    _running = false;
                    return;
                }
                ValidateVars();
                UpdateUi();
            }
예제 #20
0
    public override void Startup()
    {
        base.Startup();
        var stationSystem     = EntitySystem.Get <StationSystem>();
        var stationJobsSystem = EntitySystem.Get <StationJobsSystem>();

        if (stationSystem.Stations.Count == 0)
        {
            return;                                    // No stations
        }
        var chosenStation = _random.Pick(stationSystem.Stations.ToList());
        var jobList       = stationJobsSystem.GetJobs(chosenStation).Keys.ToList();

        // Low chance to completely change up the late-join landscape by closing all positions except infinite slots.
        // Lower chance than the /tg/ equivalent of this event.
        if (_random.Prob(0.25f))
        {
            var chosenJob = _random.PickAndTake(jobList);
            stationJobsSystem.MakeJobUnlimited(chosenStation, chosenJob); // INFINITE chaos.
            foreach (var job in jobList)
            {
                if (stationJobsSystem.IsJobUnlimited(chosenStation, job))
                {
                    continue;
                }
                stationJobsSystem.TrySetJobSlot(chosenStation, job, 0);
            }
        }
        else
        {
            // Changing every role is maybe a bit too chaotic so instead change 20-30% of them.
            for (var i = 0; i < _random.Next((int)(jobList.Count * 0.20), (int)(jobList.Count * 0.30)); i++)
            {
                var chosenJob = _random.PickAndTake(jobList);
                if (stationJobsSystem.IsJobUnlimited(chosenStation, chosenJob))
                {
                    continue;
                }

                stationJobsSystem.TryAdjustJobSlot(chosenStation, chosenJob, _random.Next(-3, 6));
            }
        }
    }
예제 #21
0
    public override void Startup()
    {
        base.Startup();

        var targetList = _entityManager.EntityQuery <SentienceTargetComponent>().ToList();

        _random.Shuffle(targetList);

        var toMakeSentient = _random.Next(2, 5);
        var groups         = new HashSet <string>();

        foreach (var target in targetList)
        {
            if (toMakeSentient-- == 0)
            {
                break;
            }

            MakeSentientCommand.MakeSentient(target.Owner, _entityManager);
            _entityManager.RemoveComponent <SentienceTargetComponent>(target.Owner);
            var comp = _entityManager.AddComponent <GhostTakeoverAvailableComponent>(target.Owner);
            comp.RoleName        = _entityManager.GetComponent <MetaDataComponent>(target.Owner).EntityName;
            comp.RoleDescription = Loc.GetString("station-event-random-sentience-role-description", ("name", comp.RoleName));
            groups.Add(target.FlavorKind);
        }

        if (groups.Count == 0)
        {
            return;
        }

        var groupList = groups.ToList();
        var kind1     = groupList.Count > 0 ? groupList[0] : "???";
        var kind2     = groupList.Count > 1 ? groupList[1] : "???";
        var kind3     = groupList.Count > 2 ? groupList[2] : "???";

        _chatManager.DispatchStationAnnouncement(
            Loc.GetString("station-event-random-sentience-announcement",
                          ("kind1", kind1), ("kind2", kind2), ("kind3", kind3), ("amount", groupList.Count),
                          ("data", Loc.GetString($"random-sentience-event-data-{_random.Next(1, 6)}")),
                          ("strength", Loc.GetString($"random-sentience-event-strength-{_random.Next(1, 8)}")))
            );
    }
예제 #22
0
        private void MoveSingulo(ServerSingularityComponent singularity, PhysicsComponent physics)
        {
            // To prevent getting stuck, ServerSingularityComponent will zero the velocity of a singularity when it goes to a level <= 1 (see here).
            if (singularity.Level <= 1)
            {
                return;
            }
            // TODO: Could try gradual changes instead but for now just try to replicate

            var pushVector = new Vector2(_robustRandom.Next(-10, 10), _robustRandom.Next(-10, 10));

            if (pushVector == Vector2.Zero)
            {
                return;
            }

            physics.LinearVelocity = Vector2.Zero;
            physics.LinearVelocity = pushVector.Normalized * 2;
        }
    private void SetupKudzu(EntityUid uid, GrowingKudzuComponent component, ComponentAdd args)
    {
        if (!EntityManager.TryGetComponent <AppearanceComponent>(uid, out var appearance))
        {
            return;
        }

        appearance.SetData(KudzuVisuals.Variant, _robustRandom.Next(1, 3));
        appearance.SetData(KudzuVisuals.GrowthLevel, 1);
    }
예제 #24
0
 private void OnComponentStartup(EntityUid uid, ThirstComponent component, ComponentStartup args)
 {
     component.CurrentThirst = _random.Next(
         (int)component.ThirstThresholds[ThirstThreshold.Thirsty] + 10,
         (int)component.ThirstThresholds[ThirstThreshold.Okay] - 1);
     component.CurrentThirstThreshold = GetThirstThreshold(component, component.CurrentThirst);
     component.LastThirstThreshold    = ThirstThreshold.Okay; // TODO: Potentially change this -> Used Okay because no effects.
     // TODO: Check all thresholds make sense and throw if they don't.
     UpdateEffects(component);
 }
예제 #25
0
 public void Roll()
 {
     _currentSide = _random.Next(1, (_sides / _step) + 1) * _step;
     if (!Owner.TryGetComponent(out SpriteComponent sprite))
     {
         return;
     }
     sprite.LayerSetState(0, $"d{_sides}{_currentSide}");
     PlayDiceEffect();
 }
            public void ExecutePlayerAction(PlayerAction action)
            {
                if (!_running)
                {
                    return;
                }

                switch (action)
                {
                case PlayerAction.Attack:
                    var attackAmount = _random.Next(2, 6);
                    _latestPlayerActionMessage = Loc.GetString("You attack {0} for {1}!", _enemyName, attackAmount);
                    SoundSystem.Play(Filter.Pvs(_owner.Owner), "/Audio/Effects/Arcade/player_attack.ogg", _owner.Owner, AudioParams.Default.WithVolume(-4f));
                    if (!_owner._enemyInvincibilityFlag)
                    {
                        _enemyHp -= attackAmount;
                    }
                    _turtleTracker -= _turtleTracker > 0 ? 1 : 0;
                    break;

                case PlayerAction.Heal:
                    var pointAmount = _random.Next(1, 3);
                    var healAmount  = _random.Next(6, 8);
                    _latestPlayerActionMessage = Loc.GetString("You use {0} magic to heal for {1} damage!", pointAmount, healAmount);
                    SoundSystem.Play(Filter.Pvs(_owner.Owner), "/Audio/Effects/Arcade/player_heal.ogg", _owner.Owner, AudioParams.Default.WithVolume(-4f));
                    if (!_owner._playerInvincibilityFlag)
                    {
                        _playerMp -= pointAmount;
                    }
                    _playerHp += healAmount;
                    _turtleTracker++;
                    break;

                case PlayerAction.Recharge:
                    var chargeAmount = _random.Next(4, 7);
                    _latestPlayerActionMessage = Loc.GetString("You regain {0} points", chargeAmount);
                    SoundSystem.Play(Filter.Pvs(_owner.Owner), "/Audio/Effects/Arcade/player_charge.ogg", _owner.Owner, AudioParams.Default.WithVolume(-4f));
                    _playerMp      += chargeAmount;
                    _turtleTracker -= _turtleTracker > 0 ? 1 : 0;
                    break;
                }

                if (!CheckGameConditions())
                {
                    return;
                }

                ValidateVars();
                ExecuteAiAction();

                if (!CheckGameConditions())
                {
                    return;
                }
                ValidateVars();
                UpdateUi();
            }
예제 #27
0
 protected override void Startup()
 {
     base.Startup();
     // Similar functionality to SS13. Should also stagger people going to the chef.
     _currentHunger = _random.Next(
         (int)_hungerThresholds[HungerThreshold.Peckish] + 10,
         (int)_hungerThresholds[HungerThreshold.Okay] - 1);
     _currentHungerThreshold = GetHungerThreshold(_currentHunger);
     _lastHungerThreshold    = HungerThreshold.Okay; // TODO: Potentially change this -> Used Okay because no effects.
     HungerThresholdEffect(true);
 }
    private string Accentuate(string message, float scale)
    {
        var sb = new StringBuilder();

        // This is pretty much ported from TG.
        foreach (var character in message)
        {
            if (_random.Prob(scale / 3f))
            {
                var lower     = char.ToLowerInvariant(character);
                var newString = lower switch
                {
                    'o' => "u",
                    's' => "ch",
                    'a' => "ah",
                    'u' => "oo",
                    'c' => "k",
                    _ => $"{character}",
                };

                sb.Append(newString);
            }

            if (_random.Prob(scale / 20f))
            {
                if (character == ' ')
                {
                    sb.Append(Loc.GetString("slur-accent-confused"));
                }
                else if (character == '.')
                {
                    sb.Append(' ');
                    sb.Append(Loc.GetString("slur-accent-burp"));
                }
            }

            if (!_random.Prob(scale * 3 / 20))
            {
                sb.Append(character);
                continue;
            }

            var next = _random.Next(1, 3) switch
            {
                1 => "'",
                2 => $"{character}{character}",
                _ => $"{character}{character}{character}",
            };

            sb.Append(next);
        }

        return(sb.ToString());
    }
예제 #29
0
        public override void Startup()
        {
            base.Startup();

            // Essentially we'll pick out a target amount of gas to leak, then a rate to leak it at, then work out the duration from there.
            if (TryFindRandomTile(out _targetTile, out _targetStation, out _targetGrid, out _targetCoords))
            {
                _foundTile = true;

                _leakGas = _robustRandom.Pick(LeakableGases);
                // Was 50-50 on using normal distribution.
                var totalGas = (float)_robustRandom.Next(MinimumGas, MaximumGas);
                _molesPerSecond = _robustRandom.Next(MinimumMolesPerSecond, MaximumMolesPerSecond);
                EndAfter        = totalGas / _molesPerSecond + StartAfter;
                Logger.InfoS("stationevents", $"Leaking {totalGas} of {_leakGas} over {EndAfter - StartAfter} seconds at {_targetTile}");
            }

            // Look technically if you wanted to guarantee a leak you'd do this in announcement but having the announcement
            // there just to f**k with people even if there is no valid tile is funny.
        }
예제 #30
0
 protected override void Startup()
 {
     base.Startup();
     _currentThirst = _random.Next(
         (int)_thirstThresholds[ThirstThreshold.Thirsty] + 10,
         (int)_thirstThresholds[ThirstThreshold.Okay] - 1);
     _currentThirstThreshold = GetThirstThreshold(_currentThirst);
     _lastThirstThreshold    = ThirstThreshold.Okay; // TODO: Potentially change this -> Used Okay because no effects.
     // TODO: Check all thresholds make sense and throw if they don't.
     ThirstThresholdEffect(true);
 }