0x004A97A6
| 156 | |
| 157 | // 0x004A97A6 |
| 158 | bool Vehicle1::updateRail() |
| 159 | { |
| 160 | Vehicle train{ head }; |
| 161 | uint16_t curveSpeedFraction = std::numeric_limits<uint16_t>::max(); |
| 162 | Speed16 newTargetSpeed = kSpeed16Max; |
| 163 | bool isOnRackRail = false; |
| 164 | if (!train.head->hasVehicleFlags(VehicleFlags::manualControl)) |
| 165 | { |
| 166 | RoutingManager::RingView ring(routingHandle); |
| 167 | for (auto iter = ring.rbegin(); iter != ring.rend(); ++iter) |
| 168 | { |
| 169 | auto res = RoutingManager::getRouting(*iter); |
| 170 | isOnRackRail |= (res & (1U << 13)) != 0; // rackrail |
| 171 | uint8_t trackId = (res >> 3) & 0x3F; |
| 172 | curveSpeedFraction = std::min(curveSpeedFraction, World::TrackData::getTrackMiscData(trackId).curveSpeedFraction); |
| 173 | if (res & (1U << 12)) |
| 174 | { |
| 175 | const auto* bridgeObj = ObjectManager::get<BridgeObject>((res & 0xE00) >> 9); |
| 176 | if (bridgeObj->maxSpeed != kSpeed16Null) |
| 177 | { |
| 178 | newTargetSpeed = std::min(bridgeObj->maxSpeed, newTargetSpeed); |
| 179 | } |
| 180 | } |
| 181 | } |
| 182 | } |
| 183 | |
| 184 | const auto* trackObj = ObjectManager::get<TrackObject>(trackType); |
| 185 | const Speed32 fractionalSpeed = Speed32(static_cast<uint32_t>(curveSpeedFraction) * trackObj->curveSpeed.getRaw()); |
| 186 | newTargetSpeed = std::min(toSpeed16(fractionalSpeed + 1.0_mph), newTargetSpeed); |
| 187 | |
| 188 | if (train.head->has38Flags(Flags38::fasterAroundCurves)) |
| 189 | { |
| 190 | newTargetSpeed += newTargetSpeed / 4; |
| 191 | newTargetSpeed = std::min(trackObj->curveSpeed, newTargetSpeed); |
| 192 | } |
| 193 | |
| 194 | const auto veh2MaxSpeed = [veh2 = train.veh2]() { |
| 195 | if (veh2->has73Flags(Flags73::isBrokenDown)) |
| 196 | { |
| 197 | return veh2->maxSpeed / 4; |
| 198 | } |
| 199 | return veh2->maxSpeed; |
| 200 | }(); |
| 201 | |
| 202 | newTargetSpeed = std::min(newTargetSpeed, veh2MaxSpeed); |
| 203 | if (isOnRackRail) |
| 204 | { |
| 205 | newTargetSpeed = std::min(newTargetSpeed, train.veh2->rackRailMaxSpeed); |
| 206 | } |
| 207 | |
| 208 | if (!train.head->hasVehicleFlags(VehicleFlags::manualControl)) |
| 209 | { |
| 210 | // TODO: Original CS Bug. Fix when we diverge on replays |
| 211 | // newTargetSpeed = std::min(newTargetSpeed, toSpeed16(speedFromDistanceInATick(var_3C)) + 5_mph); |
| 212 | newTargetSpeed = std::min(newTargetSpeed, Speed16(static_cast<uint32_t>(var_3C) >> 15) + 5_mph); |
| 213 | } |
| 214 | |
| 215 | if ((train.head->hasVehicleFlags(VehicleFlags::manualControl) && train.head->manualPower <= -20) |
nothing calls this directly
no test coverage detected