train_gui.cpp

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

Generated on Mon Sep 22 20:34:20 2008 for openttd by  doxygen 1.5.6