12 #include "gui.h" |
12 #include "gui.h" |
13 #include "command.h" |
13 #include "command.h" |
14 #include "variables.h" |
14 #include "variables.h" |
15 #include "vehicle_gui.h" |
15 #include "vehicle_gui.h" |
16 #include "newgrf_engine.h" |
16 #include "newgrf_engine.h" |
|
17 #include "group.h" |
17 |
18 |
18 |
19 |
19 static RailType _railtype_selected_in_replace_gui; |
20 static RailType _railtype_selected_in_replace_gui; |
20 |
21 |
21 static bool _rebuild_left_list; |
22 static bool _rebuild_left_list; |
60 } |
61 } |
61 |
62 |
62 /** When an engine is made buildable or is removed from being buildable, add/remove it from the build/autoreplace lists |
63 /** When an engine is made buildable or is removed from being buildable, add/remove it from the build/autoreplace lists |
63 * @param type The type of engine |
64 * @param type The type of engine |
64 */ |
65 */ |
65 void AddRemoveEngineFromAutoreplaceAndBuildWindows(byte type) |
66 void AddRemoveEngineFromAutoreplaceAndBuildWindows(VehicleType type) |
66 { |
67 { |
67 _rebuild_left_list = false; // left list is only for the vehicles the player owns and is not related to being buildable |
68 _rebuild_left_list = false; // left list is only for the vehicles the player owns and is not related to being buildable |
68 _rebuild_right_list = true; |
69 _rebuild_right_list = true; |
69 InvalidateWindowData(WC_REPLACE_VEHICLE, type); // Update the autoreplace window |
70 InvalidateWindowData(WC_REPLACE_VEHICLE, type); // Update the autoreplace window |
70 InvalidateWindowClassesData(WC_BUILD_VEHICLE); // The build windows needs updating as well |
71 InvalidateWindowClassesData(WC_BUILD_VEHICLE); // The build windows needs updating as well |
148 |
149 |
149 FOR_ALL_ENGINEIDS_OF_TYPE(e, type) { |
150 FOR_ALL_ENGINEIDS_OF_TYPE(e, type) { |
150 if (type == VEH_TRAIN && !GenerateReplaceRailList(e, draw_left, WP(w, replaceveh_d).wagon_btnstate)) continue; // special rules for trains |
151 if (type == VEH_TRAIN && !GenerateReplaceRailList(e, draw_left, WP(w, replaceveh_d).wagon_btnstate)) continue; // special rules for trains |
151 |
152 |
152 if (draw_left) { |
153 if (draw_left) { |
|
154 const GroupID selected_group = WP(w, replaceveh_d).sel_group; |
|
155 const uint num_engines = IsDefaultGroupID(selected_group) ? p->num_engines[e] : GetGroup(selected_group)->num_engines[e]; |
|
156 |
153 /* Skip drawing the engines we don't have any of and haven't set for replacement */ |
157 /* Skip drawing the engines we don't have any of and haven't set for replacement */ |
154 if (p->num_engines[e] == 0 && EngineReplacementForPlayer(GetPlayer(_local_player), e) == INVALID_ENGINE) continue; |
158 if (num_engines == 0 && EngineReplacementForPlayer(GetPlayer(_local_player), e, selected_group) == INVALID_ENGINE) continue; |
155 } else { |
159 } else { |
156 /* This is for engines we can replace to and they should depend on what we selected to replace from */ |
160 /* This is for engines we can replace to and they should depend on what we selected to replace from */ |
157 if (!IsEngineBuildable(e, type, _local_player)) continue; // we need to be able to build the engine |
161 if (!IsEngineBuildable(e, type, _local_player)) continue; // we need to be able to build the engine |
158 if (!EnginesGotCargoInCommon(e, WP(w, replaceveh_d).sel_engine[0])) continue; // the engines needs to be able to carry the same cargo |
162 if (!EnginesGotCargoInCommon(e, WP(w, replaceveh_d).sel_engine[0])) continue; // the engines needs to be able to carry the same cargo |
159 if (e == WP(w, replaceveh_d).sel_engine[0]) continue; // we can't replace an engine into itself (that would be autorenew) |
163 if (e == WP(w, replaceveh_d).sel_engine[0]) continue; // we can't replace an engine into itself (that would be autorenew) |
200 WP(w, replaceveh_d).update_right = false; |
204 WP(w, replaceveh_d).update_right = false; |
201 WP(w, replaceveh_d).init_lists = false; |
205 WP(w, replaceveh_d).init_lists = false; |
202 } |
206 } |
203 |
207 |
204 |
208 |
205 void DrawEngineList(byte type, int x, int y, const EngineList eng_list, uint16 min, uint16 max, EngineID selected_id, bool show_count); |
209 void DrawEngineList(VehicleType type, int x, int y, const EngineList eng_list, uint16 min, uint16 max, EngineID selected_id, bool show_count, GroupID selected_group); |
206 |
210 |
207 static void ReplaceVehicleWndProc(Window *w, WindowEvent *e) |
211 static void ReplaceVehicleWndProc(Window *w, WindowEvent *e) |
208 { |
212 { |
209 /* Strings for the pulldown menu */ |
213 /* Strings for the pulldown menu */ |
210 static const StringID _vehicle_type_names[] = { |
214 static const StringID _vehicle_type_names[] = { |
229 case WE_PAINT: { |
233 case WE_PAINT: { |
230 if (WP(w, replaceveh_d).update_left || WP(w, replaceveh_d).update_right) GenerateLists(w); |
234 if (WP(w, replaceveh_d).update_left || WP(w, replaceveh_d).update_right) GenerateLists(w); |
231 |
235 |
232 Player *p = GetPlayer(_local_player); |
236 Player *p = GetPlayer(_local_player); |
233 EngineID selected_id[2]; |
237 EngineID selected_id[2]; |
|
238 const GroupID selected_group = WP(w,replaceveh_d).sel_group; |
234 |
239 |
235 selected_id[0] = WP(w, replaceveh_d).sel_engine[0]; |
240 selected_id[0] = WP(w, replaceveh_d).sel_engine[0]; |
236 selected_id[1] = WP(w, replaceveh_d).sel_engine[1]; |
241 selected_id[1] = WP(w, replaceveh_d).sel_engine[1]; |
237 |
242 |
238 /* Disable the "Start Replacing" button if: |
243 /* Disable the "Start Replacing" button if: |
240 * or The selected replacement engine has a replacement (to prevent loops) |
245 * or The selected replacement engine has a replacement (to prevent loops) |
241 * or The right list (new replacement) has the existing replacement vehicle selected */ |
246 * or The right list (new replacement) has the existing replacement vehicle selected */ |
242 SetWindowWidgetDisabledState(w, 4, |
247 SetWindowWidgetDisabledState(w, 4, |
243 selected_id[0] == INVALID_ENGINE || |
248 selected_id[0] == INVALID_ENGINE || |
244 selected_id[1] == INVALID_ENGINE || |
249 selected_id[1] == INVALID_ENGINE || |
245 EngineReplacementForPlayer(p, selected_id[1]) != INVALID_ENGINE || |
250 EngineReplacementForPlayer(p, selected_id[1], selected_group) != INVALID_ENGINE || |
246 EngineReplacementForPlayer(p, selected_id[0]) == selected_id[1]); |
251 EngineReplacementForPlayer(p, selected_id[0], selected_group) == selected_id[1]); |
247 |
252 |
248 /* Disable the "Stop Replacing" button if: |
253 /* Disable the "Stop Replacing" button if: |
249 * The left list (existing vehicle) is empty |
254 * The left list (existing vehicle) is empty |
250 * or The selected vehicle has no replacement set up */ |
255 * or The selected vehicle has no replacement set up */ |
251 SetWindowWidgetDisabledState(w, 6, |
256 SetWindowWidgetDisabledState(w, 6, |
252 selected_id[0] == INVALID_ENGINE || |
257 selected_id[0] == INVALID_ENGINE || |
253 !EngineHasReplacementForPlayer(p, selected_id[0])); |
258 !EngineHasReplacementForPlayer(p, selected_id[0], selected_group)); |
254 |
259 |
255 /* now the actual drawing of the window itself takes place */ |
260 /* now the actual drawing of the window itself takes place */ |
256 SetDParam(0, _vehicle_type_names[w->window_number]); |
261 SetDParam(0, _vehicle_type_names[w->window_number]); |
257 |
262 |
258 if (w->window_number == VEH_TRAIN) { |
263 if (w->window_number == VEH_TRAIN) { |
275 DrawString(157, w->widget[14].top + 1, _rail_types_list[railtype], 0x10); |
280 DrawString(157, w->widget[14].top + 1, _rail_types_list[railtype], 0x10); |
276 } |
281 } |
277 |
282 |
278 /* sets up the string for the vehicle that is being replaced to */ |
283 /* sets up the string for the vehicle that is being replaced to */ |
279 if (selected_id[0] != INVALID_ENGINE) { |
284 if (selected_id[0] != INVALID_ENGINE) { |
280 if (!EngineHasReplacementForPlayer(p, selected_id[0])) { |
285 if (!EngineHasReplacementForPlayer(p, selected_id[0], selected_group)) { |
281 SetDParam(0, STR_NOT_REPLACING); |
286 SetDParam(0, STR_NOT_REPLACING); |
282 } else { |
287 } else { |
283 SetDParam(0, GetCustomEngineName(EngineReplacementForPlayer(p, selected_id[0]))); |
288 SetDParam(0, GetCustomEngineName(EngineReplacementForPlayer(p, selected_id[0], selected_group))); |
284 } |
289 } |
285 } else { |
290 } else { |
286 SetDParam(0, STR_NOT_REPLACING_VEHICLE_SELECTED); |
291 SetDParam(0, STR_NOT_REPLACING_VEHICLE_SELECTED); |
287 } |
292 } |
288 |
293 |
294 EngineList list = WP(w, replaceveh_d).list[i]; // which list to draw |
299 EngineList list = WP(w, replaceveh_d).list[i]; // which list to draw |
295 EngineID start = i == 0 ? w->vscroll.pos : w->vscroll2.pos; // what is the offset for the start (scrolling) |
300 EngineID start = i == 0 ? w->vscroll.pos : w->vscroll2.pos; // what is the offset for the start (scrolling) |
296 EngineID end = min((i == 0 ? w->vscroll.cap : w->vscroll2.cap) + start, EngList_Count(&list)); |
301 EngineID end = min((i == 0 ? w->vscroll.cap : w->vscroll2.cap) + start, EngList_Count(&list)); |
297 |
302 |
298 /* Do the actual drawing */ |
303 /* Do the actual drawing */ |
299 DrawEngineList(w->window_number, x, 15, list, start, end, WP(w, replaceveh_d).sel_engine[i], i == 0); |
304 DrawEngineList((VehicleType)w->window_number, x, 15, list, start, end, WP(w, replaceveh_d).sel_engine[i], i == 0, selected_group); |
300 |
305 |
301 /* Also draw the details if an engine is selected */ |
306 /* Also draw the details if an engine is selected */ |
302 if (WP(w, replaceveh_d).sel_engine[i] != INVALID_ENGINE) { |
307 if (WP(w, replaceveh_d).sel_engine[i] != INVALID_ENGINE) { |
303 const Widget *wi = &w->widget[i == 0 ? 3 : 11]; |
308 const Widget *wi = &w->widget[i == 0 ? 3 : 11]; |
304 DrawVehiclePurchaseInfo(wi->left + 2, wi->top + 1, wi->right - wi->left - 2, WP(w, replaceveh_d).sel_engine[i]); |
309 DrawVehiclePurchaseInfo(wi->left + 2, wi->top + 1, wi->right - wi->left - 2, WP(w, replaceveh_d).sel_engine[i]); |
326 break; |
331 break; |
327 |
332 |
328 case 4: { /* Start replacing */ |
333 case 4: { /* Start replacing */ |
329 EngineID veh_from = WP(w, replaceveh_d).sel_engine[0]; |
334 EngineID veh_from = WP(w, replaceveh_d).sel_engine[0]; |
330 EngineID veh_to = WP(w, replaceveh_d).sel_engine[1]; |
335 EngineID veh_to = WP(w, replaceveh_d).sel_engine[1]; |
331 DoCommandP(0, 3, veh_from + (veh_to << 16), NULL, CMD_SET_AUTOREPLACE); |
336 DoCommandP(0, 3 + (WP(w, replaceveh_d).sel_group << 16) , veh_from + (veh_to << 16), NULL, CMD_SET_AUTOREPLACE); |
332 } break; |
337 } break; |
333 |
338 |
334 case 6: { /* Stop replacing */ |
339 case 6: { /* Stop replacing */ |
335 EngineID veh_from = WP(w, replaceveh_d).sel_engine[0]; |
340 EngineID veh_from = WP(w, replaceveh_d).sel_engine[0]; |
336 DoCommandP(0, 3, veh_from + (INVALID_ENGINE << 16), NULL, CMD_SET_AUTOREPLACE); |
341 DoCommandP(0, 3 + (WP(w, replaceveh_d).sel_group << 16), veh_from + (INVALID_ENGINE << 16), NULL, CMD_SET_AUTOREPLACE); |
337 } break; |
342 } break; |
338 |
343 |
339 case 7: |
344 case 7: |
340 case 9: { |
345 case 9: { |
341 uint i = (e->we.click.pt.y - 14) / w->resize.step_height; |
346 uint i = (e->we.click.pt.y - 14) / w->resize.step_height; |
478 _replace_ship_aircraft_vehicle_widgets, |
483 _replace_ship_aircraft_vehicle_widgets, |
479 ReplaceVehicleWndProc |
484 ReplaceVehicleWndProc |
480 }; |
485 }; |
481 |
486 |
482 |
487 |
483 void ShowReplaceVehicleWindow(byte vehicletype) |
488 void ShowReplaceVehicleWindow(VehicleType vehicletype) |
484 { |
489 { |
485 Window *w; |
490 Window *w; |
486 |
491 |
487 DeleteWindowById(WC_REPLACE_VEHICLE, vehicletype); |
492 DeleteWindowById(WC_REPLACE_VEHICLE, vehicletype); |
488 |
493 |
507 default: return; |
512 default: return; |
508 } |
513 } |
509 |
514 |
510 w->caption_color = _local_player; |
515 w->caption_color = _local_player; |
511 w->vscroll2.cap = w->vscroll.cap; // these two are always the same |
516 w->vscroll2.cap = w->vscroll.cap; // these two are always the same |
512 } |
517 WP(w, replaceveh_d).sel_group = DEFAULT_GROUP; |
|
518 } |
|
519 |
|
520 void ShowReplaceGroupVehicleWindow(GroupID id_g, VehicleType vehicletype) |
|
521 { |
|
522 Window *w; |
|
523 |
|
524 DeleteWindowById(WC_REPLACE_VEHICLE, vehicletype); |
|
525 |
|
526 switch (vehicletype) { |
|
527 default: NOT_REACHED(); |
|
528 case VEH_TRAIN: |
|
529 w = AllocateWindowDescFront(&_replace_rail_vehicle_desc, vehicletype); |
|
530 w->vscroll.cap = 8; |
|
531 w->resize.step_height = 14; |
|
532 WP(w, replaceveh_d).wagon_btnstate = true; |
|
533 break; |
|
534 case VEH_ROAD: |
|
535 w = AllocateWindowDescFront(&_replace_road_vehicle_desc, vehicletype); |
|
536 w->vscroll.cap = 8; |
|
537 w->resize.step_height = 14; |
|
538 break; |
|
539 case VEH_SHIP: |
|
540 case VEH_AIRCRAFT: |
|
541 w = AllocateWindowDescFront(&_replace_ship_aircraft_vehicle_desc, vehicletype); |
|
542 w->vscroll.cap = 4; |
|
543 w->resize.step_height = 24; |
|
544 break; |
|
545 } |
|
546 |
|
547 w->caption_color = _local_player; |
|
548 WP(w, replaceveh_d).sel_group = id_g; |
|
549 w->vscroll2.cap = w->vscroll.cap; // these two are always the same |
|
550 } |