public IncomingAttackPrepStage(BaseActivity parent, IncomingRangedAttack incoming, EvasionMode <T> evasionMode, params object[] args) : base("IncomingAttackPrep")
 {
     ParentActivity = parent;
     Incoming       = incoming;
     Evasion        = evasionMode;
     Provider       = Evasion.CreateProvider(args);
     SetUpProvider(Provider, true);
     BaseActivity.BackgroundStages.Add(this); // Put into startAction() or even Activate() if the timing on this (not yet defined and all) is an issue.
 }
        public IncomingAttackReactionStage(BaseActivity parent, IncomingRangedAttack incoming, EvasionMode <T> evasionMode, IProvider <T> provider) : base("IncomingAttackReaction")
        {
            ParentActivity = parent;
            Incoming       = incoming;
            Evasion        = evasionMode;
            Provider       = provider ?? Evasion.CreateProvider();

            SetUpProvider(Provider);
            Stopwatch = new System.Diagnostics.Stopwatch();
        }
Beispiel #3
0
            public async void ResolveTriggerPull()
            {
                try
                {
                    // Both debouncing and conceptually letting the gun's mechanism cycle - two birds, one rock!
                    if (DateTime.Now < nextReadyTime)
                    {
                        return;
                    }
                    lastTriggerPull = DateTime.Now;
                    nextReadyTime   = DateTime.Now + Weapon.CooldownPeriod;

                    // Is the weapon being pointed up?
                    var AngleToGravity = Gravity.Vector.AngleTo(Weapon.vectorPointedForward);
                    if (AngleToGravity < 30)
                    {
                        Weapon.ReloadSFX?.Play(useSpeakers: true);
                        nextReadyTime += Weapon.ReloadTime;
                        while (Weapon.CurrentAmmoCount < Weapon.MaxAmmoCapacity)
                        {
                            await Task.Delay((int)(Weapon.ReloadTime.TotalMilliseconds / (Weapon.MaxAmmoCapacity + 1)));

                            //await Task.Delay((int)(Weapon.ReloadTime.TotalMilliseconds / Weapon.MaxAmmoCapacity));
                            Current.SetBulletDisplay(++Weapon.CurrentAmmoCount);
                            //Weapon.ClickEmptySFX.Play(0.5); // Stand-in for the currently null ReloadSFX.
                        }
                        return;
                    }

                    // Or... is it being pointed down?  We've coded that to be "change fire mode."
                    if (AngleToGravity > 150)
                    {
                        if (!Weapon.SupportsBurstFire && !Weapon.SupportsFullAutomatic)
                        {
                            Speech.Say("This weapon supports single shot mode only.", SoundOptions.OnHeadphones);
                            return;
                        }
                        if (Weapon.CurrentFireMode == Gun.FireMode.SingleShot)
                        {
                            if (Weapon.SupportsBurstFire)
                            {
                                Weapon.CurrentFireMode = Gun.FireMode.BurstFire;
                            }
                            else if (Weapon.SupportsFullAutomatic)
                            {
                                Weapon.CurrentFireMode = Gun.FireMode.FullAuto;
                            }
                        }
                        else if (Weapon.CurrentFireMode == Gun.FireMode.BurstFire)
                        {
                            if (Weapon.SupportsFullAutomatic)
                            {
                                Weapon.CurrentFireMode = Gun.FireMode.FullAuto;
                            }
                            else
                            {
                                Weapon.CurrentFireMode = Gun.FireMode.SingleShot;
                            }
                        }
                        else
                        {
                            Weapon.CurrentFireMode = Gun.FireMode.SingleShot;
                        }
                        Speech.Say(Weapon.CurrentFireMode.ToString(), SoundOptions.OnHeadphones);
                        return;
                    }

                    // Okay. Are they out of ammo?
                    if (Weapon.CurrentAmmoCount == 0)
                    {
                        await(Weapon.ClickEmptySFX?.PlayToCompletion(null, true) ?? Task.CompletedTask);
                        return;
                    }

                    Weapon.CurrentAmmoCount--;
                    Current.SetBulletDisplay(Weapon.CurrentAmmoCount);

                    exhaleCueHasBeenProvided = false;

                    await Task.WhenAll(Task.Delay(150).ContinueWith(_ => CrossVibrate.Current.Vibration(50)),
                                       Weapon.ShotSFX.PlayToCompletion(1.0, true));

                    await Task.Delay(random.Next(100, 400));

                    // Do the dice rolls now
                    var DidHit = DidItHit();

                    // And assess the results one way or the other
                    bool   DoResultSFX;
                    double ResultSFXVolume;
                    if (DidHit)
                    {
                        DoResultSFX     = random.Next(1, 20) < 17;
                        ResultSFXVolume = 0.25 * (3.0 + Math.Max(random.NextDouble(), random.NextDouble()));
                        Current.AddKillTallymark();
                    }
                    else
                    {
                        DoResultSFX     = random.Next(1, 20) < 11;
                        ResultSFXVolume = random.NextDouble();
                    }

                    // Play the SFX depending on hit/miss status and the odds (within each) of an audible response.  Not every wound/ricochet is audible!
                    if (DoResultSFX)
                    {
                        if (DidHit)
                        {
                            ShotHitSFX.Play(ResultSFXVolume, useSpeakers: true);
                            // Experimental!!
                            Atropos.Communications.HeyYou.MyTeammates.PlaySFX(ShotHitSFX);
                        }
                        else
                        {
                            ShotMissSFX.Play(ResultSFXVolume, useSpeakers: true);
                            // Experimental!!
                            Atropos.Communications.HeyYou.MyTeammates.PlaySFX(ShotMissSFX);
                        }
                    }

                    // Testing the new Evasion code here... for now after every third shot.
                    if (Weapon.CurrentAmmoCount % 3 == 0)
                    {
                        var Incoming = new IncomingRangedAttack();
                        EvasionMode <Vector3> Evasion = (Res.CoinFlip) ? new EvasionMode.Dodge() : new EvasionMode.Duck();
                        var EvasionStage = new IncomingAttackPrepStage <Vector3>(Current, Incoming, Evasion);
                        EvasionStage.Activate();
                    }
                }
                catch (Exception)
                {
                    throw;
                }
            }