224 * We want power/running cost, but since we usually got higher running cost than power and we store the result in an int, |
224 * We want power/running cost, but since we usually got higher running cost than power and we store the result in an int, |
225 * we will actually calculate cunning cost/power (to make it more than 1). |
225 * we will actually calculate cunning cost/power (to make it more than 1). |
226 * Because of this, the return value have to be reversed as well and we return b - a instead of a - b. |
226 * Because of this, the return value have to be reversed as well and we return b - a instead of a - b. |
227 * Another thing is that both power and running costs should be doubled for multiheaded engines. |
227 * Another thing is that both power and running costs should be doubled for multiheaded engines. |
228 * Since it would be multipling with 2 in both numerator and denumerator, it will even themselves out and we skip checking for multiheaded. */ |
228 * Since it would be multipling with 2 in both numerator and denumerator, it will even themselves out and we skip checking for multiheaded. */ |
229 Money va = (rvi_a->running_cost_base * _price.running_rail[rvi_a->running_cost_class]) / max((uint16)1, rvi_a->power); |
229 Money va = (rvi_a->running_cost_base * _price.running_rail[rvi_a->running_cost_class]) / max(1U, (uint)rvi_a->power); |
230 Money vb = (rvi_b->running_cost_base * _price.running_rail[rvi_b->running_cost_class]) / max((uint16)1, rvi_b->power); |
230 Money vb = (rvi_b->running_cost_base * _price.running_rail[rvi_b->running_cost_class]) / max(1U, (uint)rvi_b->power); |
231 int r = ClampToI32(vb - va); |
231 int r = ClampToI32(vb - va); |
232 |
232 |
233 return _internal_sort_order ? -r : r; |
233 return _internal_sort_order ? -r : r; |
234 } |
234 } |
235 |
235 |
435 /* Draw rail wagon specific details */ |
435 /* Draw rail wagon specific details */ |
436 static int DrawRailWagonPurchaseInfo(int x, int y, EngineID engine_number, const RailVehicleInfo *rvi) |
436 static int DrawRailWagonPurchaseInfo(int x, int y, EngineID engine_number, const RailVehicleInfo *rvi) |
437 { |
437 { |
438 /* Purchase cost */ |
438 /* Purchase cost */ |
439 SetDParam(0, (GetEngineProperty(engine_number, 0x17, rvi->base_cost) * _price.build_railwagon) >> 8); |
439 SetDParam(0, (GetEngineProperty(engine_number, 0x17, rvi->base_cost) * _price.build_railwagon) >> 8); |
440 DrawString(x, y, STR_PURCHASE_INFO_COST, 0); |
440 DrawString(x, y, STR_PURCHASE_INFO_COST, TC_FROMSTRING); |
441 y += 10; |
441 y += 10; |
442 |
442 |
443 /* Wagon weight - (including cargo) */ |
443 /* Wagon weight - (including cargo) */ |
444 uint weight = GetEngineProperty(engine_number, 0x16, rvi->weight); |
444 uint weight = GetEngineProperty(engine_number, 0x16, rvi->weight); |
445 SetDParam(0, weight); |
445 SetDParam(0, weight); |
446 SetDParam(1, (GetCargo(rvi->cargo_type)->weight * GetEngineProperty(engine_number, 0x14, rvi->capacity) >> 4) + weight); |
446 SetDParam(1, (GetCargo(rvi->cargo_type)->weight * GetEngineProperty(engine_number, 0x14, rvi->capacity) >> 4) + weight); |
447 DrawString(x, y, STR_PURCHASE_INFO_WEIGHT_CWEIGHT, 0); |
447 DrawString(x, y, STR_PURCHASE_INFO_WEIGHT_CWEIGHT, TC_FROMSTRING); |
448 y += 10; |
448 y += 10; |
449 |
449 |
450 /* Wagon speed limit, displayed if above zero */ |
450 /* Wagon speed limit, displayed if above zero */ |
451 if (_patches.wagon_speed_limits) { |
451 if (_patches.wagon_speed_limits) { |
452 uint max_speed = GetEngineProperty(engine_number, 0x09, rvi->max_speed); |
452 uint max_speed = GetEngineProperty(engine_number, 0x09, rvi->max_speed); |
453 if (max_speed > 0) { |
453 if (max_speed > 0) { |
454 SetDParam(0, max_speed * 10 / 16); |
454 SetDParam(0, max_speed * 10 / 16); |
455 DrawString(x, y, STR_PURCHASE_INFO_SPEED, 0); |
455 DrawString(x, y, STR_PURCHASE_INFO_SPEED, TC_FROMSTRING); |
456 y += 10; |
456 y += 10; |
457 } |
457 } |
458 } |
458 } |
459 return y; |
459 return y; |
460 } |
460 } |
466 uint weight = GetEngineProperty(engine_number, 0x16, rvi->weight); |
466 uint weight = GetEngineProperty(engine_number, 0x16, rvi->weight); |
467 |
467 |
468 /* Purchase Cost - Engine weight */ |
468 /* Purchase Cost - Engine weight */ |
469 SetDParam(0, GetEngineProperty(engine_number, 0x17, rvi->base_cost) * (_price.build_railvehicle >> 3) >> 5); |
469 SetDParam(0, GetEngineProperty(engine_number, 0x17, rvi->base_cost) * (_price.build_railvehicle >> 3) >> 5); |
470 SetDParam(1, weight << multihead); |
470 SetDParam(1, weight << multihead); |
471 DrawString(x, y, STR_PURCHASE_INFO_COST_WEIGHT, 0); |
471 DrawString(x, y, STR_PURCHASE_INFO_COST_WEIGHT, TC_FROMSTRING); |
472 y += 10; |
472 y += 10; |
473 |
473 |
474 /* Max speed - Engine power */ |
474 /* Max speed - Engine power */ |
475 SetDParam(0, GetEngineProperty(engine_number, 0x09, rvi->max_speed) * 10 / 16); |
475 SetDParam(0, GetEngineProperty(engine_number, 0x09, rvi->max_speed) * 10 / 16); |
476 SetDParam(1, GetEngineProperty(engine_number, 0x0B, rvi->power) << multihead); |
476 SetDParam(1, GetEngineProperty(engine_number, 0x0B, rvi->power) << multihead); |
477 DrawString(x, y, STR_PURCHASE_INFO_SPEED_POWER, 0); |
477 DrawString(x, y, STR_PURCHASE_INFO_SPEED_POWER, TC_FROMSTRING); |
478 y += 10; |
478 y += 10; |
479 |
479 |
480 /* Max tractive effort - not applicable if old acceleration or maglev */ |
480 /* Max tractive effort - not applicable if old acceleration or maglev */ |
481 if (_patches.realistic_acceleration && rvi->railtype != RAILTYPE_MAGLEV) { |
481 if (_patches.realistic_acceleration && rvi->railtype != RAILTYPE_MAGLEV) { |
482 SetDParam(0, ((weight << multihead) * 10 * GetEngineProperty(engine_number, 0x1F, rvi->tractive_effort)) / 256); |
482 SetDParam(0, ((weight << multihead) * 10 * GetEngineProperty(engine_number, 0x1F, rvi->tractive_effort)) / 256); |
483 DrawString(x, y, STR_PURCHASE_INFO_MAX_TE, 0); |
483 DrawString(x, y, STR_PURCHASE_INFO_MAX_TE, TC_FROMSTRING); |
484 y += 10; |
484 y += 10; |
485 } |
485 } |
486 |
486 |
487 /* Running cost */ |
487 /* Running cost */ |
488 SetDParam(0, (GetEngineProperty(engine_number, 0x0D, rvi->running_cost_base) * _price.running_rail[rvi->running_cost_class] >> 8) << multihead); |
488 SetDParam(0, (GetEngineProperty(engine_number, 0x0D, rvi->running_cost_base) * _price.running_rail[rvi->running_cost_class] >> 8) << multihead); |
489 DrawString(x, y, STR_PURCHASE_INFO_RUNNINGCOST, 0); |
489 DrawString(x, y, STR_PURCHASE_INFO_RUNNINGCOST, TC_FROMSTRING); |
490 y += 10; |
490 y += 10; |
491 |
491 |
492 /* Powered wagons power - Powered wagons extra weight */ |
492 /* Powered wagons power - Powered wagons extra weight */ |
493 if (rvi->pow_wag_power != 0) { |
493 if (rvi->pow_wag_power != 0) { |
494 SetDParam(0, rvi->pow_wag_power); |
494 SetDParam(0, rvi->pow_wag_power); |
495 SetDParam(1, rvi->pow_wag_weight); |
495 SetDParam(1, rvi->pow_wag_weight); |
496 DrawString(x, y, STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT, 0); |
496 DrawString(x, y, STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT, TC_FROMSTRING); |
497 y += 10; |
497 y += 10; |
498 }; |
498 }; |
499 |
499 |
500 return y; |
500 return y; |
501 } |
501 } |
506 bool refittable = (EngInfo(engine_number)->refit_mask != 0); |
506 bool refittable = (EngInfo(engine_number)->refit_mask != 0); |
507 |
507 |
508 /* Purchase cost - Max speed */ |
508 /* Purchase cost - Max speed */ |
509 SetDParam(0, GetEngineProperty(engine_number, 0x11, rvi->base_cost) * (_price.roadveh_base >> 3) >> 5); |
509 SetDParam(0, GetEngineProperty(engine_number, 0x11, rvi->base_cost) * (_price.roadveh_base >> 3) >> 5); |
510 SetDParam(1, rvi->max_speed * 10 / 32); |
510 SetDParam(1, rvi->max_speed * 10 / 32); |
511 DrawString(x, y, STR_PURCHASE_INFO_COST_SPEED, 0); |
511 DrawString(x, y, STR_PURCHASE_INFO_COST_SPEED, TC_FROMSTRING); |
512 y += 10; |
512 y += 10; |
513 |
513 |
514 /* Running cost */ |
514 /* Running cost */ |
515 SetDParam(0, rvi->running_cost * _price.roadveh_running >> 8); |
515 SetDParam(0, rvi->running_cost * _price.roadveh_running >> 8); |
516 DrawString(x, y, STR_PURCHASE_INFO_RUNNINGCOST, 0); |
516 DrawString(x, y, STR_PURCHASE_INFO_RUNNINGCOST, TC_FROMSTRING); |
517 y += 10; |
517 y += 10; |
518 |
518 |
519 /* Cargo type + capacity */ |
519 /* Cargo type + capacity */ |
520 SetDParam(0, rvi->cargo_type); |
520 SetDParam(0, rvi->cargo_type); |
521 SetDParam(1, GetEngineProperty(engine_number, 0x0F, rvi->capacity)); |
521 SetDParam(1, GetEngineProperty(engine_number, 0x0F, rvi->capacity)); |
522 SetDParam(2, refittable ? STR_9842_REFITTABLE : STR_EMPTY); |
522 SetDParam(2, refittable ? STR_9842_REFITTABLE : STR_EMPTY); |
523 DrawString(x, y, STR_PURCHASE_INFO_CAPACITY, 0); |
523 DrawString(x, y, STR_PURCHASE_INFO_CAPACITY, TC_FROMSTRING); |
524 y += 10; |
524 y += 10; |
525 |
525 |
526 return y; |
526 return y; |
527 } |
527 } |
528 |
528 |
530 static int DrawShipPurchaseInfo(int x, int y, EngineID engine_number, const ShipVehicleInfo *svi) |
530 static int DrawShipPurchaseInfo(int x, int y, EngineID engine_number, const ShipVehicleInfo *svi) |
531 { |
531 { |
532 /* Purchase cost - Max speed */ |
532 /* Purchase cost - Max speed */ |
533 SetDParam(0, GetEngineProperty(engine_number, 0x0A, svi->base_cost) * (_price.ship_base >> 3) >> 5); |
533 SetDParam(0, GetEngineProperty(engine_number, 0x0A, svi->base_cost) * (_price.ship_base >> 3) >> 5); |
534 SetDParam(1, GetEngineProperty(engine_number, 0x0B, svi->max_speed) * 10 / 32); |
534 SetDParam(1, GetEngineProperty(engine_number, 0x0B, svi->max_speed) * 10 / 32); |
535 DrawString(x, y, STR_PURCHASE_INFO_COST_SPEED, 0); |
535 DrawString(x, y, STR_PURCHASE_INFO_COST_SPEED, TC_FROMSTRING); |
536 y += 10; |
536 y += 10; |
537 |
537 |
538 /* Cargo type + capacity */ |
538 /* Cargo type + capacity */ |
539 SetDParam(0, svi->cargo_type); |
539 SetDParam(0, svi->cargo_type); |
540 SetDParam(1, GetEngineProperty(engine_number, 0x0D, svi->capacity)); |
540 SetDParam(1, GetEngineProperty(engine_number, 0x0D, svi->capacity)); |
541 SetDParam(2, svi->refittable ? STR_9842_REFITTABLE : STR_EMPTY); |
541 SetDParam(2, svi->refittable ? STR_9842_REFITTABLE : STR_EMPTY); |
542 DrawString(x, y, STR_PURCHASE_INFO_CAPACITY, 0); |
542 DrawString(x, y, STR_PURCHASE_INFO_CAPACITY, TC_FROMSTRING); |
543 y += 10; |
543 y += 10; |
544 |
544 |
545 /* Running cost */ |
545 /* Running cost */ |
546 SetDParam(0, GetEngineProperty(engine_number, 0x0F, svi->running_cost) * _price.ship_running >> 8); |
546 SetDParam(0, GetEngineProperty(engine_number, 0x0F, svi->running_cost) * _price.ship_running >> 8); |
547 DrawString(x, y, STR_PURCHASE_INFO_RUNNINGCOST, 0); |
547 DrawString(x, y, STR_PURCHASE_INFO_RUNNINGCOST, TC_FROMSTRING); |
548 y += 10; |
548 y += 10; |
549 |
549 |
550 return y; |
550 return y; |
551 } |
551 } |
552 |
552 |
556 CargoID cargo; |
556 CargoID cargo; |
557 |
557 |
558 /* Purchase cost - Max speed */ |
558 /* Purchase cost - Max speed */ |
559 SetDParam(0, GetEngineProperty(engine_number, 0x0B, avi->base_cost) * (_price.aircraft_base >> 3) >> 5); |
559 SetDParam(0, GetEngineProperty(engine_number, 0x0B, avi->base_cost) * (_price.aircraft_base >> 3) >> 5); |
560 SetDParam(1, avi->max_speed * 10 / 16); |
560 SetDParam(1, avi->max_speed * 10 / 16); |
561 DrawString(x, y, STR_PURCHASE_INFO_COST_SPEED, 0); |
561 DrawString(x, y, STR_PURCHASE_INFO_COST_SPEED, TC_FROMSTRING); |
562 y += 10; |
562 y += 10; |
563 |
563 |
564 /* Cargo capacity */ |
564 /* Cargo capacity */ |
565 cargo = FindFirstRefittableCargo(engine_number); |
565 cargo = FindFirstRefittableCargo(engine_number); |
566 if (cargo == CT_INVALID || cargo == CT_PASSENGERS) { |
566 if (cargo == CT_INVALID || cargo == CT_PASSENGERS) { |
567 SetDParam(0, avi->passenger_capacity); |
567 SetDParam(0, avi->passenger_capacity); |
568 SetDParam(1, avi->mail_capacity); |
568 SetDParam(1, avi->mail_capacity); |
569 DrawString(x, y, STR_PURCHASE_INFO_AIRCRAFT_CAPACITY, 0); |
569 DrawString(x, y, STR_PURCHASE_INFO_AIRCRAFT_CAPACITY, TC_FROMSTRING); |
570 } else { |
570 } else { |
571 /* Note, if the default capacity is selected by the refit capacity |
571 /* Note, if the default capacity is selected by the refit capacity |
572 * callback, then the capacity shown is likely to be incorrect. */ |
572 * callback, then the capacity shown is likely to be incorrect. */ |
573 SetDParam(0, cargo); |
573 SetDParam(0, cargo); |
574 SetDParam(1, AircraftDefaultCargoCapacity(cargo, avi)); |
574 SetDParam(1, AircraftDefaultCargoCapacity(cargo, avi)); |
575 SetDParam(2, STR_9842_REFITTABLE); |
575 SetDParam(2, STR_9842_REFITTABLE); |
576 DrawString(x, y, STR_PURCHASE_INFO_CAPACITY, 0); |
576 DrawString(x, y, STR_PURCHASE_INFO_CAPACITY, TC_FROMSTRING); |
577 } |
577 } |
578 y += 10; |
578 y += 10; |
579 |
579 |
580 /* Running cost */ |
580 /* Running cost */ |
581 SetDParam(0, GetEngineProperty(engine_number, 0x0E, avi->running_cost) * _price.aircraft_running >> 8); |
581 SetDParam(0, GetEngineProperty(engine_number, 0x0E, avi->running_cost) * _price.aircraft_running >> 8); |
582 DrawString(x, y, STR_PURCHASE_INFO_RUNNINGCOST, 0); |
582 DrawString(x, y, STR_PURCHASE_INFO_RUNNINGCOST, TC_FROMSTRING); |
583 y += 10; |
583 y += 10; |
584 |
584 |
585 return y; |
585 return y; |
586 } |
586 } |
587 |
587 |
622 |
622 |
623 SetDParam(0, rvi->cargo_type); |
623 SetDParam(0, rvi->cargo_type); |
624 SetDParam(1, (capacity * (CountArticulatedParts(engine_number, true) + 1)) << multihead); |
624 SetDParam(1, (capacity * (CountArticulatedParts(engine_number, true) + 1)) << multihead); |
625 SetDParam(2, refitable ? STR_9842_REFITTABLE : STR_EMPTY); |
625 SetDParam(2, refitable ? STR_9842_REFITTABLE : STR_EMPTY); |
626 } |
626 } |
627 DrawString(x, y, STR_PURCHASE_INFO_CAPACITY, 0); |
627 DrawString(x, y, STR_PURCHASE_INFO_CAPACITY, TC_FROMSTRING); |
628 y += 10; |
628 y += 10; |
629 } |
629 } |
630 break; |
630 break; |
631 case VEH_ROAD: |
631 case VEH_ROAD: |
632 y = DrawRoadVehPurchaseInfo(x, y, engine_number, RoadVehInfo(engine_number)); |
632 y = DrawRoadVehPurchaseInfo(x, y, engine_number, RoadVehInfo(engine_number)); |
646 /* Draw details, that applies to all types except rail wagons */ |
646 /* Draw details, that applies to all types except rail wagons */ |
647 if (e->type != VEH_TRAIN || RailVehInfo(engine_number)->railveh_type != RAILVEH_WAGON) { |
647 if (e->type != VEH_TRAIN || RailVehInfo(engine_number)->railveh_type != RAILVEH_WAGON) { |
648 /* Design date - Life length */ |
648 /* Design date - Life length */ |
649 SetDParam(0, ymd.year); |
649 SetDParam(0, ymd.year); |
650 SetDParam(1, e->lifelength); |
650 SetDParam(1, e->lifelength); |
651 DrawString(x, y, STR_PURCHASE_INFO_DESIGNED_LIFE, 0); |
651 DrawString(x, y, STR_PURCHASE_INFO_DESIGNED_LIFE, TC_FROMSTRING); |
652 y += 10; |
652 y += 10; |
653 |
653 |
654 /* Reliability */ |
654 /* Reliability */ |
655 SetDParam(0, e->reliability * 100 >> 16); |
655 SetDParam(0, e->reliability * 100 >> 16); |
656 DrawString(x, y, STR_PURCHASE_INFO_RELIABILITY, 0); |
656 DrawString(x, y, STR_PURCHASE_INFO_RELIABILITY, TC_FROMSTRING); |
657 y += 10; |
657 y += 10; |
658 } |
658 } |
659 |
659 |
660 /* Additional text from NewGRF */ |
660 /* Additional text from NewGRF */ |
661 y += ShowAdditionalText(x, y, w, engine_number); |
661 y += ShowAdditionalText(x, y, w, engine_number); |
720 |
720 |
721 sel_id = INVALID_ENGINE; |
721 sel_id = INVALID_ENGINE; |
722 |
722 |
723 for (eid = ROAD_ENGINES_INDEX; eid < ROAD_ENGINES_INDEX + NUM_ROAD_ENGINES; eid++) { |
723 for (eid = ROAD_ENGINES_INDEX; eid < ROAD_ENGINES_INDEX + NUM_ROAD_ENGINES; eid++) { |
724 if (!IsEngineBuildable(eid, VEH_ROAD, _local_player)) continue; |
724 if (!IsEngineBuildable(eid, VEH_ROAD, _local_player)) continue; |
725 if (!HASBIT(bv->filter.roadtypes, HASBIT(EngInfo(eid)->misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD)) continue; |
725 if (!HasBit(bv->filter.roadtypes, HasBit(EngInfo(eid)->misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD)) continue; |
726 EngList_Add(&bv->eng_list, eid); |
726 EngList_Add(&bv->eng_list, eid); |
727 |
727 |
728 if (eid == bv->sel_engine) sel_id = eid; |
728 if (eid == bv->sel_engine) sel_id = eid; |
729 } |
729 } |
730 bv->sel_engine = sel_id; |
730 bv->sel_engine = sel_id; |
855 const EngineID engine = eng_list[min]; |
855 const EngineID engine = eng_list[min]; |
856 /* Note: num_engines is only used in the autoreplace GUI, so it is correct to use _local_player here. */ |
856 /* Note: num_engines is only used in the autoreplace GUI, so it is correct to use _local_player here. */ |
857 const uint num_engines = GetGroupNumEngines(_local_player, selected_group, engine); |
857 const uint num_engines = GetGroupNumEngines(_local_player, selected_group, engine); |
858 |
858 |
859 SetDParam(0, engine); |
859 SetDParam(0, engine); |
860 DrawString(x + x_offset, y, STR_ENGINE_NAME, engine == selected_id ? 0xC : 0x10); |
860 DrawString(x + x_offset, y, STR_ENGINE_NAME, engine == selected_id ? TC_WHITE : TC_BLACK); |
861 DrawVehicleEngine(type, x, y + y_offset, engine, (show_count && num_engines == 0) ? PALETTE_CRASH : GetEnginePalette(engine, _local_player)); |
861 DrawVehicleEngine(type, x, y + y_offset, engine, (show_count && num_engines == 0) ? PALETTE_CRASH : GetEnginePalette(engine, _local_player)); |
862 if (show_count) { |
862 if (show_count) { |
863 SetDParam(0, num_engines); |
863 SetDParam(0, num_engines); |
864 DrawStringRightAligned(213, y + (GetVehicleListHeight(type) == 14 ? 3 : 8), STR_TINY_BLACK, 0); |
864 DrawStringRightAligned(213, y + (GetVehicleListHeight(type) == 14 ? 3 : 8), STR_TINY_BLACK, TC_FROMSTRING); |
865 } |
865 } |
866 } |
866 } |
867 } |
867 } |
868 |
868 |
869 static void ExpandPurchaseInfoWidget(Window *w, int expand_by) |
869 static void ExpandPurchaseInfoWidget(Window *w, int expand_by) |
901 int text_end = DrawVehiclePurchaseInfo(2, wi->top + 1, wi->right - wi->left - 2, bv->sel_engine); |
901 int text_end = DrawVehiclePurchaseInfo(2, wi->top + 1, wi->right - wi->left - 2, bv->sel_engine); |
902 |
902 |
903 if (text_end > wi->bottom) ExpandPurchaseInfoWidget(w, text_end - wi->bottom); |
903 if (text_end > wi->bottom) ExpandPurchaseInfoWidget(w, text_end - wi->bottom); |
904 } |
904 } |
905 |
905 |
906 DrawString(85, 15, _sort_listing[bv->vehicle_type][bv->sort_criteria], 0x10); |
906 DrawString(85, 15, _sort_listing[bv->vehicle_type][bv->sort_criteria], TC_BLACK); |
907 DoDrawString(bv->descending_sort_order ? DOWNARROW : UPARROW, 69, 15, 0x10); |
907 DoDrawString(bv->descending_sort_order ? DOWNARROW : UPARROW, 69, 15, TC_BLACK); |
908 } |
908 } |
909 |
909 |
910 static void BuildVehicleClickEvent(Window *w, WindowEvent *e) |
910 static void BuildVehicleClickEvent(Window *w, WindowEvent *e) |
911 { |
911 { |
912 buildvehicle_d *bv = &WP(w, buildvehicle_d); |
912 buildvehicle_d *bv = &WP(w, buildvehicle_d); |