34 #include "string_func.h" |
34 #include "string_func.h" |
35 #include "settings_type.h" |
35 #include "settings_type.h" |
36 #include "widgets/dropdown_func.h" |
36 #include "widgets/dropdown_func.h" |
37 #include "order_func.h" |
37 #include "order_func.h" |
38 #include "timetable.h" |
38 #include "timetable.h" |
|
39 #include "vehiclelist.h" |
39 |
40 |
40 #include "table/sprites.h" |
41 #include "table/sprites.h" |
41 #include "table/strings.h" |
42 #include "table/strings.h" |
42 |
43 |
43 Sorting _sorting; |
44 Sorting _sorting; |
90 { |
91 { |
91 if (!(vl->vehicles.flags & VL_REBUILD)) return; |
92 if (!(vl->vehicles.flags & VL_REBUILD)) return; |
92 |
93 |
93 DEBUG(misc, 3, "Building vehicle list for player %d at station %d", owner, index); |
94 DEBUG(misc, 3, "Building vehicle list for player %d at station %d", owner, index); |
94 |
95 |
95 vl->vehicles.list_length = GenerateVehicleSortList(&vl->vehicles.sort_list, &vl->vehicles.list_length, vl->vehicle_type, owner, index, window_type); |
96 GenerateVehicleSortList(&vl->vehicles, vl->vehicle_type, owner, index, window_type); |
96 |
97 |
97 vl->vehicles.flags &= ~VL_REBUILD; |
98 vl->vehicles.flags &= ~VL_REBUILD; |
98 vl->vehicles.flags |= VL_RESORT; |
99 vl->vehicles.flags |= VL_RESORT; |
99 } |
100 } |
100 |
101 |
108 |
109 |
109 /* invalidate cached values for name sorter - vehicle names could change */ |
110 /* invalidate cached values for name sorter - vehicle names could change */ |
110 _last_vehicle[0] = _last_vehicle[1] = NULL; |
111 _last_vehicle[0] = _last_vehicle[1] = NULL; |
111 |
112 |
112 _internal_sort_order = (vl->vehicles.flags & VL_DESC) != 0; |
113 _internal_sort_order = (vl->vehicles.flags & VL_DESC) != 0; |
113 qsort((void*)vl->vehicles.sort_list, vl->vehicles.list_length, sizeof(vl->vehicles.sort_list[0]), |
114 qsort((void*)vl->vehicles.Begin(), vl->vehicles.Length(), sizeof(*vl->vehicles.Begin()), |
114 _vehicle_sorter[vl->vehicles.sort_type]); |
115 _vehicle_sorter[vl->vehicles.sort_type]); |
115 |
116 |
116 vl->vehicles.resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS; |
117 vl->vehicles.resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS; |
117 vl->vehicles.flags &= ~VL_RESORT; |
118 vl->vehicles.flags &= ~VL_RESORT; |
118 } |
119 } |
119 |
120 |
120 void DepotSortList(VehicleList *list) |
121 void DepotSortList(VehicleList *list) |
121 { |
122 { |
122 _internal_sort_order = 0; |
123 _internal_sort_order = 0; |
123 if (list->Length() < 2) return; |
124 if (list->Length() < 2) return; |
124 qsort((void*)list->Begin(), list->Length(), sizeof(list->Begin()), _vehicle_sorter[0]); |
125 qsort((void*)list->Begin(), list->Length(), sizeof(*list->Begin()), _vehicle_sorter[0]); |
125 } |
126 } |
126 |
127 |
127 /** draw the vehicle profit button in the vehicle list window. */ |
128 /** draw the vehicle profit button in the vehicle list window. */ |
128 void DrawVehicleProfitButton(const Vehicle *v, int x, int y) |
129 void DrawVehicleProfitButton(const Vehicle *v, int x, int y) |
129 { |
130 { |
804 { |
805 { |
805 uint16 window_type = this->window_number & VLW_MASK; |
806 uint16 window_type = this->window_number & VLW_MASK; |
806 PlayerID player = (PlayerID)GB(this->window_number, 0, 8); |
807 PlayerID player = (PlayerID)GB(this->window_number, 0, 8); |
807 |
808 |
808 this->vehicle_type = (VehicleType)GB(this->window_number, 11, 5); |
809 this->vehicle_type = (VehicleType)GB(this->window_number, 11, 5); |
809 this->vehicles.list_length = 0; |
|
810 this->vehicles.sort_list = NULL; |
|
811 this->caption_color = player; |
810 this->caption_color = player; |
812 |
811 |
813 /* Hide the widgets that we will not use in this window |
812 /* Hide the widgets that we will not use in this window |
814 * Some windows contains actions only fit for the owner */ |
813 * Some windows contains actions only fit for the owner */ |
815 if (player == _local_player) { |
814 if (player == _local_player) { |
938 const uint16 window_type = this->window_number & VLW_MASK; |
936 const uint16 window_type = this->window_number & VLW_MASK; |
939 const uint16 index = GB(this->window_number, 16, 16); |
937 const uint16 index = GB(this->window_number, 16, 16); |
940 |
938 |
941 BuildVehicleList(this, owner, index, window_type); |
939 BuildVehicleList(this, owner, index, window_type); |
942 SortVehicleList(this); |
940 SortVehicleList(this); |
943 SetVScrollCount(this, this->vehicles.list_length); |
941 SetVScrollCount(this, this->vehicles.Length()); |
944 |
942 |
945 /* draw the widgets */ |
943 /* draw the widgets */ |
946 switch (window_type) { |
944 switch (window_type) { |
947 case VLW_SHARED_ORDERS: /* Shared Orders */ |
945 case VLW_SHARED_ORDERS: /* Shared Orders */ |
948 if (this->vehicles.list_length == 0) { |
946 if (this->vehicles.Length() == 0) { |
949 /* We can't open this window without vehicles using this order |
947 /* We can't open this window without vehicles using this order |
950 * and we should close the window when deleting the order */ |
948 * and we should close the window when deleting the order */ |
951 NOT_REACHED(); |
949 NOT_REACHED(); |
952 } |
950 } |
953 SetDParam(0, this->vscroll.count); |
951 SetDParam(0, this->vscroll.count); |
979 SetDParam(2, this->vscroll.count); |
977 SetDParam(2, this->vscroll.count); |
980 break; |
978 break; |
981 default: NOT_REACHED(); break; |
979 default: NOT_REACHED(); break; |
982 } |
980 } |
983 |
981 |
984 this->SetWidgetsDisabledState(this->vehicles.list_length == 0, |
982 this->SetWidgetsDisabledState(this->vehicles.Length() == 0, |
985 VLW_WIDGET_MANAGE_VEHICLES_DROPDOWN, |
983 VLW_WIDGET_MANAGE_VEHICLES_DROPDOWN, |
986 VLW_WIDGET_STOP_ALL, |
984 VLW_WIDGET_STOP_ALL, |
987 VLW_WIDGET_START_ALL, |
985 VLW_WIDGET_START_ALL, |
988 WIDGET_LIST_END); |
986 WIDGET_LIST_END); |
989 |
987 |
992 /* draw sorting criteria string */ |
990 /* draw sorting criteria string */ |
993 DrawString(85, 15, _vehicle_sort_listing[this->vehicles.sort_type], TC_BLACK); |
991 DrawString(85, 15, _vehicle_sort_listing[this->vehicles.sort_type], TC_BLACK); |
994 /* draw arrow pointing up/down for ascending/descending sorting */ |
992 /* draw arrow pointing up/down for ascending/descending sorting */ |
995 this->DrawSortButtonState(VLW_WIDGET_SORT_ORDER, this->vehicles.flags & VL_DESC ? SBS_DOWN : SBS_UP); |
993 this->DrawSortButtonState(VLW_WIDGET_SORT_ORDER, this->vehicles.flags & VL_DESC ? SBS_DOWN : SBS_UP); |
996 |
994 |
997 max = min(this->vscroll.pos + this->vscroll.cap, this->vehicles.list_length); |
995 max = min(this->vscroll.pos + this->vscroll.cap, this->vehicles.Length()); |
998 for (i = this->vscroll.pos; i < max; ++i) { |
996 for (i = this->vscroll.pos; i < max; ++i) { |
999 const Vehicle *v = this->vehicles.sort_list[i]; |
997 const Vehicle *v = this->vehicles[i]; |
1000 StringID str; |
998 StringID str; |
1001 |
999 |
1002 SetDParam(0, v->GetDisplayProfitThisYear()); |
1000 SetDParam(0, v->GetDisplayProfitThisYear()); |
1003 SetDParam(1, v->GetDisplayProfitLastYear()); |
1001 SetDParam(1, v->GetDisplayProfitLastYear()); |
1004 |
1002 |
1047 |
1045 |
1048 if (id_v >= this->vscroll.cap) return; // click out of bounds |
1046 if (id_v >= this->vscroll.cap) return; // click out of bounds |
1049 |
1047 |
1050 id_v += this->vscroll.pos; |
1048 id_v += this->vscroll.pos; |
1051 |
1049 |
1052 if (id_v >= this->vehicles.list_length) return; // click out of list bound |
1050 if (id_v >= this->vehicles.Length()) return; // click out of list bound |
1053 |
1051 |
1054 v = this->vehicles.sort_list[id_v]; |
1052 v = this->vehicles[id_v]; |
1055 |
1053 |
1056 ShowVehicleViewWindow(v); |
1054 ShowVehicleViewWindow(v); |
1057 } break; |
1055 } break; |
1058 |
1056 |
1059 case VLW_WIDGET_AVAILABLE_VEHICLES: |
1057 case VLW_WIDGET_AVAILABLE_VEHICLES: |
1098 this->vehicles.sort_type = index; |
1096 this->vehicles.sort_type = index; |
1099 this->sorting->criteria = this->vehicles.sort_type; |
1097 this->sorting->criteria = this->vehicles.sort_type; |
1100 } |
1098 } |
1101 break; |
1099 break; |
1102 case VLW_WIDGET_MANAGE_VEHICLES_DROPDOWN: |
1100 case VLW_WIDGET_MANAGE_VEHICLES_DROPDOWN: |
1103 assert(this->vehicles.list_length != 0); |
1101 assert(this->vehicles.Length() != 0); |
1104 |
1102 |
1105 switch (index) { |
1103 switch (index) { |
1106 case 0: /* Replace window */ |
1104 case 0: /* Replace window */ |
1107 ShowReplaceGroupVehicleWindow(DEFAULT_GROUP, this->vehicle_type); |
1105 ShowReplaceGroupVehicleWindow(DEFAULT_GROUP, this->vehicle_type); |
1108 break; |
1106 break; |
1218 } |
1216 } |
1219 } |
1217 } |
1220 |
1218 |
1221 void ShowVehicleListWindow(PlayerID player, VehicleType vehicle_type) |
1219 void ShowVehicleListWindow(PlayerID player, VehicleType vehicle_type) |
1222 { |
1220 { |
1223 /* If _settings.gui.advanced_vehicle_list > 1, display the Advanced list |
1221 /* If _settings_client.gui.advanced_vehicle_list > 1, display the Advanced list |
1224 * if _settings.gui.advanced_vehicle_list == 1, display Advanced list only for local player |
1222 * if _settings_client.gui.advanced_vehicle_list == 1, display Advanced list only for local player |
1225 * if _ctrl_pressed, do the opposite action (Advanced list x Normal list) |
1223 * if _ctrl_pressed, do the opposite action (Advanced list x Normal list) |
1226 */ |
1224 */ |
1227 |
1225 |
1228 if ((_settings.gui.advanced_vehicle_list > (uint)(player != _local_player)) != _ctrl_pressed) { |
1226 if ((_settings_client.gui.advanced_vehicle_list > (uint)(player != _local_player)) != _ctrl_pressed) { |
1229 ShowPlayerGroup(player, vehicle_type); |
1227 ShowPlayerGroup(player, vehicle_type); |
1230 } else { |
1228 } else { |
1231 ShowVehicleListWindowLocal(player, VLW_STANDARD, vehicle_type, 0); |
1229 ShowVehicleListWindowLocal(player, VLW_STANDARD, vehicle_type, 0); |
1232 } |
1230 } |
1233 } |
1231 } |
1409 /** Checks whether service interval is enabled for the vehicle. */ |
1407 /** Checks whether service interval is enabled for the vehicle. */ |
1410 static bool IsVehicleServiceIntervalEnabled(const VehicleType vehicle_type) |
1408 static bool IsVehicleServiceIntervalEnabled(const VehicleType vehicle_type) |
1411 { |
1409 { |
1412 switch (vehicle_type) { |
1410 switch (vehicle_type) { |
1413 default: NOT_REACHED(); |
1411 default: NOT_REACHED(); |
1414 case VEH_TRAIN: return _settings.vehicle.servint_trains != 0; break; |
1412 case VEH_TRAIN: return _settings_game.vehicle.servint_trains != 0; break; |
1415 case VEH_ROAD: return _settings.vehicle.servint_roadveh != 0; break; |
1413 case VEH_ROAD: return _settings_game.vehicle.servint_roadveh != 0; break; |
1416 case VEH_SHIP: return _settings.vehicle.servint_ships != 0; break; |
1414 case VEH_SHIP: return _settings_game.vehicle.servint_ships != 0; break; |
1417 case VEH_AIRCRAFT: return _settings.vehicle.servint_aircraft != 0; break; |
1415 case VEH_AIRCRAFT: return _settings_game.vehicle.servint_aircraft != 0; break; |
1418 } |
1416 } |
1419 return false; // kill a compiler warning |
1417 return false; // kill a compiler warning |
1420 } |
1418 } |
1421 |
1419 |
1422 /** |
1420 /** |
1484 case VEH_TRAIN: |
1482 case VEH_TRAIN: |
1485 SetDParam(2, v->GetDisplayMaxSpeed()); |
1483 SetDParam(2, v->GetDisplayMaxSpeed()); |
1486 SetDParam(1, v->u.rail.cached_power); |
1484 SetDParam(1, v->u.rail.cached_power); |
1487 SetDParam(0, v->u.rail.cached_weight); |
1485 SetDParam(0, v->u.rail.cached_weight); |
1488 SetDParam(3, v->u.rail.cached_max_te / 1000); |
1486 SetDParam(3, v->u.rail.cached_max_te / 1000); |
1489 DrawString(2, 25, (_settings.vehicle.realistic_acceleration && v->u.rail.railtype != RAILTYPE_MAGLEV) ? |
1487 DrawString(2, 25, (_settings_game.vehicle.realistic_acceleration && v->u.rail.railtype != RAILTYPE_MAGLEV) ? |
1490 STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE : |
1488 STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE : |
1491 STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED, TC_FROMSTRING); |
1489 STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED, TC_FROMSTRING); |
1492 break; |
1490 break; |
1493 |
1491 |
1494 case VEH_ROAD: |
1492 case VEH_ROAD: |
1512 DrawString(2, 45, _vehicle_translation_table[VST_VEHICLE_RELIABILITY_BREAKDOWNS][v->type], TC_FROMSTRING); |
1510 DrawString(2, 45, _vehicle_translation_table[VST_VEHICLE_RELIABILITY_BREAKDOWNS][v->type], TC_FROMSTRING); |
1513 |
1511 |
1514 /* Draw service interval text */ |
1512 /* Draw service interval text */ |
1515 SetDParam(0, v->service_interval); |
1513 SetDParam(0, v->service_interval); |
1516 SetDParam(1, v->date_of_last_service); |
1514 SetDParam(1, v->date_of_last_service); |
1517 DrawString(13, this->height - (v->type != VEH_TRAIN ? 11 : 23), _settings.vehicle.servint_ispercent ? STR_SERVICING_INTERVAL_PERCENT : STR_883C_SERVICING_INTERVAL_DAYS, TC_FROMSTRING); |
1515 DrawString(13, this->height - (v->type != VEH_TRAIN ? 11 : 23), _settings_game.vehicle.servint_ispercent ? STR_SERVICING_INTERVAL_PERCENT : STR_883C_SERVICING_INTERVAL_DAYS, TC_FROMSTRING); |
1518 |
1516 |
1519 switch (v->type) { |
1517 switch (v->type) { |
1520 case VEH_TRAIN: |
1518 case VEH_TRAIN: |
1521 DrawVehicleDetails(v, 2, 57, this->vscroll.pos, this->vscroll.cap, det_tab); |
1519 DrawVehicleDetails(v, 2, 57, this->vscroll.pos, this->vscroll.cap, det_tab); |
1522 break; |
1520 break; |
1951 } else { |
1949 } else { |
1952 str = STR_8861_STOPPED; |
1950 str = STR_8861_STOPPED; |
1953 } |
1951 } |
1954 } else { |
1952 } else { |
1955 SetDParam(0, v->GetDisplaySpeed()); |
1953 SetDParam(0, v->GetDisplaySpeed()); |
1956 str = STR_TRAIN_STOPPING + _settings.gui.vehicle_speed; |
1954 str = STR_TRAIN_STOPPING + _settings_client.gui.vehicle_speed; |
1957 } |
1955 } |
1958 } else { // no train |
1956 } else { // no train |
1959 str = STR_8861_STOPPED; |
1957 str = STR_8861_STOPPED; |
1960 } |
1958 } |
1961 } else { // vehicle is in a "normal" state, show current order |
1959 } else { // vehicle is in a "normal" state, show current order |
1962 switch (v->current_order.GetType()) { |
1960 switch (v->current_order.GetType()) { |
1963 case OT_GOTO_STATION: { |
1961 case OT_GOTO_STATION: { |
1964 SetDParam(0, v->current_order.GetDestination()); |
1962 SetDParam(0, v->current_order.GetDestination()); |
1965 SetDParam(1, v->GetDisplaySpeed()); |
1963 SetDParam(1, v->GetDisplaySpeed()); |
1966 str = STR_HEADING_FOR_STATION + _settings.gui.vehicle_speed; |
1964 str = STR_HEADING_FOR_STATION + _settings_client.gui.vehicle_speed; |
1967 } break; |
1965 } break; |
1968 |
1966 |
1969 case OT_GOTO_DEPOT: { |
1967 case OT_GOTO_DEPOT: { |
1970 if (v->type == VEH_AIRCRAFT) { |
1968 if (v->type == VEH_AIRCRAFT) { |
1971 /* Aircrafts always go to a station, even if you say depot */ |
1969 /* Aircrafts always go to a station, even if you say depot */ |
1975 Depot *depot = GetDepot(v->current_order.GetDestination()); |
1973 Depot *depot = GetDepot(v->current_order.GetDestination()); |
1976 SetDParam(0, depot->town_index); |
1974 SetDParam(0, depot->town_index); |
1977 SetDParam(1, v->GetDisplaySpeed()); |
1975 SetDParam(1, v->GetDisplaySpeed()); |
1978 } |
1976 } |
1979 if ((v->current_order.GetDepotActionType() & ODATFB_HALT) && !(v->current_order.GetDepotOrderType() & ODTFB_PART_OF_ORDERS)) { |
1977 if ((v->current_order.GetDepotActionType() & ODATFB_HALT) && !(v->current_order.GetDepotOrderType() & ODTFB_PART_OF_ORDERS)) { |
1980 str = _heading_for_depot_strings[v->type] + _settings.gui.vehicle_speed; |
1978 str = _heading_for_depot_strings[v->type] + _settings_client.gui.vehicle_speed; |
1981 } else { |
1979 } else { |
1982 str = _heading_for_depot_service_strings[v->type] + _settings.gui.vehicle_speed; |
1980 str = _heading_for_depot_service_strings[v->type] + _settings_client.gui.vehicle_speed; |
1983 } |
1981 } |
1984 } break; |
1982 } break; |
1985 |
1983 |
1986 case OT_LOADING: |
1984 case OT_LOADING: |
1987 str = STR_882F_LOADING_UNLOADING; |
1985 str = STR_882F_LOADING_UNLOADING; |
1988 break; |
1986 break; |
1989 |
1987 |
1990 case OT_GOTO_WAYPOINT: { |
1988 case OT_GOTO_WAYPOINT: { |
1991 assert(v->type == VEH_TRAIN); |
1989 assert(v->type == VEH_TRAIN); |
1992 SetDParam(0, v->current_order.GetDestination()); |
1990 SetDParam(0, v->current_order.GetDestination()); |
1993 str = STR_HEADING_FOR_WAYPOINT + _settings.gui.vehicle_speed; |
1991 str = STR_HEADING_FOR_WAYPOINT + _settings_client.gui.vehicle_speed; |
1994 SetDParam(1, v->GetDisplaySpeed()); |
1992 SetDParam(1, v->GetDisplaySpeed()); |
1995 break; |
1993 break; |
1996 } |
1994 } |
1997 |
1995 |
1998 case OT_LEAVESTATION: |
1996 case OT_LEAVESTATION: |