예제 #1
0
        private void OnInteractHand(EntityUid uid, EmitterComponent component, InteractHandEvent args)
        {
            args.Handled = true;
            if (EntityManager.TryGetComponent(uid, out LockComponent? lockComp) && lockComp.Locked)
            {
                component.Owner.PopupMessage(args.User, Loc.GetString("comp-emitter-access-locked", ("target", component.Owner)));
                return;
            }

            if (EntityManager.TryGetComponent(component.Owner, out PhysicsComponent? phys) && phys.BodyType == BodyType.Static)
            {
                if (!component.IsOn)
                {
                    SwitchOn(component);
                    component.Owner.PopupMessage(args.User, Loc.GetString("comp-emitter-turned-on", ("target", component.Owner)));
                }
                else
                {
                    SwitchOff(component);
                    component.Owner.PopupMessage(args.User, Loc.GetString("comp-emitter-turned-off", ("target", component.Owner)));
                }

                _adminLog.Add(LogType.Emitter,
                              component.IsOn ? LogImpact.Medium : LogImpact.High,
                              $"{ToPrettyString(args.User):player} toggled {ToPrettyString(uid):emitter}");
            }
            else
            {
                component.Owner.PopupMessage(args.User, Loc.GetString("comp-emitter-not-anchored", ("target", component.Owner)));
            }
        }
예제 #2
0
        private void OnInteractUsing(EntityUid uid, EmitterComponent component, InteractUsingEvent args)
        {
            if (args.Handled)
            {
                return;
            }

            if (component.AccessReader == null || !args.Used.TryGetComponent(out IAccess? access))
            {
                return;
            }

            if (component.AccessReader.IsAllowed(access))
            {
                component.IsLocked ^= true;

                if (component.IsLocked)
                {
                    component.Owner.PopupMessage(args.User, Loc.GetString("comp-emitter-lock", ("target", component.Owner)));
                }
                else
                {
                    component.Owner.PopupMessage(args.User, Loc.GetString("comp-emitter-unlock", ("target", component.Owner)));
                }

                UpdateAppearance(component);
            }
            else
            {
                component.Owner.PopupMessage(args.User, Loc.GetString("comp-emitter-access-denied"));
            }

            args.Handled = true;
        }
예제 #3
0
        private void Fire(EmitterComponent component)
        {
            var projectile = EntityManager.SpawnEntity(component.BoltType, EntityManager.GetComponent <TransformComponent>(component.Owner).Coordinates);

            if (!EntityManager.TryGetComponent <PhysicsComponent?>(projectile, out var physicsComponent))
            {
                Logger.Error("Emitter tried firing a bolt, but it was spawned without a PhysicsComponent");
                return;
            }

            physicsComponent.BodyStatus = BodyStatus.InAir;

            if (!EntityManager.TryGetComponent <ProjectileComponent?>(projectile, out var projectileComponent))
            {
                Logger.Error("Emitter tried firing a bolt, but it was spawned without a ProjectileComponent");
                return;
            }

            projectileComponent.IgnoreEntity(component.Owner);

            physicsComponent
            .LinearVelocity = EntityManager.GetComponent <TransformComponent>(component.Owner).WorldRotation.ToWorldVec() * 20f;
            EntityManager.GetComponent <TransformComponent>(projectile).WorldRotation = EntityManager.GetComponent <TransformComponent>(component.Owner).WorldRotation;

            // TODO: Move to projectile's code.
            Timer.Spawn(3000, () => EntityManager.DeleteEntity(projectile));

            SoundSystem.Play(Filter.Pvs(component.Owner), component.FireSound.GetSound(), component.Owner,
                             AudioHelpers.WithVariation(EmitterComponent.Variation).WithVolume(EmitterComponent.Volume).WithMaxDistance(EmitterComponent.Distance));
        }
예제 #4
0
        private void OnInteractHand(EntityUid uid, EmitterComponent component, InteractHandEvent args)
        {
            args.Handled = true;
            if (EntityManager.TryGetComponent(uid, out LockComponent? lockComp) && lockComp.Locked)
            {
                component.Owner.PopupMessage(args.User, Loc.GetString("comp-emitter-access-locked", ("target", component.Owner)));
                return;
            }

            if (EntityManager.TryGetComponent(component.Owner, out PhysicsComponent? phys) && phys.BodyType == BodyType.Static)
            {
                if (!component.IsOn)
                {
                    SwitchOn(component);
                    component.Owner.PopupMessage(args.User, Loc.GetString("comp-emitter-turned-on", ("target", component.Owner)));
                }
                else
                {
                    SwitchOff(component);
                    component.Owner.PopupMessage(args.User, Loc.GetString("comp-emitter-turned-off", ("target", component.Owner)));
                }
            }
            else
            {
                component.Owner.PopupMessage(args.User, Loc.GetString("comp-emitter-not-anchored", ("target", component.Owner)));
            }
        }
예제 #5
0
        private void ShotTimerCallback(EmitterComponent component)
        {
            if (component.Deleted)
            {
                return;
            }

            // Any power-off condition should result in the timer for this method being cancelled
            // and thus not firing
            DebugTools.Assert(component.IsPowered);
            DebugTools.Assert(component.IsOn);
            DebugTools.Assert(component.PowerConsumer != null && (component.PowerConsumer.DrawRate <= component.PowerConsumer.ReceivedPower));

            Fire(component);

            TimeSpan delay;

            if (component.FireShotCounter < component.FireBurstSize)
            {
                component.FireShotCounter += 1;
                delay = component.FireInterval;
            }
            else
            {
                component.FireShotCounter = 0;
                var diff = component.FireBurstDelayMax - component.FireBurstDelayMin;
                // TIL you can do TimeSpan * double.
                delay = component.FireBurstDelayMin + _random.NextFloat() * diff;
            }

            // Must be set while emitter powered.
            DebugTools.AssertNotNull(component.TimerCancel);
            Timer.Spawn(delay, () => ShotTimerCallback(component), component.TimerCancel !.Token);
        }
예제 #6
0
 public void SwitchOff(EmitterComponent component)
 {
     component.IsOn = false;
     if (component.PowerConsumer != null)
     {
         component.PowerConsumer.DrawRate = 0;
     }
     PowerOff(component);
     UpdateAppearance(component);
 }
예제 #7
0
 public void SwitchOff(EmitterComponent component)
 {
     component.IsOn = false;
     if (TryComp <PowerConsumerComponent>(component.Owner, out var powerConsumer))
     {
         powerConsumer.DrawRate = 0;
     }
     PowerOff(component);
     UpdateAppearance(component);
 }
예제 #8
0
 public void SwitchOn(EmitterComponent component)
 {
     component.IsOn = true;
     if (component.PowerConsumer != null)
     {
         component.PowerConsumer.DrawRate = component.PowerUseActive;
     }
     // Do not directly PowerOn().
     // OnReceivedPowerChanged will get fired due to DrawRate change which will turn it on.
     UpdateAppearance(component);
 }
예제 #9
0
        public void PowerOff(EmitterComponent component)
        {
            if (!component.IsPowered)
            {
                return;
            }

            component.IsPowered = false;

            // Must be set while emitter powered.
            DebugTools.AssertNotNull(component.TimerCancel);
            component.TimerCancel?.Cancel();

            UpdateAppearance(component);
        }
예제 #10
0
        public void PowerOn(EmitterComponent component)
        {
            if (component.IsPowered)
            {
                return;
            }

            component.IsPowered = true;

            component.FireShotCounter = 0;
            component.TimerCancel     = new CancellationTokenSource();

            Timer.Spawn(component.FireBurstDelayMax, () => ShotTimerCallback(component), component.TimerCancel.Token);

            UpdateAppearance(component);
        }
예제 #11
0
        private void ReceivedChanged(
            EntityUid uid,
            EmitterComponent component,
            PowerConsumerReceivedChanged args)
        {
            if (!component.IsOn)
            {
                return;
            }

            if (args.ReceivedPower < args.DrawRate)
            {
                PowerOff(component);
            }
            else
            {
                PowerOn(component);
            }
        }
예제 #12
0
        private void UpdateAppearance(EmitterComponent component)
        {
            if (component.Appearance == null)
            {
                return;
            }

            EmitterVisualState state;

            if (component.IsPowered)
            {
                state = EmitterVisualState.On;
            }
            else if (component.IsOn)
            {
                state = EmitterVisualState.Underpowered;
            }
            else
            {
                state = EmitterVisualState.Off;
            }

            component.Appearance.SetData(EmitterVisuals.VisualState, state);
        }
예제 #13
0
        private void UpdateAppearance(EmitterComponent component)
        {
            if (!TryComp <AppearanceComponent>(component.Owner, out var appearanceComponent))
            {
                return;
            }

            EmitterVisualState state;

            if (component.IsPowered)
            {
                state = EmitterVisualState.On;
            }
            else if (component.IsOn)
            {
                state = EmitterVisualState.Underpowered;
            }
            else
            {
                state = EmitterVisualState.Off;
            }

            appearanceComponent.SetData(EmitterVisuals.VisualState, state);
        }