118 uint32 type; |
118 uint32 type; |
119 GUIBridgeList *bridges; |
119 GUIBridgeList *bridges; |
120 |
120 |
121 void BuildBridge(uint8 i) |
121 void BuildBridge(uint8 i) |
122 { |
122 { |
123 DoCommandP(this->end_tile, this->start_tile, this->type | this->bridges->sort_list[i].index, |
123 DoCommandP(this->end_tile, this->start_tile, this->type | this->bridges->Get(i)->index, |
124 CcBuildBridge, CMD_BUILD_BRIDGE | CMD_MSG(STR_5015_CAN_T_BUILD_BRIDGE_HERE)); |
124 CcBuildBridge, CMD_BUILD_BRIDGE | CMD_MSG(STR_5015_CAN_T_BUILD_BRIDGE_HERE)); |
125 } |
125 } |
126 |
126 |
127 /** Sort the builable bridges */ |
127 /** Sort the builable bridges */ |
128 void SortBridgeList() |
128 void SortBridgeList() |
129 { |
129 { |
130 /* Skip sorting if resort bit is not set */ |
130 /* Skip sorting if resort bit is not set */ |
131 if (!(bridges->flags & VL_RESORT)) return; |
131 if (!(bridges->flags & VL_RESORT)) return; |
132 |
132 |
133 qsort(this->bridges->sort_list, this->bridges->list_length, sizeof(this->bridges->sort_list[0]), _bridge_sorter[_bridge_sorting.criteria]); |
133 qsort(this->bridges->Begin(), this->bridges->Length(), sizeof(this->bridges->Begin()), _bridge_sorter[_bridge_sorting.criteria]); |
134 |
134 |
135 /* Display the current sort variant */ |
135 /* Display the current sort variant */ |
136 this->widget[BBSW_DROPDOWN_CRITERIA].data = _bridge_sort_listing[this->bridges->sort_type]; |
136 this->widget[BBSW_DROPDOWN_CRITERIA].data = _bridge_sort_listing[this->bridges->sort_type]; |
137 |
137 |
138 bridges->flags &= ~VL_RESORT; |
138 bridges->flags &= ~VL_RESORT; |
153 |
153 |
154 /* Change the data, or the caption of the gui. Set it to road or rail, accordingly */ |
154 /* Change the data, or the caption of the gui. Set it to road or rail, accordingly */ |
155 this->widget[BBSW_CAPTION].data = (GB(this->type, 15, 2) == TRANSPORT_ROAD) ? STR_1803_SELECT_ROAD_BRIDGE : STR_100D_SELECT_RAIL_BRIDGE; |
155 this->widget[BBSW_CAPTION].data = (GB(this->type, 15, 2) == TRANSPORT_ROAD) ? STR_1803_SELECT_ROAD_BRIDGE : STR_100D_SELECT_RAIL_BRIDGE; |
156 |
156 |
157 this->resize.step_height = 22; |
157 this->resize.step_height = 22; |
158 this->vscroll.count = bl->list_length; |
158 this->vscroll.count = bl->Length(); |
159 |
159 |
160 if (this->last_size <= 4) { |
160 if (this->last_size <= 4) { |
161 this->vscroll.cap = 4; |
161 this->vscroll.cap = 4; |
162 } else { |
162 } else { |
163 /* Resize the bridge selection window if we used a bigger one the last time */ |
163 /* Resize the bridge selection window if we used a bigger one the last time */ |
181 |
180 |
182 this->DrawSortButtonState(BBSW_DROPDOWN_ORDER, (this->bridges->flags & VL_DESC) ? SBS_DOWN : SBS_UP); |
181 this->DrawSortButtonState(BBSW_DROPDOWN_ORDER, (this->bridges->flags & VL_DESC) ? SBS_DOWN : SBS_UP); |
183 |
182 |
184 uint y = this->widget[BBSW_BRIDGE_LIST].top + 2; |
183 uint y = this->widget[BBSW_BRIDGE_LIST].top + 2; |
185 |
184 |
186 for (int i = this->vscroll.pos; (i < (this->vscroll.cap + this->vscroll.pos)) && (i < this->bridges->list_length); i++) { |
185 for (int i = this->vscroll.pos; (i < (this->vscroll.cap + this->vscroll.pos)) && (i < (int)this->bridges->Length()); i++) { |
187 const BridgeSpec *b = this->bridges->sort_list[i].spec; |
186 const BridgeSpec *b = this->bridges->Get(i)->spec; |
188 |
187 |
189 SetDParam(2, this->bridges->sort_list[i].cost); |
188 SetDParam(2, this->bridges->Get(i)->cost); |
190 SetDParam(1, b->speed * 10 / 16); |
189 SetDParam(1, b->speed * 10 / 16); |
191 SetDParam(0, b->material); |
190 SetDParam(0, b->material); |
192 |
191 |
193 DrawSprite(b->sprite, b->pal, 3, y); |
192 DrawSprite(b->sprite, b->pal, 3, y); |
194 DrawString(44, y, STR_500D, TC_FROMSTRING); |
193 DrawString(44, y, STR_500D, TC_FROMSTRING); |
198 } |
197 } |
199 |
198 |
200 virtual EventState OnKeyPress(uint16 key, uint16 keycode) |
199 virtual EventState OnKeyPress(uint16 key, uint16 keycode) |
201 { |
200 { |
202 const uint8 i = keycode - '1'; |
201 const uint8 i = keycode - '1'; |
203 if (i < 9 && i < this->bridges->list_length) { |
202 if (i < 9 && i < this->bridges->Length()) { |
204 /* Build the requested bridge */ |
203 /* Build the requested bridge */ |
205 this->BuildBridge(i); |
204 this->BuildBridge(i); |
206 delete this; |
205 delete this; |
207 return ES_HANDLED; |
206 return ES_HANDLED; |
208 } |
207 } |
215 default: break; |
214 default: break; |
216 case BBSW_BRIDGE_LIST: { |
215 case BBSW_BRIDGE_LIST: { |
217 uint i = ((int)pt.y - this->widget[BBSW_BRIDGE_LIST].top) / this->resize.step_height; |
216 uint i = ((int)pt.y - this->widget[BBSW_BRIDGE_LIST].top) / this->resize.step_height; |
218 if (i < this->vscroll.cap) { |
217 if (i < this->vscroll.cap) { |
219 i += this->vscroll.pos; |
218 i += this->vscroll.pos; |
220 if (i < this->bridges->list_length) { |
219 if (i < this->bridges->Length()) { |
221 this->BuildBridge(i); |
220 this->BuildBridge(i); |
222 delete this; |
221 delete this; |
223 } |
222 } |
224 } |
223 } |
225 } break; |
224 } break; |
252 |
251 |
253 virtual void OnResize(Point new_size, Point delta) |
252 virtual void OnResize(Point new_size, Point delta) |
254 { |
253 { |
255 this->vscroll.cap += delta.y / (int)this->resize.step_height; |
254 this->vscroll.cap += delta.y / (int)this->resize.step_height; |
256 this->widget[BBSW_BRIDGE_LIST].data = (this->vscroll.cap << 8) + 1; |
255 this->widget[BBSW_BRIDGE_LIST].data = (this->vscroll.cap << 8) + 1; |
257 SetVScrollCount(this, this->bridges->list_length); |
256 SetVScrollCount(this, this->bridges->Length()); |
258 |
257 |
259 this->last_size = this->vscroll.cap; |
258 this->last_size = this->vscroll.cap; |
260 } |
259 } |
261 }; |
260 }; |
262 |
261 |
282 WDP_AUTO, WDP_AUTO, 200, 114, 200, 114, |
281 WDP_AUTO, WDP_AUTO, 200, 114, 200, 114, |
283 WC_BUILD_BRIDGE, WC_BUILD_TOOLBAR, |
282 WC_BUILD_BRIDGE, WC_BUILD_TOOLBAR, |
284 WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_RESIZABLE, |
283 WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_RESIZABLE, |
285 _build_bridge_widgets, |
284 _build_bridge_widgets, |
286 }; |
285 }; |
287 |
|
288 /** |
|
289 * Add a buildable bridge to the list. |
|
290 * If the list is empty a new one is created. |
|
291 * |
|
292 * @param bl The list which we want to manage |
|
293 * @param item The item to add |
|
294 * @return The pointer to the list |
|
295 */ |
|
296 static GUIBridgeList *PushBridgeList(GUIBridgeList *bl, BuildBridgeData item) |
|
297 { |
|
298 if (bl == NULL) { |
|
299 /* Create the list if needed */ |
|
300 bl = new GUIBridgeList(); |
|
301 bl->flags |= VL_RESORT; |
|
302 if (_bridge_sorting.order) bl->flags |= VL_DESC; |
|
303 bl->list_length = 1; |
|
304 bl->sort_type = _bridge_sorting.criteria; |
|
305 } else { |
|
306 /* Resize the list */ |
|
307 bl->list_length++; |
|
308 } |
|
309 |
|
310 bl->sort_list = ReallocT(bl->sort_list, bl->list_length); |
|
311 |
|
312 bl->sort_list[bl->list_length - 1] = item; |
|
313 |
|
314 return bl; |
|
315 } |
|
316 |
286 |
317 /** |
287 /** |
318 * Prepare the data for the build a bridge window. |
288 * Prepare the data for the build a bridge window. |
319 * If we can't build a bridge under the given conditions |
289 * If we can't build a bridge under the given conditions |
320 * show an error message. |
290 * show an error message. |
348 * length of the middle parts of the bridge */ |
318 * length of the middle parts of the bridge */ |
349 const uint bridge_len = GetTunnelBridgeLength(start, end); |
319 const uint bridge_len = GetTunnelBridgeLength(start, end); |
350 /* total length of bridge */ |
320 /* total length of bridge */ |
351 const uint tot_bridgedata_len = CalcBridgeLenCostFactor(bridge_len + 2); |
321 const uint tot_bridgedata_len = CalcBridgeLenCostFactor(bridge_len + 2); |
352 |
322 |
|
323 bl = new GUIBridgeList(); |
|
324 |
353 /* loop for all bridgetypes */ |
325 /* loop for all bridgetypes */ |
354 for (BridgeType brd_type = 0; brd_type != MAX_BRIDGES; brd_type++) { |
326 for (BridgeType brd_type = 0; brd_type != MAX_BRIDGES; brd_type++) { |
355 if (CheckBridge_Stuff(brd_type, bridge_len)) { |
327 if (CheckBridge_Stuff(brd_type, bridge_len)) { |
356 /* bridge is accepted, add to list */ |
328 /* bridge is accepted, add to list */ |
357 BuildBridgeData item; |
329 BuildBridgeData *item = bl->Append(); |
358 item.index = brd_type; |
330 item->index = brd_type; |
359 item.spec = GetBridgeSpec(brd_type); |
331 item->spec = GetBridgeSpec(brd_type); |
360 /* Add to terraforming & bulldozing costs the cost of the |
332 /* Add to terraforming & bulldozing costs the cost of the |
361 * bridge itself (not computed with DC_QUERY_COST) */ |
333 * bridge itself (not computed with DC_QUERY_COST) */ |
362 item.cost = ret.GetCost() + (((int64)tot_bridgedata_len * _price.build_bridge * item.spec->price) >> 8); |
334 item->cost = ret.GetCost() + (((int64)tot_bridgedata_len * _price.build_bridge * item->spec->price) >> 8); |
363 bl = PushBridgeList(bl, item); |
|
364 } |
335 } |
365 } |
336 } |
366 } |
337 } |
367 |
338 |
368 if (bl != NULL) { |
339 if (bl != NULL && bl->Length() != 0) { |
369 new BuildBridgeWindow(&_build_bridge_desc, start, end, type, bl); |
340 new BuildBridgeWindow(&_build_bridge_desc, start, end, type, bl); |
370 } else { |
341 } else { |
|
342 if (bl != NULL) delete bl; |
371 ShowErrorMessage(errmsg, STR_5015_CAN_T_BUILD_BRIDGE_HERE, TileX(end) * TILE_SIZE, TileY(end) * TILE_SIZE); |
343 ShowErrorMessage(errmsg, STR_5015_CAN_T_BUILD_BRIDGE_HERE, TileX(end) * TILE_SIZE, TileY(end) * TILE_SIZE); |
372 } |
344 } |
373 } |
345 } |