mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-03-06 14:27:16 +00:00
(svn r10071) -Feature [FS#828]: moving of orders (skidd13).
This commit is contained in:
parent
98c3056aa6
commit
6b1cb3aaae
@ -176,6 +176,8 @@ DEF_COMMAND(CmdAddSharedVehicleGroup);
|
|||||||
DEF_COMMAND(CmdRemoveAllVehiclesGroup);
|
DEF_COMMAND(CmdRemoveAllVehiclesGroup);
|
||||||
DEF_COMMAND(CmdSetGroupReplaceProtection);
|
DEF_COMMAND(CmdSetGroupReplaceProtection);
|
||||||
|
|
||||||
|
DEF_COMMAND(CmdMoveOrder);
|
||||||
|
|
||||||
/* The master command table */
|
/* The master command table */
|
||||||
static const Command _command_proc_table[] = {
|
static const Command _command_proc_table[] = {
|
||||||
{CmdBuildRailroadTrack, 0}, /* 0 */
|
{CmdBuildRailroadTrack, 0}, /* 0 */
|
||||||
@ -328,6 +330,7 @@ static const Command _command_proc_table[] = {
|
|||||||
{CmdAddSharedVehicleGroup, 0}, /* 124 */
|
{CmdAddSharedVehicleGroup, 0}, /* 124 */
|
||||||
{CmdRemoveAllVehiclesGroup, 0}, /* 125 */
|
{CmdRemoveAllVehiclesGroup, 0}, /* 125 */
|
||||||
{CmdSetGroupReplaceProtection, 0}, /* 126 */
|
{CmdSetGroupReplaceProtection, 0}, /* 126 */
|
||||||
|
{CmdMoveOrder, 0}, /* 127 */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* This function range-checks a cmd, and checks if the cmd is not NULL */
|
/* This function range-checks a cmd, and checks if the cmd is not NULL */
|
||||||
|
@ -143,6 +143,7 @@ enum {
|
|||||||
CMD_MASS_START_STOP = 117,
|
CMD_MASS_START_STOP = 117,
|
||||||
CMD_DEPOT_SELL_ALL_VEHICLES = 118,
|
CMD_DEPOT_SELL_ALL_VEHICLES = 118,
|
||||||
CMD_DEPOT_MASS_AUTOREPLACE = 119,
|
CMD_DEPOT_MASS_AUTOREPLACE = 119,
|
||||||
|
|
||||||
CMD_CREATE_GROUP = 120,
|
CMD_CREATE_GROUP = 120,
|
||||||
CMD_DELETE_GROUP = 121,
|
CMD_DELETE_GROUP = 121,
|
||||||
CMD_RENAME_GROUP = 122,
|
CMD_RENAME_GROUP = 122,
|
||||||
@ -150,6 +151,8 @@ enum {
|
|||||||
CMD_ADD_SHARED_VEHICLE_GROUP = 124,
|
CMD_ADD_SHARED_VEHICLE_GROUP = 124,
|
||||||
CMD_REMOVE_ALL_VEHICLES_GROUP = 125,
|
CMD_REMOVE_ALL_VEHICLES_GROUP = 125,
|
||||||
CMD_SET_GROUP_REPLACE_PROTECTION = 126,
|
CMD_SET_GROUP_REPLACE_PROTECTION = 126,
|
||||||
|
|
||||||
|
CMD_MOVE_ORDER = 127,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -2663,6 +2663,7 @@ STR_8832_TOO_MANY_ORDERS :{WHITE}Too many
|
|||||||
STR_8833_CAN_T_INSERT_NEW_ORDER :{WHITE}Can't insert new order...
|
STR_8833_CAN_T_INSERT_NEW_ORDER :{WHITE}Can't insert new order...
|
||||||
STR_8834_CAN_T_DELETE_THIS_ORDER :{WHITE}Can't delete this order...
|
STR_8834_CAN_T_DELETE_THIS_ORDER :{WHITE}Can't delete this order...
|
||||||
STR_8835_CAN_T_MODIFY_THIS_ORDER :{WHITE}Can't modify this order...
|
STR_8835_CAN_T_MODIFY_THIS_ORDER :{WHITE}Can't modify this order...
|
||||||
|
STR_CAN_T_MOVE_THIS_ORDER :{WHITE}Can't move this order...
|
||||||
STR_CAN_T_SKIP_ORDER :{WHITE}Can't skip current order...
|
STR_CAN_T_SKIP_ORDER :{WHITE}Can't skip current order...
|
||||||
STR_CAN_T_SKIP_TO_ORDER :{WHITE}Can't skip to selected order...
|
STR_CAN_T_SKIP_TO_ORDER :{WHITE}Can't skip to selected order...
|
||||||
STR_8837_CAN_T_MOVE_VEHICLE :{WHITE}Can't move vehicle...
|
STR_8837_CAN_T_MOVE_VEHICLE :{WHITE}Can't move vehicle...
|
||||||
|
@ -598,6 +598,91 @@ int32 CmdSkipToOrder(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Move an order inside the orderlist
|
||||||
|
* @param tile unused
|
||||||
|
* @param p1 the ID of the vehicle
|
||||||
|
* @param p2 order to move and target
|
||||||
|
* bit 0-15 : the order to move
|
||||||
|
* bit 16-31 : the target order
|
||||||
|
* @note The target order will move one place down in the orderlist
|
||||||
|
* if you move the order upwards else it'll move it one place down
|
||||||
|
*/
|
||||||
|
int32 CmdMoveOrder(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
||||||
|
{
|
||||||
|
VehicleID veh = p1;
|
||||||
|
VehicleOrderID moving_order = GB(p2, 0, 16);
|
||||||
|
VehicleOrderID target_order = GB(p2, 16, 16);
|
||||||
|
|
||||||
|
if (!IsValidVehicleID(veh)) return CMD_ERROR;
|
||||||
|
|
||||||
|
Vehicle *v = GetVehicle(veh);
|
||||||
|
if (!CheckOwnership(v->owner)) return CMD_ERROR;
|
||||||
|
|
||||||
|
/* Don't make senseless movements */
|
||||||
|
if (moving_order >= v->num_orders || target_order >= v->num_orders ||
|
||||||
|
moving_order == target_order || v->num_orders <= 1)
|
||||||
|
return CMD_ERROR;
|
||||||
|
|
||||||
|
Order *moving_one = GetVehicleOrder(v, moving_order);
|
||||||
|
/* Don't move an empty order */
|
||||||
|
if (moving_one == NULL) return CMD_ERROR;
|
||||||
|
|
||||||
|
if (flags & DC_EXEC) {
|
||||||
|
/* Take the moving order out of the pointer-chain */
|
||||||
|
Order *one_before = GetVehicleOrder(v, moving_order - 1);
|
||||||
|
Order *one_past = GetVehicleOrder(v, moving_order + 1);
|
||||||
|
|
||||||
|
if (one_before == NULL) {
|
||||||
|
/* First order edit */
|
||||||
|
v->orders = moving_one->next;
|
||||||
|
} else {
|
||||||
|
one_before->next = moving_one->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Insert the moving_order again in the pointer-chain */
|
||||||
|
one_before = GetVehicleOrder(v, target_order - 1);
|
||||||
|
one_past = GetVehicleOrder(v, target_order);
|
||||||
|
|
||||||
|
moving_one->next = one_past;
|
||||||
|
|
||||||
|
if (one_before == NULL) {
|
||||||
|
/* first order edit */
|
||||||
|
SwapOrders(v->orders, moving_one);
|
||||||
|
v->orders->next = moving_one;
|
||||||
|
} else {
|
||||||
|
one_before->next = moving_one;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update shared list */
|
||||||
|
Vehicle *u = GetFirstVehicleFromSharedList(v);
|
||||||
|
|
||||||
|
DeleteOrderWarnings(u);
|
||||||
|
|
||||||
|
for (; u != NULL; u = u->next_shared) {
|
||||||
|
/* Update the first order */
|
||||||
|
if (u->orders != v->orders) u->orders = v->orders;
|
||||||
|
|
||||||
|
/* Update the current order */
|
||||||
|
if (u->cur_order_index == moving_order) {
|
||||||
|
u->cur_order_index = target_order;
|
||||||
|
} else if(u->cur_order_index > moving_order && u->cur_order_index <= target_order) {
|
||||||
|
u->cur_order_index--;
|
||||||
|
} else if(u->cur_order_index < moving_order && u->cur_order_index >= target_order) {
|
||||||
|
u->cur_order_index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(v->orders == u->orders);
|
||||||
|
/* Update any possible open window of the vehicle */
|
||||||
|
InvalidateVehicleOrder(u);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure to rebuild the whole list */
|
||||||
|
RebuildVehicleLists();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/** Modify an order in the orderlist of a vehicle.
|
/** Modify an order in the orderlist of a vehicle.
|
||||||
* @param tile unused
|
* @param tile unused
|
||||||
|
@ -44,6 +44,13 @@ enum OrderWindowWidgets {
|
|||||||
ORDER_WIDGET_RESIZE,
|
ORDER_WIDGET_RESIZE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the memorised selected order.
|
||||||
|
*
|
||||||
|
* @param w current window
|
||||||
|
* @return the memorised order if it is a vaild one
|
||||||
|
* else return the number of orders
|
||||||
|
*/
|
||||||
static int OrderGetSel(const Window *w)
|
static int OrderGetSel(const Window *w)
|
||||||
{
|
{
|
||||||
const Vehicle *v = GetVehicle(w->window_number);
|
const Vehicle *v = GetVehicle(w->window_number);
|
||||||
@ -52,6 +59,33 @@ static int OrderGetSel(const Window *w)
|
|||||||
return (num >= 0 && num < v->num_orders) ? num : v->num_orders;
|
return (num >= 0 && num < v->num_orders) ? num : v->num_orders;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate the selected order.
|
||||||
|
* The calculation is based on the relative (to the window) y click position and
|
||||||
|
* the position of the scrollbar.
|
||||||
|
*
|
||||||
|
* @param w current window
|
||||||
|
* @param y Y-value of the click relative to the window origin
|
||||||
|
* @param v current vehicle
|
||||||
|
* @return the new selected order if the order is valid else return that
|
||||||
|
* an invalid one has been selected.
|
||||||
|
*/
|
||||||
|
static int GetOrderFromOrderWndPt(Window *w, int y, const Vehicle *v)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Calculation description:
|
||||||
|
* 15 = 14 (w->widget[ORDER_WIDGET_ORDER_LIST].top) + 1 (frame-line)
|
||||||
|
* 10 = order text hight
|
||||||
|
*/
|
||||||
|
int sel = (y - 15) / 10;
|
||||||
|
|
||||||
|
if ((uint)sel >= w->vscroll.cap) return INVALID_ORDER;
|
||||||
|
|
||||||
|
sel += w->vscroll.pos;
|
||||||
|
|
||||||
|
return (sel <= v->num_orders && sel >= 0) ? sel : INVALID_ORDER;
|
||||||
|
}
|
||||||
|
|
||||||
static StringID StationOrderStrings[] = {
|
static StringID StationOrderStrings[] = {
|
||||||
STR_8806_GO_TO,
|
STR_8806_GO_TO,
|
||||||
STR_8807_GO_TO_TRANSFER,
|
STR_8807_GO_TO_TRANSFER,
|
||||||
@ -513,14 +547,14 @@ static void OrdersWndProc(Window *w, WindowEvent *e)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case WE_CLICK: {
|
case WE_CLICK: {
|
||||||
Vehicle *v = GetVehicle(w->window_number);
|
const Vehicle *v = GetVehicle(w->window_number);
|
||||||
switch (e->we.click.widget) {
|
switch (e->we.click.widget) {
|
||||||
case ORDER_WIDGET_ORDER_LIST: {
|
case ORDER_WIDGET_ORDER_LIST: {
|
||||||
int sel = (e->we.click.pt.y - 15) / 10;
|
ResetObjectToPlace();
|
||||||
|
|
||||||
if ((uint)sel >= w->vscroll.cap) return;
|
int sel = GetOrderFromOrderWndPt(w, e->we.click.pt.y, v);
|
||||||
|
|
||||||
sel += w->vscroll.pos;
|
if (sel == INVALID_ORDER) return;
|
||||||
|
|
||||||
if (_ctrl_pressed && sel < v->num_orders) {
|
if (_ctrl_pressed && sel < v->num_orders) {
|
||||||
const Order *ord = GetVehicleOrder(v, sel);
|
const Order *ord = GetVehicleOrder(v, sel);
|
||||||
@ -535,10 +569,21 @@ static void OrdersWndProc(Window *w, WindowEvent *e)
|
|||||||
|
|
||||||
if (xy != 0) ScrollMainWindowToTile(xy);
|
if (xy != 0) ScrollMainWindowToTile(xy);
|
||||||
return;
|
return;
|
||||||
|
} else {
|
||||||
|
if (sel == WP(w,order_d).sel) {
|
||||||
|
/* Deselect clicked order */
|
||||||
|
WP(w,order_d).sel = -1;
|
||||||
|
} else {
|
||||||
|
/* Select clicked order */
|
||||||
|
WP(w,order_d).sel = sel;
|
||||||
|
|
||||||
|
if (v->owner == _local_player) {
|
||||||
|
/* Activate drag and drop */
|
||||||
|
SetObjectToPlaceWnd(SPR_CURSOR_MOUSE, PAL_NONE, 4, w);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sel == WP(w,order_d).sel) sel = -1;
|
|
||||||
WP(w,order_d).sel = sel;
|
|
||||||
SetWindowDirty(w);
|
SetWindowDirty(w);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@ -578,6 +623,31 @@ static void OrdersWndProc(Window *w, WindowEvent *e)
|
|||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case WE_DRAGDROP: {
|
||||||
|
const Vehicle *v = GetVehicle(w->window_number);
|
||||||
|
|
||||||
|
switch (e->we.click.widget) {
|
||||||
|
case ORDER_WIDGET_ORDER_LIST: {
|
||||||
|
int from_order = OrderGetSel(w);
|
||||||
|
int to_order = GetOrderFromOrderWndPt(w, e->we.dragdrop.pt.y, v);
|
||||||
|
|
||||||
|
if (!(from_order == to_order || from_order == INVALID_ORDER || from_order > v->num_orders || to_order == INVALID_ORDER || to_order > v->num_orders) &&
|
||||||
|
DoCommandP(v->tile, v->index, from_order | (to_order << 16), NULL, CMD_MOVE_ORDER | CMD_MSG(STR_CAN_T_MOVE_THIS_ORDER))) {
|
||||||
|
WP(w, order_d).sel = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ORDER_WIDGET_DELETE:
|
||||||
|
OrderClick_Delete(w, v);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ResetObjectToPlace();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case WE_KEYPRESS: {
|
case WE_KEYPRESS: {
|
||||||
Vehicle *v = GetVehicle(w->window_number);
|
Vehicle *v = GetVehicle(w->window_number);
|
||||||
uint i;
|
uint i;
|
||||||
|
Loading…
Reference in New Issue
Block a user