# train_gui.cpp

Go to the documentation of this file.

    00001 /* $Id: train_gui.cpp 16835 2009-07-15 20:29:45Z rubidium $ */
    00002
    00005 #include "stdafx.h"
    00006 #include "window_gui.h"
    00007 #include "gfx_func.h"
    00008 #include "command_func.h"
    00009 #include "vehicle_gui.h"
    00010 #include "train.h"
    00011 #include "newgrf_engine.h"
    00012 #include "strings_func.h"
    00013 #include "vehicle_func.h"
    00014 #include "engine_base.h"
    00015 #include "window_func.h"
    00016 #include "settings_type.h"
    00017
    00018 #include "table/sprites.h"
    00019 #include "table/strings.h"
    00020
    00021 void CcBuildWagon(bool success, TileIndex tile, uint32 p1, uint32 p2)
    00022 {
    00023   if (!success) return;
    00024
    00025   /* find a locomotive in the depot. */
    00026   const Vehicle *found = NULL;
    00027   const Vehicle *v;
    00028   FOR_ALL_VEHICLES(v) {
    00029     if (v->type == VEH_TRAIN && IsFrontEngine(v) &&
    00030         v->tile == tile &&
    00031         v->u.rail.track == TRACK_BIT_DEPOT) {
    00032       if (found != NULL) return; // must be exactly one.
    00033       found = v;
    00034     }
    00035   }
    00036
    00037   /* if we found a loco, */
    00038   if (found != NULL) {
    00039     found = GetLastVehicleInChain(found);
    00040     /* put the new wagon at the end of the loco. */
    00041     DoCommandP(0, _new_vehicle_id | (found->index << 16), 0, CMD_MOVE_RAIL_VEHICLE);
    00042     InvalidateWindowClassesData(WC_TRAINS_LIST, 0);
    00043   }
    00044 }
    00045
    00046 void CcBuildLoco(bool success, TileIndex tile, uint32 p1, uint32 p2)
    00047 {
    00048   if (!success) return;
    00049
    00050   const Vehicle *v = GetVehicle(_new_vehicle_id);
    00051   if (tile == _backup_orders_tile) {
    00052     _backup_orders_tile = 0;
    00053     RestoreVehicleOrders(v);
    00054   }
    00055   ShowVehicleViewWindow(v);
    00056 }
    00057
    00063 int WagonLengthToPixels(int len)
    00064 {
    00065   return (len * _traininfo_vehicle_width) / 8;
    00066 }
    00067
    00068 void DrawTrainImage(const Vehicle *v, int x, int y, VehicleID selection, int count, int skip)
    00069 {
    00070   DrawPixelInfo tmp_dpi, *old_dpi;
    00071   int dx = -(skip * 8) / _traininfo_vehicle_width;
    00072   /* Position of highlight box */
    00073   int highlight_l = 0;
    00074   int highlight_r = 0;
    00075
    00076   if (!FillDrawPixelInfo(&tmp_dpi, x - 2, y - 1, count + 1, 14)) return;
    00077
    00078   count = (count * 8) / _traininfo_vehicle_width;
    00079
    00080   old_dpi = _cur_dpi;
    00081   _cur_dpi = &tmp_dpi;
    00082
    00083   do {
    00084     int width = v->u.rail.cached_veh_length;
    00085
    00086     if (dx + width > 0) {
    00087       if (dx <= count) {
    00088         SpriteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v);
    00089         DrawSprite(v->GetImage(DIR_W), pal, 16 + WagonLengthToPixels(dx), 7 + (is_custom_sprite(RailVehInfo(v->engine_type)->image_index) ? _traininfo_vehicle_pitch : 0));
    00090         if (v->index == selection) {
    00091           /* Set the highlight position */
    00092           highlight_l = WagonLengthToPixels(dx) + 1;
    00093           highlight_r = WagonLengthToPixels(dx + width) + 1;
    00094         } else if (_cursor.vehchain && highlight_r != 0) {
    00095           highlight_r += WagonLengthToPixels(width);
    00096         }
    00097       }
    00098     }
    00099     dx += width;
    00100
    00101     v = v->Next();
    00102   } while (dx < count && v != NULL);
    00103
    00104   if (highlight_l != highlight_r) {
    00105     /* Draw the highlight. Now done after drawing all the engines, as
    00106      * the next engine after the highlight could overlap it. */
    00107     DrawFrameRect(highlight_l, 0, highlight_r, 13, COLOUR_WHITE, FR_BORDERONLY);
    00108   }
    00109
    00110   _cur_dpi = old_dpi;
    00111 }
    00112
    00113 static void TrainDetailsCargoTab(const Vehicle *v, int x, int y)
    00114 {
    00115   if (v->cargo_cap != 0) {
    00116     StringID str = STR_8812_EMPTY;
    00117
    00118     if (!v->cargo.Empty()) {
    00119       SetDParam(0, v->cargo_type);
    00120       SetDParam(1, v->cargo.Count());
    00121       SetDParam(2, v->cargo.Source());
    00122       SetDParam(3, _settings_game.vehicle.freight_trains);
    00123       str = FreightWagonMult(v->cargo_type) > 1 ? STR_FROM_MULT : STR_8813_FROM;
    00124     }
    00125     DrawString(x, y, str, TC_FROMSTRING);
    00126   }
    00127 }
    00128
    00129 static void TrainDetailsInfoTab(const Vehicle *v, int x, int y)
    00130 {
    00131   if (RailVehInfo(v->engine_type)->railveh_type == RAILVEH_WAGON) {
    00132     SetDParam(0, v->engine_type);
    00133     SetDParam(1, v->value);
    00134     DrawString(x, y, STR_882D_VALUE, TC_BLACK);
    00135   } else {
    00136     SetDParam(0, v->engine_type);
    00137     SetDParam(1, v->build_year);
    00138     SetDParam(2, v->value);
    00139     DrawString(x, y, STR_882C_BUILT_VALUE, TC_BLACK);
    00140   }
    00141 }
    00142
    00143 static void TrainDetailsCapacityTab(const Vehicle *v, int x, int y)
    00144 {
    00145   if (v->cargo_cap != 0) {
    00146     SetDParam(0, v->cargo_type);
    00147     SetDParam(1, v->cargo_cap);
    00148     SetDParam(2, GetCargoSubtypeText(v));
    00149     SetDParam(3, _settings_game.vehicle.freight_trains);
    00150     DrawString(x, y, FreightWagonMult(v->cargo_type) > 1 ? STR_CAPACITY_MULT : STR_013F_CAPACITY, TC_FROMSTRING);
    00151   }
    00152 }
    00153
    00154 int GetTrainDetailsWndVScroll(VehicleID veh_id, byte det_tab)
    00155 {
    00156   AcceptedCargo act_cargo;
    00157   AcceptedCargo max_cargo;
    00158   int num = 0;
    00159
    00160   if (det_tab == 3) { // Total cargo tab
    00161     memset(max_cargo, 0, sizeof(max_cargo));
    00162     memset(act_cargo, 0, sizeof(act_cargo));
    00163
    00164     for (const Vehicle *v = GetVehicle(veh_id) ; v != NULL ; v = v->Next()) {
    00165       act_cargo[v->cargo_type] += v->cargo.Count();
    00166       max_cargo[v->cargo_type] += v->cargo_cap;
    00167     }
    00168
    00169     /* Set scroll-amount seperately from counting, as to not compute num double
    00170      * for more carriages of the same type
    00171      */
    00172     for (CargoID i = 0; i < NUM_CARGO; i++) {
    00173       if (max_cargo[i] > 0) num++; // only count carriages that the train has
    00174     }
    00175     num++; // needs one more because first line is description string
    00176   } else {
    00177     for (const Vehicle *v = GetVehicle(veh_id) ; v != NULL ; v = v->Next()) {
    00178       if (!IsArticulatedPart(v) || v->cargo_cap != 0) num++;
    00179     }
    00180   }
    00181
    00182   return num;
    00183 }
    00184
    00185 void DrawTrainDetails(const Vehicle *v, int x, int y, int vscroll_pos, uint16 vscroll_cap, byte det_tab)
    00186 {
    00187   /* draw the first 3 details tabs */
    00188   if (det_tab != 3) {
    00189     const Vehicle *u = v;
    00190     x = 1;
    00191     for (;;) {
    00192       if (--vscroll_pos < 0 && vscroll_pos >= -vscroll_cap) {
    00193         int dx = 0;
    00194
    00195         u = v;
    00196         do {
    00197           SpriteID pal = (u->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(u);
    00198           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));
    00199           dx += u->u.rail.cached_veh_length;
    00200           u = u->Next();
    00201         } while (u != NULL && IsArticulatedPart(u) && u->cargo_cap == 0);
    00202
    00203         int px = x + WagonLengthToPixels(dx) + 2;
    00204         int py = y + 2;
    00205         switch (det_tab) {
    00206           default: NOT_REACHED();
    00207           case 0: TrainDetailsCargoTab(   v, px, py); break;
    00208           case 1:
    00209             /* Only show name and value for the 'real' part */
    00210             if (!IsArticulatedPart(v)) {
    00211               TrainDetailsInfoTab(v, px, py);
    00212             }
    00213             break;
    00214           case 2: TrainDetailsCapacityTab(v, px, py); break;
    00215         }
    00216         y += 14;
    00217
    00218         v = u;
    00219       } else {
    00220         /* Move to the next line */
    00221         do {
    00222           v = v->Next();
    00223         } while (v != NULL && IsArticulatedPart(v) && v->cargo_cap == 0);
    00224       }
    00225       if (v == NULL) return;
    00226     }
    00227   } else {
    00228     AcceptedCargo act_cargo;
    00229     AcceptedCargo max_cargo;
    00230     Money         feeder_share = 0;
    00231
    00232     memset(max_cargo, 0, sizeof(max_cargo));
    00233     memset(act_cargo, 0, sizeof(act_cargo));
    00234
    00235     for (const Vehicle *u = v; u != NULL ; u = u->Next()) {
    00236       act_cargo[u->cargo_type] += u->cargo.Count();
    00237       max_cargo[u->cargo_type] += u->cargo_cap;
    00238       feeder_share             += u->cargo.FeederShare();
    00239     }
    00240
    00241     /* draw total cargo tab */
    00242     DrawString(x, y + 2, STR_TOTAL_CAPACITY_TEXT, TC_FROMSTRING);
    00243     for (CargoID i = 0; i < NUM_CARGO; i++) {
    00244       if (max_cargo[i] > 0 && --vscroll_pos < 0 && vscroll_pos > -vscroll_cap) {
    00245         y += 14;
    00246         SetDParam(0, i);            // {CARGO} #1
    00247         SetDParam(1, act_cargo[i]); // {CARGO} #2
    00248         SetDParam(2, i);            // {SHORTCARGO} #1
    00249         SetDParam(3, max_cargo[i]); // {SHORTCARGO} #2
    00250         SetDParam(4, _settings_game.vehicle.freight_trains);
    00251         DrawString(x, y + 2, FreightWagonMult(i) > 1 ? STR_TOTAL_CAPACITY_MULT : STR_TOTAL_CAPACITY, TC_FROMSTRING);
    00252       }
    00253     }
    00254     SetDParam(0, feeder_share);
    00255     DrawString(x, y + 15, STR_FEEDER_CARGO_VALUE, TC_FROMSTRING);
    00256   }
    00257 }