src/bridge_gui.cpp
changeset 7983 3b1fec9d5e31
parent 7824 5a63d41b59ea
child 8020 ba100ceda5b4
equal deleted inserted replaced
7982:0d1198a12414 7983:3b1fec9d5e31
    19 
    19 
    20 static struct BridgeData {
    20 static struct BridgeData {
    21 	uint count;
    21 	uint count;
    22 	TileIndex start_tile;
    22 	TileIndex start_tile;
    23 	TileIndex end_tile;
    23 	TileIndex end_tile;
    24 	byte type;
    24 	uint8 type;
    25 	byte indexes[MAX_BRIDGES];
    25 	uint8 indexes[MAX_BRIDGES];
    26 	Money costs[MAX_BRIDGES];
    26 	Money costs[MAX_BRIDGES];
    27 } _bridgedata;
    27 } _bridgedata;
    28 
    28 
    29 void CcBuildBridge(bool success, TileIndex tile, uint32 p1, uint32 p2)
    29 void CcBuildBridge(bool success, TileIndex tile, uint32 p1, uint32 p2)
    30 {
    30 {
    40 }
    40 }
    41 
    41 
    42 static void BuildBridgeWndProc(Window *w, WindowEvent *e)
    42 static void BuildBridgeWndProc(Window *w, WindowEvent *e)
    43 {
    43 {
    44 	switch (e->event) {
    44 	switch (e->event) {
    45 		case WE_PAINT:
    45 		case WE_PAINT: {
    46 			DrawWindowWidgets(w);
    46 			DrawWindowWidgets(w);
    47 
    47 
    48 			for (uint i = 0; i < 4 && i + w->vscroll.pos < _bridgedata.count; i++) {
    48 			uint y = 15;
       
    49 			for (uint i = 0; (i < w->vscroll.cap) && ((i + w->vscroll.pos) < _bridgedata.count); i++) {
    49 				const Bridge *b = &_bridge[_bridgedata.indexes[i + w->vscroll.pos]];
    50 				const Bridge *b = &_bridge[_bridgedata.indexes[i + w->vscroll.pos]];
    50 
    51 
    51 				SetDParam(2, _bridgedata.costs[i + w->vscroll.pos]);
    52 				SetDParam(2, _bridgedata.costs[i + w->vscroll.pos]);
    52 				SetDParam(1, b->speed * 10 / 16);
    53 				SetDParam(1, b->speed * 10 / 16);
    53 				SetDParam(0, b->material);
    54 				SetDParam(0, b->material);
    54 				DrawSprite(b->sprite, b->pal, 3, 15 + i * 22);
       
    55 
    55 
    56 				DrawString(44, 15 + i * 22 , STR_500D, TC_FROMSTRING);
    56 				DrawSprite(b->sprite, b->pal, 3, y);
       
    57 				DrawString(44, y, STR_500D, TC_FROMSTRING);
       
    58 				y += w->resize.step_height;
    57 			}
    59 			}
    58 			break;
    60 			break;
       
    61 		}
    59 
    62 
    60 		case WE_KEYPRESS: {
    63 		case WE_KEYPRESS: {
    61 			uint i = e->we.keypress.keycode - '1';
    64 			const uint8 i = e->we.keypress.keycode - '1';
    62 			if (i < 9 && i < _bridgedata.count) {
    65 			if (i < 9 && i < _bridgedata.count) {
    63 				e->we.keypress.cont = false;
    66 				e->we.keypress.cont = false;
    64 				BuildBridge(w, i);
    67 				BuildBridge(w, i);
    65 			}
    68 			}
    66 
    69 
    67 			break;
    70 			break;
    68 		}
    71 		}
    69 
    72 
    70 		case WE_CLICK:
    73 		case WE_CLICK:
    71 			if (e->we.click.widget == 2) {
    74 			if (e->we.click.widget == 2) {
    72 				uint ind = ((int)e->we.click.pt.y - 14) / 22;
    75 				uint ind = ((int)e->we.click.pt.y - 14) / w->resize.step_height;
    73 				if (ind < 4 && (ind += w->vscroll.pos) < _bridgedata.count)
    76 				if (ind < w->vscroll.cap) {
    74 					BuildBridge(w, ind);
    77 					ind += w->vscroll.pos;
       
    78 					if (ind < _bridgedata.count) {
       
    79 						BuildBridge(w, ind);
       
    80 					}
       
    81 				}
    75 			}
    82 			}
       
    83 			break;
       
    84 
       
    85 		case WE_RESIZE:
       
    86 			w->vscroll.cap += e->we.sizing.diff.y / (int)w->resize.step_height;
       
    87 			w->widget[2].data = (w->vscroll.cap << 8) + 1;
       
    88 			SetVScrollCount(w, _bridgedata.count);
    76 			break;
    89 			break;
    77 	}
    90 	}
    78 }
    91 }
    79 
    92 
    80 static const Widget _build_bridge_widgets[] = {
    93 static const Widget _build_bridge_widgets[] = {
    81 {   WWT_CLOSEBOX,   RESIZE_NONE,     7,     0,    10,     0,    13, STR_00C5,                    STR_018B_CLOSE_WINDOW},
    94 {   WWT_CLOSEBOX,   RESIZE_NONE,  7,   0,  10,   0,  13, STR_00C5,                    STR_018B_CLOSE_WINDOW},
    82 {    WWT_CAPTION,   RESIZE_NONE,     7,    11,   199,     0,    13, STR_100D_SELECT_RAIL_BRIDGE, STR_018C_WINDOW_TITLE_DRAG_THIS},
    95 {    WWT_CAPTION,   RESIZE_NONE,  7,  11, 199,   0,  13, STR_100D_SELECT_RAIL_BRIDGE, STR_018C_WINDOW_TITLE_DRAG_THIS},
    83 {     WWT_MATRIX,   RESIZE_NONE,     7,     0,   187,    14,   101, 0x401,                       STR_101F_BRIDGE_SELECTION_CLICK},
    96 {     WWT_MATRIX, RESIZE_BOTTOM,  7,   0, 187,  14, 101, 0x401,                       STR_101F_BRIDGE_SELECTION_CLICK},
    84 {  WWT_SCROLLBAR,   RESIZE_NONE,     7,   188,   199,    14,   101, 0x0,                         STR_0190_SCROLL_BAR_SCROLLS_LIST},
    97 {  WWT_SCROLLBAR, RESIZE_BOTTOM,  7, 188, 199,  14,  89, 0x0,                         STR_0190_SCROLL_BAR_SCROLLS_LIST},
       
    98 {  WWT_RESIZEBOX,     RESIZE_TB,  7, 188, 199,  90, 101, 0x0,                         STR_RESIZE_BUTTON},
    85 {   WIDGETS_END},
    99 {   WIDGETS_END},
    86 };
   100 };
    87 
   101 
    88 static const WindowDesc _build_bridge_desc = {
   102 static const WindowDesc _build_bridge_desc = {
    89 	WDP_AUTO, WDP_AUTO, 200, 102, 200, 102,
   103 	WDP_AUTO, WDP_AUTO, 200, 102, 200, 102,
    90 	WC_BUILD_BRIDGE, WC_BUILD_TOOLBAR,
   104 	WC_BUILD_BRIDGE, WC_BUILD_TOOLBAR,
    91 	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
   105 	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_RESIZABLE,
    92 	_build_bridge_widgets,
   106 	_build_bridge_widgets,
    93 	BuildBridgeWndProc
   107 	BuildBridgeWndProc
    94 };
   108 };
    95 
   109 
    96 
   110 
    97 static const Widget _build_road_bridge_widgets[] = {
   111 static const Widget _build_road_bridge_widgets[] = {
    98 {   WWT_CLOSEBOX,   RESIZE_NONE,     7,     0,    10,     0,    13, STR_00C5,                    STR_018B_CLOSE_WINDOW},
   112 {   WWT_CLOSEBOX,   RESIZE_NONE,  7,   0,  10,   0,  13, STR_00C5,                    STR_018B_CLOSE_WINDOW},
    99 {    WWT_CAPTION,   RESIZE_NONE,     7,    11,   199,     0,    13, STR_1803_SELECT_ROAD_BRIDGE, STR_018C_WINDOW_TITLE_DRAG_THIS},
   113 {    WWT_CAPTION,   RESIZE_NONE,  7,  11, 199,   0,  13, STR_1803_SELECT_ROAD_BRIDGE, STR_018C_WINDOW_TITLE_DRAG_THIS},
   100 {     WWT_MATRIX,   RESIZE_NONE,     7,     0,   187,    14,   101, 0x401,                       STR_101F_BRIDGE_SELECTION_CLICK},
   114 {     WWT_MATRIX, RESIZE_BOTTOM,  7,   0, 187,  14, 101, 0x401,                       STR_101F_BRIDGE_SELECTION_CLICK},
   101 {  WWT_SCROLLBAR,   RESIZE_NONE,     7,   188,   199,    14,   101, 0x0,                         STR_0190_SCROLL_BAR_SCROLLS_LIST},
   115 {  WWT_SCROLLBAR, RESIZE_BOTTOM,  7, 188, 199,  14,  89, 0x0,                         STR_0190_SCROLL_BAR_SCROLLS_LIST},
       
   116 {  WWT_RESIZEBOX,     RESIZE_TB,  7, 188, 199,  90, 101, 0x0,                         STR_RESIZE_BUTTON},
   102 {   WIDGETS_END},
   117 {   WIDGETS_END},
   103 };
   118 };
   104 
   119 
   105 static const WindowDesc _build_road_bridge_desc = {
   120 static const WindowDesc _build_road_bridge_desc = {
   106 	WDP_AUTO, WDP_AUTO, 200, 102, 200, 102,
   121 	WDP_AUTO, WDP_AUTO, 200, 102, 200, 102,
   107 	WC_BUILD_BRIDGE, WC_BUILD_TOOLBAR,
   122 	WC_BUILD_BRIDGE, WC_BUILD_TOOLBAR,
   108 	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
   123 	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_RESIZABLE,
   109 	_build_road_bridge_widgets,
   124 	_build_road_bridge_widgets,
   110 	BuildBridgeWndProc
   125 	BuildBridgeWndProc
   111 };
   126 };
   112 
   127 
   113 
   128 
   114 void ShowBuildBridgeWindow(TileIndex start, TileIndex end, byte bridge_type)
   129 void ShowBuildBridgeWindow(TileIndex start, TileIndex end, byte bridge_type)
   115 {
   130 {
   116 	uint j = 0;
       
   117 	CommandCost ret;
       
   118 	StringID errmsg;
       
   119 
       
   120 	DeleteWindowById(WC_BUILD_BRIDGE, 0);
   131 	DeleteWindowById(WC_BUILD_BRIDGE, 0);
   121 
   132 
   122 	_bridgedata.type = bridge_type;
   133 	_bridgedata.type = bridge_type;
   123 	_bridgedata.start_tile = start;
   134 	_bridgedata.start_tile = start;
   124 	_bridgedata.end_tile = end;
   135 	_bridgedata.end_tile = end;
   125 
   136 
   126 	errmsg = INVALID_STRING_ID;
   137 	/* only query bridge building possibility once, result is the same for all bridges!
       
   138 	 * returns CMD_ERROR on failure, and price on success */
       
   139 	StringID errmsg = INVALID_STRING_ID;
       
   140 	CommandCost ret = DoCommand(end, start, (bridge_type << 8), DC_AUTO | DC_QUERY_COST, CMD_BUILD_BRIDGE);
   127 
   141 
   128 	// only query bridge building possibility once, result is the same for all bridges!
   142 	uint8 j = 0;
   129 	// returns CMD_ERROR on failure, and price on success
       
   130 	ret = DoCommand(end, start, (bridge_type << 8), DC_AUTO | DC_QUERY_COST, CMD_BUILD_BRIDGE);
       
   131 
       
   132 	if (CmdFailed(ret)) {
   143 	if (CmdFailed(ret)) {
   133 		errmsg = _error_message;
   144 		errmsg = _error_message;
   134 	} else {
   145 	} else {
   135 		// check which bridges can be built
   146 		/* check which bridges can be built
   136 		// get absolute bridge length
   147 		 * get absolute bridge length
   137 		// length of the middle parts of the bridge
   148 		 * length of the middle parts of the bridge */
   138 		int bridge_len = GetBridgeLength(start, end);
   149 		const uint bridge_len = GetBridgeLength(start, end);
   139 		// total length of bridge
   150 		/* total length of bridge */
   140 		int tot_bridgedata_len = bridge_len + 2;
   151 		const uint tot_bridgedata_len = CalcBridgeLenCostFactor(bridge_len + 2);
   141 
   152 
   142 		tot_bridgedata_len = CalcBridgeLenCostFactor(tot_bridgedata_len);
   153 		/* loop for all bridgetypes */
   143 
   154 		for (bridge_type = 0; bridge_type != MAX_BRIDGES; bridge_type++) {
   144 		for (bridge_type = 0; bridge_type != MAX_BRIDGES; bridge_type++) { // loop for all bridgetypes
       
   145 			if (CheckBridge_Stuff(bridge_type, bridge_len)) {
   155 			if (CheckBridge_Stuff(bridge_type, bridge_len)) {
       
   156 				/* bridge is accepted, add to list */
   146 				const Bridge *b = &_bridge[bridge_type];
   157 				const Bridge *b = &_bridge[bridge_type];
   147 				// bridge is accepted, add to list
   158 				/* Add to terraforming & bulldozing costs the cost of the
   148 				// add to terraforming & bulldozing costs the cost of the bridge itself (not computed with DC_QUERY_COST)
   159 				 * bridge itself (not computed with DC_QUERY_COST) */
   149 				_bridgedata.costs[j] = ret.GetCost() + (((int64)tot_bridgedata_len * _price.build_bridge * b->price) >> 8);
   160 				_bridgedata.costs[j] = ret.GetCost() + (((int64)tot_bridgedata_len * _price.build_bridge * b->price) >> 8);
   150 				_bridgedata.indexes[j] = bridge_type;
   161 				_bridgedata.indexes[j] = bridge_type;
   151 				j++;
   162 				j++;
   152 			}
   163 			}
   153 		}
   164 		}
       
   165 
       
   166 		_bridgedata.count = j;
   154 	}
   167 	}
   155 
       
   156 	_bridgedata.count = j;
       
   157 
   168 
   158 	if (j != 0) {
   169 	if (j != 0) {
   159 		Window *w = AllocateWindowDesc((_bridgedata.type & 0x80) ? &_build_road_bridge_desc : &_build_bridge_desc);
   170 		Window *w = AllocateWindowDesc((_bridgedata.type & 0x80) ? &_build_road_bridge_desc : &_build_bridge_desc);
   160 		w->vscroll.cap = 4;
   171 		w->vscroll.cap = 4;
   161 		w->vscroll.count = (byte)j;
   172 		w->vscroll.count = j;
       
   173 		w->resize.step_height = 22;
   162 	} else {
   174 	} else {
   163 		ShowErrorMessage(errmsg, STR_5015_CAN_T_BUILD_BRIDGE_HERE, TileX(end) * TILE_SIZE, TileY(end) * TILE_SIZE);
   175 		ShowErrorMessage(errmsg, STR_5015_CAN_T_BUILD_BRIDGE_HERE, TileX(end) * TILE_SIZE, TileY(end) * TILE_SIZE);
   164 	}
   176 	}
   165 }
   177 }