예제 #1
0
        private void EndRound(Victory victory)
        {
            string text;

            switch (victory)
            {
            case Victory.Innocents:
                text = Loc.GetString("The innocents have won!");
                break;

            case Victory.Traitors:
                text = Loc.GetString("The traitors have won!");
                break;

            default:
                text = Loc.GetString("Nobody wins!");
                break;
            }

            _gameTicker.EndRound(text);

            var restartDelay = 10;

            _chatManager.DispatchServerAnnouncement(Loc.GetString("Restarting in {0} seconds.", restartDelay));
            _checkTimerCancel.Cancel();

            Timer.Spawn(TimeSpan.FromSeconds(restartDelay), () => _gameTicker.RestartRound());
        }
예제 #2
0
        public void Update(float delta)
        {
            if (Stunned)
            {
                _stunnedTimer -= delta;

                if (_stunnedTimer <= 0)
                {
                    _stunnedTimer = 0f;
                    Dirty();
                }
            }

            if (KnockedDown)
            {
                _knockdownTimer -= delta;

                if (_knockdownTimer <= 0f)
                {
                    StandingStateHelper.Standing(Owner);

                    _knockdownTimer = 0f;
                    Dirty();
                }
            }

            if (SlowedDown)
            {
                _slowdownTimer -= delta;

                if (_slowdownTimer <= 0f)
                {
                    _slowdownTimer = 0f;

                    if (Owner.TryGetComponent(out MovementSpeedModifierComponent movement))
                    {
                        movement.RefreshMovementSpeedModifiers();
                    }
                    Dirty();
                }
            }

            if (!StunStart.HasValue || !StunEnd.HasValue ||
                !Owner.TryGetComponent(out ServerStatusEffectsComponent status))
            {
                return;
            }

            var start = StunStart.Value;
            var end   = StunEnd.Value;

            var length   = (end - start).TotalSeconds;
            var progress = (_gameTiming.CurTime - start).TotalSeconds;

            if (progress >= length)
            {
                Timer.Spawn(250, () => status.RemoveStatusEffect(StatusEffect.Stun), _statusRemoveCancellation.Token);
                _lastStun = null;
            }
        }
예제 #3
0
 private void EndRound()
 {
     _gameTicker.EndRound();
     _chatManager.DispatchServerAnnouncement($"Restarting in 10 seconds.");
     _checkTimerCancel.Cancel();
     Timer.Spawn(TimeSpan.FromSeconds(10), () => _gameTicker.RestartRound());
 }
        private void _runDelayedCheck()
        {
            _checkTimerCancel?.Cancel();
            _checkTimerCancel = new CancellationTokenSource();

            Timer.Spawn(DeadCheckDelay, _checkForWinner, _checkTimerCancel.Token);
        }
예제 #5
0
        private void Fire()
        {
            var projectile = Owner.EntityManager.SpawnEntity(_boltType, Owner.Transform.Coordinates);

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

            physicsComponent.Status = BodyStatus.InAir;

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

            projectileComponent.IgnoreEntity(Owner);

            physicsComponent
            .EnsureController <BulletController>()
            .LinearVelocity = Owner.Transform.WorldRotation.ToVec() * 20f;

            projectile.Transform.LocalRotation = Owner.Transform.WorldRotation;

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

            EntitySystem.Get <AudioSystem>().PlayFromEntity(_fireSound, Owner);
        }
예제 #6
0
        public override void Shutdown()
        {
            base.Shutdown();

            foreach (var entity in _powered)
            {
                if (entity.Deleted)
                {
                    continue;
                }

                if (entity.TryGetComponent(out PowerReceiverComponent powerReceiverComponent))
                {
                    powerReceiverComponent.PowerDisabled = false;
                }
            }

            _announceCancelToken?.Cancel();
            _announceCancelToken = new CancellationTokenSource();
            Timer.Spawn(3000, () =>
            {
                EntitySystem.Get <AudioSystem>().PlayGlobal("/Audio/Announcements/power_on.ogg");
            }, _announceCancelToken.Token);
            _powered.Clear();
        }
예제 #7
0
        private void EndRound()
        {
            OnRoundEndCountdownFinished?.Invoke();
            _gameTicker.EndRound();

            _chatManager.DispatchServerAnnouncement(Loc.GetString("Restarting the round in {0} seconds...", RestartRoundTime));

            Timer.Spawn(TimeSpan.FromSeconds(RestartRoundTime), () => _gameTicker.RestartRound(), CancellationToken.None);
        }
예제 #8
0
        public void RequestRoundEnd()
        {
            if (IsRoundEndCountdownStarted)
            {
                return;
            }

            IsRoundEndCountdownStarted = true;

            ExpectedCountdownEnd = _gameTiming.CurTime + RoundEndCountdownTime;
            Timer.Spawn(RoundEndCountdownTime, EndRound, _roundEndCancellationTokenSource.Token);
            OnRoundEndCountdownStarted?.Invoke();
        }
        public static void MakeSentient(IEntity entity)
        {
            if (entity.HasComponent <AiControllerComponent>())
            {
                entity.RemoveComponent <AiControllerComponent>();
            }

            // Delay spawning these components to avoid race conditions with the deferred removal of AiController.
            Timer.Spawn(100, () =>
            {
                entity.EnsureComponent <MindComponent>();
                entity.EnsureComponent <PlayerInputMoverComponent>();
                entity.EnsureComponent <SharedSpeechComponent>();
                entity.EnsureComponent <SharedEmotingComponent>();
            });
        }
예제 #10
0
        public void TestSpawn()
        {
            var timerManager = IoCManager.Resolve <ITimerManager>();

            var fired = false;

            Timer.Spawn(TimeSpan.FromMilliseconds(500), () => fired = true);
            Assert.That(fired, Is.False);

            // Set timers ahead 250 ms
            timerManager.UpdateTimers(new FrameEventArgs(.25f));
            Assert.That(fired, Is.False);
            // Another 300ms should do it.
            timerManager.UpdateTimers(new FrameEventArgs(.30f));
            Assert.That(fired, Is.True);
        }
예제 #11
0
        private void PowerOn()
        {
            if (_isPowered)
            {
                return;
            }

            _isPowered = true;

            _fireShotCounter = 0;
            _timerCancel     = new CancellationTokenSource();

            Timer.Spawn(_fireBurstDelayMax, ShotTimerCallback, _timerCancel.Token);

            UpdateAppearance();
        }
예제 #12
0
        private void _checkForWinner()
        {
            _checkTimerCancel = null;

            if (!_cfg.GetCVar <bool>("game.enablewin"))
            {
                return;
            }

            IPlayerSession winner = null;

            foreach (var playerSession in _playerManager.GetAllPlayers())
            {
                if (playerSession.AttachedEntity == null ||
                    !playerSession.AttachedEntity.TryGetComponent(out IDamageableComponent damageable))
                {
                    continue;
                }

                if (damageable.CurrentDamageState != DamageState.Alive)
                {
                    continue;
                }

                if (winner != null)
                {
                    // Found a second person alive, nothing decided yet!
                    return;
                }

                winner = playerSession;
            }

            if (winner == null)
            {
                _chatManager.DispatchServerAnnouncement("Everybody is dead, it's a stalemate!");
            }
            else
            {
                // We have a winner!
                _chatManager.DispatchServerAnnouncement($"{winner} wins the death match!");
            }

            _chatManager.DispatchServerAnnouncement($"Restarting in 10 seconds.");

            Timer.Spawn(TimeSpan.FromSeconds(10), () => _gameTicker.RestartRound());
        }
        bool IInteractHand.InteractHand(InteractHandEventArgs eventArgs)
        {
            if (!_canHelp || !KnockedDown)
            {
                return(false);
            }

            _canHelp = false;
            Timer.Spawn((int)_helpInterval * 1000, () => _canHelp = true);

            KnockdownTimer -= _helpKnockdownRemove;

            SetStatusEffect();
            Dirty();

            return(true);
        }
예제 #14
0
        public bool InteractHand(InteractHandEventArgs eventArgs)
        {
            if (!_canHelp || !KnockedDown)
            {
                return(false);
            }

            _canHelp = false;
            Timer.Spawn(((int)_helpInterval * 1000), () => _canHelp = true);

            EntitySystem.Get <AudioSystem>()
            .PlayFromEntity("/Audio/effects/thudswoosh.ogg", Owner, AudioHelpers.WithVariation(0.25f));

            _knockdownTimer -= _helpKnockdownRemove;

            return(true);
        }
예제 #15
0
        private void _checkForWinner()
        {
            _checkTimerCancel = null;

            if (!_cfg.GetCVar(CCVars.GameLobbyEnableWin))
            {
                return;
            }

            IPlayerSession winner = null;

            foreach (var playerSession in _playerManager.GetAllPlayers())
            {
                var playerEntity = playerSession.AttachedEntity;
                if (playerEntity == null ||
                    !playerEntity.TryGetComponent(out IMobStateComponent state))
                {
                    continue;
                }

                if (!state.IsAlive())
                {
                    continue;
                }

                if (winner != null)
                {
                    // Found a second person alive, nothing decided yet!
                    return;
                }

                winner = playerSession;
            }

            _chatManager.DispatchServerAnnouncement(winner == null
                ? Loc.GetString("Everybody is dead, it's a stalemate!")
                : Loc.GetString("{0} wins the death match!", winner));

            var restartDelay = 10;

            _chatManager.DispatchServerAnnouncement(Loc.GetString("Restarting in {0} seconds.", restartDelay));

            Timer.Spawn(TimeSpan.FromSeconds(restartDelay), () => _gameTicker.RestartRound());
        }
        private void EnableOverlay(double duration)
        {
            // If the timer gets reset
            if (_overlay != null)
            {
                _overlay.Duration  = _duration;
                _overlay.StartTime = _startTime;
                _cancelToken.Cancel();
            }
            else
            {
                var overlayManager = IoCManager.Resolve <IOverlayManager>();
                _overlay = new FlashOverlay(_duration);
                overlayManager.AddOverlay(_overlay);
            }

            _cancelToken = new CancellationTokenSource();
            Timer.Spawn((int)duration * 1000, DisableOverlay, _cancelToken.Token);
        }
예제 #17
0
        public void TestCancellation()
        {
            var timerManager = IoCManager.Resolve <ITimerManager>();
            var taskManager  = IoCManager.Resolve <ITaskManager>();

            var cts = new CancellationTokenSource();
            var ran = false;

            Timer.Spawn(1000, () => ran = true, cts.Token);

            timerManager.UpdateTimers(new FrameEventArgs(.5f));

            Assert.That(ran, Is.False);

            cts.Cancel();

            timerManager.UpdateTimers(new FrameEventArgs(.6f));

            Assert.That(ran, Is.False);
        }
예제 #18
0
        private void EndRound(Victory victory)
        {
            string text;

            switch (victory)
            {
            case Victory.Innocents:
                text = "The innocents have won!";
                break;

            case Victory.Traitors:
                text = "The traitors have won!";
                break;

            default:
                text = "Nobody wins!";
                break;
            }

            _gameTicker.EndRound(text);
            _chatManager.DispatchServerAnnouncement($"Restarting in 10 seconds.");
            _checkTimerCancel.Cancel();
            Timer.Spawn(TimeSpan.FromSeconds(10), () => _gameTicker.RestartRound());
        }
예제 #19
0
        /// <summary>
        /// Will try and get around obstacles if stuck
        /// </summary>
        protected void AntiStuck(float frameTime)
        {
            // TODO: More work because these are sketchy af
            // TODO: Check if a wall was spawned in front of us and then immediately dump route if it was

            // First check if we're still in a stuck state from last frame
            if (IsStuck && !_tryingAntiStuck)
            {
                switch (_antiStuckMethod)
                {
                case AntiStuckMethod.None:
                    break;

                case AntiStuckMethod.Jiggle:
                    var randomRange = IoCManager.Resolve <IRobustRandom>().Next(0, 359);
                    var angle       = Angle.FromDegrees(randomRange);
                    Owner.TryGetComponent(out AiControllerComponent mover);
                    mover.VelocityDir = angle.ToVec().Normalized;

                    break;

                case AntiStuckMethod.PhaseThrough:
                    if (Owner.TryGetComponent(out CollidableComponent collidableComponent))
                    {
                        // TODO Fix this because they are yeeting themselves when they charge
                        // TODO: If something updates this this will f**k it
                        collidableComponent.CanCollide = false;

                        Timer.Spawn(100, () =>
                        {
                            if (!collidableComponent.CanCollide)
                            {
                                collidableComponent.CanCollide = true;
                            }
                        });
                    }
                    break;

                case AntiStuckMethod.Teleport:
                    Owner.Transform.DetachParent();
                    Owner.Transform.GridPosition = NextGrid;
                    break;

                case AntiStuckMethod.ReRoute:
                    GetRoute();
                    break;

                case AntiStuckMethod.Angle:
                    var random = IoCManager.Resolve <IRobustRandom>();
                    _addedAngle = new Angle(random.Next(-60, 60));
                    IsStuck     = false;
                    Timer.Spawn(100, () =>
                    {
                        _addedAngle = Angle.Zero;
                    });
                    break;

                default:
                    throw new InvalidOperationException();
                }
            }

            _stuckTimerRemaining -= frameTime;

            // Stuck check cooldown
            if (_stuckTimerRemaining > 0.0f)
            {
                return;
            }

            _tryingAntiStuck     = false;
            _stuckTimerRemaining = 0.5f;

            // Are we actually stuck
            if ((_ourLastPosition.Position - Owner.Transform.GridPosition.Position).Length < TileTolerance)
            {
                _antiStuckAttempts++;

                // Maybe it's just 1 tile that's borked so try next 1?
                if (_antiStuckAttempts >= 2 && _antiStuckAttempts < 5 && Route.Count > 1)
                {
                    var nextTile = Route.Dequeue();
                    NextGrid = _mapManager.GetGrid(nextTile.GridIndex).GridTileToLocal(nextTile.GridIndices);
                    return;
                }

                if (_antiStuckAttempts >= 5 || Route.Count == 0)
                {
                    Logger.DebugS("ai", $"{Owner} is stuck at {Owner.Transform.GridPosition}, trying new route");
                    _antiStuckAttempts = 0;
                    IsStuck            = false;
                    _ourLastPosition   = Owner.Transform.GridPosition;
                    GetRoute();
                    return;
                }
                Stuck?.Invoke();
                IsStuck = true;
                return;
            }

            IsStuck = false;

            _ourLastPosition = Owner.Transform.GridPosition;
        }