00001
00002
00005 #include "stdafx.h"
00006 #include "openttd.h"
00007 #include "gui.h"
00008 #include "window_gui.h"
00009 #include "gfx_func.h"
00010 #include "engine.h"
00011 #include "command_func.h"
00012 #include "economy_func.h"
00013 #include "news.h"
00014 #include "variables.h"
00015 #include "newgrf_engine.h"
00016 #include "strings_func.h"
00017 #include "articulated_vehicles.h"
00018
00019 #include "table/strings.h"
00020 #include "table/sprites.h"
00021
00022 static StringID GetEngineCategoryName(EngineID engine)
00023 {
00024 switch (GetEngine(engine)->type) {
00025 default: NOT_REACHED();
00026 case VEH_ROAD: return STR_8103_ROAD_VEHICLE;
00027 case VEH_AIRCRAFT: return STR_8104_AIRCRAFT;
00028 case VEH_SHIP: return STR_8105_SHIP;
00029 case VEH_TRAIN:
00030 switch (RailVehInfo(engine)->railtype) {
00031 default: NOT_REACHED();
00032 case RAILTYPE_RAIL: return STR_8102_RAILROAD_LOCOMOTIVE;
00033 case RAILTYPE_ELECTRIC: return STR_8102_RAILROAD_LOCOMOTIVE;
00034 case RAILTYPE_MONO: return STR_8106_MONORAIL_LOCOMOTIVE;
00035 case RAILTYPE_MAGLEV: return STR_8107_MAGLEV_LOCOMOTIVE;
00036 }
00037 }
00038 }
00039
00040 static const Widget _engine_preview_widgets[] = {
00041 { WWT_CLOSEBOX, RESIZE_NONE, 5, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
00042 { WWT_CAPTION, RESIZE_NONE, 5, 11, 299, 0, 13, STR_8100_MESSAGE_FROM_VEHICLE_MANUFACTURE, STR_018C_WINDOW_TITLE_DRAG_THIS},
00043 { WWT_PANEL, RESIZE_NONE, 5, 0, 299, 14, 191, 0x0, STR_NULL},
00044 { WWT_PUSHTXTBTN, RESIZE_NONE, 5, 85, 144, 172, 183, STR_00C9_NO, STR_NULL},
00045 { WWT_PUSHTXTBTN, RESIZE_NONE, 5, 155, 214, 172, 183, STR_00C8_YES, STR_NULL},
00046 { WIDGETS_END},
00047 };
00048
00049 typedef void DrawEngineProc(int x, int y, EngineID engine, SpriteID pal);
00050 typedef void DrawEngineInfoProc(EngineID, int x, int y, int maxw);
00051
00052 struct DrawEngineInfo {
00053 DrawEngineProc *engine_proc;
00054 DrawEngineInfoProc *info_proc;
00055 };
00056
00057 static void DrawTrainEngineInfo(EngineID engine, int x, int y, int maxw);
00058 static void DrawRoadVehEngineInfo(EngineID engine, int x, int y, int maxw);
00059 static void DrawShipEngineInfo(EngineID engine, int x, int y, int maxw);
00060 static void DrawAircraftEngineInfo(EngineID engine, int x, int y, int maxw);
00061
00062 static const DrawEngineInfo _draw_engine_list[4] = {
00063 { DrawTrainEngine, DrawTrainEngineInfo },
00064 { DrawRoadVehEngine, DrawRoadVehEngineInfo },
00065 { DrawShipEngine, DrawShipEngineInfo },
00066 { DrawAircraftEngine, DrawAircraftEngineInfo },
00067 };
00068
00069 static void EnginePreviewWndProc(Window *w, WindowEvent *e)
00070 {
00071 switch (e->event) {
00072 case WE_PAINT: {
00073 EngineID engine = w->window_number;
00074 const DrawEngineInfo* dei;
00075 int width;
00076
00077 DrawWindowWidgets(w);
00078
00079 SetDParam(0, GetEngineCategoryName(engine));
00080 DrawStringMultiCenter(150, 44, STR_8101_WE_HAVE_JUST_DESIGNED_A, 296);
00081
00082 SetDParam(0, engine);
00083 DrawStringCentered(w->width >> 1, 80, STR_ENGINE_NAME, TC_BLACK);
00084
00085 dei = &_draw_engine_list[GetEngine(engine)->type];
00086
00087 width = w->width;
00088 dei->engine_proc(width >> 1, 100, engine, 0);
00089 dei->info_proc(engine, width >> 1, 130, width - 52);
00090 break;
00091 }
00092
00093 case WE_CLICK:
00094 switch (e->we.click.widget) {
00095 case 4:
00096 DoCommandP(0, w->window_number, 0, NULL, CMD_WANT_ENGINE_PREVIEW);
00097
00098 case 3:
00099 DeleteWindow(w);
00100 break;
00101 }
00102 break;
00103 }
00104 }
00105
00106 static const WindowDesc _engine_preview_desc = {
00107 WDP_CENTER, WDP_CENTER, 300, 192, 300, 192,
00108 WC_ENGINE_PREVIEW, WC_NONE,
00109 WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
00110 _engine_preview_widgets,
00111 EnginePreviewWndProc
00112 };
00113
00114
00115 void ShowEnginePreviewWindow(EngineID engine)
00116 {
00117 AllocateWindowDescFront(&_engine_preview_desc, engine);
00118 }
00119
00120 static uint GetTotalCapacityOfArticulatedParts(EngineID engine, VehicleType type)
00121 {
00122 uint total = 0;
00123
00124 uint16 *cap = GetCapacityOfArticulatedParts(engine, type);
00125 for (uint c = 0; c < NUM_CARGO; c++) {
00126 total += cap[c];
00127 }
00128
00129 return total;
00130 }
00131
00132 static void DrawTrainEngineInfo(EngineID engine, int x, int y, int maxw)
00133 {
00134 const RailVehicleInfo *rvi = RailVehInfo(engine);
00135 int multihead = (rvi->railveh_type == RAILVEH_MULTIHEAD) ? 1 : 0;
00136
00137 SetDParam(0, (_price.build_railvehicle >> 3) * GetEngineProperty(engine, 0x17, rvi->base_cost) >> 5);
00138 SetDParam(2, GetEngineProperty(engine, 0x09, rvi->max_speed) * 10 / 16);
00139 SetDParam(3, GetEngineProperty(engine, 0x0B, rvi->power));
00140 SetDParam(1, GetEngineProperty(engine, 0x16, rvi->weight) << multihead);
00141
00142 SetDParam(4, GetEngineProperty(engine, 0x0D, rvi->running_cost) * GetPriceByIndex(rvi->running_cost_class) >> 8);
00143
00144 uint capacity = GetTotalCapacityOfArticulatedParts(engine, VEH_TRAIN);
00145 if (capacity != 0) {
00146 SetDParam(5, rvi->cargo_type);
00147 SetDParam(6, capacity);
00148 } else {
00149 SetDParam(5, CT_INVALID);
00150 }
00151 DrawStringMultiCenter(x, y, STR_VEHICLE_INFO_COST_WEIGHT_SPEED_POWER, maxw);
00152 }
00153
00154 static void DrawAircraftEngineInfo(EngineID engine, int x, int y, int maxw)
00155 {
00156 const AircraftVehicleInfo *avi = AircraftVehInfo(engine);
00157 SetDParam(0, (_price.aircraft_base >> 3) * GetEngineProperty(engine, 0x0B, avi->base_cost) >> 5);
00158 SetDParam(1, avi->max_speed * 10 / 16);
00159 SetDParam(2, avi->passenger_capacity);
00160 SetDParam(3, avi->mail_capacity);
00161 SetDParam(4, GetEngineProperty(engine, 0x0E, avi->running_cost) * _price.aircraft_running >> 8);
00162
00163 DrawStringMultiCenter(x, y, STR_A02E_COST_MAX_SPEED_CAPACITY, maxw);
00164 }
00165
00166 static void DrawRoadVehEngineInfo(EngineID engine, int x, int y, int maxw)
00167 {
00168 const RoadVehicleInfo *rvi = RoadVehInfo(engine);
00169
00170 SetDParam(0, (_price.roadveh_base >> 3) * GetEngineProperty(engine, 0x11, rvi->base_cost) >> 5);
00171 SetDParam(1, rvi->max_speed * 10 / 32);
00172 SetDParam(2, rvi->running_cost * GetPriceByIndex(rvi->running_cost_class) >> 8);
00173 SetDParam(3, rvi->cargo_type);
00174 SetDParam(4, GetTotalCapacityOfArticulatedParts(engine, VEH_ROAD));
00175
00176 DrawStringMultiCenter(x, y, STR_902A_COST_SPEED_RUNNING_COST, maxw);
00177 }
00178
00179 static void DrawShipEngineInfo(EngineID engine, int x, int y, int maxw)
00180 {
00181 const ShipVehicleInfo *svi = ShipVehInfo(engine);
00182 SetDParam(0, GetEngineProperty(engine, 0x0A, svi->base_cost) * (_price.ship_base >> 3) >> 5);
00183 SetDParam(1, GetEngineProperty(engine, 0x0B, svi->max_speed) * 10 / 32);
00184 SetDParam(2, svi->cargo_type);
00185 SetDParam(3, GetEngineProperty(engine, 0x0D, svi->capacity));
00186 SetDParam(4, GetEngineProperty(engine, 0x0F, svi->running_cost) * _price.ship_running >> 8);
00187 DrawStringMultiCenter(x, y, STR_982E_COST_MAX_SPEED_CAPACITY, maxw);
00188 }
00189
00190
00191 StringID GetNewsStringNewVehicleAvail(const NewsItem *ni)
00192 {
00193 EngineID engine = ni->string_id;
00194 SetDParam(0, GetEngineCategoryName(engine));
00195 SetDParam(1, engine);
00196 return STR_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE;
00197 }
00198
00199 void DrawNewsNewVehicleAvail(Window *w)
00200 {
00201 DrawNewsBorder(w);
00202
00203 EngineID engine = WP(w, news_d).ni->string_id;
00204 const DrawEngineInfo *dei = &_draw_engine_list[GetEngine(engine)->type];
00205
00206 SetDParam(0, GetEngineCategoryName(engine));
00207 DrawStringMultiCenter(w->width >> 1, 20, STR_NEW_VEHICLE_NOW_AVAILABLE, w->width - 2);
00208
00209 GfxFillRect(25, 56, w->width - 25, w->height - 2, 10);
00210
00211 SetDParam(0, engine);
00212 DrawStringMultiCenter(w->width >> 1, 57, STR_NEW_VEHICLE_TYPE, w->width - 2);
00213
00214 dei->engine_proc(w->width >> 1, 88, engine, 0);
00215 GfxFillRect(25, 56, w->width - 56, 112, PALETTE_TO_STRUCT_GREY | (1 << USE_COLORTABLE));
00216 dei->info_proc(engine, w->width >> 1, 129, w->width - 52);
00217 }