Files
@ r15145:7bf3f132181e
Branch filter:
Location: cpp/openttd-patchpack/source/src/train.h - annotation
r15145:7bf3f132181e
15.0 KiB
text/x-c
(svn r19784) -Fix [FS#3770]: if a waypoint is immediately followed by a path signal a reservation would be made from that path signal before the waypoint is marked passed. As a result the order to go to the waypoint is used to reserve the path after the waypoint and as such trains get lost
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 | r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r12768:980ae0491352 r12768:980ae0491352 r12768:980ae0491352 r12768:980ae0491352 r12768:980ae0491352 r12768:980ae0491352 r12768:980ae0491352 r9111:983de9c5a848 r6422:5983361e241a r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14739:f991a219ff8a r5475:3f5cd13d1b63 r11980:193f7a6b6e37 r5475:3f5cd13d1b63 r11981:3840cc07cbe4 r11981:3840cc07cbe4 r11981:3840cc07cbe4 r11981:3840cc07cbe4 r11981:3840cc07cbe4 r11981:3840cc07cbe4 r11981:3840cc07cbe4 r11981:3840cc07cbe4 r11981:3840cc07cbe4 r11981:3840cc07cbe4 r11981:3840cc07cbe4 r11981:3840cc07cbe4 r11981:3840cc07cbe4 r11981:3840cc07cbe4 r11981:3840cc07cbe4 r11981:3840cc07cbe4 r11981:3840cc07cbe4 r11981:3840cc07cbe4 r11981:3840cc07cbe4 r11981:3840cc07cbe4 r11981:3840cc07cbe4 r11981:3840cc07cbe4 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r9704:108fa337b182 r7490:4e86e893fa7f r11980:193f7a6b6e37 r11980:193f7a6b6e37 r9810:a537c0857d3f r11980:193f7a6b6e37 r11980:193f7a6b6e37 r11982:ff4390b32b95 r14740:9c3af6ca7b4c r11982:ff4390b32b95 r11982:ff4390b32b95 r11982:ff4390b32b95 r11982:ff4390b32b95 r11982:ff4390b32b95 r11982:ff4390b32b95 r14393:2a8179560351 r14393:2a8179560351 r14393:2a8179560351 r11982:ff4390b32b95 r12080:8115dddfc1a2 r12080:8115dddfc1a2 r12080:8115dddfc1a2 r12080:8115dddfc1a2 r11982:ff4390b32b95 r11982:ff4390b32b95 r11982:ff4390b32b95 r11982:ff4390b32b95 r11982:ff4390b32b95 r11982:ff4390b32b95 r11982:ff4390b32b95 r11982:ff4390b32b95 r11982:ff4390b32b95 r11982:ff4390b32b95 r13171:0e07c3ba2aa9 r11982:ff4390b32b95 r11982:ff4390b32b95 r6552:7cade7798fcb r12033:6a560c929ec8 r6552:7cade7798fcb r14739:f991a219ff8a r11982:ff4390b32b95 r11982:ff4390b32b95 r11981:3840cc07cbe4 r11981:3840cc07cbe4 r11981:3840cc07cbe4 r11981:3840cc07cbe4 r11981:3840cc07cbe4 r11981:3840cc07cbe4 r11981:3840cc07cbe4 r11981:3840cc07cbe4 r11981:3840cc07cbe4 r11981:3840cc07cbe4 r11981:3840cc07cbe4 r14203:aea88883737e r14203:aea88883737e r14203:aea88883737e r12090:c20f83257241 r14739:f991a219ff8a r6552:7cade7798fcb r7412:e5f07529a093 r6552:7cade7798fcb r14741:668486b3d9e3 r14741:668486b3d9e3 r6563:67c636a8e3d4 r6553:04028e73a0f7 r6558:469828caa298 r6563:67c636a8e3d4 r6593:469af92ae569 r12290:442d5d533a57 r9022:5be8b7703ae9 r11982:ff4390b32b95 r11982:ff4390b32b95 r7488:e5f4cea230c4 r12423:199e8b46a11b r13938:79b6be1ab675 r13938:79b6be1ab675 r11965:2b94ac4aa35a r8467:0ea88f22d4aa r13863:252b1a5c4f87 r11971:ac7eb21a00e4 r8827:6ee5217ef94b r8890:02179c54681e r12290:442d5d533a57 r12413:18cb483f6737 r12296:564aa4953d26 r14251:3ca1b5f41119 r14251:3ca1b5f41119 r14251:3ca1b5f41119 r14251:3ca1b5f41119 r14274:562f45526a0b r14274:562f45526a0b r14251:3ca1b5f41119 r14251:3ca1b5f41119 r14276:fe74de3c3311 r14276:fe74de3c3311 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12290:442d5d533a57 r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12293:15e6328523ce r12291:690f4158878e r12291:690f4158878e r12290:442d5d533a57 r12290:442d5d533a57 r12291:690f4158878e r12291:690f4158878e r12291:690f4158878e r12291:690f4158878e r12291:690f4158878e r12291:690f4158878e r12292:c3b6baef441a r12292:c3b6baef441a r12292:c3b6baef441a r12292:c3b6baef441a r12292:c3b6baef441a r12292:c3b6baef441a r12292:c3b6baef441a r12292:c3b6baef441a r12292:c3b6baef441a r12292:c3b6baef441a r12292:c3b6baef441a r12292:c3b6baef441a r12292:c3b6baef441a r12292:c3b6baef441a r12292:c3b6baef441a r12292:c3b6baef441a r12292:c3b6baef441a r12292:c3b6baef441a r12292:c3b6baef441a r12292:c3b6baef441a r12292:c3b6baef441a r12292:c3b6baef441a r12292:c3b6baef441a r12292:c3b6baef441a r12292:c3b6baef441a r12292:c3b6baef441a r12292:c3b6baef441a r12292:c3b6baef441a r12292:c3b6baef441a r12292:c3b6baef441a r12292:c3b6baef441a r12292:c3b6baef441a r12292:c3b6baef441a r12292:c3b6baef441a r12292:c3b6baef441a r12295:bb9023f54628 r12292:c3b6baef441a r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12440:97b7db79722d r12440:97b7db79722d r12440:97b7db79722d r12440:97b7db79722d r12440:97b7db79722d r12440:97b7db79722d r12440:97b7db79722d r12440:97b7db79722d r12440:97b7db79722d r12440:97b7db79722d r12440:97b7db79722d r12440:97b7db79722d r12440:97b7db79722d r12440:97b7db79722d r12440:97b7db79722d r12440:97b7db79722d r12440:97b7db79722d r12440:97b7db79722d r12440:97b7db79722d r12440:97b7db79722d r12440:97b7db79722d r12440:97b7db79722d r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r12296:564aa4953d26 r14276:fe74de3c3311 r14276:fe74de3c3311 r14509:7fa74c77b7ed r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14292:0a897b68b658 r14276:fe74de3c3311 r14292:0a897b68b658 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14276:fe74de3c3311 r14372:c020b32eb5e4 r14372:c020b32eb5e4 r14372:c020b32eb5e4 r14372:c020b32eb5e4 r14372:c020b32eb5e4 r14372:c020b32eb5e4 r14372:c020b32eb5e4 r14372:c020b32eb5e4 r14372:c020b32eb5e4 r14738:57a777833535 r14738:57a777833535 r14738:57a777833535 r14738:57a777833535 r14738:57a777833535 r14738:57a777833535 r14738:57a777833535 r14738:57a777833535 r14738:57a777833535 r14738:57a777833535 r14738:57a777833535 r14738:57a777833535 r14738:57a777833535 r14738:57a777833535 r14738:57a777833535 r14738:57a777833535 r14738:57a777833535 r14738:57a777833535 r14744:20a253ef5af6 r14744:20a253ef5af6 r14744:20a253ef5af6 r14744:20a253ef5af6 r14744:20a253ef5af6 r14744:20a253ef5af6 r14744:20a253ef5af6 r14744:20a253ef5af6 r14744:20a253ef5af6 r14744:20a253ef5af6 r6552:7cade7798fcb r6552:7cade7798fcb r12029:5b077ec055c0 r12029:5b077ec055c0 r5475:3f5cd13d1b63 | /* $Id$ */
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file train.h Base for the train class. */
#ifndef TRAIN_H
#define TRAIN_H
#include "newgrf_engine.h"
#include "cargotype.h"
#include "rail.h"
#include "engine_base.h"
#include "rail_map.h"
#include "ground_vehicle.hpp"
struct Train;
enum VehicleRailFlags {
VRF_REVERSING = 0,
/* used to store if a wagon is powered or not */
VRF_POWEREDWAGON = 3,
/* used to reverse the visible direction of the vehicle */
VRF_REVERSE_DIRECTION = 4,
/* used to mark train as lost because PF can't find the route */
VRF_NO_PATH_TO_DESTINATION = 5,
/* used to mark that electric train engine is allowed to run on normal rail */
VRF_EL_ENGINE_ALLOWED_NORMAL_RAIL = 6,
/* used for vehicle var 0xFE bit 8 (toggled each time the train is reversed, accurate for first vehicle only) */
VRF_TOGGLE_REVERSE = 7,
/* used to mark a train that can't get a path reservation */
VRF_TRAIN_STUCK = 8,
};
byte FreightWagonMult(CargoID cargo);
void CheckTrainsLengths();
void FreeTrainTrackReservation(const Train *v, TileIndex origin = INVALID_TILE, Trackdir orig_td = INVALID_TRACKDIR);
bool TryPathReserve(Train *v, bool mark_as_stuck = false, bool first_tile_okay = false);
int GetTrainStopLocation(StationID station_id, TileIndex tile, const Train *v, int *station_ahead, int *station_length);
/** Variables that are cached to improve performance and such */
struct TrainCache {
/* Cached wagon override spritegroup */
const struct SpriteGroup *cached_override;
uint16 last_speed; // NOSAVE: only used in UI
/* cached values, recalculated on load and each time a vehicle is added to/removed from the consist. */
uint16 cached_total_length; ///< Length of the whole train, valid only for first engine.
uint8 cached_veh_length; ///< length of this vehicle in units of 1/8 of normal length, cached because this can be set by a callback
bool cached_tilt; ///< train can tilt; feature provides a bonus in curves
/* cached max. speed / acceleration data */
uint16 cached_max_speed; ///< max speed of the consist. (minimum of the max speed of all vehicles in the consist)
int cached_max_curve_speed; ///< max consist speed limited by curves
/**
* Position/type of visual effect.
* bit 0 - 3 = position of effect relative to vehicle. (0 = front, 8 = centre, 15 = rear)
* bit 4 - 5 = type of effect. (0 = default for engine class, 1 = steam, 2 = diesel, 3 = electric)
* bit 6 = disable visual effect.
* bit 7 = disable powered wagons.
*/
byte cached_vis_effect;
byte user_def_data;
EngineID first_engine; ///< cached EngineID of the front vehicle. INVALID_ENGINE for the front vehicle itself.
};
/**
* 'Train' is either a loco or a wagon.
*/
struct Train : public GroundVehicle<Train, VEH_TRAIN> {
TrainCache tcache;
/* Link between the two ends of a multiheaded engine */
Train *other_multiheaded_part;
uint16 crash_anim_pos;
uint16 flags;
TrackBitsByte track;
byte force_proceed;
RailTypeByte railtype;
RailTypes compatible_railtypes;
/** Ticks waiting in front of a signal, ticks being stuck or a counter for forced proceeding through signals. */
uint16 wait_counter;
/** We don't want GCC to zero our struct! It already is zeroed and has an index! */
Train() : GroundVehicle<Train, VEH_TRAIN>() {}
/** We want to 'destruct' the right class. */
virtual ~Train() { this->PreDestructor(); }
friend struct GroundVehicle<Train, VEH_TRAIN>; // GroundVehicle needs to use the acceleration functions defined at Train.
const char *GetTypeString() const { return "train"; }
void MarkDirty();
void UpdateDeltaXY(Direction direction);
ExpensesType GetExpenseType(bool income) const { return income ? EXPENSES_TRAIN_INC : EXPENSES_TRAIN_RUN; }
void PlayLeaveStationSound() const;
bool IsPrimaryVehicle() const { return this->IsFrontEngine(); }
SpriteID GetImage(Direction direction) const;
int GetDisplaySpeed() const { return this->tcache.last_speed; }
int GetDisplayMaxSpeed() const { return this->tcache.cached_max_speed; }
Money GetRunningCost() const;
int GetDisplayImageWidth(Point *offset = NULL) const;
bool IsInDepot() const;
bool IsStoppedInDepot() const;
bool Tick();
void OnNewDay();
uint Crash(bool flooded = false);
Trackdir GetVehicleTrackdir() const;
TileIndex GetOrderStationLocation(StationID station);
bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse);
void ReserveTrackUnderConsist() const;
int GetCurveSpeedLimit() const;
void ConsistChanged(bool same_length);
int UpdateSpeed();
void UpdateAcceleration();
int GetCurrentMaxSpeed() const;
/**
* enum to handle train subtypes
* Do not access it directly unless you have to. Use the access functions below
* This is an enum to tell what bit to access as it is a bitmask
*/
enum TrainSubtype {
TS_FRONT = 0, ///< Leading engine of a train
TS_ARTICULATED_PART = 1, ///< Articulated part of an engine
TS_WAGON = 2, ///< Wagon
TS_ENGINE = 3, ///< Engine, that can be front engine, but might be placed behind another engine
TS_FREE_WAGON = 4, ///< First in a wagon chain (in depot)
TS_MULTIHEADED = 5, ///< Engine is multiheaded
};
/**
* Set front engine state
*/
FORCEINLINE void SetFrontEngine() { SetBit(this->subtype, TS_FRONT); }
/**
* Remove the front engine state
*/
FORCEINLINE void ClearFrontEngine() { ClrBit(this->subtype, TS_FRONT); }
/**
* Set a vehicle to be an articulated part
*/
FORCEINLINE void SetArticulatedPart() { SetBit(this->subtype, TS_ARTICULATED_PART); }
/**
* Clear a vehicle from being an articulated part
*/
FORCEINLINE void ClearArticulatedPart() { ClrBit(this->subtype, TS_ARTICULATED_PART); }
/**
* Set a vehicle to be a wagon
*/
FORCEINLINE void SetWagon() { SetBit(this->subtype, TS_WAGON); }
/**
* Clear wagon property
*/
FORCEINLINE void ClearWagon() { ClrBit(this->subtype, TS_WAGON); }
/**
* Set engine status
*/
FORCEINLINE void SetEngine() { SetBit(this->subtype, TS_ENGINE); }
/**
* Clear engine status
*/
FORCEINLINE void ClearEngine() { ClrBit(this->subtype, TS_ENGINE); }
/**
* Set if a vehicle is a free wagon
*/
FORCEINLINE void SetFreeWagon() { SetBit(this->subtype, TS_FREE_WAGON); }
/**
* Clear a vehicle from being a free wagon
*/
FORCEINLINE void ClearFreeWagon() { ClrBit(this->subtype, TS_FREE_WAGON); }
/**
* Set if a vehicle is a multiheaded engine
*/
FORCEINLINE void SetMultiheaded() { SetBit(this->subtype, TS_MULTIHEADED); }
/**
* Clear multiheaded engine property
*/
FORCEINLINE void ClearMultiheaded() { ClrBit(this->subtype, TS_MULTIHEADED); }
/**
* Check if train is a front engine
* @return Returns true if train is a front engine
*/
FORCEINLINE bool IsFrontEngine() const { return HasBit(this->subtype, TS_FRONT); }
/**
* Check if train is a free wagon (got no engine in front of it)
* @return Returns true if train is a free wagon
*/
FORCEINLINE bool IsFreeWagon() const { return HasBit(this->subtype, TS_FREE_WAGON); }
/**
* Check if a vehicle is an engine (can be first in a train)
* @return Returns true if vehicle is an engine
*/
FORCEINLINE bool IsEngine() const { return HasBit(this->subtype, TS_ENGINE); }
/**
* Check if a train is a wagon
* @return Returns true if vehicle is a wagon
*/
FORCEINLINE bool IsWagon() const { return HasBit(this->subtype, TS_WAGON); }
/**
* Check if train is a multiheaded engine
* @return Returns true if vehicle is a multiheaded engine
*/
FORCEINLINE bool IsMultiheaded() const { return HasBit(this->subtype, TS_MULTIHEADED); }
/**
* Tell if we are dealing with the rear end of a multiheaded engine.
* @return True if the engine is the rear part of a dualheaded engine.
*/
FORCEINLINE bool IsRearDualheaded() const { return this->IsMultiheaded() && !this->IsEngine(); }
/**
* Check if train is an articulated part of an engine
* @return Returns true if train is an articulated part
*/
FORCEINLINE bool IsArticulatedPart() const { return HasBit(this->subtype, TS_ARTICULATED_PART); }
/**
* Check if an engine has an articulated part.
* @return True if the engine has an articulated part.
*/
FORCEINLINE bool HasArticulatedPart() const { return this->Next() != NULL && this->Next()->IsArticulatedPart(); }
/**
* Get the next part of a multi-part engine.
* Will only work on a multi-part engine (this->EngineHasArticPart() == true),
* Result is undefined for normal engine.
* @return next part of articulated engine
*/
FORCEINLINE Train *GetNextArticPart() const
{
assert(this->HasArticulatedPart());
return this->Next();
}
/**
* Get the first part of a multi-part engine.
* @return First part of the engine.
*/
FORCEINLINE Train *GetFirstEnginePart()
{
Train *v = this;
while (v->IsArticulatedPart()) v = v->Previous();
return v;
}
/**
* Get the first part of a multi-part engine.
* @return First part of the engine.
*/
FORCEINLINE const Train *GetFirstEnginePart() const
{
const Train *v = this;
while (v->IsArticulatedPart()) v = v->Previous();
return v;
}
/**
* Get the last part of a multi-part engine.
* @return Last part of the engine.
*/
FORCEINLINE Train *GetLastEnginePart()
{
Train *v = this;
while (v->HasArticulatedPart()) v = v->GetNextArticPart();
return v;
}
/**
* Get the next real (non-articulated part) vehicle in the consist.
* @return Next vehicle in the consist.
*/
FORCEINLINE Train *GetNextVehicle() const
{
const Train *v = this;
while (v->HasArticulatedPart()) v = v->GetNextArticPart();
/* v now contains the last artic part in the engine */
return v->Next();
}
/**
* Get the previous real (non-articulated part) vehicle in the consist.
* @return Previous vehicle in the consist.
*/
FORCEINLINE Train *GetPrevVehicle() const
{
Train *v = this->Previous();
while (v != NULL && v->IsArticulatedPart()) v = v->Previous();
return v;
}
/**
* Get the next real (non-articulated part and non rear part of dualheaded engine) vehicle in the consist.
* @return Next vehicle in the consist.
*/
FORCEINLINE Train *GetNextUnit() const
{
Train *v = this->GetNextVehicle();
if (v != NULL && v->IsRearDualheaded()) v = v->GetNextVehicle();
return v;
}
/**
* Get the previous real (non-articulated part and non rear part of dualheaded engine) vehicle in the consist.
* @return Previous vehicle in the consist.
*/
FORCEINLINE Train *GetPrevUnit()
{
Train *v = this->GetPrevVehicle();
if (v != NULL && v->IsRearDualheaded()) v = v->GetPrevVehicle();
return v;
}
protected: // These functions should not be called outside acceleration code.
/**
* Allows to know the power value that this vehicle will use.
* @return Power value from the engine in HP, or zero if the vehicle is not powered.
*/
FORCEINLINE uint16 GetPower() const
{
/* Power is not added for articulated parts */
if (!this->IsArticulatedPart() && HasPowerOnRail(this->railtype, GetRailType(this->tile))) {
uint16 power = GetVehicleProperty(this, PROP_TRAIN_POWER, RailVehInfo(this->engine_type)->power);
/* Halve power for multiheaded parts */
if (this->IsMultiheaded()) power /= 2;
return power;
}
return 0;
}
/**
* Returns a value if this articulated part is powered.
* @return Power value from the articulated part in HP, or zero if it is not powered.
*/
FORCEINLINE uint16 GetPoweredPartPower(const Train *head) const
{
if (HasBit(this->flags, VRF_POWEREDWAGON) && HasPowerOnRail(head->railtype, GetRailType(head->tile))) {
return RailVehInfo(this->tcache.first_engine)->pow_wag_power;
}
return 0;
}
/**
* Allows to know the weight value that this vehicle will use.
* @return Weight value from the engine in tonnes.
*/
FORCEINLINE uint16 GetWeight() const
{
uint16 weight = (CargoSpec::Get(this->cargo_type)->weight * this->cargo.Count() * FreightWagonMult(this->cargo_type)) / 16;
/* Vehicle weight is not added for articulated parts. */
if (!this->IsArticulatedPart()) {
weight += GetVehicleProperty(this, PROP_TRAIN_WEIGHT, RailVehInfo(this->engine_type)->weight);
}
/* Powered wagons have extra weight added. */
if (HasBit(this->flags, VRF_POWEREDWAGON)) {
weight += RailVehInfo(this->tcache.first_engine)->pow_wag_weight;
}
return weight;
}
/**
* Allows to know the tractive effort value that this vehicle will use.
* @return Tractive effort value from the engine.
*/
FORCEINLINE byte GetTractiveEffort() const
{
return GetVehicleProperty(this, PROP_TRAIN_TRACTIVE_EFFORT, RailVehInfo(this->engine_type)->tractive_effort);
}
/**
* Checks the current acceleration status of this vehicle.
* @return Acceleration status.
*/
FORCEINLINE AccelStatus GetAccelerationStatus() const
{
return (this->vehstatus & VS_STOPPED) || HasBit(this->flags, VRF_REVERSING) || HasBit(this->flags, VRF_TRAIN_STUCK) ? AS_BRAKE : AS_ACCEL;
}
/**
* Calculates the current speed of this vehicle.
* @return Current speed in mph.
*/
FORCEINLINE uint16 GetCurrentSpeed() const
{
return this->cur_speed * 10 / 16;
}
/**
* Returns the rolling friction coefficient of this vehicle.
* @return Rolling friction coefficient in [1e-3].
*/
FORCEINLINE uint32 GetRollingFriction() const
{
return 35;
}
/**
* Allows to know the acceleration type of a vehicle.
* @return Acceleration type of the vehicle.
*/
FORCEINLINE int GetAccelerationType() const
{
return GetRailTypeInfo(this->railtype)->acceleration_type;
}
/**
* Returns the slope steepness used by this vehicle.
* @return Slope steepness used by the vehicle.
*/
FORCEINLINE uint32 GetSlopeSteepness() const
{
return 20 * _settings_game.vehicle.train_slope_steepness; // 1% slope * slope steepness
}
/**
* Gets the maximum speed of the vehicle, ignoring the limitations of the kind of track the vehicle is on.
* @return Maximum speed of the vehicle.
*/
FORCEINLINE uint16 GetInitialMaxSpeed() const
{
return this->tcache.cached_max_speed;
}
/**
* Gets the maximum speed allowed by the track for this vehicle.
* @return Maximum speed allowed.
*/
FORCEINLINE uint16 GetMaxTrackSpeed() const
{
return GetRailTypeInfo(GetRailType(this->tile))->max_speed;
}
/**
* Checks if the vehicle is at a tile that can be sloped.
* @return True if the tile can be sloped.
*/
FORCEINLINE bool TileMayHaveSlopedTrack() const
{
/* Any track that isn't TRACK_BIT_X or TRACK_BIT_Y cannot be sloped. */
return this->track == TRACK_BIT_X || this->track == TRACK_BIT_Y;
}
};
#define FOR_ALL_TRAINS(var) FOR_ALL_VEHICLES_OF_TYPE(Train, var)
#endif /* TRAIN_H */
|