mirror of https://github.com/OpenTTD/OpenTTD
(svn r21567) -Feature: Allow to refit only the selected part of a train consist.
parent
96f706fa83
commit
f8c31319e9
|
@ -3131,6 +3131,7 @@ STR_REFIT_CAPTION :{WHITE}{VEHICLE
|
||||||
STR_REFIT_TITLE :{GOLD}Select cargo type to carry:
|
STR_REFIT_TITLE :{GOLD}Select cargo type to carry:
|
||||||
STR_REFIT_NEW_CAPACITY_COST_OF_REFIT :{BLACK}New capacity: {GOLD}{CARGO}{}{BLACK}Cost of refit: {GOLD}{CURRENCY}
|
STR_REFIT_NEW_CAPACITY_COST_OF_REFIT :{BLACK}New capacity: {GOLD}{CARGO}{}{BLACK}Cost of refit: {GOLD}{CURRENCY}
|
||||||
STR_REFIT_NEW_CAPACITY_COST_OF_AIRCRAFT_REFIT :{BLACK}New capacity: {GOLD}{CARGO}, {GOLD}{CARGO}{}{BLACK}Cost of refit: {GOLD}{CURRENCY}
|
STR_REFIT_NEW_CAPACITY_COST_OF_AIRCRAFT_REFIT :{BLACK}New capacity: {GOLD}{CARGO}, {GOLD}{CARGO}{}{BLACK}Cost of refit: {GOLD}{CURRENCY}
|
||||||
|
STR_REFIT_SELECT_VEHICLES_TOOLTIP :{BLACK}Select the vehicles to refit. Dragging with the mouse allows to select multiple vehicles. Clicking on an empty space will select the whole vehicle
|
||||||
|
|
||||||
STR_REFIT_TRAIN_LIST_TOOLTIP :{BLACK}Select type of cargo for train to carry
|
STR_REFIT_TRAIN_LIST_TOOLTIP :{BLACK}Select type of cargo for train to carry
|
||||||
STR_REFIT_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Select type of cargo for road vehicle to carry
|
STR_REFIT_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Select type of cargo for road vehicle to carry
|
||||||
|
|
|
@ -368,6 +368,10 @@ struct RefitWindow : public Window {
|
||||||
int vehicle_width; ///< Width of the vehicle being drawn.
|
int vehicle_width; ///< Width of the vehicle being drawn.
|
||||||
int sprite_left; ///< Left position of the vehicle sprite.
|
int sprite_left; ///< Left position of the vehicle sprite.
|
||||||
int sprite_right; ///< Right position of the vehicle sprite.
|
int sprite_right; ///< Right position of the vehicle sprite.
|
||||||
|
uint vehicle_margin; ///< Margin to use while selecting vehicles when the vehicle image is centered.
|
||||||
|
int click_x; ///< Position of the first click while dragging.
|
||||||
|
VehicleID selected_vehicle; ///< First vehicle in the current selection.
|
||||||
|
uint8 num_vehicles; ///< Number of selected vehicles.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Collects all (cargo, subcargo) refit options of a vehicle chain.
|
* Collects all (cargo, subcargo) refit options of a vehicle chain.
|
||||||
|
@ -377,7 +381,12 @@ struct RefitWindow : public Window {
|
||||||
for (uint i = 0; i < NUM_CARGO; i++) this->list[i].Clear();
|
for (uint i = 0; i < NUM_CARGO; i++) this->list[i].Clear();
|
||||||
Vehicle *v = Vehicle::Get(this->window_number);
|
Vehicle *v = Vehicle::Get(this->window_number);
|
||||||
|
|
||||||
|
/* Check only the selected vehicles. */
|
||||||
|
VehicleSet vehicles_to_refit;
|
||||||
|
GetVehicleSet(vehicles_to_refit, Vehicle::Get(this->selected_vehicle), this->num_vehicles);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
if (v->type == VEH_TRAIN && !vehicles_to_refit.Contains(v->index)) continue;
|
||||||
const Engine *e = Engine::Get(v->engine_type);
|
const Engine *e = Engine::Get(v->engine_type);
|
||||||
uint32 cmask = e->info.refit_mask;
|
uint32 cmask = e->info.refit_mask;
|
||||||
byte callback_mask = e->info.callback_mask;
|
byte callback_mask = e->info.callback_mask;
|
||||||
|
@ -484,6 +493,7 @@ struct RefitWindow : public Window {
|
||||||
nwi->widget_data = STR_REFIT_TRAIN_REFIT_BUTTON + v->type;
|
nwi->widget_data = STR_REFIT_TRAIN_REFIT_BUTTON + v->type;
|
||||||
nwi->tool_tip = STR_REFIT_TRAIN_REFIT_TOOLTIP + v->type;
|
nwi->tool_tip = STR_REFIT_TRAIN_REFIT_TOOLTIP + v->type;
|
||||||
this->GetWidget<NWidgetStacked>(VRW_SHOW_HSCROLLBAR)->SetDisplayedPlane(v->IsGroundVehicle() ? 0 : SZSP_HORIZONTAL);
|
this->GetWidget<NWidgetStacked>(VRW_SHOW_HSCROLLBAR)->SetDisplayedPlane(v->IsGroundVehicle() ? 0 : SZSP_HORIZONTAL);
|
||||||
|
this->GetWidget<NWidgetCore>(VRW_VEHICLE_PANEL_DISPLAY)->tool_tip = (v->type == VEH_TRAIN) ? STR_REFIT_SELECT_VEHICLES_TOOLTIP : STR_NULL;
|
||||||
|
|
||||||
this->FinishInitNested(desc, v->index);
|
this->FinishInitNested(desc, v->index);
|
||||||
this->owner = v->owner;
|
this->owner = v->owner;
|
||||||
|
@ -536,8 +546,10 @@ struct RefitWindow : public Window {
|
||||||
this->sprite_right = vehicle_panel_display->pos_x + vehicle_panel_display->current_x - 1;
|
this->sprite_right = vehicle_panel_display->pos_x + vehicle_panel_display->current_x - 1;
|
||||||
if (_current_text_dir == TD_RTL) {
|
if (_current_text_dir == TD_RTL) {
|
||||||
this->sprite_right -= sprite_width;
|
this->sprite_right -= sprite_width;
|
||||||
|
this->vehicle_margin = vehicle_panel_display->current_x - sprite_right;
|
||||||
} else {
|
} else {
|
||||||
this->sprite_left += sprite_width;
|
this->sprite_left += sprite_width;
|
||||||
|
this->vehicle_margin = sprite_left;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->DrawWidgets();
|
this->DrawWidgets();
|
||||||
|
@ -575,7 +587,8 @@ struct RefitWindow : public Window {
|
||||||
StringID GetCapacityString(RefitOption *option) const
|
StringID GetCapacityString(RefitOption *option) const
|
||||||
{
|
{
|
||||||
Vehicle *v = Vehicle::Get(this->window_number);
|
Vehicle *v = Vehicle::Get(this->window_number);
|
||||||
CommandCost cost = DoCommand(v->tile, v->index, option->cargo | option->subtype << 8, DC_QUERY_COST, GetCmdRefitVeh(v->type));
|
CommandCost cost = DoCommand(v->tile, this->selected_vehicle, option->cargo | option->subtype << 8 |
|
||||||
|
this->num_vehicles << 17, DC_QUERY_COST, GetCmdRefitVeh(v->type));
|
||||||
|
|
||||||
if (cost.Failed()) return INVALID_STRING_ID;
|
if (cost.Failed()) return INVALID_STRING_ID;
|
||||||
|
|
||||||
|
@ -623,8 +636,17 @@ struct RefitWindow : public Window {
|
||||||
virtual void OnInvalidateData(int data)
|
virtual void OnInvalidateData(int data)
|
||||||
{
|
{
|
||||||
switch (data) {
|
switch (data) {
|
||||||
case 0: { // The consist lenght of the vehicle has changed; rebuild the entire list.
|
case 0: { // The consist has changed; rebuild the entire list.
|
||||||
|
/* Clear the selection. */
|
||||||
|
Vehicle *v = Vehicle::Get(this->window_number);
|
||||||
|
this->selected_vehicle = v->index;
|
||||||
|
this->num_vehicles = UINT8_MAX;
|
||||||
|
/* FALL THROUGH */
|
||||||
|
}
|
||||||
|
|
||||||
|
case 2: { // The vehicle selection has changed; rebuild the entire list.
|
||||||
this->BuildRefitList();
|
this->BuildRefitList();
|
||||||
|
|
||||||
/* The vehicle width has changed too. */
|
/* The vehicle width has changed too. */
|
||||||
this->vehicle_width = GetVehicleWidth(Vehicle::Get(this->window_number));
|
this->vehicle_width = GetVehicleWidth(Vehicle::Get(this->window_number));
|
||||||
uint max_width = 0;
|
uint max_width = 0;
|
||||||
|
@ -653,9 +675,72 @@ struct RefitWindow : public Window {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int GetClickPosition(int click_x)
|
||||||
|
{
|
||||||
|
const NWidgetCore *matrix_widget = this->GetWidget<NWidgetCore>(VRW_VEHICLE_PANEL_DISPLAY);
|
||||||
|
if (_current_text_dir == TD_RTL) click_x = matrix_widget->current_x - click_x;
|
||||||
|
click_x -= this->vehicle_margin;
|
||||||
|
click_x += this->hscroll->GetPosition();
|
||||||
|
|
||||||
|
return click_x;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetSelectedVehicles(int drag_x)
|
||||||
|
{
|
||||||
|
drag_x = GetClickPosition(drag_x);
|
||||||
|
|
||||||
|
int left_x = min(this->click_x, drag_x);
|
||||||
|
int right_x = max(this->click_x, drag_x);
|
||||||
|
this->num_vehicles = 0;
|
||||||
|
|
||||||
|
Vehicle *v = Vehicle::Get(this->window_number);
|
||||||
|
/* Find the vehicle part that was clicked. */
|
||||||
|
switch (v->type) {
|
||||||
|
case VEH_TRAIN: {
|
||||||
|
/* Don't select anything if we are not clicking in the vehicle. */
|
||||||
|
if (left_x >= 0) {
|
||||||
|
const Train *u = Train::From(v);
|
||||||
|
bool start_counting = false;
|
||||||
|
for (; u != NULL; u = u->Next()) {
|
||||||
|
int current_width = u->GetDisplayImageWidth();
|
||||||
|
left_x -= current_width;
|
||||||
|
right_x -= current_width;
|
||||||
|
|
||||||
|
if (left_x < 0 && !start_counting) {
|
||||||
|
this->selected_vehicle = u->index;
|
||||||
|
start_counting = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (start_counting) this->num_vehicles++;
|
||||||
|
if (right_x < 0) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the selection is not correct, clear it. */
|
||||||
|
if (this->num_vehicles != 0) break;
|
||||||
|
/* FALL THROUGH */
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* Clear the selection. */
|
||||||
|
this->selected_vehicle = v->index;
|
||||||
|
this->num_vehicles = UINT8_MAX;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
virtual void OnClick(Point pt, int widget, int click_count)
|
virtual void OnClick(Point pt, int widget, int click_count)
|
||||||
{
|
{
|
||||||
switch (widget) {
|
switch (widget) {
|
||||||
|
case VRW_VEHICLE_PANEL_DISPLAY: { // Vehicle image.
|
||||||
|
if (this->order != INVALID_VEH_ORDER_ID) break;
|
||||||
|
NWidgetBase *nwi = this->GetWidget<NWidgetBase>(VRW_VEHICLE_PANEL_DISPLAY);
|
||||||
|
this->click_x = GetClickPosition(pt.x - nwi->pos_x);
|
||||||
|
this->SetSelectedVehicles(pt.x - nwi->pos_x);
|
||||||
|
SetObjectToPlaceWnd(SPR_CURSOR_MOUSE, PAL_NONE, HT_DRAG, this);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case VRW_MATRIX: { // listbox
|
case VRW_MATRIX: { // listbox
|
||||||
this->sel = this->vscroll->GetScrolledRowFromWidget(pt.y, this, VRW_MATRIX);
|
this->sel = this->vscroll->GetScrolledRowFromWidget(pt.y, this, VRW_MATRIX);
|
||||||
if (this->sel == INT_MAX) this->sel = -1;
|
if (this->sel == INT_MAX) this->sel = -1;
|
||||||
|
@ -671,7 +756,7 @@ struct RefitWindow : public Window {
|
||||||
const Vehicle *v = Vehicle::Get(this->window_number);
|
const Vehicle *v = Vehicle::Get(this->window_number);
|
||||||
|
|
||||||
if (this->order == INVALID_VEH_ORDER_ID) {
|
if (this->order == INVALID_VEH_ORDER_ID) {
|
||||||
if (DoCommandP(v->tile, v->index, this->cargo->cargo | this->cargo->subtype << 8, GetCmdRefitVeh(v))) delete this;
|
if (DoCommandP(v->tile, this->selected_vehicle, this->cargo->cargo | this->cargo->subtype << 8 | this->num_vehicles << 17, GetCmdRefitVeh(v))) delete this;
|
||||||
} else {
|
} else {
|
||||||
if (DoCommandP(v->tile, v->index, this->cargo->cargo | this->cargo->subtype << 8 | this->order << 16, CMD_ORDER_REFIT)) delete this;
|
if (DoCommandP(v->tile, v->index, this->cargo->cargo | this->cargo->subtype << 8 | this->order << 16, CMD_ORDER_REFIT)) delete this;
|
||||||
}
|
}
|
||||||
|
@ -680,6 +765,19 @@ struct RefitWindow : public Window {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void OnDragDrop(Point pt, int widget)
|
||||||
|
{
|
||||||
|
switch (widget) {
|
||||||
|
case VRW_VEHICLE_PANEL_DISPLAY: { // Vehicle image.
|
||||||
|
if (this->order != INVALID_VEH_ORDER_ID) break;
|
||||||
|
NWidgetBase *nwi = this->GetWidget<NWidgetBase>(VRW_VEHICLE_PANEL_DISPLAY);
|
||||||
|
this->SetSelectedVehicles(pt.x - nwi->pos_x);
|
||||||
|
this->InvalidateData(2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
virtual void OnResize()
|
virtual void OnResize()
|
||||||
{
|
{
|
||||||
this->vehicle_width = GetVehicleWidth(Vehicle::Get(this->window_number));
|
this->vehicle_width = GetVehicleWidth(Vehicle::Get(this->window_number));
|
||||||
|
|
Loading…
Reference in New Issue