21 #include "cargotype.h" |
21 #include "cargotype.h" |
22 #include "date_func.h" |
22 #include "date_func.h" |
23 #include "vehicle_func.h" |
23 #include "vehicle_func.h" |
24 #include "core/random_func.hpp" |
24 #include "core/random_func.hpp" |
25 #include "direction_func.h" |
25 #include "direction_func.h" |
|
26 #include "rail_map.h" |
|
27 #include "rail.h" |
26 |
28 |
27 |
29 |
28 int _traininfo_vehicle_pitch = 0; |
30 int _traininfo_vehicle_pitch = 0; |
29 int _traininfo_vehicle_width = 29; |
31 int _traininfo_vehicle_width = 29; |
30 |
32 |
396 |
398 |
397 |
399 |
398 /* Vehicle Resolver Functions */ |
400 /* Vehicle Resolver Functions */ |
399 static inline const Vehicle *GRV(const ResolverObject *object) |
401 static inline const Vehicle *GRV(const ResolverObject *object) |
400 { |
402 { |
401 return object->scope == VSG_SCOPE_SELF ? object->u.vehicle.self : object->u.vehicle.parent; |
403 switch (object->scope) { |
|
404 default: NOT_REACHED(); |
|
405 case VSG_SCOPE_SELF: return object->u.vehicle.self; |
|
406 case VSG_SCOPE_PARENT: return object->u.vehicle.parent; |
|
407 case VSG_SCOPE_RELATIVE: { |
|
408 const Vehicle *v = NULL; |
|
409 switch (GB(object->count, 6, 2)) { |
|
410 default: NOT_REACHED(); |
|
411 case 0x00: // count back (away from the engine), starting at this vehicle |
|
412 case 0x01: // count forward (toward the engine), starting at this vehicle |
|
413 v = object->u.vehicle.self; |
|
414 break; |
|
415 case 0x02: // count back, starting at the engine |
|
416 v = object->u.vehicle.parent; |
|
417 break; |
|
418 case 0x03: { // count back, starting at the first vehicle in this chain of vehicles with the same ID, as for vehicle variable 41 |
|
419 const Vehicle *self = object->u.vehicle.self; |
|
420 for (const Vehicle *u = self->First(); u != self; u = u->Next()) { |
|
421 if (u->engine_type != self->engine_type) { |
|
422 v = NULL; |
|
423 } else { |
|
424 if (v == NULL) v = u; |
|
425 } |
|
426 } |
|
427 if (v == NULL) v = self; |
|
428 } break; |
|
429 } |
|
430 uint32 count = GB(object->count, 0, 4); |
|
431 if (count == 0) count = GetRegister(0x100); |
|
432 while (v != NULL && count-- != 0) v = (GB(object->count, 6, 2) == 0x01) ? v->Previous() : v->Next(); |
|
433 return v; |
|
434 } |
|
435 } |
402 } |
436 } |
403 |
437 |
404 |
438 |
405 static uint32 VehicleGetRandomBits(const ResolverObject *object) |
439 static uint32 VehicleGetRandomBits(const ResolverObject *object) |
406 { |
440 { |
510 /* Reset our arrays */ |
544 /* Reset our arrays */ |
511 memset(common_cargos, 0, sizeof(common_cargos)); |
545 memset(common_cargos, 0, sizeof(common_cargos)); |
512 memset(common_subtypes, 0, sizeof(common_subtypes)); |
546 memset(common_subtypes, 0, sizeof(common_subtypes)); |
513 |
547 |
514 for (u = v; u != NULL; u = u->Next()) { |
548 for (u = v; u != NULL; u = u->Next()) { |
|
549 if (v->type == VEH_TRAIN) user_def_data |= u->u.rail.user_def_data; |
|
550 |
515 /* Skip empty engines */ |
551 /* Skip empty engines */ |
516 if (u->cargo_cap == 0) continue; |
552 if (u->cargo_cap == 0) continue; |
517 |
553 |
518 cargo_classes |= GetCargo(u->cargo_type)->classes; |
554 cargo_classes |= GetCargo(u->cargo_type)->classes; |
519 common_cargos[u->cargo_type]++; |
555 common_cargos[u->cargo_type]++; |
520 if (v->type == VEH_TRAIN) user_def_data |= u->u.rail.user_def_data; |
|
521 common_subtypes[u->cargo_subtype]++; |
556 common_subtypes[u->cargo_subtype]++; |
522 } |
557 } |
523 |
558 |
524 /* Pick the most common cargo type */ |
559 /* Pick the most common cargo type */ |
525 for (CargoID cargo = 0; cargo < NUM_CARGO; cargo++) { |
560 for (CargoID cargo = 0; cargo < NUM_CARGO; cargo++) { |
621 |
656 |
622 case 0xFE: |
657 case 0xFE: |
623 case 0xFF: { |
658 case 0xFF: { |
624 uint16 modflags = 0; |
659 uint16 modflags = 0; |
625 |
660 |
626 /* @todo: There are some other bits that should be implemented: |
661 if (v->type == VEH_TRAIN) { |
627 * bit 5: Whether the rail vehicle is powered or not (mostly useful for wagons). |
662 const Vehicle *u = IsTrainWagon(v) && HasBit(v->vehicle_flags, VRF_POWEREDWAGON) ? v->First() : v; |
628 * bit 6: This is an electrically powered rail vehicle which is running on normal rail. |
663 RailType railtype = GetRailType(v->tile); |
629 * bit 8: (Maybe?) Toggled whenever the train reverses. |
664 bool powered = IsTrainEngine(v) || (IsTrainWagon(v) && HasBit(v->vehicle_flags, VRF_POWEREDWAGON)); |
630 */ |
665 bool has_power = powered && HasPowerOnRail(u->u.rail.railtype, railtype); |
631 |
666 bool is_electric = powered && u->u.rail.railtype == RAILTYPE_ELECTRIC; |
|
667 |
|
668 if (has_power) SetBit(modflags, 5); |
|
669 if (is_electric && !has_power) SetBit(modflags, 6); |
|
670 if (HasBit(v->u.rail.flags, VRF_TOGGLE_REVERSE)) SetBit(modflags, 8); |
|
671 } |
632 if (HasBit(v->vehicle_flags, VF_BUILT_AS_PROTOTYPE)) SetBit(modflags, 10); |
672 if (HasBit(v->vehicle_flags, VF_BUILT_AS_PROTOTYPE)) SetBit(modflags, 10); |
633 |
673 |
634 return variable == 0xFE ? modflags : GB(modflags, 8, 8); |
674 return variable == 0xFE ? modflags : GB(modflags, 8, 8); |
635 } |
675 } |
636 } |
676 } |