darkvater@164: #include "stdafx.h" darkvater@164: #include "ttd.h" darkvater@164: darkvater@164: #include "vehicle.h" darkvater@164: darkvater@164: /* General Vehicle GUI based procedures that are independent of vehicle types */ darkvater@164: void InitializeVehiclesGuiList() darkvater@164: { darkvater@243: memset(_train_sort_dirty, true, sizeof(_train_sort_dirty)); darkvater@243: memset(_aircraft_sort_dirty, true, sizeof(_aircraft_sort_dirty)); darkvater@243: memset(_ship_sort_dirty, true, sizeof(_ship_sort_dirty)); darkvater@243: memset(_road_sort_dirty, true, sizeof(_road_sort_dirty)); darkvater@243: memset(_vehicle_sort_dirty, true, sizeof(_vehicle_sort_dirty)); darkvater@164: } darkvater@164: darkvater@164: // draw the vehicle profit button in the vehicle list window. darkvater@164: void DrawVehicleProfitButton(Vehicle *v, int x, int y) darkvater@164: { darkvater@164: uint32 ormod; darkvater@164: darkvater@164: // draw profit-based colored icons darkvater@164: if(v->age <= 365 * 2) darkvater@164: ormod = 0x3158000; // grey darkvater@164: else if(v->profit_last_year < 0) darkvater@164: ormod = 0x30b8000; //red darkvater@164: else if(v->profit_last_year < 10000) darkvater@164: ormod = 0x30a8000; // yellow darkvater@164: else darkvater@164: ormod = 0x30d8000; // green darkvater@164: DrawSprite((SPR_OPENTTD_BASE + 10) | ormod, x, y); darkvater@164: } darkvater@164: darkvater@164: /************ Sorter functions *****************/ darkvater@164: int CDECL GeneralOwnerSorter(const void *a, const void *b) darkvater@164: { darkvater@168: return (*(const SortStruct*)a).owner - (*(const SortStruct*)b).owner; darkvater@168: } darkvater@168: darkvater@168: /* Variables you need to set before calling this function! darkvater@168: * 1. (byte)_internal_sort_type: sorting criteria to sort on darkvater@168: * 2. (bool)_internal_sort_order: sorting order, descending/ascending darkvater@168: * 3. (uint32)_internal_name_sorter_id: default StringID of the vehicle when no name is set. eg darkvater@168: * STR_SV_TRAIN_NAME for trains or STR_SV_AIRCRAFT_NAME for aircraft darkvater@168: */ darkvater@168: int CDECL VehicleUnsortedSorter(const void *a, const void *b) darkvater@168: { darkvater@168: return DEREF_VEHICLE((*(const SortStruct*)a).index)->index - DEREF_VEHICLE((*(const SortStruct*)b).index)->index; darkvater@168: } darkvater@168: darkvater@243: // if the sorting criteria had the same value, sort vehicle by unitnumber darkvater@243: #define VEHICLEUNITNUMBERSORTER(r, a, b) {if (r == 0) {r = a->unitnumber - b->unitnumber;}} darkvater@243: darkvater@168: int CDECL VehicleNumberSorter(const void *a, const void *b) darkvater@168: { darkvater@168: const Vehicle *va = DEREF_VEHICLE((*(const SortStruct*)a).index); darkvater@168: const Vehicle *vb = DEREF_VEHICLE((*(const SortStruct*)b).index); darkvater@168: int r = va->unitnumber - vb->unitnumber; darkvater@168: darkvater@168: return (_internal_sort_order & 1) ? -r : r; darkvater@164: } darkvater@164: darkvater@164: static char _bufcache[64]; // used together with _last_vehicle_idx to hopefully speed up stringsorting darkvater@164: int CDECL VehicleNameSorter(const void *a, const void *b) darkvater@164: { darkvater@171: const SortStruct *cmp1 = (const SortStruct*)a; darkvater@171: const SortStruct *cmp2 = (const SortStruct*)b; darkvater@168: const Vehicle *va = DEREF_VEHICLE(cmp1->index); darkvater@168: const Vehicle *vb = DEREF_VEHICLE(cmp2->index); darkvater@164: char buf1[64] = "\0"; darkvater@164: int r; darkvater@164: darkvater@168: if (va->string_id != _internal_name_sorter_id) { darkvater@168: SET_DPARAM16(0, va->string_id); darkvater@164: GetString(buf1, STR_0315); darkvater@164: } darkvater@164: darkvater@164: if ( cmp2->index != _last_vehicle_idx) { darkvater@164: _last_vehicle_idx = cmp2->index; darkvater@164: _bufcache[0] = '\0'; darkvater@168: if (vb->string_id != _internal_name_sorter_id) { darkvater@168: SET_DPARAM16(0, vb->string_id); darkvater@164: GetString(_bufcache, STR_0315); darkvater@164: } darkvater@164: } darkvater@164: darkvater@164: r = strcmp(buf1, _bufcache); // sort by name truelight@193: darkvater@243: VEHICLEUNITNUMBERSORTER(r, va, vb); darkvater@168: darkvater@168: return (_internal_sort_order & 1) ? -r : r; darkvater@164: } darkvater@164: darkvater@168: int CDECL VehicleAgeSorter(const void *a, const void *b) darkvater@164: { darkvater@168: const Vehicle *va = DEREF_VEHICLE((*(const SortStruct*)a).index); darkvater@168: const Vehicle *vb = DEREF_VEHICLE((*(const SortStruct*)b).index); darkvater@168: int r = va->age - vb->age; darkvater@164: darkvater@243: VEHICLEUNITNUMBERSORTER(r, va, vb); darkvater@168: darkvater@168: return (_internal_sort_order & 1) ? -r : r; darkvater@168: } darkvater@168: darkvater@168: int CDECL VehicleProfitThisYearSorter(const void *a, const void *b) darkvater@168: { darkvater@168: const Vehicle *va = DEREF_VEHICLE((*(const SortStruct*)a).index); darkvater@168: const Vehicle *vb = DEREF_VEHICLE((*(const SortStruct*)b).index); darkvater@168: int r = va->profit_this_year - vb->profit_this_year; truelight@193: darkvater@243: VEHICLEUNITNUMBERSORTER(r, va, vb); darkvater@168: darkvater@168: return (_internal_sort_order & 1) ? -r : r; darkvater@168: } darkvater@168: darkvater@168: int CDECL VehicleProfitLastYearSorter(const void *a, const void *b) darkvater@168: { darkvater@168: const Vehicle *va = DEREF_VEHICLE((*(const SortStruct*)a).index); darkvater@168: const Vehicle *vb = DEREF_VEHICLE((*(const SortStruct*)b).index); darkvater@168: int r = va->profit_last_year - vb->profit_last_year; darkvater@168: darkvater@243: VEHICLEUNITNUMBERSORTER(r, va, vb); darkvater@168: darkvater@168: return (_internal_sort_order & 1) ? -r : r; darkvater@168: } darkvater@168: darkvater@168: int CDECL VehicleCargoSorter(const void *a, const void *b) darkvater@168: { darkvater@168: // FIXME - someone write a normal cargo sorter that also works by cargo_cap, darkvater@168: // FIXME - since I seem to be unable to do so :S darkvater@168: const Vehicle *va = DEREF_VEHICLE((*(const SortStruct*)a).index); darkvater@168: const Vehicle *vb = DEREF_VEHICLE((*(const SortStruct*)b).index); darkvater@168: int r = 0; darkvater@168: int i; darkvater@168: byte _cargo_counta[NUM_CARGO]; darkvater@168: byte _cargo_countb[NUM_CARGO]; darkvater@168: memset(_cargo_counta, 0, sizeof(_cargo_counta)); darkvater@168: memset(_cargo_countb, 0, sizeof(_cargo_countb)); darkvater@168: darkvater@168: do { darkvater@168: _cargo_counta[va->cargo_type]++; darkvater@168: } while ( (va = va->next) != NULL); darkvater@168: darkvater@168: do { darkvater@168: _cargo_countb[vb->cargo_type]++; darkvater@168: } while ( (vb = vb->next) != NULL); darkvater@168: darkvater@168: for (i = 0; i < NUM_CARGO; i++) { darkvater@168: r = _cargo_counta[i] - _cargo_countb[i]; darkvater@168: if (r != 0) darkvater@164: break; darkvater@168: } darkvater@164: darkvater@168: return (_internal_sort_order & 1) ? -r : r; darkvater@164: } darkvater@168: darkvater@168: int CDECL VehicleReliabilitySorter(const void *a, const void *b) darkvater@168: { darkvater@168: const Vehicle *va = DEREF_VEHICLE((*(const SortStruct*)a).index); darkvater@168: const Vehicle *vb = DEREF_VEHICLE((*(const SortStruct*)b).index); darkvater@168: int r = va->reliability - vb->reliability; darkvater@168: darkvater@243: VEHICLEUNITNUMBERSORTER(r, va, vb); darkvater@168: darkvater@168: return (_internal_sort_order & 1) ? -r : r; darkvater@168: } darkvater@168: darkvater@168: int CDECL VehicleMaxSpeedSorter(const void *a, const void *b) darkvater@168: { darkvater@168: const Vehicle *va = DEREF_VEHICLE((*(const SortStruct*)a).index); darkvater@168: const Vehicle *vb = DEREF_VEHICLE((*(const SortStruct*)b).index); darkvater@168: int r = va->max_speed - vb->max_speed; darkvater@168: darkvater@243: VEHICLEUNITNUMBERSORTER(r, va, vb); darkvater@168: darkvater@168: return (_internal_sort_order & 1) ? -r : r; truelight@193: }