Ejemplo n.º 1
0
        /// <summary>
        /// Fires a round of ammo out of the weapon.
        /// </summary>
        /// <param name="shooter">Entity that is operating the weapon, usually the player.</param>
        /// <param name="targetPos">Target position on the map to shoot at.</param>
        private void Fire(EntityUid shooter, Vector2 targetPos)
        {
            if (ShotsLeft == 0)
            {
                SoundSystem.Play(Filter.Broadcast(), SoundEmpty.GetSound(), Owner);
                return;
            }

            var ammo = PeekAmmo();

            if (TakeProjectile(Entities.GetComponent <TransformComponent>(shooter).Coordinates) is not {
                Valid: true
            } projectile)
            {
                SoundSystem.Play(Filter.Broadcast(), SoundEmpty.GetSound(), Owner);
                return;
            }

            // At this point firing is confirmed
            var direction = (targetPos - Entities.GetComponent <TransformComponent>(shooter).WorldPosition).ToAngle();
            var angle     = GetRecoilAngle(direction);

            // This should really be client-side but for now we'll just leave it here
            if (Entities.HasComponent <CameraRecoilComponent>(shooter))
            {
                var kick = -angle.ToVec() * 0.15f;
                EntitySystem.Get <CameraRecoilSystem>().KickCamera(shooter, kick);
            }

            // This section probably needs tweaking so there can be caseless hitscan etc.
            if (Entities.TryGetComponent(projectile, out HitscanComponent? hitscan))
            {
                FireHitscan(shooter, hitscan, angle);
            }
            else if (Entities.HasComponent <ProjectileComponent>(projectile) &&
                     Entities.TryGetComponent(ammo, out AmmoComponent? ammoComponent))
            {
                FireProjectiles(shooter, projectile, ammoComponent.ProjectilesFired, ammoComponent.EvenSpreadAngle, angle, ammoComponent.Velocity, ammo.Value);

                if (CanMuzzleFlash)
                {
                    EntitySystem.Get <GunSystem>().MuzzleFlash(Owner, ammoComponent, angle);
                }

                if (ammoComponent.Caseless)
                {
                    Entities.DeleteEntity(ammo.Value);
                }
            }
            else
            {
                // Invalid types
                throw new InvalidOperationException();
            }

            SoundSystem.Play(Filter.Broadcast(), SoundGunshot.GetSound(), Owner);

            _lastFire = _gameTiming.CurTime;
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Fires a round of ammo out of the weapon.
        /// </summary>
        /// <param name="shooter">Entity that is operating the weapon, usually the player.</param>
        /// <param name="targetPos">Target position on the map to shoot at.</param>
        private void Fire(IEntity shooter, Vector2 targetPos)
        {
            if (ShotsLeft == 0)
            {
                SoundSystem.Play(Filter.Broadcast(), SoundEmpty.GetSound(), Owner);
                return;
            }

            var ammo       = PeekAmmo();
            var projectile = TakeProjectile(shooter.Transform.Coordinates);

            if (projectile == null)
            {
                SoundSystem.Play(Filter.Broadcast(), SoundEmpty.GetSound(), Owner);
                return;
            }

            // At this point firing is confirmed
            var direction = (targetPos - shooter.Transform.WorldPosition).ToAngle();
            var angle     = GetRecoilAngle(direction);

            // This should really be client-side but for now we'll just leave it here
            if (shooter.TryGetComponent(out CameraRecoilComponent? recoilComponent))
            {
                recoilComponent.Kick(-angle.ToVec() * 0.15f);
            }

            // This section probably needs tweaking so there can be caseless hitscan etc.
            if (projectile.TryGetComponent(out HitscanComponent? hitscan))
            {
                FireHitscan(shooter, hitscan, angle);
            }
            else if (projectile.HasComponent <ProjectileComponent>() &&
                     ammo != null &&
                     ammo.TryGetComponent(out AmmoComponent? ammoComponent))
            {
                FireProjectiles(shooter, projectile, ammoComponent.ProjectilesFired, ammoComponent.EvenSpreadAngle, angle, ammoComponent.Velocity, ammo);

                if (CanMuzzleFlash)
                {
                    ammoComponent.MuzzleFlash(Owner, angle);
                }

                if (ammoComponent.Caseless)
                {
                    ammo.Delete();
                }
            }
            else
            {
                // Invalid types
                throw new InvalidOperationException();
            }

            SoundSystem.Play(Filter.Broadcast(), SoundGunshot.GetSound(), Owner);

            _lastFire = _gameTiming.CurTime;
        }
Ejemplo n.º 3
0
        public override ComponentState GetComponentState()
        {
            var slotsSpent = new bool?[Capacity];

            for (var i = 0; i < Capacity; i++)
            {
                slotsSpent[i] = null;
                var ammoEntity = _ammoSlots[i];
                if (ammoEntity != default && Entities.TryGetComponent(ammoEntity, out AmmoComponent? ammo))
                {
                    slotsSpent[i] = ammo.Spent;
                }
            }

            //TODO: make yaml var to not sent currentSlot/UI? (for russian roulette)
            return(new RevolverBarrelComponentState(
                       _currentSlot,
                       FireRateSelector,
                       slotsSpent,
                       SoundGunshot.GetSound()));
        }