예제 #1
0
        public override void Spawn()
        {
            if (RarePrototypes.Count > 0 && (RareChance == 1.0f || _robustRandom.Prob(RareChance)))
            {
                Owner.EntityManager.SpawnEntity(_robustRandom.Pick(RarePrototypes), Owner.Transform.Coordinates);
                return;
            }

            if (Chance != 1.0f && !_robustRandom.Prob(Chance))
            {
                return;
            }

            if (Prototypes.Count == 0)
            {
                Logger.Warning($"Prototype list in TrashSpawnComponent is empty! Entity: {Owner}");
                return;
            }

            if (!Owner.Deleted)
            {
                var random = IoCManager.Resolve <IRobustRandom>();

                var x_negative = random.Prob(0.5f) ? -1 : 1;
                var y_negative = random.Prob(0.5f) ? -1 : 1;

                var entity = Owner.EntityManager.SpawnEntity(_robustRandom.Pick(Prototypes), Owner.Transform.Coordinates);
                entity.Transform.LocalPosition += new Vector2(random.NextFloat() * Offset * x_negative, random.NextFloat() * Offset * y_negative);
            }
        }
        protected override bool OnHitEntities(IReadOnlyList <IEntity> entities, AttackEvent eventArgs)
        {
            if (!Activated || entities.Count == 0 || Cell == null)
            {
                return(true);
            }

            if (!Cell.TryUseCharge(EnergyPerUse))
            {
                return(true);
            }

            SoundSystem.Play(Filter.Pvs(Owner), "/Audio/Weapons/egloves.ogg", Owner.Transform.Coordinates, AudioHelpers.WithVariation(0.25f));

            foreach (var entity in entities)
            {
                if (!entity.TryGetComponent(out StunnableComponent? stunnable))
                {
                    continue;
                }

                if (!stunnable.SlowedDown)
                {
                    if (_robustRandom.Prob(_paralyzeChanceNoSlowdown))
                    {
                        stunnable.Paralyze(_paralyzeTime);
                    }
                    else
                    {
                        stunnable.Slowdown(_slowdownTime);
                    }
                }
                else
                {
                    if (_robustRandom.Prob(_paralyzeChanceWithSlowdown))
                    {
                        stunnable.Paralyze(_paralyzeTime);
                    }
                    else
                    {
                        stunnable.Slowdown(_slowdownTime);
                    }
                }
            }

            if (!(Cell.CurrentCharge < EnergyPerUse))
            {
                return(true);
            }

            SoundSystem.Play(Filter.Pvs(Owner), AudioHelpers.GetRandomFileFromSoundCollection("sparks"), Owner.Transform.Coordinates, AudioHelpers.WithVariation(0.25f));
            TurnOff();

            return(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());
    }
        private void HandleCollide(EntityUid uid, DamageOnHighSpeedImpactComponent component, StartCollideEvent args)
        {
            if (!EntityManager.HasComponent <DamageableComponent>(uid))
            {
                return;
            }

            var otherBody = args.OtherFixture.Body.Owner;
            var speed     = args.OurFixture.Body.LinearVelocity.Length;

            if (speed < component.MinimumSpeed)
            {
                return;
            }

            SoundSystem.Play(Filter.Pvs(otherBody), component.SoundHit.GetSound(), otherBody, AudioHelpers.WithVariation(0.125f).WithVolume(-0.125f));

            if ((_gameTiming.CurTime - component.LastHit).TotalSeconds < component.DamageCooldown)
            {
                return;
            }

            component.LastHit = _gameTiming.CurTime;

            if (_robustRandom.Prob(component.StunChance))
            {
                _stunSystem.TryStun(uid, TimeSpan.FromSeconds(component.StunSeconds), true);
            }

            var damageScale = (speed / component.MinimumSpeed) * component.Factor;

            _damageableSystem.TryChangeDamage(uid, component.Damage * damageScale);
        }
예제 #5
0
    public override void Startup()
    {
        base.Startup();

        // TODO: "safe random" for chems. Right now this includes admin chemicals.
        var allReagents = _prototypeManager.EnumeratePrototypes <ReagentPrototype>()
                          .Where(x => !x.Abstract)
                          .Select(x => x.ID).ToList();

        // This is gross, but not much can be done until event refactor, which needs Dynamic.
        var sound = new SoundPathSpecifier("/Audio/Effects/extinguish.ogg");

        foreach (var(_, transform) in _entityManager.EntityQuery <GasVentPumpComponent, TransformComponent>())
        {
            var solution = new Solution();

            if (_random.Prob(0.05f))
            {
                solution.AddReagent(_random.Pick(allReagents), 100);
            }
            else
            {
                solution.AddReagent(_random.Pick(SafeishVentChemicals), 100);
            }

            FoamAreaReactionEffect.SpawnFoam("Foam", transform.Coordinates, solution, _random.Next(2, 6), 20, 1,
                                             1, sound, _entityManager);
        }
    }
        public void CollideWith(IEntity collidedWith)
        {
            if (!Owner.TryGetComponent(out IPhysicsComponent physics) || !Owner.TryGetComponent(out IDamageableComponent damageable))
            {
                return;
            }

            var speed = physics.LinearVelocity.Length;

            if (speed < MinimumSpeed)
            {
                return;
            }

            if (!string.IsNullOrEmpty(SoundHit))
            {
                EntitySystem.Get <AudioSystem>().PlayFromEntity(SoundHit, collidedWith, AudioHelpers.WithVariation(0.125f).WithVolume(-0.125f));
            }

            if ((_gameTiming.CurTime - _lastHit).TotalSeconds < DamageCooldown)
            {
                return;
            }

            _lastHit = _gameTiming.CurTime;

            var damage = (int)(BaseDamage * (speed / MinimumSpeed) * Factor);

            if (Owner.TryGetComponent(out StunnableComponent stun) && _robustRandom.Prob(StunChance))
            {
                stun.Stun(StunSeconds);
            }

            damageable.ChangeDamage(Damage, damage, false, collidedWith);
        }
예제 #7
0
    private void OnCollide(EntityUid uid, ImmovableRodComponent component, StartCollideEvent args)
    {
        var ent = args.OtherFixture.Body.Owner;

        if (_random.Prob(component.HitSoundProbability))
        {
            SoundSystem.Play(component.Sound.GetSound(), Filter.Pvs(uid), uid, component.Sound.Params);
        }

        if (HasComp <ImmovableRodComponent>(ent))
        {
            // oh god.
            var coords = Transform(uid).Coordinates;
            _popup.PopupCoordinates(Loc.GetString("immovable-rod-collided-rod-not-good"), coords, Filter.Pvs(uid));

            Del(uid);
            Del(ent);
            Spawn("Singularity", coords);

            return;
        }

        // gib em
        if (TryComp <BodyComponent>(ent, out var body))
        {
            component.MobCount++;

            _popup.PopupEntity(Loc.GetString("immovable-rod-penetrated-mob", ("rod", uid), ("mob", ent)), uid, Filter.Pvs(uid));
            body.Gib();
        }

        QueueDel(ent);
    }
        public void CollideWith(IEntity collidedWith)
        {
            if (!Owner.TryGetComponent(out ICollidableComponent collidable) || !Owner.TryGetComponent(out DamageableComponent damageable))
            {
                return;
            }

            var speed = collidable.LinearVelocity.Length;

            if (speed < MinimumSpeed)
            {
                return;
            }

            var damage = (int)(BaseDamage * (speed / MinimumSpeed) * Factor);

            if (!string.IsNullOrEmpty(SoundHit))
            {
                EntitySystem.Get <AudioSystem>().PlayFromEntity(SoundHit, collidedWith, AudioHelpers.WithVariation(0.125f).WithVolume(-0.125f));
            }

            if (Owner.TryGetComponent(out StunnableComponent stun) && _robustRandom.Prob(StunChance))
            {
                stun.Stun(StunSeconds);
            }

            damageable.TakeDamage(Damage, damage, collidedWith, Owner);
        }
예제 #9
0
        private void OnDisarmed(EntityUid uid, StatusEffectsComponent status, DisarmedActEvent args)
        {
            if (args.Handled || !_random.Prob(args.PushProbability))
            {
                return;
            }

            if (!TryParalyze(uid, TimeSpan.FromSeconds(4f), true, status))
            {
                return;
            }

            var source = args.Source;
            var target = args.Target;

            if (source != null)
            {
                var knock = EntityManager.GetComponent <KnockedDownComponent>(uid);
                SoundSystem.Play(Filter.Pvs(source), knock.StunAttemptSound.GetSound(), source, AudioHelpers.WithVariation(0.025f));

                if (target != null)
                {
                    // TODO: Use PopupSystem
                    source.PopupMessageOtherClients(Loc.GetString("stunned-component-disarm-success-others", ("source", Name: EntityManager.GetComponent <MetaDataComponent>(source).EntityName), ("target", Name: EntityManager.GetComponent <MetaDataComponent>(target).EntityName)));
                    source.PopupMessageCursor(Loc.GetString("stunned-component-disarm-success", ("target", Name: EntityManager.GetComponent <MetaDataComponent>(target).EntityName)));
                }
            }

            _adminLogSystem.Add(LogType.DisarmedKnockdown, LogImpact.Medium, $"{args.Source:performer} knocked down {args.Target:target}");

            args.Handled = true;
        }
    public override void Update(float frameTime)
    {
        _accumulatedFrameTime += frameTime;

        if (!(_accumulatedFrameTime >= 0.5f))
        {
            return;
        }

        _accumulatedFrameTime -= 0.5f;

        foreach (var(kudzu, appearance) in EntityManager.EntityQuery <GrowingKudzuComponent, AppearanceComponent>())
        {
            if (kudzu.GrowthLevel >= 3 || !_robustRandom.Prob(kudzu.GrowthTickSkipChange))
            {
                continue;
            }
            kudzu.GrowthLevel += 1;

            if (kudzu.GrowthLevel == 3 &&
                EntityManager.TryGetComponent <SpreaderComponent>((kudzu).Owner, out var spreader))
            {
                // why cache when you can simply cease to be? Also saves a bit of memory/time.
                EntityManager.RemoveComponent <GrowingKudzuComponent>((kudzu).Owner);
            }

            appearance.SetData(KudzuVisuals.GrowthLevel, kudzu.GrowthLevel);
        }
    }
예제 #11
0
        private void OnDisarmed(EntityUid uid, StatusEffectsComponent status, DisarmedEvent args)
        {
            if (args.Handled || !_random.Prob(args.PushProbability))
            {
                return;
            }

            if (!TryParalyze(uid, TimeSpan.FromSeconds(4f), true, status))
            {
                return;
            }

            var source = args.Source;
            var target = args.Target;

            var knock = EntityManager.GetComponent <KnockedDownComponent>(uid);

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

            var targetEnt = Identity.Entity(target, EntityManager);
            var sourceEnt = Identity.Entity(source, EntityManager);

            // TODO: Use PopupSystem
            source.PopupMessageOtherClients(Loc.GetString("stunned-component-disarm-success-others", ("source", sourceEnt), ("target", targetEnt)));
            source.PopupMessageCursor(Loc.GetString("stunned-component-disarm-success", ("target", targetEnt)));

            _adminLogger.Add(LogType.DisarmedKnockdown, LogImpact.Medium, $"{ToPrettyString(args.Source):user} knocked down {ToPrettyString(args.Target):target}");

            args.Handled = true;
        }
예제 #12
0
 private void HandleDecompressionFloorRip(float sum)
 {
     if (sum > 20 && _robustRandom.Prob(MathF.Clamp(sum / 100, 0.005f, 0.5f)))
     {
         _gridAtmosphereComponent.PryTile(GridIndices);
     }
 }
예제 #13
0
        private void OnAfterInteract(EntityUid uid, BibleComponent component, AfterInteractEvent args)
        {
            if (!args.CanReach)
            {
                return;
            }

            var currentTime = _gameTiming.CurTime;

            if (currentTime < component.CooldownEnd)
            {
                return;
            }
            if (args.Target == null || args.Target == args.User || !HasComp <MobStateComponent>(args.Target))
            {
                return;
            }

            component.LastAttackTime = currentTime;
            component.CooldownEnd    = component.LastAttackTime + TimeSpan.FromSeconds(component.CooldownTime);
            RaiseLocalEvent(uid, new RefreshItemCooldownEvent(component.LastAttackTime, component.CooldownEnd), false);

            if (!HasComp <BibleUserComponent>(args.User))
            {
                _popupSystem.PopupEntity(Loc.GetString("bible-sizzle"), args.User, Filter.Entities(args.User));

                SoundSystem.Play(Filter.Pvs(args.User), "/Audio/Effects/lightburn.ogg", args.User);
                _damageableSystem.TryChangeDamage(args.User, component.DamageOnUntrainedUse, true);

                return;
            }

            if (!_invSystem.TryGetSlotEntity(args.Target.Value, "head", out var entityUid))
            {
                if (_random.Prob(component.FailChance))
                {
                    var othersFailMessage = Loc.GetString("bible-heal-fail-others", ("user", args.User), ("target", args.Target), ("bible", uid));
                    _popupSystem.PopupEntity(othersFailMessage, args.User, Filter.Pvs(args.User).RemoveWhereAttachedEntity(puid => puid == args.User));

                    var selfFailMessage = Loc.GetString("bible-heal-fail-self", ("target", args.Target), ("bible", uid));
                    _popupSystem.PopupEntity(selfFailMessage, args.User, Filter.Entities(args.User));

                    SoundSystem.Play(Filter.Pvs(args.Target.Value), "/Audio/Effects/hit_kick.ogg", args.User);
                    _damageableSystem.TryChangeDamage(args.Target.Value, component.DamageOnFail, true);
                    return;
                }
            }

            var othersMessage = Loc.GetString("bible-heal-success-others", ("user", args.User), ("target", args.Target), ("bible", uid));

            _popupSystem.PopupEntity(othersMessage, args.User, Filter.Pvs(args.User).RemoveWhereAttachedEntity(puid => puid == args.User));

            var selfMessage = Loc.GetString("bible-heal-success-self", ("target", args.Target), ("bible", uid));

            _popupSystem.PopupEntity(selfMessage, args.User, Filter.Entities(args.User));

            SoundSystem.Play(Filter.Pvs(args.Target.Value), "/Audio/Effects/holy.ogg", args.User);
            _damageableSystem.TryChangeDamage(args.Target.Value, component.Damage, true);
        }
        private void OnEntityActionPerform(EntityUid uid, SharedCombatModeComponent component, DisarmActionEvent args)
        {
            if (args.Handled)
            {
                return;
            }

            if (!_actionBlockerSystem.CanAttack(args.Performer))
            {
                return;
            }

            var attemptEvent = new DisarmAttemptEvent(args.Target, args.Performer);

            RaiseLocalEvent(args.Target, attemptEvent);
            if (attemptEvent.Cancelled)
            {
                return;
            }

            var diff  = Transform(args.Target).MapPosition.Position - Transform(args.Performer).MapPosition.Position;
            var angle = Angle.FromWorldVec(diff);

            var filterAll   = Filter.Pvs(args.Performer);
            var filterOther = filterAll.RemoveWhereAttachedEntity(e => e == args.Performer);

            args.Handled = true;

            if (_random.Prob(component.DisarmFailChance))
            {
                SoundSystem.Play(Filter.Pvs(args.Performer), component.DisarmFailSound.GetSound(), args.Performer, AudioHelpers.WithVariation(0.025f));

                var targetName = Name(args.Target);

                var msgOther = Loc.GetString(
                    "disarm-action-popup-message-other-clients",
                    ("performerName", Name(args.Performer)),
                    ("targetName", targetName));

                var msgUser = Loc.GetString("disarm-action-popup-message-cursor", ("targetName", targetName));

                _popupSystem.PopupEntity(msgOther, args.Performer, filterOther);
                _popupSystem.PopupEntity(msgUser, args.Performer, Filter.Entities(args.Performer));

                _meleeWeaponSystem.SendLunge(angle, args.Performer);
                return;
            }

            _meleeWeaponSystem.SendAnimation("disarm", angle, args.Performer, args.Performer, new[] { args.Target });
            SoundSystem.Play(filterAll, component.DisarmSuccessSound.GetSound(), args.Performer, AudioHelpers.WithVariation(0.025f));
            _logSystem.Add(LogType.DisarmedAction, $"{ToPrettyString(args.Performer):user} used disarm on {ToPrettyString(args.Target):target}");

            var eventArgs = new DisarmedEvent()
            {
                Target = args.Target, Source = args.Performer, PushProbability = component.DisarmPushChance
            };

            RaiseLocalEvent(args.Target, eventArgs);
        }
        private void StunEntity(IEntity entity, StunbatonComponent comp)
        {
            if (!entity.TryGetComponent(out StatusEffectsComponent? status) || !comp.Activated)
            {
                return;
            }

            // TODO: Make slowdown inflicted customizable.

            SoundSystem.Play(Filter.Pvs(comp.Owner), comp.StunSound.GetSound(), comp.Owner, AudioHelpers.WithVariation(0.25f));
            if (!EntityManager.HasComponent <SlowedDownComponent>(entity.Uid))
            {
                if (_robustRandom.Prob(comp.ParalyzeChanceNoSlowdown))
                {
                    _stunSystem.TryParalyze(entity.Uid, TimeSpan.FromSeconds(comp.ParalyzeTime), status);
                }
                else
                {
                    _stunSystem.TrySlowdown(entity.Uid, TimeSpan.FromSeconds(comp.SlowdownTime), 0.5f, 0.5f, status);
                }
            }
            else
            {
                if (_robustRandom.Prob(comp.ParalyzeChanceWithSlowdown))
                {
                    _stunSystem.TryParalyze(entity.Uid, TimeSpan.FromSeconds(comp.ParalyzeTime), status);
                }
                else
                {
                    _stunSystem.TrySlowdown(entity.Uid, TimeSpan.FromSeconds(comp.SlowdownTime), 0.5f, 0.5f, status);
                }
            }

            var slowdownTime = TimeSpan.FromSeconds(comp.SlowdownTime);

            _jitterSystem.DoJitter(entity.Uid, slowdownTime, status: status);
            _stutteringSystem.DoStutter(entity.Uid, slowdownTime, status);

            if (!comp.Owner.TryGetComponent <PowerCellSlotComponent>(out var slot) || slot.Cell == null || !(slot.Cell.CurrentCharge < comp.EnergyPerUse))
            {
                return;
            }

            SoundSystem.Play(Filter.Pvs(comp.Owner), comp.SparksSound.GetSound(), comp.Owner, AudioHelpers.WithVariation(0.25f));
            TurnOff(comp);
        }
예제 #16
0
    private void OnDamageChanged(EntityUid uid, BloodstreamComponent component, DamageChangedEvent args)
    {
        if (args.DamageDelta is null)
        {
            return;
        }

        // TODO probably cache this or something. humans get hurt a lot
        if (!_prototypeManager.TryIndex <DamageModifierSetPrototype>(component.DamageBleedModifiers, out var modifiers))
        {
            return;
        }

        var bloodloss = DamageSpecifier.ApplyModifierSet(args.DamageDelta, modifiers);

        if (bloodloss.Empty)
        {
            return;
        }

        var oldBleedAmount = component.BleedAmount;
        var total          = bloodloss.Total;
        var totalFloat     = total.Float();

        TryModifyBleedAmount(uid, totalFloat, component);

        var prob          = Math.Clamp(totalFloat / 50, 0, 1);
        var healPopupProb = Math.Clamp(Math.Abs(totalFloat) / 25, 0, 1);

        if (totalFloat > 0 && _robustRandom.Prob(prob))
        {
            TryModifyBloodLevel(uid, (-total) / 5, component);
            SoundSystem.Play(Filter.Pvs(uid), component.InstantBloodSound.GetSound(), uid, AudioParams.Default);
        }
        else if (totalFloat < 0 && oldBleedAmount > 0 && _robustRandom.Prob(healPopupProb))
        {
            // Magically, this damage has healed some bleeding, likely
            // because it's burn damage that cauterized their wounds.

            // We'll play a special sound and popup for feedback.
            SoundSystem.Play(Filter.Pvs(uid), component.BloodHealedSound.GetSound(), uid, AudioParams.Default);
            _popupSystem.PopupEntity(Loc.GetString("bloodstream-component-wounds-cauterized"), uid,
                                     Filter.Entities(uid));
            ;
        }
    }
        private void Spawn(ConditionalSpawnerComponent component)
        {
            if (component.Chance != 1.0f && !_robustRandom.Prob(component.Chance))
            {
                return;
            }

            if (component.Prototypes.Count == 0)
            {
                Logger.Warning($"Prototype list in ConditionalSpawnComponent is empty! Entity: {component.Owner}");
                return;
            }

            if (!Deleted(component.Owner))
            {
                EntityManager.SpawnEntity(_robustRandom.Pick(component.Prototypes), Transform(component.Owner).Coordinates);
            }
        }
예제 #18
0
        private void OnThrowCollide(EntityUid uid, StunbatonComponent comp, ThrowDoHitEvent args)
        {
            if (!comp.Activated)
            {
                return;
            }

            if (!TryComp <BatteryComponent>(uid, out var battery))
            {
                return;
            }

            if (_robustRandom.Prob(comp.OnThrowStunChance) && battery.TryUseCharge(comp.EnergyPerUse))
            {
                SendPowerPulse(args.Target, args.User, uid);
                StunEntity(args.Target, comp);
            }
        }
예제 #19
0
        private void HandleDecompressionFloorRip(float sum)
        {
            var chance = MathHelper.Clamp(sum / 500, 0.005f, 0.5f);

            if (sum > 20 && _robustRandom.Prob(chance))
            {
                _gridAtmosphereComponent.PryTile(GridIndices);
            }
        }
        private void OnUseInHand(EntityUid uid, SpawnItemsOnUseComponent component, UseInHandEvent args)
        {
            if (args.Handled)
            {
                return;
            }

            var     owner = EntityManager.GetEntity(uid);
            var     alreadySpawnedGroups = new List <string>();
            IEntity?entityToPlaceInHands = null;

            foreach (var storageItem in component.Items)
            {
                if (!string.IsNullOrEmpty(storageItem.GroupId) &&
                    alreadySpawnedGroups.Contains(storageItem.GroupId))
                {
                    continue;
                }

                if (storageItem.SpawnProbability != 1f &&
                    !_random.Prob(storageItem.SpawnProbability))
                {
                    continue;
                }

                for (var i = 0; i < storageItem.Amount; i++)
                {
                    entityToPlaceInHands = EntityManager.SpawnEntity(storageItem.PrototypeId, args.User.Transform.Coordinates);
                }

                if (!string.IsNullOrEmpty(storageItem.GroupId))
                {
                    alreadySpawnedGroups.Add(storageItem.GroupId);
                }
            }

            if (component.Sound != null)
            {
                SoundSystem.Play(Filter.Pvs(owner), component.Sound.GetSound());
            }

            component.Uses--;
            if (component.Uses == 0)
            {
                args.Handled = true;
                owner.Delete();
            }

            if (entityToPlaceInHands != null &&
                args.User.TryGetComponent <SharedHandsComponent>(out var hands))
            {
                hands.TryPutInAnyHand(entityToPlaceInHands);
            }
        }
예제 #21
0
        public void ExperiencePressureDifference(int cycle, float pressureDifference, AtmosDirection direction,
                                                 float pressureResistanceProbDelta, EntityCoordinates throwTarget)
        {
            if (!Owner.TryGetComponent(out PhysicsComponent? physics))
            {
                return;
            }

            physics.WakeBody();
            // TODO ATMOS stuns?

            var transform = physics.Owner.Transform;
            var maxForce  = MathF.Sqrt(pressureDifference) * 2.25f;
            var moveProb  = 100f;

            if (PressureResistance > 0)
            {
                moveProb = MathF.Abs((pressureDifference / PressureResistance * ProbabilityBasePercent) -
                                     ProbabilityOffset);
            }

            if (moveProb > ProbabilityOffset && _robustRandom.Prob(MathF.Min(moveProb / 100f, 1f)) &&
                !float.IsPositiveInfinity(MoveResist) &&
                (!physics.Anchored &&
                 (maxForce >= (MoveResist * MoveForcePushRatio))) ||
                (physics.Anchored && (maxForce >= (MoveResist * MoveForceForcePushRatio))))
            {
                if (physics.Owner.HasComponent <IMobStateComponent>())
                {
                    physics.BodyStatus = BodyStatus.InAir;

                    foreach (var fixture in physics.Fixtures)
                    {
                        fixture.CollisionMask &= ~(int)CollisionGroup.VaultImpassable;
                    }

                    Owner.SpawnTimer(2000, () =>
                    {
                        if (Deleted || !Owner.TryGetComponent(out PhysicsComponent? physicsComponent))
                        {
                            return;
                        }

                        // Uhh if you get race conditions good luck buddy.
                        if (physicsComponent.Owner.HasComponent <IMobStateComponent>())
                        {
                            physicsComponent.BodyStatus = BodyStatus.OnGround;
                        }

                        foreach (var fixture in physics.Fixtures)
                        {
                            fixture.CollisionMask |= (int)CollisionGroup.VaultImpassable;
                        }
                    });
        private void OnDamage(EntityUid uid, VendingMachineComponent component, DamageChangedEvent args)
        {
            if (component.DispenseOnHitChance == null || args.DamageDelta == null)
            {
                return;
            }

            if (args.DamageDelta.Total >= component.DispenseOnHitThreshold && _random.Prob(component.DispenseOnHitChance.Value))
            {
                EjectRandom(uid, true, component);
            }
        }
예제 #23
0
        private void StunEntity(IEntity entity, StunbatonComponent comp)
        {
            if (!entity.TryGetComponent(out StunnableComponent? stunnable) || !comp.Activated)
            {
                return;
            }

            SoundSystem.Play(Filter.Pvs(comp.Owner), comp.StunSound.GetSound(), comp.Owner, AudioHelpers.WithVariation(0.25f));
            if (!stunnable.SlowedDown)
            {
                if (_robustRandom.Prob(comp.ParalyzeChanceNoSlowdown))
                {
                    stunnable.Paralyze(comp.ParalyzeTime);
                }
                else
                {
                    stunnable.Slowdown(comp.SlowdownTime);
                }
            }
            else
            {
                if (_robustRandom.Prob(comp.ParalyzeChanceWithSlowdown))
                {
                    stunnable.Paralyze(comp.ParalyzeTime);
                }
                else
                {
                    stunnable.Slowdown(comp.SlowdownTime);
                }
            }


            if (!comp.Owner.TryGetComponent <PowerCellSlotComponent>(out var slot) || slot.Cell == null || !(slot.Cell.CurrentCharge < comp.EnergyPerUse))
            {
                return;
            }

            SoundSystem.Play(Filter.Pvs(comp.Owner), comp.SparksSound.GetSound(), comp.Owner, AudioHelpers.WithVariation(0.25f));
            TurnOff(comp);
        }
        private void StunEntity(IEntity entity, StunbatonComponent comp)
        {
            if (!entity.TryGetComponent(out StunnableComponent? stunnable) || !comp.Activated)
            {
                return;
            }

            SoundSystem.Play(Filter.Pvs(comp.Owner), "/Audio/Weapons/egloves.ogg", comp.Owner.Transform.Coordinates, AudioHelpers.WithVariation(0.25f));
            if (!stunnable.SlowedDown)
            {
                if (_robustRandom.Prob(comp.ParalyzeChanceNoSlowdown))
                {
                    stunnable.Paralyze(comp.ParalyzeTime);
                }
                else
                {
                    stunnable.Slowdown(comp.SlowdownTime);
                }
            }
            else
            {
                if (_robustRandom.Prob(comp.ParalyzeChanceWithSlowdown))
                {
                    stunnable.Paralyze(comp.ParalyzeTime);
                }
                else
                {
                    stunnable.Slowdown(comp.SlowdownTime);
                }
            }


            if (!comp.Owner.TryGetComponent <PowerCellSlotComponent>(out var slot) || slot.Cell == null || !(slot.Cell.CurrentCharge < comp.EnergyPerUse))
            {
                return;
            }

            SoundSystem.Play(Filter.Pvs(comp.Owner), AudioHelpers.GetRandomFileFromSoundCollection("sparks"), comp.Owner.Transform.Coordinates, AudioHelpers.WithVariation(0.25f));
            TurnOff(comp);
        }
예제 #25
0
        private void OnUseInHand(EntityUid uid, SpawnItemsOnUseComponent component, UseInHandEvent args)
        {
            if (args.Handled)
            {
                return;
            }

            var       alreadySpawnedGroups = new List <string>();
            EntityUid?entityToPlaceInHands = null;

            foreach (var storageItem in component.Items)
            {
                if (!string.IsNullOrEmpty(storageItem.GroupId) &&
                    alreadySpawnedGroups.Contains(storageItem.GroupId))
                {
                    continue;
                }

                if (storageItem.SpawnProbability != 1f &&
                    !_random.Prob(storageItem.SpawnProbability))
                {
                    continue;
                }

                for (var i = 0; i < storageItem.Amount; i++)
                {
                    entityToPlaceInHands = EntityManager.SpawnEntity(storageItem.PrototypeId, EntityManager.GetComponent <TransformComponent>(args.User).Coordinates);
                }

                if (!string.IsNullOrEmpty(storageItem.GroupId))
                {
                    alreadySpawnedGroups.Add(storageItem.GroupId);
                }
            }

            if (component.Sound != null)
            {
                SoundSystem.Play(Filter.Pvs(uid), component.Sound.GetSound(), uid);
            }

            component.Uses--;
            if (component.Uses == 0)
            {
                args.Handled = true;
                EntityManager.DeleteEntity(uid);
            }

            if (entityToPlaceInHands != null)
            {
                _handsSystem.PickupOrDrop(args.User, entityToPlaceInHands.Value);
            }
        }
예제 #26
0
        /// <summary>
        /// Attempt to break the utensil after interaction.
        /// </summary>
        /// <param name="uid">Utensil.</param>
        /// <param name="userUid">User of the utensil.</param>
        public void TryBreak(EntityUid uid, EntityUid userUid, UtensilComponent?component = null)
        {
            if (!Resolve(uid, ref component))
            {
                return;
            }

            if (_robustRandom.Prob(component.BreakChance))
            {
                SoundSystem.Play(Filter.Pvs(userUid), component.BreakSound.GetSound(), userUid, AudioParams.Default.WithVolume(-2f));
                EntityManager.DeleteEntity(component.Owner);
            }
        }
예제 #27
0
        public void DoInstantAction(InstantActionEventArgs args)
        {
            if (!EntitySystem.Get <ActionBlockerSystem>().CanSpeak(args.Performer))
            {
                return;
            }
            if (!args.Performer.TryGetComponent <HumanoidAppearanceComponent>(out var humanoid))
            {
                return;
            }
            if (!args.Performer.TryGetComponent <SharedActionsComponent>(out var actions))
            {
                return;
            }

            if (_random.Prob(.01f) && !string.IsNullOrWhiteSpace(_wilhelm))
            {
                SoundSystem.Play(Filter.Pvs(args.Performer), _wilhelm, args.Performer, AudioParams.Default.WithVolume(Volume));
            }
            else
            {
                switch (humanoid.Sex)
                {
                case Sex.Male:
                    if (_male == null)
                    {
                        break;
                    }
                    SoundSystem.Play(Filter.Pvs(args.Performer), _random.Pick(_male), args.Performer,
                                     AudioHelpers.WithVariation(Variation).WithVolume(Volume));
                    break;

                case Sex.Female:
                    if (_female == null)
                    {
                        break;
                    }
                    SoundSystem.Play(Filter.Pvs(args.Performer), _random.Pick(_female), args.Performer,
                                     AudioHelpers.WithVariation(Variation).WithVolume(Volume));
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }



            actions.Cooldown(args.ActionType, Cooldowns.SecondsFromNow(_cooldown));
        }
 /// <summary>
 /// Handles the logic of the AI
 /// </summary>
 /// <returns>An Enemyaction-message.</returns>
 private void ExecuteAiAction()
 {
     if (_turtleTracker >= 4)
     {
         var boomAmount = _random.Next(5, 10);
         _latestEnemyActionMessage = Loc.GetString("space-villain-game-enemy-throws-bomb-message",
                                                   ("enemyName", _enemyName),
                                                   ("damageReceived", boomAmount));
         if (_owner._playerInvincibilityFlag)
         {
             return;
         }
         _playerHp -= boomAmount;
         _turtleTracker--;
     }
     else if (_enemyMp <= 5 && _random.Prob(0.7f))
     {
         var stealAmount = _random.Next(2, 3);
         _latestEnemyActionMessage = Loc.GetString("space-villain-game-enemy-steals-player-power-message",
                                                   ("enemyName", _enemyName),
                                                   ("stolenAmount", stealAmount));
         if (_owner._playerInvincibilityFlag)
         {
             return;
         }
         _playerMp -= stealAmount;
         _enemyMp  += stealAmount;
     }
     else if (_enemyHp <= 10 && _enemyMp > 4)
     {
         _enemyHp += 4;
         _enemyMp -= 4;
         _latestEnemyActionMessage = Loc.GetString("space-villain-game-enemy-heals-message",
                                                   ("enemyName", _enemyName),
                                                   ("healedAmount", 4));
     }
     else
     {
         var attackAmount = _random.Next(3, 6);
         _latestEnemyActionMessage =
             Loc.GetString("space-villain-game-enemy-attacks-message",
                           ("enemyName", _enemyName),
                           ("damageDealt", attackAmount));
         if (_owner._playerInvincibilityFlag)
         {
             return;
         }
         _playerHp -= attackAmount;
     }
 }
        private void Spawn()
        {
            if (Chance != 1.0f && !_robustRandom.Prob(Chance))
            {
                return;
            }

            if (Prototypes.Count == 0)
            {
                Logger.Warning($"Prototype list in ConditionalSpawnComponent is empty! Entity: {Owner}");
                return;
            }

            _entityManager.SpawnEntity(_robustRandom.Pick(Prototypes), Owner.Transform.GridPosition);
        }
        private void OnTimerFired()
        {
            if (!_robustRandom.Prob(Chance))
            {
                return;
            }

            var number = _robustRandom.Next(MinimumEntitiesSpawned, MaximumEntitiesSpawned);

            for (int i = 0; i < number; i++)
            {
                var entity = _robustRandom.Pick(Prototypes);
                _entityManager.SpawnEntity(entity, Owner.Transform.GridPosition);
            }
        }