0x004A9969
| 52 | |
| 53 | // 0x004A9969 |
| 54 | bool Vehicle1::updateRoad() |
| 55 | { |
| 56 | uint16_t curveSpeedFraction = std::numeric_limits<uint16_t>::max(); |
| 57 | Speed16 newTargetSpeed = kSpeed16Max; |
| 58 | RoutingManager::RingView ring(routingHandle); |
| 59 | bool isOnRackRail = false; |
| 60 | for (auto iter = ring.rbegin(); iter != ring.rend(); ++iter) |
| 61 | { |
| 62 | auto res = RoutingManager::getRouting(*iter); |
| 63 | isOnRackRail |= (res & (1 << 13)) != 0; // rackrail |
| 64 | uint8_t roadId = (res >> 3) & 0xF; |
| 65 | curveSpeedFraction = std::min(curveSpeedFraction, World::TrackData::getRoadMiscData(roadId).curveSpeedFraction); |
| 66 | if (res & (1 << 12)) |
| 67 | { |
| 68 | const auto* bridgeObj = ObjectManager::get<BridgeObject>((res & 0xE00) >> 9); |
| 69 | if (bridgeObj->maxSpeed != kSpeed16Null) |
| 70 | { |
| 71 | newTargetSpeed = std::min(bridgeObj->maxSpeed, newTargetSpeed); |
| 72 | } |
| 73 | } |
| 74 | } |
| 75 | |
| 76 | Vehicle train(head); |
| 77 | if (train.veh2->var_4F != -1) |
| 78 | { |
| 79 | const auto* roadObj = ObjectManager::get<RoadObject>(train.veh2->var_4F); |
| 80 | const Speed32 fractionalSpeed = Speed32(static_cast<uint32_t>(curveSpeedFraction) * roadObj->maxSpeed.getRaw()); |
| 81 | newTargetSpeed = std::min(toSpeed16(fractionalSpeed + 1.0_mph), newTargetSpeed); |
| 82 | newTargetSpeed = std::max(newTargetSpeed, 12_mph); |
| 83 | |
| 84 | if (train.head->has38Flags(Flags38::fasterAroundCurves)) |
| 85 | { |
| 86 | newTargetSpeed += newTargetSpeed / 4; |
| 87 | newTargetSpeed = std::min(roadObj->maxSpeed, newTargetSpeed); |
| 88 | } |
| 89 | } |
| 90 | else |
| 91 | { |
| 92 | const Speed32 fractionalSpeed = Speed32(static_cast<uint32_t>(curveSpeedFraction) * (60_mph).getRaw()); |
| 93 | newTargetSpeed = toSpeed16(fractionalSpeed); |
| 94 | } |
| 95 | |
| 96 | newTargetSpeed = std::min(newTargetSpeed, train.veh2->maxSpeed); |
| 97 | if (isOnRackRail) |
| 98 | { |
| 99 | newTargetSpeed = std::min(newTargetSpeed, train.veh2->rackRailMaxSpeed); |
| 100 | } |
| 101 | |
| 102 | // TODO: Original CS Bug. Fix when we diverge on replays |
| 103 | // newTargetSpeed = std::min(newTargetSpeed, toSpeed16(speedFromDistanceInATick(var_3C)) + 5_mph); |
| 104 | newTargetSpeed = std::min(newTargetSpeed, Speed16(static_cast<uint32_t>(var_3C) >> 15) + 5_mph); |
| 105 | |
| 106 | if ((train.head->hasVehicleFlags(VehicleFlags::manualControl) && train.head->manualPower <= -20) |
| 107 | || train.head->hasVehicleFlags(VehicleFlags::commandStop)) |
| 108 | { |
| 109 | if (train.veh2->currentSpeed == 0.0_mph) |
| 110 | { |
| 111 | newTargetSpeed = 0_mph; |
nothing calls this directly
no test coverage detected