Changeset - r8900:dfe0b94b8d96
[Not reviewed]
master
0 6 0
rubidium - 17 years ago 2008-04-12 11:58:19
rubidium@openttd.org
(svn r12667) -Feature: conditional 'skip/jump' orders.
6 files changed with 463 insertions and 37 deletions:
0 comments (0 inline, 0 general)
src/lang/english.txt
Show inline comments
 
@@ -2649,14 +2649,14 @@ STR_8107_MAGLEV_LOCOMOTIVE              
 

	
 
##id 0x8800
 
STR_8800_TRAIN_DEPOT                                            :{WHITE}{TOWN} Train Depot
 
STR_8801_CITIZENS_CELEBRATE_FIRST                               :{BLACK}{BIGFONT}Citizens celebrate . . .{}First train arrives at {STATION}!
 
STR_8802_DETAILS                                                :{WHITE}{VEHICLE} (Details)
 
STR_8803_TRAIN_IN_THE_WAY                                       :{WHITE}Train in the way
 
STR_8804                                                        :{SETX 10}{COMMA}: {STRING3} {STRING2}
 
STR_8805                                                        :{RIGHTARROW}{SETX 10}{COMMA}: {STRING3} {STRING2}
 
STR_8804                                                        :{SETX 10}{COMMA}: {STRING4} {STRING2}
 
STR_8805                                                        :{RIGHTARROW}{SETX 10}{COMMA}: {STRING4} {STRING2}
 
STR_ORDER_GO_TO                                                 :Go to
 
STR_ORDER_GO_NON_STOP_TO                                        :Go non-stop to
 
STR_ORDER_GO_VIA                                                :Go via
 
STR_ORDER_GO_NON_STOP_VIA                                       :Go non-stop via
 
STR_ORDER_DROP_LOAD_IF_POSSIBLE                                 :Load if available
 
STR_ORDER_DROP_FULL_LOAD_ALL                                    :Full load all cargo
 
@@ -2682,13 +2682,13 @@ STR_ORDER_NO_UNLOAD_FULL_LOAD           
 
STR_ORDER_NO_UNLOAD_FULL_LOAD_ANY                               :(No unload and wait for any full load)
 
STR_ORDER_TOOLTIP_NON_STOP                                      :{BLACK}Change the stopping behaviour of the highlighted order
 
STR_ORDER_TOOLTIP_FULL_LOAD                                     :{BLACK}Change the loading behaviour of the highlighted order
 
STR_ORDER_TOOLTIP_UNLOAD                                        :{BLACK}Change the unloading behaviour of the highlighted order
 
STR_GO_TO_STATION                                               :{STRING} {STATION} {STRING}
 

	
 
STR_ORDER_GO_TO_DROPDOWN_TOOLTIP                                :Insert an advanced order
 
STR_ORDER_GO_TO_DROPDOWN_TOOLTIP                                :{BLACK}Insert an advanced order
 
STR_ORDER_GO_TO_NEAREST_DEPOT                                   :Go to nearest depot
 
STR_ORDER_GO_TO_NEAREST_HANGAR                                  :Go to nearest hangar
 
STR_ORDER_NEAREST_DEPOT                                         :the nearest
 
STR_ORDER_NEAREST_HANGAR                                        :the nearest Hangar
 
STR_ORDER_SERVICE_AT                                            :Service at
 
STR_ORDER_SERVICE_NON_STOP_AT                                   :Service non-stop at
 
@@ -2696,13 +2696,35 @@ STR_ORDER_TRAIN_DEPOT                   
 
STR_ORDER_ROAD_DEPOT                                            :Road Vehicle Depot
 
STR_ORDER_SHIP_DEPOT                                            :Ship Depot
 
STR_GO_TO_DEPOT                                                 :{STRING} {TOWN} {STRING}
 
STR_GO_TO_NEAREST_DEPOT                                         :{STRING} {STRING} {STRING}
 
STR_GO_TO_HANGAR                                                :{STRING} {STATION} Hangar
 

	
 
STR_TIMETABLE_GO_TO                                             :{STRING3} {STRING2}
 
STR_ORDER_CONDITIONAL                                           :Conditional order jump
 
STR_ORDER_CONDITIONAL_VARIABLE_TOOLTIP                          :{BLACK}Vehicle data to base jumping on
 
STR_ORDER_CONDITIONAL_COMPARATOR_TOOLTIP                        :{BLACK}How to compare the vehicle data to the given value
 
STR_ORDER_CONDITIONAL_VALUE_TOOLTIP                             :{BLACK}The value to compare the vehicle data against
 
STR_ORDER_CONDITIONAL_VALUE_CAPT                                :{WHITE}Enter value to compare against
 
STR_ORDER_CONDITIONAL_LOAD_PERCENTAGE                           :Load percentage
 
STR_ORDER_CONDITIONAL_RELIABILITY                               :Reliability
 
STR_ORDER_CONDITIONAL_MAX_SPEED                                 :Maximum speed
 
STR_ORDER_CONDITIONAL_AGE                                       :Vehicle age (years)
 
STR_ORDER_CONDITIONAL_REQUIRES_SERVICE                          :Requires service
 
STR_ORDER_CONDITIONAL_COMPARATOR_EQUALS                         :is equal to
 
STR_ORDER_CONDITIONAL_COMPARATOR_NOT_EQUALS                     :is not equal to
 
STR_ORDER_CONDITIONAL_COMPARATOR_LESS_THAN                      :is less than
 
STR_ORDER_CONDITIONAL_COMPARATOR_LESS_EQUALS                    :is less or equal to
 
STR_ORDER_CONDITIONAL_COMPARATOR_MORE_THAN                      :is more than
 
STR_ORDER_CONDITIONAL_COMPARATOR_MORE_EQUALS                    :is more or equal to
 
STR_ORDER_CONDITIONAL_COMPARATOR_IS_TRUE                        :is true
 
STR_ORDER_CONDITIONAL_COMPARATOR_IS_FALSE                       :is false
 
STR_CONDITIONAL_VALUE                                           :{SKIP}{BLACK}{COMMA}
 
STR_CONDITIONAL_NUM                                             :Jump to order {COMMA} when {STRING} {STRING} {COMMA}
 
STR_CONDITIONAL_TRUE_FALSE                                      :Jump to order {COMMA} when {STRING} {STRING}
 

	
 
STR_TIMETABLE_GO_TO                                             :{STRING4} {STRING2}
 
STR_TIMETABLE_TRAVEL_NOT_TIMETABLED                             :Travel (not timetabled)
 
STR_TIMETABLE_TRAVEL_FOR                                        :Travel for {STRING1}
 
STR_TIMETABLE_STAY_FOR                                          :and stay for {STRING1}
 
STR_TIMETABLE_DAYS                                              :{COMMA} day{P "" s}
 
STR_TIMETABLE_TICKS                                             :{COMMA} tick{P "" s}
 

	
src/order_base.h
Show inline comments
 
@@ -63,13 +63,13 @@ public:
 
	inline bool IsType(OrderType type) const { return this->GetType() == type; }
 

	
 
	/**
 
	 * Get the type of order of this order.
 
	 * @return the order type.
 
	 */
 
	inline OrderType GetType() const { return (OrderType)GB(this->type, 0, 6); }
 
	inline OrderType GetType() const { return (OrderType)GB(this->type, 0, 4); }
 

	
 
	/**
 
	 * 'Free' the order
 
	 * @note ONLY use on "current_order" vehicle orders!
 
	 */
 
	void Free();
 
@@ -109,12 +109,18 @@ public:
 
	/**
 
	 * Makes this order a Dummy order.
 
	 */
 
	void MakeDummy();
 

	
 
	/**
 
	 * Makes this order an conditional order.
 
	 * @param order the order to jump to.
 
	 */
 
	void MakeConditional(VehicleOrderID order);
 

	
 
	/**
 
	 * Free a complete order chain.
 
	 * @note do not use on "current_order" vehicle orders!
 
	 */
 
	void FreeChain();
 

	
 
	/**
 
@@ -167,23 +173,39 @@ public:
 
	/** Where must we stop? */
 
	inline OrderNonStopFlags GetNonStopType() const { return (OrderNonStopFlags)GB(this->type, 6, 2); }
 
	/** What caused us going to the depot? */
 
	inline OrderDepotTypeFlags GetDepotOrderType() const { return (OrderDepotTypeFlags)GB(this->flags, 0, 4); }
 
	/** What are we going to do when in the depot. */
 
	inline OrderDepotActionFlags GetDepotActionType() const { return (OrderDepotActionFlags)GB(this->flags, 4, 4); }
 
	/** What variable do we have to compare? */
 
	inline OrderConditionVariable GetConditionVariable() const { return (OrderConditionVariable)GB(this->dest, 11, 5); }
 
	/** What is the comparator to use? */
 
	inline OrderConditionComparator GetConditionComparator() const { return (OrderConditionComparator)GB(this->type, 5, 3); }
 
	/** Get the order to skip to. */
 
	inline VehicleOrderID GetConditionSkipToOrder() const { return this->flags; }
 
	/** Get the value to base the skip on. */
 
	inline uint16 GetConditionValue() const { return GB(this->dest, 0, 11); }
 

	
 
	/** Set how the consist must be loaded. */
 
	inline void SetLoadType(OrderLoadFlags load_type) { SB(this->flags, 4, 4, load_type); }
 
	/** Set how the consist must be unloaded. */
 
	inline void SetUnloadType(OrderUnloadFlags unload_type) { SB(this->flags, 0, 4, unload_type); }
 
	/** Set whether we must stop at stations or not. */
 
	inline void SetNonStopType(OrderNonStopFlags non_stop_type) { SB(this->type, 6, 2, non_stop_type); }
 
	/** Set the cause to go to the depot. */
 
	inline void SetDepotOrderType(OrderDepotTypeFlags depot_order_type) { SB(this->flags, 0, 4, depot_order_type); }
 
	/** Set what we are going to do in the depot. */
 
	inline void SetDepotActionType(OrderDepotActionFlags depot_service_type) { SB(this->flags, 4, 4,  depot_service_type); }
 
	inline void SetDepotActionType(OrderDepotActionFlags depot_service_type) { SB(this->flags, 4, 4, depot_service_type); }
 
	/** Set variable we have to compare. */
 
	inline void SetConditionVariable(OrderConditionVariable condition_variable) { SB(this->dest, 11, 5, condition_variable); }
 
	/** Set the comparator to use. */
 
	inline void SetConditionComparator(OrderConditionComparator condition_comparator) { SB(this->type, 5, 3, condition_comparator); }
 
	/** Get the order to skip to. */
 
	inline void SetConditionSkipToOrder(VehicleOrderID order_id) { this->flags = order_id; }
 
	/** Set the value to base the skip on. */
 
	inline void SetConditionValue(uint16 value) { SB(this->dest, 0, 11, value); }
 

	
 
	bool ShouldStopAtStation(const Vehicle *v, StationID station) const;
 

	
 
	/**
 
	 * Assign the given order to this one.
 
	 * @param other the data to copy (except next pointer).
src/order_cmd.cpp
Show inline comments
 
@@ -90,12 +90,19 @@ void Order::MakeLeaveStation()
 
void Order::MakeDummy()
 
{
 
	this->type = OT_DUMMY;
 
	this->flags = 0;
 
}
 

	
 
void Order::MakeConditional(VehicleOrderID order)
 
{
 
	this->type = OT_CONDITIONAL;
 
	this->flags = 0;
 
	this->dest = order;
 
}
 

	
 
void Order::SetRefit(CargoID cargo, byte subtype)
 
{
 
	this->refit_cargo = cargo;
 
	this->refit_subtype = subtype;
 
}
 

	
 
@@ -424,12 +431,20 @@ CommandCost CmdInsertOrder(TileIndex til
 
			 * [non-stop]
 
			 * non-stop orders (if any) are only valid for trains */
 
			if (new_order.GetNonStopType() != ONSF_STOP_EVERYWHERE && v->type != VEH_TRAIN) return CMD_ERROR;
 
			break;
 
		}
 

	
 
		case OT_CONDITIONAL: {
 
			if (!IsPlayerBuildableVehicleType(v)) return CMD_ERROR;
 

	
 
			VehicleOrderID skip_to = new_order.GetConditionSkipToOrder();
 
			if (skip_to >= v->num_orders) return CMD_ERROR;
 
			if (new_order.GetNonStopType() != ONSF_STOP_EVERYWHERE) return CMD_ERROR;
 
		} break;
 

	
 
		default: return CMD_ERROR;
 
	}
 

	
 
	if (sel_ord > v->num_orders) return CMD_ERROR;
 

	
 
	if (!HasOrderPoolFree(1)) return_cmd_error(STR_8831_NO_MORE_SPACE_FOR_ORDERS);
 
@@ -509,12 +524,28 @@ CommandCost CmdInsertOrder(TileIndex til
 
					u->cur_order_index = cur;
 
			}
 
			/* Update any possible open window of the vehicle */
 
			InvalidateVehicleOrder(u);
 
		}
 

	
 
		/* As we insert an order, the order to skip to will be 'wrong'. */
 
		VehicleOrderID cur_order_id = 0;
 
		Order *order;
 
		FOR_VEHICLE_ORDERS(v, order) {
 
			if (order->IsType(OT_CONDITIONAL)) {
 
				VehicleOrderID order_id = order->GetConditionSkipToOrder();
 
				if (order_id >= sel_ord) {
 
					order->SetConditionSkipToOrder(order_id + 1);
 
				}
 
				if (order_id == cur_order_id) {
 
					order->SetConditionSkipToOrder((order_id + 1) % v->num_orders);
 
				}
 
			}
 
			cur_order_id++;
 
		}
 

	
 
		/* Make sure to rebuild the whole list */
 
		RebuildVehicleLists();
 
	}
 

	
 
	return CommandCost();
 
}
 
@@ -622,12 +653,27 @@ CommandCost CmdDeleteOrder(TileIndex til
 
			}
 

	
 
			/* Update any possible open window of the vehicle */
 
			InvalidateVehicleOrder(u);
 
		}
 

	
 
		/* As we delete an order, the order to skip to will be 'wrong'. */
 
		VehicleOrderID cur_order_id = 0;
 
		FOR_VEHICLE_ORDERS(v, order) {
 
			if (order->IsType(OT_CONDITIONAL)) {
 
				VehicleOrderID order_id = order->GetConditionSkipToOrder();
 
				if (order_id >= sel_ord) {
 
					order->SetConditionSkipToOrder(max(order_id - 1, 0));
 
				}
 
				if (order_id == cur_order_id) {
 
					order->SetConditionSkipToOrder((order_id + 1) % v->num_orders);
 
				}
 
			}
 
			cur_order_id++;
 
		}
 

	
 
		RebuildVehicleLists();
 
	}
 

	
 
	return CommandCost();
 
}
 

	
 
@@ -743,12 +789,28 @@ CommandCost CmdMoveOrder(TileIndex tile,
 

	
 
			assert(v->orders == u->orders);
 
			/* Update any possible open window of the vehicle */
 
			InvalidateVehicleOrder(u);
 
		}
 

	
 
		/* As we move an order, the order to skip to will be 'wrong'. */
 
		Order *order;
 
		FOR_VEHICLE_ORDERS(v, order) {
 
			if (order->IsType(OT_CONDITIONAL)) {
 
				VehicleOrderID order_id = order->GetConditionSkipToOrder();
 
				if (order_id == moving_order) {
 
					order_id = target_order;
 
				} else if(order_id > moving_order && order_id <= target_order) {
 
					order_id--;
 
				} else if(order_id < moving_order && order_id >= target_order) {
 
					order_id++;
 
				}
 
				order->SetConditionSkipToOrder(order_id);
 
			}
 
		}
 

	
 
		/* Make sure to rebuild the whole list */
 
		RebuildVehicleLists();
 
	}
 

	
 
	return CommandCost();
 
}
 
@@ -759,49 +821,56 @@ CommandCost CmdMoveOrder(TileIndex tile,
 
 * @param p1 various bitstuffed elements
 
 * - p1 = (bit  0 - 15) - ID of the vehicle
 
 * - p1 = (bit 16 - 31) - the selected order (if any). If the last order is given,
 
 *                        the order will be inserted before that one
 
 *                        only the first 8 bits used currently (bit 16 - 23) (max 255)
 
 * @param p2 various bitstuffed elements
 
 *  - p2 = (bit 0 - 1) - what data to modify (@see ModifyOrderFlags)
 
 *  - p2 = (bit 2 - 5) - the data to modify
 
 *  - p2 = (bit 0 -  3) - what data to modify (@see ModifyOrderFlags)
 
 *  - p2 = (bit 4 - 15) - the data to modify
 
 */
 
CommandCost CmdModifyOrder(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	VehicleOrderID sel_ord = GB(p1, 16, 16); // XXX - automatically truncated to 8 bits.
 
	VehicleID veh          = GB(p1,  0, 16);
 
	ModifyOrderFlags mof   = (ModifyOrderFlags)GB(p2,  0,  2);
 
	uint8 data             = GB(p2,  2,  4);
 
	ModifyOrderFlags mof   = (ModifyOrderFlags)GB(p2,  0,  4);
 
	uint16 data             = GB(p2, 4, 11);
 

	
 
	if (mof >= MOF_END) return CMD_ERROR;
 
	if (!IsValidVehicleID(veh)) return CMD_ERROR;
 

	
 
	Vehicle *v = GetVehicle(veh);
 
	if (!CheckOwnership(v->owner)) return CMD_ERROR;
 

	
 
	/* Is it a valid order? */
 
	if (sel_ord >= v->num_orders) return CMD_ERROR;
 

	
 
	Order *order = GetVehicleOrder(v, sel_ord);
 
	switch (order->GetType()) {
 
		case OT_GOTO_STATION:
 
			if (mof == MOF_DEPOT_ACTION || GetStation(order->GetDestination())->IsBuoy()) return CMD_ERROR;
 
			if (mof == MOF_COND_VARIABLE || mof == MOF_COND_COMPARATOR || mof == MOF_DEPOT_ACTION || mof == MOF_COND_VALUE || GetStation(order->GetDestination())->IsBuoy()) return CMD_ERROR;
 
			break;
 

	
 
		case OT_GOTO_DEPOT:
 
			if (mof == MOF_UNLOAD || mof == MOF_LOAD) return CMD_ERROR;
 
			if (mof != MOF_NON_STOP && mof != MOF_DEPOT_ACTION) return CMD_ERROR;
 
			break;
 

	
 
		case OT_GOTO_WAYPOINT:
 
			if (mof != MOF_NON_STOP) return CMD_ERROR;
 
			break;
 

	
 
		case OT_CONDITIONAL:
 
			if (mof != MOF_COND_VARIABLE && mof != MOF_COND_COMPARATOR && mof != MOF_COND_VALUE) return CMD_ERROR;
 
			break;
 

	
 
		default:
 
			return CMD_ERROR;
 
	}
 

	
 
	switch (mof) {
 
		default: NOT_REACHED();
 

	
 
		case MOF_NON_STOP:
 
			if (data >= ONSF_END) return CMD_ERROR;
 
			if (data == order->GetNonStopType()) return CMD_ERROR;
 
			break;
 

	
 
		case MOF_UNLOAD:
 
@@ -816,12 +885,42 @@ CommandCost CmdModifyOrder(TileIndex til
 
			if (data == order->GetLoadType()) return CMD_ERROR;
 
			break;
 

	
 
		case MOF_DEPOT_ACTION:
 
			if (data != 0) return CMD_ERROR;
 
			break;
 

	
 
		case MOF_COND_VARIABLE:
 
			if (data >= OCV_END) return CMD_ERROR;
 
			break;
 

	
 
		case MOF_COND_COMPARATOR:
 
			if (data >= OCC_END) return CMD_ERROR;
 
			switch (order->GetConditionVariable()) {
 
				case OCV_REQUIRES_SERVICE:
 
					if (data != OCC_IS_TRUE && data != OCC_IS_FALSE) return CMD_ERROR;
 
					break;
 

	
 
				default:
 
					if (data == OCC_IS_TRUE || data == OCC_IS_FALSE) return CMD_ERROR;
 
					break;
 
			}
 
			break;
 

	
 
		case MOF_COND_VALUE:
 
			switch (order->GetConditionVariable()) {
 
				case OCV_LOAD_PERCENTAGE:
 
				case OCV_RELIABILITY:
 
					if (data > 100) return CMD_ERROR;
 
					break;
 

	
 
				default:
 
					if (data > 2047) return CMD_ERROR;
 
					break;
 
			}
 
			break;
 
	}
 

	
 
	if (flags & DC_EXEC) {
 
		switch (mof) {
 
			case MOF_NON_STOP:
 
				order->SetNonStopType((OrderNonStopFlags)data);
 
@@ -843,12 +942,39 @@ CommandCost CmdModifyOrder(TileIndex til
 
				break;
 

	
 
			case MOF_DEPOT_ACTION:
 
				order->SetDepotOrderType((OrderDepotTypeFlags)(order->GetDepotOrderType() ^ ODTFB_SERVICE));
 
				break;
 

	
 
			case MOF_COND_VARIABLE: {
 
				order->SetConditionVariable((OrderConditionVariable)data);
 

	
 
				OrderConditionComparator occ = order->GetConditionComparator();
 
				switch (order->GetConditionVariable()) {
 
					case OCV_REQUIRES_SERVICE:
 
						if (occ != OCC_IS_TRUE && occ != OCC_IS_FALSE) order->SetConditionComparator(OCC_IS_TRUE);
 
						break;
 

	
 
					case OCV_LOAD_PERCENTAGE:
 
					case OCV_RELIABILITY:
 
						if (order->GetConditionValue() > 100) order->SetConditionValue(100);
 
						/* FALL THROUGH */
 
					default:
 
						if (occ == OCC_IS_TRUE || occ == OCC_IS_FALSE) order->SetConditionComparator(OCC_EQUALS);
 
						break;
 
				}
 
			} break;
 

	
 
			case MOF_COND_COMPARATOR:
 
				order->SetConditionComparator((OrderConditionComparator)data);
 
				break;
 

	
 
			case MOF_COND_VALUE:
 
				order->SetConditionValue(data);
 
				break;
 

	
 
			default: NOT_REACHED();
 
		}
 

	
 
		/* Update the windows and full load flags, also for vehicles that share the same order list */
 
		Vehicle *u = GetFirstVehicleFromSharedList(v);
 
		DeleteOrderWarnings(u);
 
@@ -1414,12 +1540,30 @@ static bool CheckForValidOrders(const Ve
 
	FOR_VEHICLE_ORDERS(v, order) if (!order->IsType(OT_DUMMY)) return true;
 

	
 
	return false;
 
}
 

	
 
/**
 
 * Compare the variable and value based on the given comparator.
 
 */
 
static bool OrderConditionCompare(OrderConditionComparator occ, int variable, int value)
 
{
 
	switch (occ) {
 
		case OCC_EQUALS:      return variable == value;
 
		case OCC_NOT_EQUALS:  return variable != value;
 
		case OCC_LESS_THAN:   return variable <  value;
 
		case OCC_LESS_EQUALS: return variable <= value;
 
		case OCC_MORE_THAN:   return variable >  value;
 
		case OCC_MORE_EQUALS: return variable >= value;
 
		case OCC_IS_TRUE:     return variable != 0;
 
		case OCC_IS_FALSE:    return variable == 0;
 
		default: NOT_REACHED();
 
	}
 
}
 

	
 
/**
 
 * Handle the orders of a vehicle and determine the next place
 
 * to go to if needed.
 
 * @param v the vehicle to do this for.
 
 * @return true *if* the vehicle is eligible for reversing
 
 *              (basically only when leaving a station).
 
 */
 
@@ -1548,12 +1692,33 @@ bool ProcessOrders(Vehicle *v)
 
			break;
 

	
 
		case OT_GOTO_WAYPOINT:
 
			v->dest_tile = GetWaypoint(order->GetDestination())->xy;
 
			break;
 

	
 
		case OT_CONDITIONAL: {
 
			bool skip_order = false;
 
			OrderConditionComparator occ = order->GetConditionComparator();
 
			uint16 value = order->GetConditionValue();
 

	
 
			switch (order->GetConditionVariable()) {
 
				case OCV_LOAD_PERCENTAGE:  skip_order = OrderConditionCompare(occ, CalcPercentVehicleFilled(v, NULL), value); break;
 
				case OCV_RELIABILITY:      skip_order = OrderConditionCompare(occ, v->reliability * 100 >> 16,        value); break;
 
				case OCV_MAX_SPEED:        skip_order = OrderConditionCompare(occ, v->GetDisplayMaxSpeed(),           value); break;
 
				case OCV_AGE:              skip_order = OrderConditionCompare(occ, v->age / 366,                      value); break;
 
				case OCV_REQUIRES_SERVICE: skip_order = OrderConditionCompare(occ, v->NeedsServicing(),               value); break;
 
				default: NOT_REACHED();
 
			}
 
			UpdateVehicleTimetable(v, true);
 
			if (skip_order) {
 
				v->cur_order_index = order->GetConditionSkipToOrder();
 
			} else {
 
				v->cur_order_index++;
 
			}
 
		} return false;
 

	
 
		default:
 
			v->dest_tile = 0;
 
			return false;
 
	}
 

	
 
	return may_reverse;
src/order_gui.cpp
Show inline comments
 
@@ -24,12 +24,14 @@
 
#include "window_func.h"
 
#include "vehicle_func.h"
 
#include "settings_type.h"
 
#include "player_func.h"
 
#include "newgrf_cargo.h"
 
#include "widgets/dropdown_func.h"
 
#include "textbuf_gui.h"
 
#include "string_func.h"
 

	
 
#include "table/sprites.h"
 
#include "table/strings.h"
 

	
 
enum OrderWindowWidgets {
 
	ORDER_WIDGET_CLOSEBOX = 0,
 
@@ -43,19 +45,29 @@ enum OrderWindowWidgets {
 
	ORDER_WIDGET_GOTO,
 
	ORDER_WIDGET_GOTO_DROPDOWN,
 
	ORDER_WIDGET_FULL_LOAD,
 
	ORDER_WIDGET_UNLOAD,
 
	ORDER_WIDGET_REFIT,
 
	ORDER_WIDGET_SERVICE,
 
	ORDER_WIDGET_COND_VARIABLE,
 
	ORDER_WIDGET_COND_COMPARATOR,
 
	ORDER_WIDGET_COND_VALUE,
 
	ORDER_WIDGET_RESIZE_BAR,
 
	ORDER_WIDGET_SHARED_ORDER_LIST,
 
	ORDER_WIDGET_RESIZE,
 
};
 

	
 
/** Under what reason are we using the PlaceObject functionality? */
 
enum OrderPlaceObjectState {
 
	OPOS_GOTO,
 
	OPOS_CONDITIONAL,
 
};
 

	
 
struct order_d {
 
	int sel;
 
	OrderPlaceObjectState goto_type;
 
};
 
assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(order_d));
 

	
 
/**
 
 * Return the memorised selected order.
 
 *
 
@@ -86,13 +98,13 @@ static int GetOrderFromOrderWndPt(Window
 
{
 
	/*
 
	 * Calculation description:
 
	 * 15 = 14 (w->widget[ORDER_WIDGET_ORDER_LIST].top) + 1 (frame-line)
 
	 * 10 = order text hight
 
	 */
 
	int sel = (y - 15) / 10;
 
	int sel = (y - w->widget[ORDER_WIDGET_ORDER_LIST].top - 1) / 10;
 

	
 
	if ((uint)sel >= w->vscroll.cap) return INVALID_ORDER;
 

	
 
	sel += w->vscroll.pos;
 

	
 
	return (sel <= v->num_orders && sel >= 0) ? sel : INVALID_ORDER;
 
@@ -159,36 +171,65 @@ static const StringID _order_unload_drow
 
	INVALID_STRING_ID
 
};
 

	
 
static const StringID _order_goto_dropdown[] = {
 
	STR_ORDER_GO_TO,
 
	STR_ORDER_GO_TO_NEAREST_DEPOT,
 
	STR_ORDER_CONDITIONAL,
 
	INVALID_STRING_ID
 
};
 

	
 
static const StringID _order_goto_dropdown_aircraft[] = {
 
	STR_ORDER_GO_TO,
 
	STR_ORDER_GO_TO_NEAREST_HANGAR,
 
	STR_ORDER_CONDITIONAL,
 
	INVALID_STRING_ID
 
};
 

	
 
static const StringID _order_conditional_variable[] = {
 
	STR_ORDER_CONDITIONAL_LOAD_PERCENTAGE,
 
	STR_ORDER_CONDITIONAL_RELIABILITY,
 
	STR_ORDER_CONDITIONAL_MAX_SPEED,
 
	STR_ORDER_CONDITIONAL_AGE,
 
	STR_ORDER_CONDITIONAL_REQUIRES_SERVICE,
 
	INVALID_STRING_ID,
 
};
 

	
 
static const StringID _order_conditional_condition[] = {
 
	STR_ORDER_CONDITIONAL_COMPARATOR_EQUALS,
 
	STR_ORDER_CONDITIONAL_COMPARATOR_NOT_EQUALS,
 
	STR_ORDER_CONDITIONAL_COMPARATOR_LESS_THAN,
 
	STR_ORDER_CONDITIONAL_COMPARATOR_LESS_EQUALS,
 
	STR_ORDER_CONDITIONAL_COMPARATOR_MORE_THAN,
 
	STR_ORDER_CONDITIONAL_COMPARATOR_MORE_EQUALS,
 
	STR_ORDER_CONDITIONAL_COMPARATOR_IS_TRUE,
 
	STR_ORDER_CONDITIONAL_COMPARATOR_IS_FALSE,
 
	INVALID_STRING_ID,
 
};
 

	
 
extern uint ConvertSpeedToDisplaySpeed(uint speed);
 
extern uint ConvertDisplaySpeedToSpeed(uint speed);
 

	
 

	
 
static void DrawOrdersWindow(Window *w)
 
{
 
	const Vehicle *v = GetVehicle(w->window_number);
 
	bool shared_orders = v->IsOrderListShared();
 

	
 
	SetVScrollCount(w, v->num_orders + 1);
 

	
 
	int sel = OrderGetSel(w);
 
	const Order *order = GetVehicleOrder(v, sel);
 

	
 
	if (v->owner == _local_player) {
 
		/* Set the strings for the dropdown boxes. */
 
		w->widget[ORDER_WIDGET_NON_STOP].data  = _order_non_stop_drowdown[order == NULL ? 0 : order->GetNonStopType()];
 
		w->widget[ORDER_WIDGET_FULL_LOAD].data = _order_full_load_drowdown[order == NULL ? 0 : order->GetLoadType()];
 
		w->widget[ORDER_WIDGET_UNLOAD].data    = _order_unload_drowdown[order == NULL ? 0 : order->GetUnloadType()];
 
		w->widget[ORDER_WIDGET_NON_STOP].data        = _order_non_stop_drowdown[order == NULL ? 0 : order->GetNonStopType()];
 
		w->widget[ORDER_WIDGET_FULL_LOAD].data       = _order_full_load_drowdown[order == NULL ? 0 : order->GetLoadType()];
 
		w->widget[ORDER_WIDGET_UNLOAD].data          = _order_unload_drowdown[order == NULL ? 0 : order->GetUnloadType()];
 
		w->widget[ORDER_WIDGET_COND_VARIABLE].data   = _order_conditional_variable[order == NULL ? 0 : order->GetConditionVariable()];
 
		w->widget[ORDER_WIDGET_COND_COMPARATOR].data = _order_conditional_condition[order == NULL ? 0 : order->GetConditionComparator()];
 

	
 
		/* skip */
 
		w->SetWidgetDisabledState(ORDER_WIDGET_SKIP, v->num_orders <= 1);
 

	
 
		/* delete */
 
		w->SetWidgetDisabledState(ORDER_WIDGET_DELETE,
 
@@ -201,16 +242,19 @@ static void DrawOrdersWindow(Window *w)
 
		/* Disable list of vehicles with the same shared orders if there is no list */
 
		w->SetWidgetDisabledState(ORDER_WIDGET_SHARED_ORDER_LIST, !shared_orders || v->orders == NULL);
 
		w->SetWidgetDisabledState(ORDER_WIDGET_REFIT,     order == NULL); // Refit
 
		w->SetWidgetDisabledState(ORDER_WIDGET_SERVICE,   order == NULL); // Refit
 
		w->HideWidget(ORDER_WIDGET_REFIT); // Refit
 
		w->HideWidget(ORDER_WIDGET_SERVICE); // Service
 
	} else {
 
		w->DisableWidget(ORDER_WIDGET_FULL_LOAD);
 

	
 
		w->HideWidget(ORDER_WIDGET_COND_VARIABLE);
 
		w->HideWidget(ORDER_WIDGET_COND_COMPARATOR);
 
		w->HideWidget(ORDER_WIDGET_COND_VALUE);
 
	}
 

	
 
	w->ShowWidget(ORDER_WIDGET_NON_STOP);
 
	w->ShowWidget(ORDER_WIDGET_UNLOAD);
 
	w->ShowWidget(ORDER_WIDGET_FULL_LOAD);
 

	
 
	if (order != NULL) {
 
		switch (order->GetType()) {
 
			case OT_GOTO_STATION:
 
@@ -229,12 +273,28 @@ static void DrawOrdersWindow(Window *w)
 
				w->HideWidget(ORDER_WIDGET_UNLOAD);
 
				w->ShowWidget(ORDER_WIDGET_REFIT);
 
				w->HideWidget(ORDER_WIDGET_FULL_LOAD);
 
				w->ShowWidget(ORDER_WIDGET_SERVICE);
 
				break;
 

	
 
			case OT_CONDITIONAL: {
 
				w->HideWidget(ORDER_WIDGET_NON_STOP);
 
				w->HideWidget(ORDER_WIDGET_UNLOAD);
 
				w->HideWidget(ORDER_WIDGET_FULL_LOAD);
 
				w->ShowWidget(ORDER_WIDGET_COND_VARIABLE);
 
				w->ShowWidget(ORDER_WIDGET_COND_COMPARATOR);
 
				w->ShowWidget(ORDER_WIDGET_COND_VALUE);
 

	
 
				OrderConditionVariable ocv = order->GetConditionVariable();
 
				w->SetWidgetDisabledState(ORDER_WIDGET_COND_VALUE, ocv == OCV_REQUIRES_SERVICE);
 

	
 
				uint value = order->GetConditionValue();
 
				if (order->GetConditionVariable() == OCV_MAX_SPEED) value = ConvertSpeedToDisplaySpeed(value);
 
				SetDParam(1, value);
 
			} break;
 

	
 
			default: // every other orders
 
				w->DisableWidget(ORDER_WIDGET_NON_STOP);
 
				w->DisableWidget(ORDER_WIDGET_FULL_LOAD);
 
				w->DisableWidget(ORDER_WIDGET_UNLOAD);
 
		}
 
	}
 
@@ -246,13 +306,13 @@ static void DrawOrdersWindow(Window *w)
 

	
 
	int i = w->vscroll.pos;
 
	order = GetVehicleOrder(v, i);
 
	StringID str;
 
	while (order != NULL) {
 
		str = (v->cur_order_index == i) ? STR_8805 : STR_8804;
 
		SetDParam(5, STR_EMPTY);
 
		SetDParam(6, STR_EMPTY);
 

	
 
		if (i - w->vscroll.pos < w->vscroll.cap) {
 
			switch (order->GetType()) {
 
				case OT_DUMMY:
 
					SetDParam(1, STR_INVALID_ORDER);
 
					SetDParam(2, order->GetDestination());
 
@@ -299,22 +359,34 @@ static void DrawOrdersWindow(Window *w)
 
						SetDParam(2, (order->GetNonStopType() & ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS) ? STR_ORDER_SERVICE_NON_STOP_AT : STR_ORDER_SERVICE_AT);
 
					} else {
 
						SetDParam(2, (order->GetNonStopType() & ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS) ? STR_ORDER_GO_NON_STOP_TO : STR_ORDER_GO_TO);
 
					}
 

	
 
					if (order->IsRefit()) {
 
						SetDParam(5, STR_REFIT_ORDER);
 
						SetDParam(6, GetCargo(order->GetRefitCargo())->name);
 
						SetDParam(6, STR_REFIT_ORDER);
 
						SetDParam(7, GetCargo(order->GetRefitCargo())->name);
 
					}
 
					break;
 

	
 
				case OT_GOTO_WAYPOINT:
 
					SetDParam(1, (order->GetNonStopType() & ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS) ? STR_GO_NON_STOP_TO_WAYPOINT : STR_GO_TO_WAYPOINT);
 
					SetDParam(2, order->GetDestination());
 
					break;
 

	
 
				case OT_CONDITIONAL: {
 
					OrderConditionComparator occ = order->GetConditionComparator();
 
					SetDParam(1, (occ == OCC_IS_TRUE || occ == OCC_IS_FALSE) ? STR_CONDITIONAL_TRUE_FALSE : STR_CONDITIONAL_NUM);
 
					SetDParam(2, order->GetConditionSkipToOrder() + 1);
 
					SetDParam(3, STR_ORDER_CONDITIONAL_LOAD_PERCENTAGE + order->GetConditionVariable());
 
					SetDParam(4, STR_ORDER_CONDITIONAL_COMPARATOR_EQUALS + occ);
 

	
 
					uint value = order->GetConditionValue();
 
					if (order->GetConditionVariable() == OCV_MAX_SPEED) value = ConvertSpeedToDisplaySpeed(value);
 
					SetDParam(5, value);
 
				} break;
 

	
 
				default: NOT_REACHED();
 
			}
 

	
 
			SetDParam(0, i + 1);
 
			DrawString(2, y, str, (i == WP(w, order_d).sel) ? TC_WHITE : TC_BLACK);
 

	
 
@@ -459,12 +531,13 @@ static void OrderClick_Goto(Window *w, c
 
{
 
	w->InvalidateWidget(ORDER_WIDGET_GOTO);
 
	w->ToggleWidgetLoweredState(ORDER_WIDGET_GOTO);
 
	if (w->IsWidgetLowered(ORDER_WIDGET_GOTO)) {
 
		_place_clicked_vehicle = NULL;
 
		SetObjectToPlaceWnd(ANIMCURSOR_PICKSTATION, PAL_NONE, VHM_RECT, w);
 
		WP(w, order_d).goto_type = OPOS_GOTO;
 
	} else {
 
		ResetObjectToPlace();
 
	}
 
}
 

	
 
/**
 
@@ -487,13 +560,13 @@ static void OrderClick_FullLoad(Window *
 
			case OLFB_FULL_LOAD:       load_type = OLF_FULL_LOAD_ANY;    break;
 
			case OLF_FULL_LOAD_ANY:    load_type = OLFB_NO_LOAD;         break;
 
			case OLFB_NO_LOAD:         load_type = OLF_LOAD_IF_POSSIBLE; break;
 
			default: NOT_REACHED();
 
		}
 
	}
 
	DoCommandP(v->tile, v->index + (sel_ord << 16), MOF_LOAD | (load_type << 2), NULL, CMD_MODIFY_ORDER | CMD_MSG(STR_8835_CAN_T_MODIFY_THIS_ORDER));
 
	DoCommandP(v->tile, v->index + (sel_ord << 16), MOF_LOAD | (load_type << 4), NULL, CMD_MODIFY_ORDER | CMD_MSG(STR_8835_CAN_T_MODIFY_THIS_ORDER));
 
}
 

	
 
/**
 
 * Handle the click on the service.
 
 *
 
 * @param w current window
 
@@ -519,12 +592,26 @@ static void OrderClick_NearestDepot(Wind
 
	order.SetDepotActionType(ODATFB_NEAREST_DEPOT);
 

	
 
	DoCommandP(v->tile, v->index + (OrderGetSel(w) << 16), order.Pack(), NULL, CMD_INSERT_ORDER | CMD_MSG(STR_8833_CAN_T_INSERT_NEW_ORDER));
 
}
 

	
 
/**
 
 * Handle the click on the conditional order button.
 
 *
 
 * @param w current window
 
 * @param v current vehicle
 
 */
 
static void OrderClick_Conditional(Window *w, const Vehicle *v, int i)
 
{
 
	w->InvalidateWidget(ORDER_WIDGET_GOTO);
 
	w->LowerWidget(ORDER_WIDGET_GOTO);
 
	SetObjectToPlaceWnd(ANIMCURSOR_PICKSTATION, PAL_NONE, VHM_RECT, w);
 
	WP(w, order_d).goto_type = OPOS_CONDITIONAL;
 
}
 

	
 
/**
 
 * Handle the click on the unload button.
 
 *
 
 * @param w current window
 
 * @param v current vehicle
 
 */
 
static void OrderClick_Unload(Window *w, const Vehicle *v, int unload_type)
 
@@ -541,13 +628,13 @@ static void OrderClick_Unload(Window *w,
 
			case OUFB_TRANSFER:          unload_type = OUFB_NO_UNLOAD;         break;
 
			case OUFB_NO_UNLOAD:         unload_type = OUF_UNLOAD_IF_POSSIBLE; break;
 
			default: NOT_REACHED();
 
		}
 
	}
 

	
 
	DoCommandP(v->tile, v->index + (sel_ord << 16), MOF_UNLOAD | (unload_type << 2), NULL, CMD_MODIFY_ORDER | CMD_MSG(STR_8835_CAN_T_MODIFY_THIS_ORDER));
 
	DoCommandP(v->tile, v->index + (sel_ord << 16), MOF_UNLOAD | (unload_type << 4), NULL, CMD_MODIFY_ORDER | CMD_MSG(STR_8835_CAN_T_MODIFY_THIS_ORDER));
 
}
 

	
 
/**
 
 * Handle the click on the nonstop button.
 
 *
 
 * @param w current window
 
@@ -563,13 +650,13 @@ static void OrderClick_Nonstop(Window *w
 

	
 
	/* Keypress if negative, so 'toggle' to the next */
 
	if (non_stop < 0) {
 
		non_stop = (order->GetNonStopType() + 1) % ONSF_END;
 
	}
 

	
 
	DoCommandP(v->tile, v->index + (sel_ord << 16), MOF_NON_STOP | non_stop << 2,  NULL, CMD_MODIFY_ORDER | CMD_MSG(STR_8835_CAN_T_MODIFY_THIS_ORDER));
 
	DoCommandP(v->tile, v->index + (sel_ord << 16), MOF_NON_STOP | non_stop << 4,  NULL, CMD_MODIFY_ORDER | CMD_MSG(STR_8835_CAN_T_MODIFY_THIS_ORDER));
 
}
 

	
 
/**
 
 * Handle the click on the transfer button.
 
 *
 
 * @param w current window
 
@@ -577,13 +664,13 @@ static void OrderClick_Nonstop(Window *w
 
 */
 
static void OrderClick_Transfer(Window *w, const Vehicle *v, int i)
 
{
 
	VehicleOrderID sel_ord = OrderGetSel(w);
 
	const Order *order = GetVehicleOrder(v, sel_ord);
 

	
 
	DoCommandP(v->tile, v->index + (sel_ord << 16), MOF_UNLOAD | ((order->GetUnloadType() & ~OUFB_NO_UNLOAD) ^ OUFB_TRANSFER) << 2, NULL, CMD_MODIFY_ORDER | CMD_MSG(STR_8835_CAN_T_MODIFY_THIS_ORDER));
 
	DoCommandP(v->tile, v->index + (sel_ord << 16), MOF_UNLOAD | ((order->GetUnloadType() & ~OUFB_NO_UNLOAD) ^ OUFB_TRANSFER) << 4, NULL, CMD_MODIFY_ORDER | CMD_MSG(STR_8835_CAN_T_MODIFY_THIS_ORDER));
 
}
 

	
 
/**
 
 * Handle the click on the skip button.
 
 * If ctrl is pressed skip to selected order.
 
 *  Else skip to current order + 1
 
@@ -760,18 +847,56 @@ static void OrdersWndProc(Window *w, Win
 
					break;
 

	
 
				case ORDER_WIDGET_TIMETABLE_VIEW:
 
					ShowTimetableWindow(v);
 
					break;
 

	
 
				case ORDER_WIDGET_COND_VARIABLE:
 
					ShowDropDownMenu(w, _order_conditional_variable, GetVehicleOrder(v, OrderGetSel(w))->GetConditionVariable(), ORDER_WIDGET_COND_VARIABLE, 0, 0);
 
					break;
 

	
 
				case ORDER_WIDGET_COND_COMPARATOR: {
 
					const Order *o = GetVehicleOrder(v, OrderGetSel(w));
 
					ShowDropDownMenu(w, _order_conditional_condition, o->GetConditionComparator(), ORDER_WIDGET_COND_COMPARATOR, 0, (o->GetConditionVariable() == OCV_REQUIRES_SERVICE) ? 0x3F : 0xC0);
 
				} break;
 

	
 
				case ORDER_WIDGET_COND_VALUE: {
 
					const Order *order = GetVehicleOrder(v, OrderGetSel(w));
 
					uint value = order->GetConditionValue();
 
					if (order->GetConditionVariable() == OCV_MAX_SPEED) value = ConvertSpeedToDisplaySpeed(value);
 
					SetDParam(0, value);
 
					ShowQueryString(STR_CONFIG_PATCHES_INT32, STR_ORDER_CONDITIONAL_VALUE_CAPT, 5, 100, w, CS_NUMERAL);
 
				} break;
 

	
 
				case ORDER_WIDGET_SHARED_ORDER_LIST:
 
					ShowVehicleListWindow(v);
 
					break;
 
			}
 
			break;
 

	
 
		case WE_ON_EDIT_TEXT:
 
			if (!StrEmpty(e->we.edittext.str)) {
 
				VehicleOrderID sel = OrderGetSel(w);
 
				uint value = atoi(e->we.edittext.str);
 

	
 
				switch (GetVehicleOrder(v, sel)->GetConditionVariable()) {
 
					case OCV_MAX_SPEED:
 
						value = ConvertDisplaySpeedToSpeed(value);
 
						break;
 

	
 
					case OCV_RELIABILITY:
 
					case OCV_LOAD_PERCENTAGE:
 
						value = Clamp(value, 0, 100);
 

	
 
					default:
 
						break;
 
				}
 
				DoCommandP(v->tile, v->index + (sel << 16), MOF_COND_VALUE | Clamp(value, 0, 2047) << 4, NULL, CMD_MODIFY_ORDER | CMD_MSG(STR_8835_CAN_T_MODIFY_THIS_ORDER));
 
			}
 
			break;
 

	
 
		case WE_DROPDOWN_SELECT: // we have selected a dropdown item in the list
 
			switch (e->we.dropdown.button) {
 
				case ORDER_WIDGET_NON_STOP:
 
					OrderClick_Nonstop(w, v, e->we.dropdown.index);
 
					break;
 

	
 
@@ -782,16 +907,30 @@ static void OrdersWndProc(Window *w, Win
 
				case ORDER_WIDGET_UNLOAD:
 
					OrderClick_Unload(w, v, e->we.dropdown.index);
 
					break;
 

	
 
				case ORDER_WIDGET_GOTO:
 
					switch (e->we.dropdown.index) {
 
						case 0: OrderClick_Goto(w, v, 0); break;
 
						case 0:
 
							w->ToggleWidgetLoweredState(ORDER_WIDGET_GOTO);
 
							OrderClick_Goto(w, v, 0);
 
							break;
 

	
 
						case 1: OrderClick_NearestDepot(w, v, 0); break;
 
						case 2: OrderClick_Conditional(w, v, 0); break;
 
						default: NOT_REACHED();
 
					}
 
					break;
 

	
 
				case ORDER_WIDGET_COND_VARIABLE:
 
					DoCommandP(v->tile, v->index + (OrderGetSel(w) << 16), MOF_COND_VARIABLE | e->we.dropdown.index << 4,  NULL, CMD_MODIFY_ORDER | CMD_MSG(STR_8835_CAN_T_MODIFY_THIS_ORDER));
 
					break;
 

	
 
				case ORDER_WIDGET_COND_COMPARATOR:
 
					DoCommandP(v->tile, v->index + (OrderGetSel(w) << 16), MOF_COND_COMPARATOR | e->we.dropdown.index << 4,  NULL, CMD_MODIFY_ORDER | CMD_MSG(STR_8835_CAN_T_MODIFY_THIS_ORDER));
 
					break;
 
			}
 
			break;
 

	
 
		case WE_DRAGDROP:
 
			switch (e->we.click.widget) {
 
				case ORDER_WIDGET_ORDER_LIST: {
 
@@ -824,16 +963,35 @@ static void OrdersWndProc(Window *w, Win
 
					break;
 
				}
 
			}
 
			break;
 

	
 
		case WE_PLACE_OBJ:
 
			OrdersPlaceObj(GetVehicle(w->window_number), e->we.place.tile, w);
 
			if (WP(w, order_d).goto_type == OPOS_GOTO) {
 
				OrdersPlaceObj(GetVehicle(w->window_number), e->we.place.tile, w);
 
			}
 
			break;
 

	
 
		case WE_ABORT_PLACE_OBJ:
 
			if (WP(w, order_d).goto_type == OPOS_CONDITIONAL) {
 
				WP(w, order_d).goto_type = OPOS_GOTO;
 
				if (_cursor.pos.x >= (w->left + w->widget[ORDER_WIDGET_ORDER_LIST].left) &&
 
						_cursor.pos.y >= (w->top  + w->widget[ORDER_WIDGET_ORDER_LIST].top) &&
 
						_cursor.pos.x <= (w->left + w->widget[ORDER_WIDGET_ORDER_LIST].right) &&
 
						_cursor.pos.y <= (w->top  + w->widget[ORDER_WIDGET_ORDER_LIST].bottom)) {
 
					int order_id = GetOrderFromOrderWndPt(w, _cursor.pos.y - w->top, v);
 
					if (order_id != INVALID_ORDER) {
 
						Order order;
 
						order.next = NULL;
 
						order.index = 0;
 
						order.MakeConditional(order_id);
 

	
 
						DoCommandP(v->tile, v->index + (OrderGetSel(w) << 16), order.Pack(), NULL, CMD_INSERT_ORDER | CMD_MSG(STR_8833_CAN_T_INSERT_NEW_ORDER));
 
					}
 
				}
 
			}
 
			w->RaiseWidget(ORDER_WIDGET_GOTO);
 
			w->InvalidateWidget(ORDER_WIDGET_GOTO);
 
			break;
 

	
 
		/* check if a vehicle in a depot was clicked.. */
 
		case WE_MOUSELOOP:
 
@@ -888,12 +1046,16 @@ static const Widget _orders_train_widget
 
	{   WWT_DROPDOWN,   RESIZE_TB,      14,   360,   371,    88,    99, STR_EMPTY,               STR_ORDER_GO_TO_DROPDOWN_TOOLTIP},    // ORDER_WIDGET_GOTO_DROPDOWN
 
	{   WWT_DROPDOWN,   RESIZE_TB,      14,   124,   247,    76,    87, STR_NULL,                STR_ORDER_TOOLTIP_FULL_LOAD},         // ORDER_WIDGET_FULL_LOAD
 
	{   WWT_DROPDOWN,   RESIZE_TB,      14,   248,   371,    76,    87, STR_NULL,                STR_ORDER_TOOLTIP_UNLOAD},            // ORDER_WIDGET_UNLOAD
 
	{ WWT_PUSHTXTBTN,   RESIZE_TB,      14,   124,   247,    76,    87, STR_REFIT,               STR_REFIT_TIP},                       // ORDER_WIDGET_REFIT
 
	{ WWT_PUSHTXTBTN,   RESIZE_TB,      14,   248,   371,    76,    87, STR_SERVICE,             STR_SERVICE_HINT},                    // ORDER_WIDGET_SERVICE
 

	
 
	{   WWT_DROPDOWN,   RESIZE_TB,      14,     0,   123,    76,    87, STR_NULL,                STR_ORDER_CONDITIONAL_VARIABLE_TOOLTIP},   // ORDER_WIDGET_COND_VARIABLE
 
	{   WWT_DROPDOWN,   RESIZE_TB,      14,   124,   247,    76,    87, STR_NULL,                STR_ORDER_CONDITIONAL_COMPARATOR_TOOLTIP}, // ORDER_WIDGET_COND_COMPARATOR
 
	{ WWT_PUSHTXTBTN,   RESIZE_TB,      14,   248,   371,    76,    87, STR_CONDITIONAL_VALUE,   STR_ORDER_CONDITIONAL_VALUE_TOOLTIP},      // ORDER_WIDGET_COND_VALUE
 

	
 
	{      WWT_PANEL,   RESIZE_RTB,     14,   372,   373,    76,    99, 0x0,                     STR_NULL},                            // ORDER_WIDGET_RESIZE_BAR
 
	{ WWT_PUSHIMGBTN,   RESIZE_LRTB,    14,   372,   385,    76,    87, SPR_SHARED_ORDERS_ICON,  STR_VEH_WITH_SHARED_ORDERS_LIST_TIP}, // ORDER_WIDGET_SHARED_ORDER_LIST
 

	
 
	{  WWT_RESIZEBOX,   RESIZE_LRTB,    14,   374,   385,    88,    99, 0x0,                     STR_RESIZE_BUTTON},                   // ORDER_WIDGET_RESIZE
 
	{   WIDGETS_END},
 
};
 
@@ -921,15 +1083,19 @@ static const Widget _orders_widgets[] = 
 
	{ WWT_PUSHTXTBTN,   RESIZE_TB,      14,     0,   123,    88,    99, STR_8823_SKIP,           STR_8853_SKIP_THE_CURRENT_ORDER},     // ORDER_WIDGET_SKIP
 
	{ WWT_PUSHTXTBTN,   RESIZE_TB,      14,   124,   247,    88,    99, STR_8824_DELETE,         STR_8854_DELETE_THE_HIGHLIGHTED},     // ORDER_WIDGET_DELETE
 
	{      WWT_EMPTY,   RESIZE_TB,      14,     0,     0,    76,    87, 0x0,                     0x0},                                 // ORDER_WIDGET_NON_STOP
 
	{    WWT_TEXTBTN,   RESIZE_TB,      14,   248,   359,    88,    99, STR_8826_GO_TO,          STR_8856_INSERT_A_NEW_ORDER_BEFORE},  // ORDER_WIDGET_GOTO
 
	{   WWT_DROPDOWN,   RESIZE_TB,      14,   360,   371,    88,    99, STR_EMPTY,               STR_ORDER_GO_TO_DROPDOWN_TOOLTIP},    // ORDER_WIDGET_GOTO_DROPDOWN
 
	{   WWT_DROPDOWN,   RESIZE_TB,      14,     0,   185,    76,    87, STR_NULL,                STR_ORDER_TOOLTIP_FULL_LOAD},         // ORDER_WIDGET_FULL_LOAD
 
	{   WWT_DROPDOWN,   RESIZE_TB,      14,   186,   372,    76,    87, STR_NULL,                STR_ORDER_TOOLTIP_UNLOAD},            // ORDER_WIDGET_UNLOAD
 
	{   WWT_DROPDOWN,   RESIZE_TB,      14,   186,   371,    76,    87, STR_NULL,                STR_ORDER_TOOLTIP_UNLOAD},            // ORDER_WIDGET_UNLOAD
 
	{ WWT_PUSHTXTBTN,   RESIZE_TB,      14,     0,   185,    76,    87, STR_REFIT,               STR_REFIT_TIP},                       // ORDER_WIDGET_REFIT
 
	{ WWT_PUSHTXTBTN,   RESIZE_TB,      14,   186,   372,    76,    87, STR_SERVICE,             STR_SERVICE_HINT},                    // ORDER_WIDGET_SERVICE
 
	{ WWT_PUSHTXTBTN,   RESIZE_TB,      14,   186,   371,    76,    87, STR_SERVICE,             STR_SERVICE_HINT},                    // ORDER_WIDGET_SERVICE
 

	
 
	{   WWT_DROPDOWN,   RESIZE_TB,      14,     0,   123,    76,    87, STR_NULL,                STR_ORDER_CONDITIONAL_VARIABLE_TOOLTIP},   // ORDER_WIDGET_COND_VARIABLE
 
	{   WWT_DROPDOWN,   RESIZE_TB,      14,   124,   247,    76,    87, STR_NULL,                STR_ORDER_CONDITIONAL_COMPARATOR_TOOLTIP}, // ORDER_WIDGET_COND_COMPARATOR
 
	{ WWT_PUSHTXTBTN,   RESIZE_TB,      14,   248,   371,    76,    87, STR_CONDITIONAL_VALUE,   STR_ORDER_CONDITIONAL_VALUE_TOOLTIP},      // ORDER_WIDGET_COND_VALUE
 

	
 
	{      WWT_PANEL,   RESIZE_RTB,     14,   372,   373,    76,    99, 0x0,                     STR_NULL},                            // ORDER_WIDGET_RESIZE_BAR
 
	{ WWT_PUSHIMGBTN,   RESIZE_LRTB,    14,   372,   385,    76,    87, SPR_SHARED_ORDERS_ICON,  STR_VEH_WITH_SHARED_ORDERS_LIST_TIP}, // ORDER_WIDGET_SHARED_ORDER_LIST
 

	
 
	{  WWT_RESIZEBOX,   RESIZE_LRTB,    14,   374,   385,    88,    99, 0x0,                     STR_RESIZE_BUTTON},                   // ORDER_WIDGET_RESIZE
 
	{   WIDGETS_END},
 
@@ -962,16 +1128,20 @@ static const Widget _other_orders_widget
 
	{      WWT_EMPTY,   RESIZE_NONE,    14,     0,     0,    76,    87, 0x0,                STR_NULL},                            // ORDER_WIDGET_GOTO_DROPDOWN
 
	{      WWT_EMPTY,   RESIZE_NONE,    14,     0,     0,    76,    87, 0x0,                STR_NULL},                            // ORDER_WIDGET_FULL_LOAD
 
	{      WWT_EMPTY,   RESIZE_NONE,    14,     0,     0,    76,    87, 0x0,                STR_NULL},                            // ORDER_WIDGET_UNLOAD
 
	{      WWT_EMPTY,   RESIZE_NONE,    14,     0,     0,    76,    87, 0x0,                STR_NULL},                            // ORDER_WIDGET_REFIT
 
	{      WWT_EMPTY,   RESIZE_NONE,    14,     0,     0,    76,    87, 0x0,                STR_NULL},                            // ORDER_WIDGET_SERVICE
 

	
 
	{      WWT_EMPTY,   RESIZE_NONE,    14,     0,     0,    76,    87, 0x0,                STR_NULL},                            // ORDER_WIDGET_COND_VARIABLE
 
	{      WWT_EMPTY,   RESIZE_NONE,    14,     0,     0,    76,    87, 0x0,                STR_NULL},                            // ORDER_WIDGET_COND_COMPARATOR
 
	{      WWT_EMPTY,   RESIZE_NONE,    14,     0,     0,    76,    87, 0x0,                STR_NULL},                            // ORDER_WIDGET_COND_VALUE
 

	
 
	{      WWT_PANEL,   RESIZE_RTB,     14,     0,   373,    76,    87, 0x0,                STR_NULL},                            // ORDER_WIDGET_RESIZE_BAR
 
	{      WWT_EMPTY,   RESIZE_TB,      14,     0,     0,    76,    87, 0x0,                STR_NULL},                            // ORDER_WIDGET_SHARED_ORDER_LIST
 

	
 
	{  WWT_RESIZEBOX,   RESIZE_LRTB,    14,   374,   385,    88,    99, 0x0,                STR_RESIZE_BUTTON},              // ORDER_WIDGET_RESIZE
 
	{  WWT_RESIZEBOX,   RESIZE_LRTB,    14,   374,   385,    88,    99, 0x0,                STR_RESIZE_BUTTON},                   // ORDER_WIDGET_RESIZE
 
	{   WIDGETS_END},
 
};
 

	
 
static const WindowDesc _other_orders_desc = {
 
	WDP_AUTO, WDP_AUTO, 386, 88, 386, 88,
 
	WC_VEHICLE_ORDERS,WC_VEHICLE_VIEW,
src/order_type.h
Show inline comments
 
@@ -24,12 +24,13 @@ enum OrderType {
 
	OT_GOTO_STATION  = 1,
 
	OT_GOTO_DEPOT    = 2,
 
	OT_LOADING       = 3,
 
	OT_LEAVESTATION  = 4,
 
	OT_DUMMY         = 5,
 
	OT_GOTO_WAYPOINT = 6,
 
	OT_CONDITIONAL   = 7,
 
	OT_END
 
};
 

	
 
/* It needs to be 8bits, because we save and load it as such */
 
/** Define basic enum properties */
 
template <> struct EnumPropsT<OrderType> : MakeEnumPropsT<OrderType, byte, OT_BEGIN, OT_END, OT_END> {};
 
@@ -83,19 +84,51 @@ enum OrderDepotActionFlags {
 
	ODATF_SERVICE_ONLY   = 0,      ///< Only service the vehicle.
 
	ODATFB_HALT          = 1 << 0, ///< Service the vehicle and then halt it.
 
	ODATFB_NEAREST_DEPOT = 1 << 1, ///< Send the vehicle to the nearest depot.
 
};
 

	
 
/**
 
 * Variables (of a vehicle) to 'cause' skipping on.
 
 */
 
enum OrderConditionVariable {
 
	OCV_LOAD_PERCENTAGE,  ///< Skip based on the amount of load
 
	OCV_RELIABILITY,      ///< Skip based on the reliability
 
	OCV_MAX_SPEED,        ///< Skip based on the maximum speed
 
	OCV_AGE,              ///< Skip based on the age
 
	OCV_REQUIRES_SERVICE, ///< Skip when the vehicle requires service
 
	OCV_END
 
};
 

	
 
/**
 
 * Comparator for the skip reasoning.
 
 */
 
enum OrderConditionComparator {
 
	OCC_EQUALS,      ///< Skip if both values are equal
 
	OCC_NOT_EQUALS,  ///< Skip if both values are not equal
 
	OCC_LESS_THAN,   ///< Skip if the value is less than the limit
 
	OCC_LESS_EQUALS, ///< Skip if the value is less or equal to the limit
 
	OCC_MORE_THAN,   ///< Skip if the value is more than the limit
 
	OCC_MORE_EQUALS, ///< Skip if the value is more or equal to the limit
 
	OCC_IS_TRUE,     ///< Skip if the variable is true
 
	OCC_IS_FALSE,    ///< Skip if the variable is false
 
	OCC_END
 
};
 

	
 

	
 
/**
 
 * Enumeration for the data to set in CmdModifyOrder.
 
 */
 
enum ModifyOrderFlags {
 
	MOF_NON_STOP,      ///< Passes a OrderNonStopFlags.
 
	MOF_UNLOAD,        ///< Passes an OrderUnloadType.
 
	MOF_LOAD,          ///< Passes an OrderLoadType
 
	MOF_DEPOT_ACTION,  ///< Toggle the 'service' if needed flag.
 
	MOF_NON_STOP,        ///< Passes a OrderNonStopFlags.
 
	MOF_UNLOAD,          ///< Passes an OrderUnloadType.
 
	MOF_LOAD,            ///< Passes an OrderLoadType
 
	MOF_DEPOT_ACTION,    ///< Toggle the 'service' if needed flag.
 
	MOF_COND_VARIABLE,   ///< A conditional variable changes.
 
	MOF_COND_COMPARATOR, ///< A comparator changes.
 
	MOF_COND_VALUE,      ///< The value to set the condition to.
 
	MOF_END
 
};
 

	
 

	
 
/* Possible clone options */
 
enum {
 
	CO_SHARE   = 0,
src/timetable_gui.cpp
Show inline comments
 
@@ -113,13 +113,13 @@ static void DrawTimetableWindow(Window *
 

	
 
	while (order != NULL) {
 
		/* Don't draw anything if it extends past the end of the window. */
 
		if (i - w->vscroll.pos >= w->vscroll.cap) break;
 

	
 
		if (i % 2 == 0) {
 
			SetDParam(2, STR_EMPTY);
 
			SetDParam(5, STR_EMPTY);
 

	
 
			switch (order->GetType()) {
 
				case OT_DUMMY:
 
					SetDParam(0, STR_INVALID_ORDER);
 
					break;
 

	
 
@@ -127,14 +127,14 @@ static void DrawTimetableWindow(Window *
 
					SetDParam(0, STR_GO_TO_STATION);
 
					SetDParam(1, STR_ORDER_GO_TO + order->GetNonStopType());
 
					SetDParam(2, order->GetDestination());
 
					SetDParam(3, STR_EMPTY);
 

	
 
					if (order->wait_time > 0) {
 
						SetDParam(4, STR_TIMETABLE_STAY_FOR);
 
						SetTimetableParams(5, 6, order->wait_time);
 
						SetDParam(5, STR_TIMETABLE_STAY_FOR);
 
						SetTimetableParams(6, 7, order->wait_time);
 
					} else {
 
						SetDParam(4, STR_EMPTY);
 
					}
 

	
 
					break;
 

	
 
@@ -175,12 +175,26 @@ static void DrawTimetableWindow(Window *
 

	
 
				case OT_GOTO_WAYPOINT:
 
					SetDParam(0, (order->GetNonStopType() != ONSF_STOP_EVERYWHERE) ? STR_GO_NON_STOP_TO_WAYPOINT : STR_GO_TO_WAYPOINT);
 
					SetDParam(1, order->GetDestination());
 
					break;
 

	
 

	
 
				case OT_CONDITIONAL: {
 
					extern uint ConvertSpeedToDisplaySpeed(uint speed);
 
					OrderConditionComparator occ = order->GetConditionComparator();
 
					SetDParam(0, (occ == OCC_IS_TRUE || occ == OCC_IS_FALSE) ? STR_CONDITIONAL_TRUE_FALSE : STR_CONDITIONAL_NUM);
 
					SetDParam(1, order->GetConditionSkipToOrder() + 1);
 
					SetDParam(2, STR_ORDER_CONDITIONAL_LOAD_PERCENTAGE + order->GetConditionVariable());
 
					SetDParam(3, STR_ORDER_CONDITIONAL_COMPARATOR_EQUALS + occ);
 

	
 
					uint value = order->GetConditionValue();
 
					if (order->GetConditionVariable() == OCV_MAX_SPEED) value = ConvertSpeedToDisplaySpeed(value);
 
					SetDParam(4, value);
 
				} break;
 

	
 
				default: break;
 
			}
 

	
 
			DrawString(2, y, STR_TIMETABLE_GO_TO, (i == selected) ? TC_WHITE : TC_BLACK);
 

	
 
			order_id++;
0 comments (0 inline, 0 general)