Beispiel #1
0
        private async Task UpdateVehicleAction(QueuedVehicleAction queuedVehicleAction)
        {
            if (queuedVehicleAction.Handled)
            {
                // this queuedVehicleAction has already been handled
                return;
            }
            // This function must be re-entrant as it's running as a timer interval handler
            await _VehiclePositionsLock.WaitAsync();

            try
            {
                if (!_updatingVehiclePositions)
                {
                    _updatingVehiclePositions = true;

                    foreach (var vehicle in this._gameScenario.Vehicles
                             .Where(v => v.Key == queuedVehicleAction.Name)
                             .Select(x => x.Value))
                    {
                        if (TryUpdateVehicleAction(vehicle, queuedVehicleAction))
                        {
                            if (this._constants.allowSubjectNextInsideGameLoop)
                            {
                                _subject.OnNext(vehicle.ToModel());
                            }
                            if (queuedVehicleAction.VehicleAction == VehicleAction.TurnLeft || queuedVehicleAction.VehicleAction == VehicleAction.TurnRight)
                            {
                                await CheckVehicleForUnsafeVehiclesToSave(vehicle);
                            }
                        }
                    }
                    // very important!! don't forget to mark this as handled
                    queuedVehicleAction.Handled = true;
                    _updatingVehiclePositions   = false;
                }
            }
            finally
            {
                _VehiclePositionsLock.Release();
            }
        }
Beispiel #2
0
        private bool TryUpdateVehicleAction(Vehicle host, QueuedVehicleAction action)
        {
            if (host.DrivingStatus == DrivingStatus.Crashed.ToString())
            {
                return(false);
            }
            switch (action.VehicleAction)
            {
            case VehicleAction.IncreaseSpeed_CruiseInitiated:
                if (!host.IsGoingDesiredMph)
                {
                    // accelerating to desired speed
                    host.AddMph(_constants.VEHICLE_MPH_ACCELERATION_INCREMENT_RATE, isHumanInitiating: false);
                    if (host.DrivingStatus != DrivingStatus.Resuming.ToString())
                    {
                        host.Status        = $"resuming to {host.AdaptiveCruiseDesiredMph} mph";
                        host.DrivingStatus = DrivingStatus.Resuming.ToString();
                        if (this._constants.allowSubjectNextInsideGameLoop)
                        {
                            _subject.OnNext(host.ToModel());
                        }
                    }
                    this._gameScenario.Vehicles[host.Name] = host;
                }
                break;

            case VehicleAction.IncreaseSpeed_UserInitiated:
                if (TryIncreaseVehicleMph(host, this._constants.VEHICLE_MPH_ACCELERATION_INCREMENT_RATE))
                {
                    host.DrivingStatus = DrivingStatus.Accelerating.ToString();
                    if (host.AdaptiveCruiseOn)
                    {
                        // keep in AdaptiveCruiseMph insync w/ human accelerating
                        host.AdaptiveCruiseDesiredMph = host.Mph;
                    }
                }
                break;

            case VehicleAction.DecreaseSpeed_CruiseInitiated:
                if (host.AdaptiveCruiseDesiredMph == 0)
                {
                    // store original speed (so we can return to it when the slow car moves)
                    host.AdaptiveCruiseDesiredMph = host.Mph;
                }
                host.SubtractMph(this._constants.VEHICLE_GRADUAL_MPH_BRAKE_RATE);
                if (host.Mph == 0)
                {
                    if (host.DrivingStatus != DrivingStatus.Stopped.ToString())
                    {
                        host.Status        = $"stopped for {action.leadVehicleName}";
                        host.DrivingStatus = DrivingStatus.Stopped.ToString();
                        if (this._constants.allowSubjectNextInsideGameLoop)
                        {
                            _subject.OnNext(host.ToModel());
                        }
                    }
                    this._gameScenario.Vehicles[host.Name] = host;
                }
                else
                {
                    if (host.DrivingStatus != DrivingStatus.AutoBraking.ToString())
                    {
                        host.Status        = $"autobraking for {action.leadVehicleName}";
                        host.DrivingStatus = DrivingStatus.AutoBraking.ToString();
                        if (this._constants.allowSubjectNextInsideGameLoop)
                        {
                            _subject.OnNext(host.ToModel());
                        }
                    }
                    this._gameScenario.Vehicles[host.Name] = host;
                }
                break;

            case VehicleAction.DecreaseSpeed_UserInitiated:
                if (TryDecreaseVehicleMph(host, this._constants.VEHICLE_GRADUAL_MPH_BRAKE_RATE))
                {
                    if (host.Mph == 0)
                    {
                        if (host.DrivingStatus != DrivingStatus.Stopped.ToString())
                        {
                            TryUpdateVehicleDrivingStatus(host, DrivingStatus.Stopped);
                            host.DrivingStatus = DrivingStatus.Stopped.ToString();
                            host.Status        = $"stopped by {action.leadVehicleName}";
                            if (this._constants.allowSubjectNextInsideGameLoop)
                            {
                                _subject.OnNext(host.ToModel());
                            }
                        }
                        this._gameScenario.Vehicles[host.Name] = host;
                    }
                    else
                    {
                        TryUpdateVehicleDrivingStatus(host, DrivingStatus.Braking);
                    }

                    if (host.AdaptiveCruiseOn)
                    {
                        // keep in AdaptiveCruiseMph insync w/ human deaccelaration
                        host.AdaptiveCruiseDesiredMph = host.Mph;
                    }
                }
                break;

            case VehicleAction.TurnLeft:
                if (host.Mph > 0 && host.Y >= 3)
                {
                    host.Y -= 1;
                    TryUpdateVehicleDrivingStatus(host, DrivingStatus.TurningLeft);
                    CheckVehicleForUnsafeVehiclesToSave(host);
                }
                break;

            case VehicleAction.TurnRight:
                if (host.Mph > 0 && host.Y < 8)
                {
                    host.Y += 1;
                    TryUpdateVehicleDrivingStatus(host, DrivingStatus.TurningRight);
                    CheckVehicleForUnsafeVehiclesToSave(host);
                }
                break;

            case VehicleAction.ToggleAdaptiveCruise:
                host.AdaptiveCruiseOn = !host.AdaptiveCruiseOn;
                if (host.Mph == 0)
                {
                    host.AdaptiveCruiseDesiredMph = 0;
                }
                else if (host.AdaptiveCruiseOn && host.Mph > 0)
                {
                    TryUpdateVehicleDrivingStatus(host, DrivingStatus.Cruising);
                    // keep AdaptiveCruiseMph insync w/ human initiated events, like enabled AC
                    host.AdaptiveCruiseDesiredMph = host.Mph;
                }
                else if (!host.AdaptiveCruiseOn && host.Mph > 0)
                {
                    TryUpdateVehicleDrivingStatus(host, DrivingStatus.Driving);
                    host.AdaptiveCruiseDesiredMph = 0;
                }
                break;
            }
            return(true);
        }