00001
00002
00005 #include "stdafx.h"
00006 #include "openttd.h"
00007 #include "gui.h"
00008 #include "window_gui.h"
00009 #include "command_func.h"
00010 #include "economy_func.h"
00011 #include "variables.h"
00012 #include "bridge.h"
00013 #include "strings_func.h"
00014 #include "window_func.h"
00015 #include "sound_func.h"
00016 #include "map_func.h"
00017 #include "viewport_func.h"
00018 #include "gfx_func.h"
00019 #include "tunnelbridge.h"
00020
00021 #include "table/strings.h"
00022
00023 static struct BridgeData {
00024 uint8 last_size;
00025 uint count;
00026 TileIndex start_tile;
00027 TileIndex end_tile;
00028 uint32 type;
00029 BridgeType indexes[MAX_BRIDGES];
00030 Money costs[MAX_BRIDGES];
00031
00032 BridgeData()
00033 : last_size(4)
00034 , count(0)
00035 {};
00036 } _bridgedata;
00037
00038 void CcBuildBridge(bool success, TileIndex tile, uint32 p1, uint32 p2)
00039 {
00040 if (success) SndPlayTileFx(SND_27_BLACKSMITH_ANVIL, tile);
00041 }
00042
00043 static void BuildBridge(Window *w, int i)
00044 {
00045 DeleteWindow(w);
00046 DoCommandP(_bridgedata.end_tile, _bridgedata.start_tile,
00047 _bridgedata.type | _bridgedata.indexes[i], CcBuildBridge,
00048 CMD_BUILD_BRIDGE | CMD_MSG(STR_5015_CAN_T_BUILD_BRIDGE_HERE));
00049 }
00050
00051
00052 enum BuildBridgeSelectionWidgets {
00053 BBSW_CLOSEBOX = 0,
00054 BBSW_CAPTION,
00055 BBSW_BRIDGE_LIST,
00056 BBSW_SCROLLBAR,
00057 BBSW_RESIZEBOX
00058 };
00059
00060 static void BuildBridgeWndProc(Window *w, WindowEvent *e)
00061 {
00062 switch (e->event) {
00063 case WE_CREATE:
00064 w->resize.step_height = 22;
00065 w->vscroll.count = _bridgedata.count;
00066
00067 if (_bridgedata.last_size <= 4) {
00068 w->vscroll.cap = 4;
00069 } else {
00070
00071 w->vscroll.cap = (w->vscroll.count > _bridgedata.last_size) ? _bridgedata.last_size : w->vscroll.count;
00072 ResizeWindow(w, 0, (w->vscroll.cap - 4) * w->resize.step_height);
00073 w->widget[BBSW_BRIDGE_LIST].data = (w->vscroll.cap << 8) + 1;
00074 }
00075 break;
00076
00077 case WE_PAINT: {
00078 DrawWindowWidgets(w);
00079
00080 uint y = 15;
00081 for (uint i = 0; (i < w->vscroll.cap) && ((i + w->vscroll.pos) < _bridgedata.count); i++) {
00082 const BridgeSpec *b = GetBridgeSpec(_bridgedata.indexes[i + w->vscroll.pos]);
00083
00084 SetDParam(2, _bridgedata.costs[i + w->vscroll.pos]);
00085 SetDParam(1, b->speed * 10 / 16);
00086 SetDParam(0, b->material);
00087
00088 DrawSprite(b->sprite, b->pal, 3, y);
00089 DrawString(44, y, STR_500D, TC_FROMSTRING);
00090 y += w->resize.step_height;
00091 }
00092 break;
00093 }
00094
00095 case WE_KEYPRESS: {
00096 const uint8 i = e->we.keypress.keycode - '1';
00097 if (i < 9 && i < _bridgedata.count) {
00098 e->we.keypress.cont = false;
00099 BuildBridge(w, i);
00100 }
00101
00102 break;
00103 }
00104
00105 case WE_CLICK:
00106 if (e->we.click.widget == BBSW_BRIDGE_LIST) {
00107 uint ind = ((int)e->we.click.pt.y - 14) / w->resize.step_height;
00108 if (ind < w->vscroll.cap) {
00109 ind += w->vscroll.pos;
00110 if (ind < _bridgedata.count) {
00111 BuildBridge(w, ind);
00112 }
00113 }
00114 }
00115 break;
00116
00117 case WE_RESIZE:
00118 w->vscroll.cap += e->we.sizing.diff.y / (int)w->resize.step_height;
00119 w->widget[BBSW_BRIDGE_LIST].data = (w->vscroll.cap << 8) + 1;
00120 SetVScrollCount(w, _bridgedata.count);
00121
00122 _bridgedata.last_size = w->vscroll.cap;
00123 break;
00124 }
00125 }
00126
00127
00128 static const Widget _build_bridge_widgets[] = {
00129 { WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
00130 { WWT_CAPTION, RESIZE_NONE, 7, 11, 199, 0, 13, STR_100D_SELECT_RAIL_BRIDGE, STR_018C_WINDOW_TITLE_DRAG_THIS},
00131 { WWT_MATRIX, RESIZE_BOTTOM, 7, 0, 187, 14, 101, 0x401, STR_101F_BRIDGE_SELECTION_CLICK},
00132 { WWT_SCROLLBAR, RESIZE_BOTTOM, 7, 188, 199, 14, 89, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
00133 { WWT_RESIZEBOX, RESIZE_TB, 7, 188, 199, 90, 101, 0x0, STR_RESIZE_BUTTON},
00134 { WIDGETS_END},
00135 };
00136
00137
00138 static const WindowDesc _build_bridge_desc = {
00139 WDP_AUTO, WDP_AUTO, 200, 102, 200, 102,
00140 WC_BUILD_BRIDGE, WC_BUILD_TOOLBAR,
00141 WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_RESIZABLE,
00142 _build_bridge_widgets,
00143 BuildBridgeWndProc
00144 };
00145
00146 void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transport_type, byte bridge_type)
00147 {
00148 DeleteWindowById(WC_BUILD_BRIDGE, 0);
00149
00150 _bridgedata.type = (transport_type << 15) | (bridge_type << 8);
00151 _bridgedata.start_tile = start;
00152 _bridgedata.end_tile = end;
00153
00154
00155
00156 StringID errmsg = INVALID_STRING_ID;
00157 CommandCost ret = DoCommand(end, start, _bridgedata.type, DC_AUTO | DC_QUERY_COST, CMD_BUILD_BRIDGE);
00158
00159 uint8 j = 0;
00160 if (CmdFailed(ret)) {
00161 errmsg = _error_message;
00162 } else {
00163
00164
00165
00166 const uint bridge_len = GetTunnelBridgeLength(start, end);
00167
00168 const uint tot_bridgedata_len = CalcBridgeLenCostFactor(bridge_len + 2);
00169
00170
00171 for (BridgeType brd_type = 0; brd_type != MAX_BRIDGES; brd_type++) {
00172 if (CheckBridge_Stuff(brd_type, bridge_len)) {
00173
00174 const BridgeSpec *b = GetBridgeSpec(brd_type);
00175
00176
00177 _bridgedata.costs[j] = ret.GetCost() + (((int64)tot_bridgedata_len * _price.build_bridge * b->price) >> 8);
00178 _bridgedata.indexes[j] = brd_type;
00179 j++;
00180 }
00181 }
00182
00183 _bridgedata.count = j;
00184 }
00185
00186 if (j != 0) {
00187 Window *w = AllocateWindowDesc(&_build_bridge_desc);
00188
00189 w->widget[BBSW_CAPTION].data = (transport_type == TRANSPORT_ROAD) ? STR_1803_SELECT_ROAD_BRIDGE : STR_100D_SELECT_RAIL_BRIDGE;
00190 } else {
00191 ShowErrorMessage(errmsg, STR_5015_CAN_T_BUILD_BRIDGE_HERE, TileX(end) * TILE_SIZE, TileY(end) * TILE_SIZE);
00192 }
00193 }