train_gui.cpp

Go to the documentation of this file.
00001 /* $Id: train_gui.cpp 15480 2009-02-14 18:42:03Z michi_cc $ */
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 = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v);
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 }

Generated on Mon May 11 15:48:08 2009 for OpenTTD by  doxygen 1.5.6