private void UseWeapon(FireableWeapon weapon, IFireableWeaponModel model)
        {
            _player.Inventory.ForceSnapshot();

            var result = _weaponController.FireWeapon(_player, weapon);

            bool wasFired = false;

            switch (result)
            {
            case FireableWeaponController.FireResult.OutOfAmmo:
                Log.Info("Out of Ammo");
                _weaponController.Reload(_player.Inventory, weapon);
                Log.Info("Reloaded");
                break;

            case FireableWeaponController.FireResult.Missed:
                Log.Info("Fired, but missed");
                wasFired = true;
                break;

            case FireableWeaponController.FireResult.Hit:
                Log.Info("Fired and hit");
                wasFired = true;
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            if (wasFired && model != null)
            {
                model.TransitionToState(FireableWeaponState.Fired);
            }
        }
        /// <summary> Have the actor fire their primary weapon. </summary>
        /// <param name="player"> The actor who should fire their weapon. </param>
        /// <param name="weapon"> The weapon that should be fired. </param>
        /// <returns> The result of firing the weapon </returns>
        public FireResult FireWeapon(IPlayer player, FireableWeapon weapon)
        {
            if (weapon.ShotsRemaining == 0)
            {
                return(FireResult.OutOfAmmo);
            }

            var result = FireResult.Missed;

            var stats = weapon.Stats;

            var right = player.Transform.right;
            var up    = player.Transform.up;

            for (int i = 0; i < stats.NumberOfPellets; i++)
            {
                var ray = player.Transform.ToRay();

                if (stats.Spread > 0)
                {
                    var offset = right * _randomNumberGenerator.NextFloat(-stats.Spread, stats.Spread)
                                 + up * _randomNumberGenerator.NextFloat(-stats.Spread, stats.Spread);

                    ray.direction += offset;
                }

                float distance;
                var   hitObject = _raycastService.Raycast <IDestroyable>(ray, stats.MaxDistance, out distance);

                Debugging.Drawing.Draw(ray, distance);

                if (hitObject != null)
                {
                    float damage = weapon.Stats.CalculateDamage(distance);

                    Log.InfoFormat("Hit {0} with {1}.  Damage: {2}", hitObject, weapon, damage);
                    Damage(hitObject, (int)damage);

                    result = FireResult.Hit;
                }
            }

            weapon.ShotsRemaining--;

            return(result);
        }
        /// <summary> Reloads a weapon from inventory. </summary>
        /// <param name="inventory"> The inventory to reload the weapon with. </param>
        /// <param name="weapon"> The weapon that should be reloaded. </param>
        /// <returns> true if it succeeds, false if it fails. </returns>
        public ReloadResult Reload(StorageContainer inventory, FireableWeapon weapon)
        {
            var countController = new InventoryCountController(inventory);

            if (weapon.ShotsRemaining == weapon.Stats.ClipSize)
            {
                return(ReloadResult.ClipIsAlreadyFilled);
            }

            int initialCount = weapon.ShotsRemaining;

            while (weapon.ShotsRemaining < weapon.Stats.ClipSize)
            {
                var ammoCursor = countController.GetAmmoCursor(weapon.Stats.AmmoType);
                var ammoStack  = ammoCursor.Stack;

                if (ammoStack.IsEmpty)
                {
                    break;
                }

                inventory.Decrement(ammoCursor);

                weapon.ShotsRemaining++;
            }

            // we didn't add any
            if (weapon.ShotsRemaining == initialCount)
            {
                return(ReloadResult.OutOfAmmo);
            }
            else if (weapon.ShotsRemaining == weapon.Stats.ClipSize)
            {
                return(ReloadResult.ClipHasBeenFilled);
            }
            else
            {
                return(ReloadResult.AddedSomeAndNowOutOfAmmo);
            }
        }
Ejemplo n.º 4
0
 /// <summary> Gets the display count for fireable weapons. </summary>
 private int GetDisplayFor(FireableWeapon weapon)
 {
     return(weapon.ShotsRemaining);
 }