diff options
Diffstat (limited to 'train_gui.c')
-rw-r--r-- | train_gui.c | 412 |
1 files changed, 1 insertions, 411 deletions
diff --git a/train_gui.c b/train_gui.c index c097857d2..8866bf2be 100644 --- a/train_gui.c +++ b/train_gui.c @@ -349,7 +349,7 @@ void ShowBuildTrainWindow(TileIndex tile) * @param len Length measured in 1/8ths of a standard wagon. * @return Number of pixels across. */ -static int WagonLengthToPixels(int len) { +int WagonLengthToPixels(int len) { return (len * _traininfo_vehicle_width) / 8; } @@ -396,416 +396,6 @@ void DrawTrainImage(const Vehicle *v, int x, int y, int count, int skip, Vehicle _cur_dpi = old_dpi; } -static void DrawTrainDepotWindow(Window *w) -{ - Vehicle **vl = WP(w, traindepot_d).vehicle_list; - TileIndex tile; - int x, y, i, hnum, max; - Depot *depot; - uint16 num; - - tile = w->window_number; - - /* setup disabled buttons */ - w->disabled_state = - IsTileOwner(tile, _local_player) ? 0 : ((1 << 4) | (1 << 5) | (1 << 8) | (1<<9)); - - /* determine amount of items for scroller */ - hnum = 8; - for (num = 0; num < WP(w, traindepot_d).engine_count; num++) { - const Vehicle *v = vl[num]; - hnum = maxu(hnum, v->u.rail.cached_total_length); - } - - /* Always have 1 empty row, so people can change the setting of the train */ - SetVScrollCount(w, WP(w, traindepot_d).engine_count + WP(w, traindepot_d).wagon_count + 1); - SetHScrollCount(w, WagonLengthToPixels(hnum)); - - /* locate the depot struct */ - depot = GetDepotByTile(tile); - assert(depot != NULL); - - SetDParam(0, depot->town_index); - DrawWindowWidgets(w); - - x = 2; - y = 15; - num = w->vscroll.pos; - max = min(WP(w, traindepot_d).engine_count, w->vscroll.pos + w->vscroll.cap); - - - /* draw all trains */ - for (; num < max; num++) { - const Vehicle *v = vl[num]; - - DrawTrainImage(v, x + 21, y, w->hscroll.cap + 4, w->hscroll.pos, WP(w,traindepot_d).sel); - /* Draw the train number */ - SetDParam(0, v->unitnumber); - DrawString(x, y, (v->max_age - 366 < v->age) ? STR_00E3 : STR_00E2, 0); - - /* Number of wagons relative to a standard length wagon (rounded up) */ - SetDParam(0, (v->u.rail.cached_total_length + 7) / 8); - DrawStringRightAligned(w->widget[6].right - 1, y + 4, STR_TINY_BLACK, 0); // Draw the counter - - /* Draw the pretty flag */ - DrawSprite(v->vehstatus & VS_STOPPED ? SPR_FLAG_VEH_STOPPED : SPR_FLAG_VEH_RUNNING, x + 15, y); - - y += 14; - } - - max = min(WP(w, traindepot_d).engine_count + WP(w, traindepot_d).wagon_count, w->vscroll.pos + w->vscroll.cap); - - /* draw all remaining vehicles */ - for (; num < max; num++) { - const Vehicle *v = WP(w, traindepot_d).wagon_list[num - WP(w, traindepot_d).engine_count]; - const Vehicle *u; - - DrawTrainImage(v, x + 50, y, w->hscroll.cap - 29, 0, WP(w,traindepot_d).sel); - DrawString(x, y + 2, STR_8816, 0); - - /*Draw the train counter */ - i = 0; - u = v; - do i++; while ( (u=u->next) != NULL); // Determine length of train - SetDParam(0, i); // Set the counter - DrawStringRightAligned(w->widget[6].right - 1, y + 4, STR_TINY_BLACK, 0); // Draw the counter - y += 14; - } -} - -typedef struct GetDepotVehiclePtData { - Vehicle *head; - Vehicle *wagon; -} GetDepotVehiclePtData; - -static int GetVehicleFromTrainDepotWndPt(const Window *w, int x, int y, GetDepotVehiclePtData *d) -{ - Vehicle **vl = WP(w, traindepot_d).vehicle_list; - int row; - int skip = 0; - Vehicle *v; - - x = x - 23; - - row = (y - 14) / 14; - if ((uint)row >= w->vscroll.cap) return 1; /* means err */ - - row += w->vscroll.pos; - - if (WP(w, traindepot_d).engine_count + WP(w, traindepot_d).wagon_count <= row) { - /* empty row, so no vehicle is selected */ - d->head = NULL; - d->wagon = NULL; - return 0; - } - - if (WP(w, traindepot_d).engine_count > row) { - v = vl[row]; - skip = w->hscroll.pos; - } else { - vl = WP(w, traindepot_d).wagon_list; - v = vl[row - WP(w, traindepot_d).engine_count]; - /* free wagons don't have an initial loco. */ - x -= _traininfo_vehicle_width; - } - - d->head = d->wagon = v; - - /* either pressed the flag or the number, but only when it's a loco */ - if (x < 0 && IsFrontEngine(v)) return (x >= -10) ? -2 : -1; - - skip = (skip * 8) / _traininfo_vehicle_width; - x = (x * 8) / _traininfo_vehicle_width; - - /* Skip vehicles that are scrolled off the list */ - x += skip; - - /* find the vehicle in this row that was clicked */ - while (v != NULL && (x -= v->u.rail.cached_veh_length) >= 0) v = v->next; - - // if an articulated part was selected, find its parent - while (v != NULL && IsArticulatedPart(v)) v = GetPrevVehicleInChain(v); - - d->wagon = v; - - return 0; -} - -static void TrainDepotMoveVehicle(Vehicle *wagon, VehicleID sel, Vehicle *head) -{ - Vehicle *v; - - v = GetVehicle(sel); - - if (v == wagon) return; - - if (wagon == NULL) { - if (head != NULL) wagon = GetLastVehicleInChain(head); - } else { - wagon = GetPrevVehicleInChain(wagon); - if (wagon == NULL) return; - } - - if (wagon == v) return; - - DoCommandP(v->tile, v->index + ((wagon == NULL ? INVALID_VEHICLE : wagon->index) << 16), _ctrl_pressed ? 1 : 0, NULL, CMD_MOVE_RAIL_VEHICLE | CMD_MSG(STR_8837_CAN_T_MOVE_VEHICLE)); -} - -static void TrainDepotClickTrain(Window *w, int x, int y) -{ - GetDepotVehiclePtData gdvp; - int mode; - Vehicle *v; - - mode = GetVehicleFromTrainDepotWndPt(w, x, y, &gdvp); - - // share / copy orders - if (_thd.place_mode && mode <= 0) { - _place_clicked_vehicle = gdvp.head; - return; - } - - v = gdvp.wagon; - - switch (mode) { - case 0: { // start dragging of vehicle - VehicleID sel = WP(w, traindepot_d).sel; - - if (sel != INVALID_VEHICLE) { - WP(w,traindepot_d).sel = INVALID_VEHICLE; - TrainDepotMoveVehicle(v, sel, gdvp.head); - } else if (v != NULL) { - WP(w,traindepot_d).sel = v->index; - SetObjectToPlaceWnd(GetVehiclePalette(v) | GetTrainImage(v, DIR_W), 4, w); - SetWindowDirty(w); - } - break; - } - - case -1: // show info window - ShowTrainViewWindow(v); - break; - - case -2: // click start/stop flag - DoCommandP(v->tile, v->index, 0, NULL, CMD_START_STOP_TRAIN | CMD_MSG(STR_883B_CAN_T_STOP_START_TRAIN)); - break; - } -} - -/** - * Clones a train - * @param *v is the original vehicle to clone - * @param *w is the window of the depot where the clone is build - */ -static void HandleCloneVehClick(const Vehicle *v, const Window *w) -{ - if (v == NULL || v->type != VEH_Train) return; - - // for train vehicles: subtype 0 for locs and not zero for others - if (!IsFrontEngine(v)) { - v = GetFirstVehicleInChain(v); - // Do nothing when clicking on a train in depot with no loc attached - if (!IsFrontEngine(v)) return; - } - - DoCommandP(w->window_number, v->index, _ctrl_pressed ? 1 : 0, CcCloneTrain, - CMD_CLONE_VEHICLE | CMD_MSG(STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE) - ); - - ResetObjectToPlace(); -} - -static void ClonePlaceObj(const Window *w) -{ - Vehicle *v = CheckMouseOverVehicle(); - - if (v != NULL) HandleCloneVehClick(v, w); -} - -static void TrainDepotWndProc(Window *w, WindowEvent *e) -{ - switch (e->event) { - case WE_CREATE: - WP(w, traindepot_d).vehicle_list = NULL; - WP(w, traindepot_d).wagon_list = NULL; - WP(w, traindepot_d).engine_count = 0; - WP(w, traindepot_d).wagon_count = 0; - break; - - case WE_PAINT: - BuildDepotVehicleList(VEH_Train, w->window_number, &WP(w, traindepot_d).vehicle_list, &WP(w, traindepot_d).engine_list_length, &WP(w, traindepot_d).engine_count, - &WP(w, traindepot_d).wagon_list, &WP(w, traindepot_d).wagon_list_length, &WP(w, traindepot_d).wagon_count); - DrawTrainDepotWindow(w); - break; - - case WE_CLICK: { - switch (e->we.click.widget) { - case 8: - ResetObjectToPlace(); - ShowBuildTrainWindow(w->window_number); - break; - - case 10: ScrollMainWindowToTile(w->window_number); break; - - case 6: - TrainDepotClickTrain(w, e->we.click.pt.x, e->we.click.pt.y); - break; - case 9: /* clone button */ - InvalidateWidget(w, 9); - TOGGLEBIT(w->click_state, 9); - - if (HASBIT(w->click_state, 9)) { - _place_clicked_vehicle = NULL; - SetObjectToPlaceWnd(SPR_CURSOR_CLONE, VHM_RECT, w); - } else { - ResetObjectToPlace(); - } - break; - - } - } break; - - case WE_PLACE_OBJ: - ClonePlaceObj(w); - break; - - case WE_ABORT_PLACE_OBJ: - CLRBIT(w->click_state, 9); - InvalidateWidget(w, 9); - break; - - // check if a vehicle in a depot was clicked.. - case WE_MOUSELOOP: { - const Vehicle *v = _place_clicked_vehicle; - - // since OTTD checks all open depot windows, we will make sure that it triggers the one with a clicked clone button - if (v != NULL && HASBIT(w->click_state, 9)) { - _place_clicked_vehicle = NULL; - HandleCloneVehClick(v, w); - } - } break; - - - case WE_DESTROY: - DeleteWindowById(WC_BUILD_VEHICLE, w->window_number); - free((void*)WP(w, traindepot_d).vehicle_list); - free((void*)WP(w, traindepot_d).wagon_list); - break; - - case WE_DRAGDROP: { - switch (e->we.click.widget) { - case 4: case 5: { - Vehicle *v; - int sell_cmd; - - /* sell vehicle */ - if (w->disabled_state & (1 << e->we.click.widget)) - return; - - if (WP(w,traindepot_d).sel == INVALID_VEHICLE) - return; - - v = GetVehicle(WP(w,traindepot_d).sel); - - WP(w,traindepot_d).sel = INVALID_VEHICLE; - SetWindowDirty(w); - - HandleButtonClick(w, e->we.click.widget); - - sell_cmd = (e->we.click.widget == 5 || _ctrl_pressed) ? 1 : 0; - - if (!IsFrontEngine(v)) { - DoCommandP(v->tile, v->index, sell_cmd, NULL, CMD_SELL_RAIL_WAGON | CMD_MSG(STR_8839_CAN_T_SELL_RAILROAD_VEHICLE)); - } else { - _backup_orders_tile = v->tile; - BackupVehicleOrders(v, _backup_orders_data); - if (!DoCommandP(v->tile, v->index, sell_cmd, NULL, CMD_SELL_RAIL_WAGON | CMD_MSG(STR_8839_CAN_T_SELL_RAILROAD_VEHICLE))) - _backup_orders_tile = 0; - } - } break; - - case 6: { - GetDepotVehiclePtData gdvp; - VehicleID sel = WP(w,traindepot_d).sel; - - WP(w,traindepot_d).sel = INVALID_VEHICLE; - SetWindowDirty(w); - - if (GetVehicleFromTrainDepotWndPt(w, e->we.dragdrop.pt.x, e->we.dragdrop.pt.y, &gdvp) == 0 && - sel != INVALID_VEHICLE) { - if (gdvp.wagon != NULL && gdvp.wagon->index == sel && _ctrl_pressed) { - DoCommandP(GetVehicle(sel)->tile, GetVehicle(sel)->index, true, NULL, CMD_REVERSE_TRAIN_DIRECTION | CMD_MSG(STR_9033_CAN_T_MAKE_VEHICLE_TURN)); - } else if (gdvp.wagon == NULL || gdvp.wagon->index != sel) { - TrainDepotMoveVehicle(gdvp.wagon, sel, gdvp.head); - } else if (gdvp.head != NULL && IsFrontEngine(gdvp.head)) { - ShowTrainViewWindow(gdvp.head); - } - } - } break; - - default: - WP(w,traindepot_d).sel = INVALID_VEHICLE; - SetWindowDirty(w); - break; - } - } break; - case WE_RESIZE: { - /* Update the scroll + matrix */ - w->vscroll.cap += e->we.sizing.diff.y / 14; - w->hscroll.cap += e->we.sizing.diff.x; - w->widget[6].data = (w->vscroll.cap << 8) + 1; - } break; - } -} - -static const Widget _train_depot_widgets[] = { -{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, -{ WWT_CAPTION, RESIZE_RIGHT, 14, 11, 348, 0, 13, STR_8800_TRAIN_DEPOT, STR_018C_WINDOW_TITLE_DRAG_THIS}, -{ WWT_STICKYBOX, RESIZE_LR, 14, 349, 360, 0, 13, 0x0, STR_STICKY_BUTTON}, - -{ WWT_PANEL, RESIZE_LRB, 14, 326, 348, 14, 13, 0x0, STR_NULL}, -{ WWT_PANEL, RESIZE_LRTB, 14, 326, 348, 14, 54, 0x2A9, STR_8841_DRAG_TRAIN_VEHICLE_TO_HERE}, -{ WWT_PANEL, RESIZE_LRTB, 14, 326, 348, 55, 109, 0x2BF, STR_DRAG_WHOLE_TRAIN_TO_SELL_TIP}, - -{ WWT_MATRIX, RESIZE_RB, 14, 0, 325, 14, 97, 0x601, STR_883F_TRAINS_CLICK_ON_TRAIN_FOR}, -{ WWT_SCROLLBAR, RESIZE_LRB, 14, 349, 360, 14, 109, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST}, -{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 0, 116, 110, 121, STR_8815_NEW_VEHICLES, STR_8840_BUILD_NEW_TRAIN_VEHICLE}, -{WWT_NODISTXTBTN, RESIZE_TB, 14, 117, 232, 110, 121, STR_CLONE_TRAIN, STR_CLONE_TRAIN_DEPOT_INFO}, -{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 233, 348, 110, 121, STR_00E4_LOCATION, STR_8842_CENTER_MAIN_VIEW_ON_TRAIN}, - - -{ WWT_HSCROLLBAR, RESIZE_RTB, 14, 0, 325, 98, 109, 0x0, STR_HSCROLL_BAR_SCROLLS_LIST}, -{ WWT_PANEL, RESIZE_RTB, 14, 349, 348, 110, 121, 0x0, STR_NULL}, - -{ WWT_RESIZEBOX, RESIZE_LRTB, 14, 349, 360, 110, 121, 0x0, STR_RESIZE_BUTTON}, -{ WIDGETS_END}, -}; - -static const WindowDesc _train_depot_desc = { - -1, -1, 361, 122, - WC_VEHICLE_DEPOT,0, - WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE, - _train_depot_widgets, - TrainDepotWndProc -}; - - -void ShowTrainDepotWindow(TileIndex tile) -{ - Window *w; - - w = AllocateWindowDescFront(&_train_depot_desc, tile); - if (w) { - w->caption_color = GetTileOwner(w->window_number); - w->vscroll.cap = 6; - w->hscroll.cap = 10 * 29; - w->resize.step_width = 1; - w->resize.step_height = 14; - WP(w,traindepot_d).sel = INVALID_VEHICLE; - _backup_orders_tile = 0; - } -} - static void RailVehicleRefitWndProc(Window *w, WindowEvent *e) { switch (e->event) { |