497 { |
497 { |
498 v->u.road.crashed_ctr++; |
498 v->u.road.crashed_ctr++; |
499 if (v->u.road.crashed_ctr == 2) { |
499 if (v->u.road.crashed_ctr == 2) { |
500 CreateEffectVehicleRel(v, 4, 4, 8, EV_EXPLOSION_LARGE); |
500 CreateEffectVehicleRel(v, 4, 4, 8, EV_EXPLOSION_LARGE); |
501 } else if (v->u.road.crashed_ctr <= 45) { |
501 } else if (v->u.road.crashed_ctr <= 45) { |
502 if ((v->tick_counter&7)==0) |
502 if ((v->tick_counter & 7) == 0) |
503 RoadVehSetRandomDirection(v); |
503 RoadVehSetRandomDirection(v); |
504 } else if (v->u.road.crashed_ctr >= 2220) { |
504 } else if (v->u.road.crashed_ctr >= 2220) { |
505 RoadVehDelete(v); |
505 RoadVehDelete(v); |
506 } |
506 } |
507 } |
507 } |
524 v->vehstatus |= VS_CRASHED; |
524 v->vehstatus |= VS_CRASHED; |
525 |
525 |
526 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); |
526 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); |
527 |
527 |
528 pass = 1; |
528 pass = 1; |
529 if (v->cargo_type == 0) |
529 if (v->cargo_type == 0) pass += v->cargo_count; |
530 pass += v->cargo_count; |
|
531 v->cargo_count = 0; |
530 v->cargo_count = 0; |
|
531 |
532 SetDParam(0, pass); |
532 SetDParam(0, pass); |
533 |
|
534 AddNewsItem( |
533 AddNewsItem( |
535 (pass == 1) ? |
534 (pass == 1) ? |
536 STR_9031_ROAD_VEHICLE_CRASH_DRIVER : STR_9032_ROAD_VEHICLE_CRASH_DIE, |
535 STR_9031_ROAD_VEHICLE_CRASH_DRIVER : STR_9032_ROAD_VEHICLE_CRASH_DIE, |
537 NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_VEHICLE, NT_ACCIDENT, 0), |
536 NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_VEHICLE, NT_ACCIDENT, 0), |
538 v->index, |
537 v->index, |
797 } |
793 } |
798 } |
794 } |
799 |
795 |
800 static bool RoadVehAccelerate(Vehicle *v) |
796 static bool RoadVehAccelerate(Vehicle *v) |
801 { |
797 { |
802 uint spd = v->cur_speed + 1 + ((v->u.road.overtaking != 0)?1:0); |
798 uint spd = v->cur_speed + 1 + (v->u.road.overtaking != 0 ? 1 : 0); |
803 byte t; |
799 byte t; |
804 |
800 |
805 // Clamp |
801 // Clamp |
806 spd = min(spd, v->max_speed); |
802 spd = min(spd, v->max_speed); |
807 |
803 |
808 //updates statusbar only if speed have changed to save CPU time |
804 //updates statusbar only if speed have changed to save CPU time |
809 if (spd != v->cur_speed) { |
805 if (spd != v->cur_speed) { |
810 v->cur_speed = spd; |
806 v->cur_speed = spd; |
811 if (_patches.vehicle_speed) |
807 if (_patches.vehicle_speed) { |
812 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); |
808 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); |
|
809 } |
813 } |
810 } |
814 |
811 |
815 // Decrease somewhat when turning |
812 // Decrease somewhat when turning |
816 if (!(v->direction&1)) |
813 if (!(v->direction & 1)) spd = spd * 3 >> 2; |
817 spd = spd * 3 >> 2; |
814 |
818 |
815 if (spd == 0) return false; |
819 if (spd == 0) |
816 |
820 return false; |
817 if ((byte)++spd == 0) return true; |
821 |
|
822 if ((byte)++spd == 0) |
|
823 return true; |
|
824 |
818 |
825 v->progress = (t = v->progress) - (byte)spd; |
819 v->progress = (t = v->progress) - (byte)spd; |
826 |
820 |
827 return (t < v->progress); |
821 return (t < v->progress); |
828 } |
822 } |
888 |
882 |
889 od.v = v; |
883 od.v = v; |
890 od.u = u; |
884 od.u = u; |
891 |
885 |
892 if (u->max_speed >= v->max_speed && |
886 if (u->max_speed >= v->max_speed && |
893 !(u->vehstatus&VS_STOPPED) && |
887 !(u->vehstatus & VS_STOPPED) && |
894 u->cur_speed != 0) |
888 u->cur_speed != 0) { |
895 return; |
889 return; |
|
890 } |
896 |
891 |
897 if (v->direction != u->direction || !(v->direction&1)) |
892 if (v->direction != u->direction || !(v->direction&1)) |
898 return; |
893 return; |
899 |
894 |
900 if (v->u.road.state >= 32 || (v->u.road.state&7) > 1 ) |
895 if (v->u.road.state >= 32 || (v->u.road.state&7) > 1 ) |
901 return; |
896 return; |
902 |
897 |
903 tt = GetTileTrackStatus(v->tile, TRANSPORT_ROAD) & 0x3F; |
898 tt = GetTileTrackStatus(v->tile, TRANSPORT_ROAD) & 0x3F; |
904 if ((tt & 3) == 0) |
899 if ((tt & 3) == 0) return; |
905 return; |
900 if ((tt & 0x3C) != 0) return; |
906 if ((tt & 0x3C) != 0) |
901 |
907 return; |
902 if (tt == 3) tt = (v->direction & 2) ? 2 : 1; |
908 |
|
909 if (tt == 3) { |
|
910 tt = (v->direction&2)?2:1; |
|
911 } |
|
912 od.tilebits = tt; |
903 od.tilebits = tt; |
913 |
904 |
914 od.tile = v->tile; |
905 od.tile = v->tile; |
915 if (FindRoadVehToOvertake(&od)) |
906 if (FindRoadVehToOvertake(&od)) return; |
916 return; |
|
917 |
907 |
918 od.tile = v->tile + TileOffsByDir(v->direction >> 1); |
908 od.tile = v->tile + TileOffsByDir(v->direction >> 1); |
919 if (FindRoadVehToOvertake(&od)) |
909 if (FindRoadVehToOvertake(&od)) return; |
920 return; |
|
921 |
910 |
922 if (od.u->cur_speed == 0 || od.u->vehstatus&VS_STOPPED) { |
911 if (od.u->cur_speed == 0 || od.u->vehstatus&VS_STOPPED) { |
923 v->u.road.overtaking_ctr = 0x11; |
912 v->u.road.overtaking_ctr = 0x11; |
924 v->u.road.overtaking = 0x10; |
913 v->u.road.overtaking = 0x10; |
925 } else { |
914 } else { |
926 // if (FindRoadVehToOvertake(&od)) |
915 // if (FindRoadVehToOvertake(&od)) return; |
927 // return; |
|
928 v->u.road.overtaking_ctr = 0; |
916 v->u.road.overtaking_ctr = 0; |
929 v->u.road.overtaking = 0x10; |
917 v->u.road.overtaking = 0x10; |
930 } |
918 } |
931 } |
919 } |
932 |
920 |
1234 |
1217 |
1235 InvalidateWindow(WC_VEHICLE_DEPOT, v->tile); |
1218 InvalidateWindow(WC_VEHICLE_DEPOT, v->tile); |
1236 return; |
1219 return; |
1237 } |
1220 } |
1238 |
1221 |
1239 if (!RoadVehAccelerate(v)) |
1222 if (!RoadVehAccelerate(v)) return; |
1240 return; |
|
1241 |
1223 |
1242 if (v->u.road.overtaking != 0) { |
1224 if (v->u.road.overtaking != 0) { |
1243 if (++v->u.road.overtaking_ctr >= 35) |
1225 if (++v->u.road.overtaking_ctr >= 35) |
1244 /* If overtaking just aborts at a random moment, we can have a out-of-bound problem, |
1226 /* If overtaking just aborts at a random moment, we can have a out-of-bound problem, |
1245 * if the vehicle started a corner. To protect that, only allow an abort of |
1227 * if the vehicle started a corner. To protect that, only allow an abort of |
1610 RoadStopType type = (v->cargo_type == CT_PASSENGERS) ? RS_BUS : RS_TRUCK; |
1592 RoadStopType type = (v->cargo_type == CT_PASSENGERS) ? RS_BUS : RS_TRUCK; |
1611 |
1593 |
1612 st = GetStation(v->current_order.station); |
1594 st = GetStation(v->current_order.station); |
1613 |
1595 |
1614 //Current slot has expired |
1596 //Current slot has expired |
1615 if ( (v->u.road.slot_age++ <= 0) && (v->u.road.slot != NULL)) |
1597 if (v->u.road.slot_age++ <= 0 && v->u.road.slot != NULL) { |
1616 ClearSlot(v, v->u.road.slot); |
1598 ClearSlot(v, v->u.road.slot); |
|
1599 } |
1617 |
1600 |
1618 //We do not have a slot, so make one |
1601 //We do not have a slot, so make one |
1619 if (v->u.road.slot == NULL) { |
1602 if (v->u.road.slot == NULL) { |
1620 RoadStop *rs = GetPrimaryRoadStop(st, type); |
1603 RoadStop *rs = GetPrimaryRoadStop(st, type); |
1621 RoadStop *first_stop = rs; |
1604 RoadStop *first_stop = rs; |
1622 RoadStop *best_stop = NULL; |
1605 RoadStop *best_stop = NULL; |
1623 uint32 mindist = 12, dist; // 12 is threshold distance. |
1606 uint32 mindist = 12, dist; // 12 is threshold distance. |
1624 |
1607 |
1625 //first we need to find out how far our stations are away. |
1608 //first we need to find out how far our stations are away. |
1626 DEBUG(ms, 2) ("Multistop: Attempting to obtain a slot for vehicle %d at station %d (0x%x)", v->unitnumber, st->index, st->xy); |
1609 DEBUG(ms, 2) ("Multistop: Attempting to obtain a slot for vehicle %d at station %d (0x%x)", v->unitnumber, st->index, st->xy); |
1627 for(; rs != NULL; rs = rs->next) { |
1610 for (; rs != NULL; rs = rs->next) { |
1628 // Only consider those with at least a free slot. |
1611 // Only consider those with at least a free slot. |
1629 if (!(rs->slot[0] == INVALID_SLOT || rs->slot[1] == INVALID_SLOT)) |
1612 if (!(rs->slot[0] == INVALID_SLOT || rs->slot[1] == INVALID_SLOT)) |
1630 continue; |
1613 continue; |
1631 |
1614 |
1632 // Previously the NPF pathfinder was used here even if NPF is OFF.. WTF? |
1615 // Previously the NPF pathfinder was used here even if NPF is OFF.. WTF? |
1633 assert(NUM_SLOTS == 2); |
1616 assert(NUM_SLOTS == 2); |
1634 dist = DistanceManhattan(v->tile, rs->xy); |
1617 dist = DistanceManhattan(v->tile, rs->xy); |
1635 |
1618 |
1636 // Check if the station is located BEHIND the vehicle.. |
1619 // Check if the station is located BEHIND the vehicle.. |
1637 // In that case, add penalty. |
1620 // In that case, add penalty. |
1638 switch(v->direction) { |
1621 switch (v->direction) { |
1639 case 1: // going north east,x position decreasing |
1622 case 1: // going north east,x position decreasing |
1640 if (v->x_pos <= (int32)TileX(rs->xy) * 16 + 15) |
1623 if (v->x_pos <= (int32)TileX(rs->xy) * 16 + 15) dist += 6; |
1641 dist += 6; |
1624 break; |
1642 break; |
1625 case 3: // Going south east, y position increasing |
1643 case 3: // Going south east, y position increasing |
1626 if (v->y_pos >= (int32)TileY(rs->xy) * 16) dist += 6; |
1644 if (v->y_pos >= (int32)TileY(rs->xy) * 16) |
1627 break; |
1645 dist += 6; |
1628 case 5: // Going south west, x position increasing |
1646 break; |
1629 if (v->x_pos >= (int32)TileX(rs->xy) * 16) dist += 6; |
1647 case 5: // Going south west, x position increasing |
1630 break; |
1648 if (v->x_pos >= (int32)TileX(rs->xy) * 16) |
1631 case 7: // Going north west, y position decrasing. |
1649 dist += 6; |
1632 if (v->y_pos <= (int32)TileY(rs->xy) * 16 + 15) dist += 6; |
1650 break; |
1633 break; |
1651 case 7: // Going north west, y position decrasing. |
|
1652 if (v->y_pos <= (int32)TileY(rs->xy) * 16 + 15) |
|
1653 dist += 6; |
|
1654 break; |
|
1655 } |
1634 } |
1656 |
1635 |
1657 // Remember the one with the shortest distance |
1636 // Remember the one with the shortest distance |
1658 if (dist < mindist) { |
1637 if (dist < mindist) { |
1659 mindist = dist; |
1638 mindist = dist; |