tron@2186: /* $Id$ */ tron@2186: belugas@6918: /** @file train_gui.cpp */ belugas@6918: truelight@0: #include "stdafx.h" Darkvater@1891: #include "openttd.h" tron@1299: #include "debug.h" truelight@0: #include "gui.h" rubidium@8603: #include "window_gui.h" rubidium@8720: #include "gfx_func.h" rubidium@8612: #include "command_func.h" tron@588: #include "vehicle_gui.h" truelight@1313: #include "depot.h" bjarni@2676: #include "train.h" peter1138@2962: #include "newgrf_engine.h" rubidium@8610: #include "strings_func.h" rubidium@8640: #include "vehicle_func.h" rubidium@8707: #include "settings_type.h" truelight@0: rubidium@8760: #include "table/sprites.h" rubidium@8760: #include "table/strings.h" rubidium@8760: tron@1977: void CcBuildWagon(bool success, TileIndex tile, uint32 p1, uint32 p2) truelight@0: { belugas@4171: Vehicle *v, *found; truelight@0: tron@4077: if (!success) return; truelight@0: belugas@6918: /* find a locomotive in the depot. */ truelight@0: found = NULL; truelight@0: FOR_ALL_VEHICLES(v) { rubidium@6585: if (v->type == VEH_TRAIN && IsFrontEngine(v) && truelight@0: v->tile == tile && rubidium@6319: v->u.rail.track == TRACK_BIT_DEPOT) { tron@4077: if (found != NULL) return; // must be exactly one. truelight@0: found = v; truelight@0: } truelight@0: } truelight@0: belugas@6918: /* if we found a loco, */ truelight@0: if (found != NULL) { truelight@0: found = GetLastVehicleInChain(found); belugas@6918: /* put the new wagon at the end of the loco. */ tron@3948: DoCommandP(0, _new_vehicle_id | (found->index << 16), 0, NULL, CMD_MOVE_RAIL_VEHICLE); tron@588: RebuildVehicleLists(); truelight@0: } truelight@0: } truelight@0: tron@1977: void CcBuildLoco(bool success, TileIndex tile, uint32 p1, uint32 p2) truelight@0: { belugas@4171: const Vehicle *v; truelight@0: tron@2639: if (!success) return; truelight@193: tron@3948: v = GetVehicle(_new_vehicle_id); truelight@0: if (tile == _backup_orders_tile) { truelight@0: _backup_orders_tile = 0; rubidium@8149: RestoreVehicleOrders(v); truelight@0: } rubidium@7982: ShowVehicleViewWindow(v); truelight@0: } truelight@0: peter1138@2593: /** peter1138@2593: * Get the number of pixels for the given wagon length. peter1138@2593: * @param len Length measured in 1/8ths of a standard wagon. peter1138@2593: * @return Number of pixels across. peter1138@2593: */ rubidium@7817: int WagonLengthToPixels(int len) rubidium@7817: { peter1138@3845: return (len * _traininfo_vehicle_width) / 8; peter1138@2593: } peter1138@2593: rubidium@8640: void DrawTrainImage(const Vehicle *v, int x, int y, VehicleID selection, int count, int skip) truelight@0: { peter1138@3919: DrawPixelInfo tmp_dpi, *old_dpi; peter1138@3919: int dx = -(skip * 8) / _traininfo_vehicle_width; peter1138@4049: /* Position of highlight box */ peter1138@4049: int highlight_l = 0; peter1138@4049: int highlight_r = 0; peter1138@3919: tron@4429: if (!FillDrawPixelInfo(&tmp_dpi, x - 2, y - 1, count + 1, 14)) return; peter1138@3919: peter1138@3919: count = (count * 8) / _traininfo_vehicle_width; peter1138@3919: peter1138@3919: old_dpi = _cur_dpi; peter1138@3919: _cur_dpi = &tmp_dpi; hackykid@1922: truelight@0: do { peter1138@3919: int width = v->u.rail.cached_veh_length; hackykid@1922: peter1138@3919: if (dx + width > 0) { peter1138@3919: if (dx <= count) { peter1138@5919: SpriteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v); rubidium@7630: DrawSprite(v->GetImage(DIR_W), pal, 16 + WagonLengthToPixels(dx), 7 + (is_custom_sprite(RailVehInfo(v->engine_type)->image_index) ? _traininfo_vehicle_pitch : 0)); peter1138@4049: if (v->index == selection) { peter1138@4049: /* Set the highlight position */ peter1138@4049: highlight_l = WagonLengthToPixels(dx) + 1; peter1138@4049: highlight_r = WagonLengthToPixels(dx + width) + 1; peter1138@4049: } hackykid@1922: } truelight@0: } peter1138@3919: dx += width; truelight@0: rubidium@7988: v = v->Next(); peter1138@3919: } while (dx < count && v != NULL); peter1138@3919: peter1138@4049: if (highlight_l != highlight_r) { peter1138@4049: /* Draw the highlight. Now done after drawing all the engines, as peter1138@4049: * the next engine after the highlight could overlap it. */ peter1138@4049: DrawFrameRect(highlight_l, 0, highlight_r, 13, 15, FR_BORDERONLY); peter1138@4049: } peter1138@4049: peter1138@3919: _cur_dpi = old_dpi; truelight@0: } truelight@0: Darkvater@1790: static void TrainDetailsCargoTab(const Vehicle *v, int x, int y) truelight@0: { tron@4492: if (v->cargo_cap != 0) { tron@4492: StringID str = STR_8812_EMPTY; truelight@0: rubidium@7506: if (!v->cargo.Empty()) { tron@534: SetDParam(0, v->cargo_type); rubidium@7506: SetDParam(1, v->cargo.Count()); rubidium@7506: SetDParam(2, v->cargo.Source()); peter1138@5163: SetDParam(3, _patches.freight_trains); peter1138@5316: str = FreightWagonMult(v->cargo_type) > 1 ? STR_FROM_MULT : STR_8813_FROM; truelight@0: } belugas@8320: DrawString(x, y, str, TC_FROMSTRING); truelight@0: } truelight@0: } truelight@0: Darkvater@1790: static void TrainDetailsInfoTab(const Vehicle *v, int x, int y) truelight@0: { belugas@6119: if (RailVehInfo(v->engine_type)->railveh_type == RAILVEH_WAGON) { peter1138@7555: SetDParam(0, v->engine_type); rubidium@7498: SetDParam(1, v->value); belugas@8320: DrawString(x, y, STR_882D_VALUE, TC_BLACK); tron@4492: } else { peter1138@7555: SetDParam(0, v->engine_type); rubidium@4329: SetDParam(1, v->build_year); rubidium@7498: SetDParam(2, v->value); belugas@8320: DrawString(x, y, STR_882C_BUILT_VALUE, TC_BLACK); truelight@193: } truelight@0: } truelight@0: Darkvater@1790: static void TrainDetailsCapacityTab(const Vehicle *v, int x, int y) truelight@0: { truelight@0: if (v->cargo_cap != 0) { peter1138@4896: SetDParam(0, v->cargo_type); tron@534: SetDParam(1, v->cargo_cap); peter1138@5163: SetDParam(2, _patches.freight_trains); belugas@8320: DrawString(x, y, FreightWagonMult(v->cargo_type) > 1 ? STR_CAPACITY_MULT : STR_013F_CAPACITY, TC_FROMSTRING); truelight@0: } truelight@0: } truelight@0: rubidium@8026: int GetTrainDetailsWndVScroll(VehicleID veh_id, byte det_tab) truelight@0: { tron@4492: AcceptedCargo act_cargo; tron@4492: AcceptedCargo max_cargo; rubidium@8026: int num = 0; truelight@0: tron@4492: if (det_tab == 3) { // Total cargo tab rubidium@8026: memset(max_cargo, 0, sizeof(max_cargo)); rubidium@8026: memset(act_cargo, 0, sizeof(act_cargo)); rubidium@8026: rubidium@8026: for (const Vehicle *v = GetVehicle(veh_id) ; v != NULL ; v = v->Next()) { rubidium@8026: act_cargo[v->cargo_type] += v->cargo.Count(); rubidium@8026: max_cargo[v->cargo_type] += v->cargo_cap; truelight@0: } truelight@0: tron@4492: /* Set scroll-amount seperately from counting, as to not compute num double tron@4492: * for more carriages of the same type tron@4492: */ peter1138@6676: for (CargoID i = 0; i < NUM_CARGO; i++) { tron@4492: if (max_cargo[i] > 0) num++; // only count carriages that the train has truelight@0: } rubidium@4434: num++; // needs one more because first line is description string tron@4492: } else { rubidium@8026: for (const Vehicle *v = GetVehicle(veh_id) ; v != NULL ; v = v->Next()) { rubidium@8026: if (!IsArticulatedPart(v) || v->cargo_cap != 0) num++; rubidium@8026: } truelight@0: } truelight@0: rubidium@8026: return num; rubidium@8026: } truelight@0: rubidium@8026: void DrawTrainDetails(const Vehicle *v, int x, int y, int vscroll_pos, uint16 vscroll_cap, byte det_tab) rubidium@8026: { belugas@6918: /* draw the first 3 details tabs */ truelight@0: if (det_tab != 3) { rubidium@8026: const Vehicle *u = v; peter1138@2822: x = 1; tron@2952: for (;;) { rubidium@8026: if (--vscroll_pos < 0 && vscroll_pos >= -vscroll_cap) { peter1138@2602: int dx = 0; tron@4492: int px; tron@4492: int py; tron@4492: peter1138@2602: u = v; peter1138@2602: do { peter1138@5919: SpriteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v); rubidium@7630: DrawSprite(u->GetImage(DIR_W), pal, x + WagonLengthToPixels(4 + dx), y + 6 + (is_custom_sprite(RailVehInfo(u->engine_type)->image_index) ? _traininfo_vehicle_pitch : 0)); peter1138@2602: dx += u->u.rail.cached_veh_length; rubidium@7988: u = u->Next(); peter1138@4868: } while (u != NULL && IsArticulatedPart(u) && u->cargo_cap == 0); tron@4492: tron@4492: px = x + WagonLengthToPixels(dx) + 2; tron@4492: py = y + 2; tron@4492: switch (det_tab) { tron@4492: default: NOT_REACHED(); tron@4492: case 0: TrainDetailsCargoTab( v, px, py); break; peter1138@4868: case 1: belugas@6918: /* Only show name and value for the 'real' part */ peter1138@4868: if (!IsArticulatedPart(v)) { peter1138@4868: TrainDetailsInfoTab(v, px, py); peter1138@4868: } peter1138@4868: break; tron@4492: case 2: TrainDetailsCapacityTab(v, px, py); break; tron@4492: } truelight@0: y += 14; peter1138@4868: peter1138@4868: v = u; peter1138@4868: } else { belugas@6918: /* Move to the next line */ peter1138@4868: do { rubidium@7988: v = v->Next(); peter1138@4868: } while (v != NULL && IsArticulatedPart(v) && v->cargo_cap == 0); truelight@0: } tron@4492: if (v == NULL) return; truelight@0: } peter1138@2959: } else { rubidium@8026: AcceptedCargo act_cargo; rubidium@8026: AcceptedCargo max_cargo; rubidium@8026: rubidium@8026: memset(max_cargo, 0, sizeof(max_cargo)); rubidium@8026: memset(act_cargo, 0, sizeof(act_cargo)); rubidium@8026: rubidium@8026: for (const Vehicle *u = v; u != NULL ; u = u->Next()) { rubidium@8026: act_cargo[u->cargo_type] += u->cargo.Count(); rubidium@8026: max_cargo[u->cargo_type] += u->cargo_cap; rubidium@8026: } rubidium@8026: belugas@6918: /* draw total cargo tab */ maedhros@8920: DrawString(x, y + 2, STR_TOTAL_CAPACITY_TEXT, TC_FROMSTRING); peter1138@6676: for (CargoID i = 0; i < NUM_CARGO; i++) { rubidium@8026: if (max_cargo[i] > 0 && --vscroll_pos < 0 && vscroll_pos > -vscroll_cap) { truelight@0: y += 14; tron@4492: SetDParam(0, i); // {CARGO} #1 tron@4492: SetDParam(1, act_cargo[i]); // {CARGO} #2 tron@4492: SetDParam(2, i); // {SHORTCARGO} #1 tron@4492: SetDParam(3, max_cargo[i]); // {SHORTCARGO} #2 peter1138@5163: SetDParam(4, _patches.freight_trains); maedhros@8920: DrawString(x, y + 2, FreightWagonMult(i) > 1 ? STR_TOTAL_CAPACITY_MULT : STR_TOTAL_CAPACITY, TC_FROMSTRING); truelight@0: } peter1138@2959: } rubidium@7506: SetDParam(0, v->cargo.FeederShare()); belugas@8320: DrawString(x, y + 15, STR_FEEDER_CARGO_VALUE, TC_FROMSTRING); truelight@0: } truelight@0: }