order_cmd.c
changeset 1786 a54634efeb98
parent 1760 0aaab0007731
child 1789 a0708f7418ae
equal deleted inserted replaced
1785:998f4b5eec29 1786:a54634efeb98
   138 	order->type    = data.type;
   138 	order->type    = data.type;
   139 	order->flags   = data.flags;
   139 	order->flags   = data.flags;
   140 	order->station = data.station;
   140 	order->station = data.station;
   141 }
   141 }
   142 
   142 
   143 /**
   143 /** Add an order to the orderlist of a vehicle.
   144  *
   144  * @param x,y unused
   145  * Add an order to the orderlist of a vehicle
   145  * @param p1 various bitstuffed elements
   146  *
   146  * - p1 = (bit  0 - 15) - ID of the vehicle (p1 & 0xFFFF)
   147  * @param veh_sel      First 16 bits are the ID of the vehicle. The next 16 are the selected order (if any)
   147  * - p1 = (bit 16 - 31) - the selected order (if any). If the last order is given,
   148  *                       If the lastone is given, order will be inserted above thatone
   148  *                        the order will be inserted before that one (p1 & 0xFFFF0000)>>16
   149  * @param packed_order Packed order to insert
   149  *                        only the first 8 bytes used currently (bit 16 - 23) (max 255)
   150  *
   150  * @param p2 packed order to insert
   151  */
   151  */
   152 int32 CmdInsertOrder(int x, int y, uint32 flags, uint32 veh_sel, uint32 packed_order)
   152 int32 CmdInsertOrder(int x, int y, uint32 flags, uint32 p1, uint32 p2)
   153 {
   153 {
   154 	Vehicle *v;
   154 	Vehicle *v;
   155 	int sel         = veh_sel >> 16;
   155 	VehicleID veh = p1 & 0xFFFF;
   156 	Order new_order = UnpackOrder(packed_order);
   156 	OrderID sel_ord = p1 >> 16;
   157 
   157 	Order new_order = UnpackOrder(p2);
   158 	if (!IsVehicleIndex(veh_sel & 0xFFFF)) return CMD_ERROR;
   158 
   159 	v = GetVehicle(veh_sel & 0xFFFF);
   159 	if (!IsVehicleIndex(veh)) return CMD_ERROR;
       
   160 	v = GetVehicle(veh);
   160 	if (v->type == 0 || !CheckOwnership(v->owner)) return CMD_ERROR;
   161 	if (v->type == 0 || !CheckOwnership(v->owner)) return CMD_ERROR;
   161 
   162 
       
   163 	/* Check if the inserted order is to the correct destination (owner, type),
       
   164 	 * and has the correct flags if any */
   162 	switch (new_order.type) {
   165 	switch (new_order.type) {
   163 		case OT_GOTO_STATION: {
   166 		case OT_GOTO_STATION: {
   164 			const Station* st;
   167 			const Station *st;
   165 
   168 
   166 			if (!IsStationIndex(new_order.station)) return CMD_ERROR;
   169 			if (!IsStationIndex(new_order.station)) return CMD_ERROR;
   167 			st = GetStation(new_order.station);
   170 			st = GetStation(new_order.station);
   168 
   171 
   169 			if (!IsValidStation(st) ||
   172 			if (!IsValidStation(st) ||
   190 
   193 
   191 				case VEH_Aircraft:
   194 				case VEH_Aircraft:
   192 					if (!(st->facilities & FACIL_AIRPORT)) return CMD_ERROR;
   195 					if (!(st->facilities & FACIL_AIRPORT)) return CMD_ERROR;
   193 					break;
   196 					break;
   194 
   197 
   195 				default:
   198 				default: return CMD_ERROR;
   196 					return CMD_ERROR;
       
   197 			}
   199 			}
   198 
   200 
   199 			switch (new_order.flags) {
   201 			switch (new_order.flags) {
   200 				case 0:
   202 				case 0:
   201 				case OF_FULL_LOAD:
   203 				case OF_FULL_LOAD:
   203 				case OF_NON_STOP:
   205 				case OF_NON_STOP:
   204 				case OF_NON_STOP | OF_FULL_LOAD:
   206 				case OF_NON_STOP | OF_FULL_LOAD:
   205 				case OF_NON_STOP | OF_UNLOAD:
   207 				case OF_NON_STOP | OF_UNLOAD:
   206 					break;
   208 					break;
   207 
   209 
   208 				default:
   210 				default: return CMD_ERROR;
   209 					return CMD_ERROR;
       
   210 			}
   211 			}
   211 			break;
   212 			break;
   212 		}
   213 		}
   213 
   214 
   214 		case OT_GOTO_DEPOT: {
   215 		case OT_GOTO_DEPOT: {
   246 
   247 
   247 					case VEH_Ship:
   248 					case VEH_Ship:
   248 						if (!IsTileDepotType(dp->xy, TRANSPORT_WATER)) return CMD_ERROR;
   249 						if (!IsTileDepotType(dp->xy, TRANSPORT_WATER)) return CMD_ERROR;
   249 						break;
   250 						break;
   250 
   251 
   251 					default:
   252 					default: return CMD_ERROR;
   252 						return CMD_ERROR;
       
   253 				}
   253 				}
   254 			}
   254 			}
   255 
   255 
   256 			switch (new_order.flags) {
   256 			switch (new_order.flags) {
   257 				case OF_PART_OF_ORDERS:
   257 				case OF_PART_OF_ORDERS:
   258 				case OF_PART_OF_ORDERS | OF_HALT_IN_DEPOT:
   258 				case OF_PART_OF_ORDERS | OF_HALT_IN_DEPOT:
   259 				case OF_NON_STOP | OF_PART_OF_ORDERS:
   259 				case OF_NON_STOP | OF_PART_OF_ORDERS:
   260 				case OF_NON_STOP | OF_PART_OF_ORDERS | OF_HALT_IN_DEPOT:
   260 				case OF_NON_STOP | OF_PART_OF_ORDERS | OF_HALT_IN_DEPOT:
   261 					break;
   261 					break;
   262 
   262 
   263 				default:
   263 				default: return CMD_ERROR;
   264 					return CMD_ERROR;
       
   265 			}
   264 			}
   266 			break;
   265 			break;
   267 		}
   266 		}
   268 
   267 
   269 		case OT_GOTO_WAYPOINT: {
   268 		case OT_GOTO_WAYPOINT: {
   279 			switch (new_order.flags) {
   278 			switch (new_order.flags) {
   280 				case 0:
   279 				case 0:
   281 				case OF_NON_STOP:
   280 				case OF_NON_STOP:
   282 					break;
   281 					break;
   283 
   282 
   284 				default:
   283 				default: return CMD_ERROR;
   285 					return CMD_ERROR;
       
   286 			}
   284 			}
   287 			break;
   285 			break;
   288 		}
   286 		}
   289 
   287 
   290 		default:
   288 		default: return CMD_ERROR;
   291 			return CMD_ERROR;
   289 	}
   292 	}
   290 
   293 
   291 	if (sel_ord > v->num_orders) return CMD_ERROR;
   294 	if (sel > v->num_orders)
   292 
   295 		return_cmd_error(STR_EMPTY);
   293 	if (IsOrderPoolFull()) return_cmd_error(STR_8831_NO_MORE_SPACE_FOR_ORDERS);
   296 
       
   297 	if (IsOrderPoolFull())
       
   298 		return_cmd_error(STR_8831_NO_MORE_SPACE_FOR_ORDERS);
       
   299 
   294 
   300 	/* XXX - This limit is only here because the backuppedorders can't
   295 	/* XXX - This limit is only here because the backuppedorders can't
   301 	    handle any more then this.. */
   296 	 * handle any more then this.. */
   302 	if (v->num_orders >= 40)
   297 	if (v->num_orders >= 40) return_cmd_error(STR_8832_TOO_MANY_ORDERS);
   303 		return_cmd_error(STR_8832_TOO_MANY_ORDERS);
       
   304 
   298 
   305 	/* For ships, make sure that the station is not too far away from the
   299 	/* For ships, make sure that the station is not too far away from the
   306 	 * previous destination, for human players with new pathfinding disabled */
   300 	 * previous destination, for human players with new pathfinding disabled */
   307 	if (v->type == VEH_Ship && IS_HUMAN_PLAYER(v->owner) &&
   301 	if (v->type == VEH_Ship && IS_HUMAN_PLAYER(v->owner) &&
   308 		sel != 0 && GetVehicleOrder(v, sel - 1)->type == OT_GOTO_STATION
   302 		sel_ord != 0 && GetVehicleOrder(v, sel_ord - 1)->type == OT_GOTO_STATION
   309 		&& !_patches.new_pathfinding_all) {
   303 		&& !_patches.new_pathfinding_all) {
   310 
   304 
   311 		int dist = DistanceManhattan(
   305 		int dist = DistanceManhattan(
   312 			GetStation(GetVehicleOrder(v, sel - 1)->station)->xy,
   306 			GetStation(GetVehicleOrder(v, sel_ord - 1)->station)->xy,
   313 			GetStation(new_order.station)->xy // XXX type != OT_GOTO_STATION?
   307 			GetStation(new_order.station)->xy // XXX type != OT_GOTO_STATION?
   314 		);
   308 		);
   315 		if (dist >= 130)
   309 		if (dist >= 130)
   316 			return_cmd_error(STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO);
   310 			return_cmd_error(STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO);
   317 	}
   311 	}
   318 
   312 
   319 	if (flags & DC_EXEC) {
   313 	if (flags & DC_EXEC) {
   320 		Order *new;
       
   321 		Vehicle *u;
   314 		Vehicle *u;
   322 
   315 		Order *new = AllocateOrder();
   323 		new = AllocateOrder();
       
   324 		AssignOrder(new, new_order);
   316 		AssignOrder(new, new_order);
   325 
   317 
   326 		/* Create new order and link in list */
   318 		/* Create new order and link in list */
   327 		if (v->orders == NULL) {
   319 		if (v->orders == NULL) {
   328 			v->orders = new;
   320 			v->orders = new;
   329 		} else {
   321 		} else {
   330 			/* Try to get the previous item (we are inserting above the
   322 			/* Try to get the previous item (we are inserting above the
   331 			    selected) */
   323 			    selected) */
   332 			Order *order = GetVehicleOrder(v, sel - 1);
   324 			Order *order = GetVehicleOrder(v, sel_ord - 1);
   333 
   325 
   334 			if (order == NULL && GetVehicleOrder(v, sel) != NULL) {
   326 			if (order == NULL && GetVehicleOrder(v, sel_ord) != NULL) {
   335 				/* There is no previous item, so we are altering v->orders itself
   327 				/* There is no previous item, so we are altering v->orders itself
   336 				    But because the orders can be shared, we copy the info over
   328 				    But because the orders can be shared, we copy the info over
   337 				    the v->orders, so we don't have to change the pointers of
   329 				    the v->orders, so we don't have to change the pointers of
   338 				    all vehicles */
   330 				    all vehicles */
   339 				SwapOrders(v->orders, new);
   331 				SwapOrders(v->orders, new);
   354 		while (u != NULL) {
   346 		while (u != NULL) {
   355 			/* Increase amount of orders */
   347 			/* Increase amount of orders */
   356 			u->num_orders++;
   348 			u->num_orders++;
   357 
   349 
   358 			/* If the orderlist was empty, assign it */
   350 			/* If the orderlist was empty, assign it */
   359 			if (u->orders == NULL)
   351 			if (u->orders == NULL) u->orders = v->orders;
   360 				u->orders = v->orders;
       
   361 
   352 
   362 			assert(v->orders == u->orders);
   353 			assert(v->orders == u->orders);
   363 
   354 
   364 			/* If there is added an order before the current one, we need
   355 			/* If there is added an order before the current one, we need
   365 			to update the selected order */
   356 			to update the selected order */
   366 			if (sel <= u->cur_order_index) {
   357 			if (sel_ord <= u->cur_order_index) {
   367 				uint cur = u->cur_order_index + 1;
   358 				uint cur = u->cur_order_index + 1;
   368 				/* Check if we don't go out of bound */
   359 				/* Check if we don't go out of bound */
   369 				if (cur < u->num_orders)
   360 				if (cur < u->num_orders)
   370 					u->cur_order_index = cur;
   361 					u->cur_order_index = cur;
   371 			}
   362 			}
   380 	}
   371 	}
   381 
   372 
   382 	return 0;
   373 	return 0;
   383 }
   374 }
   384 
   375 
   385 /**
   376 /** Declone an order-list
   386  *
   377  * @param *dst delete the orders of this vehicle
   387  * Declone an order-list
   378  * @param flags execution flags
   388  *
       
   389  */
   379  */
   390 static int32 DecloneOrder(Vehicle *dst, uint32 flags)
   380 static int32 DecloneOrder(Vehicle *dst, uint32 flags)
   391 {
   381 {
   392 	if (flags & DC_EXEC) {
   382 	if (flags & DC_EXEC) {
   393 		/* Delete orders from vehicle */
   383 		/* Delete orders from vehicle */
   397 		RebuildVehicleLists();
   387 		RebuildVehicleLists();
   398 	}
   388 	}
   399 	return 0;
   389 	return 0;
   400 }
   390 }
   401 
   391 
   402 /**
   392 /** Delete an order from the orderlist of a vehicle.
   403  *
   393  * @param x,y unused
   404  * Delete an order from the orderlist of a vehicle
   394  * @param p1 the ID of the vehicle
   405  *
   395  * @param p2 the order to delete (max 255)
   406  * @param vehicle_id The ID of the vehicle
   396  */
   407  * @param selected   The order to delete
   397 int32 CmdDeleteOrder(int x, int y, uint32 flags, uint32 p1, uint32 p2)
   408  *
   398 {
   409  */
   399 	Vehicle *v, *u;
   410 int32 CmdDeleteOrder(int x, int y, uint32 flags, uint32 vehicle_id, uint32 selected)
   400 	VehicleID veh_id = p1;
   411 {
   401 	OrderID sel_ord = p2;
   412 	Vehicle *v;
       
   413 	Vehicle *u;
       
   414 	uint sel   = selected;
       
   415 	Order *order;
   402 	Order *order;
   416 
   403 
   417 	if (!IsVehicleIndex(vehicle_id)) return CMD_ERROR;
   404 	if (!IsVehicleIndex(veh_id)) return CMD_ERROR;
   418 	v = GetVehicle(vehicle_id);
   405 	v = GetVehicle(veh_id);
   419 	if (v->type == 0 || !CheckOwnership(v->owner)) return CMD_ERROR;
   406 	if (v->type == 0 || !CheckOwnership(v->owner)) return CMD_ERROR;
   420 
   407 
   421 	/* XXX -- Why is this here? :s */
       
   422 	_error_message = STR_EMPTY;
       
   423 
       
   424 	/* If we did not select an order, we maybe want to de-clone the orders */
   408 	/* If we did not select an order, we maybe want to de-clone the orders */
   425 	if (sel >= v->num_orders)
   409 	if (sel_ord >= v->num_orders)
   426 		return DecloneOrder(v, flags);
   410 		return DecloneOrder(v, flags);
   427 
   411 
   428 	order = GetVehicleOrder(v, sel);
   412 	order = GetVehicleOrder(v, sel_ord);
   429 	if (order == NULL)
   413 	if (order == NULL) return CMD_ERROR;
   430 		return CMD_ERROR;
       
   431 
   414 
   432 	if (flags & DC_EXEC) {
   415 	if (flags & DC_EXEC) {
   433 		if (GetVehicleOrder(v, sel - 1) == NULL) {
   416 		if (GetVehicleOrder(v, sel_ord - 1) == NULL) {
   434 			if (GetVehicleOrder(v, sel + 1) != NULL) {
   417 			if (GetVehicleOrder(v, sel_ord + 1) != NULL) {
   435 				/* First item, but not the last, so we need to alter v->orders
   418 				/* First item, but not the last, so we need to alter v->orders
   436 				    Because we can have shared order, we copy the data
   419 				    Because we can have shared order, we copy the data
   437 				    from the next item over the deleted */
   420 				    from the next item over the deleted */
   438 				order = GetVehicleOrder(v, sel + 1);
   421 				order = GetVehicleOrder(v, sel_ord + 1);
   439 				SwapOrders(v->orders, order);
   422 				SwapOrders(v->orders, order);
   440 			} else {
   423 			} else {
   441 				/* Last item, so clean the list */
   424 				/* Last item, so clean the list */
   442 				v->orders = NULL;
   425 				v->orders = NULL;
   443 			}
   426 			}
   444 		} else {
   427 		} else {
   445 			GetVehicleOrder(v, sel - 1)->next = order->next;
   428 			GetVehicleOrder(v, sel_ord - 1)->next = order->next;
   446 		}
   429 		}
   447 
   430 
   448 		/* Give the item free */
   431 		/* Give the item free */
   449 		order->type = OT_NOTHING;
   432 		order->type = OT_NOTHING;
   450 		order->next = NULL;
   433 		order->next = NULL;
   451 
   434 
   452 		u = GetFirstVehicleFromSharedList(v);
   435 		u = GetFirstVehicleFromSharedList(v);
   453 		while (u != NULL) {
   436 		while (u != NULL) {
   454 			u->num_orders--;
   437 			u->num_orders--;
   455 
   438 
   456 			if (sel < u->cur_order_index)
   439 			if (sel_ord < u->cur_order_index)
   457 				u->cur_order_index--;
   440 				u->cur_order_index--;
   458 
   441 
   459 			/* If we removed the last order, make sure the shared vehicles
   442 			/* If we removed the last order, make sure the shared vehicles
   460 			    also set their orders to NULL */
   443 			 * also set their orders to NULL */
   461 			if (v->orders == NULL)
   444 			if (v->orders == NULL) u->orders = NULL;
   462 				u->orders = NULL;
       
   463 
   445 
   464 			assert(v->orders == u->orders);
   446 			assert(v->orders == u->orders);
   465 
   447 
   466 			/* NON-stop flag is misused to see if a train is in a station that is
   448 			/* NON-stop flag is misused to see if a train is in a station that is
   467 			    on his order list or not */
   449 			 * on his order list or not */
   468 			if (sel == u->cur_order_index &&
   450 			if (sel_ord == u->cur_order_index && u->current_order.type == OT_LOADING &&
   469 					u->current_order.type == OT_LOADING &&
       
   470 					HASBIT(u->current_order.flags, OFB_NON_STOP)) {
   451 					HASBIT(u->current_order.flags, OFB_NON_STOP)) {
   471 				u->current_order.flags = 0;
   452 				u->current_order.flags = 0;
   472 			}
   453 			}
   473 
   454 
   474 			/* Update any possible open window of the vehicle */
   455 			/* Update any possible open window of the vehicle */
   481 	}
   462 	}
   482 
   463 
   483 	return 0;
   464 	return 0;
   484 }
   465 }
   485 
   466 
   486 /**
   467 /** Goto next order of order-list.
   487  *
   468  * @param x,y unused
   488  * Goto next order of order-list
   469  * @param p1 The ID of the vehicle which order is skipped
   489  *
   470  * @param p2 unused
   490  * @param vehicle_id The ID of the vehicle
   471  */
   491  *
   472 int32 CmdSkipOrder(int x, int y, uint32 flags, uint32 p1, uint32 p2)
   492  */
       
   493 int32 CmdSkipOrder(int x, int y, uint32 flags, uint32 vehicle_id, uint32 not_used)
       
   494 {
   473 {
   495 	Vehicle *v;
   474 	Vehicle *v;
   496 
   475 	VehicleID veh_id = p1;
   497 	if (!IsVehicleIndex(vehicle_id)) return CMD_ERROR;
   476 
   498 	v = GetVehicle(vehicle_id);
   477 	if (!IsVehicleIndex(veh_id)) return CMD_ERROR;
       
   478 	v = GetVehicle(veh_id);
   499 	if (v->type == 0 || !CheckOwnership(v->owner)) return CMD_ERROR;
   479 	if (v->type == 0 || !CheckOwnership(v->owner)) return CMD_ERROR;
   500 
   480 
   501 	if (flags & DC_EXEC) {
   481 	if (flags & DC_EXEC) {
   502 		/* Goto next order */
   482 		/* Goto next order */
   503 		{
   483 		OrderID b = v->cur_order_index + 1;
   504 			byte b = v->cur_order_index + 1;
   484 		if (b >= v->num_orders) b = 0;
   505 			if (b >= v->num_orders)
   485 
   506 				b = 0;
   486 		v->cur_order_index = b;
   507 
   487 
   508 			v->cur_order_index = b;
   488 		if (v->type == VEH_Train) v->u.rail.days_since_order_progr = 0;
   509 
   489 
   510 			if (v->type == VEH_Train)
   490 		if (v->type == VEH_Road) ClearSlot(v, v->u.road.slot);
   511 				v->u.rail.days_since_order_progr = 0;
       
   512 
       
   513 			if (v->type == VEH_Road)
       
   514 				ClearSlot(v, v->u.road.slot);
       
   515 		}
       
   516 
   491 
   517 		/* NON-stop flag is misused to see if a train is in a station that is
   492 		/* NON-stop flag is misused to see if a train is in a station that is
   518 		    on his order list or not */
   493 		 * on his order list or not */
   519 		if (v->current_order.type == OT_LOADING &&
   494 		if (v->current_order.type == OT_LOADING && HASBIT(v->current_order.flags, OFB_NON_STOP))
   520 				HASBIT(v->current_order.flags, OFB_NON_STOP)) {
       
   521 			v->current_order.flags = 0;
   495 			v->current_order.flags = 0;
   522 		}
       
   523 
   496 
   524 		InvalidateVehicleOrder(v);
   497 		InvalidateVehicleOrder(v);
   525 	}
   498 	}
   526 
   499 
   527 	/* We have an aircraft/ship, they have a mini-schedule, so update them all */
   500 	/* We have an aircraft/ship, they have a mini-schedule, so update them all */
   530 
   503 
   531 	return 0;
   504 	return 0;
   532 }
   505 }
   533 
   506 
   534 
   507 
   535 /**
   508 /** Modify an order in the orderlist of a vehicle.
   536  *
   509  * @param x,y unused
   537  * Modify an order in the orderlist of a vehicle
   510  * @param p1 various bitstuffed elements
   538  *
   511  * - p1 = (bit  0 - 15) - ID of the vehicle (p1 & 0xFFFF)
   539  * @param veh_sel      First 16 bits are the ID of the vehicle. The next 16 are the selected order (if any)
   512  * - p1 = (bit 16 - 31) - the selected order (if any). If the last order is given,
   540  *                       If the lastone is given, order will be inserted above thatone
   513  *                        the order will be inserted before that one (p1 & 0xFFFF0000)>>16
   541  * @param mode         Mode to change the order to
   514  *                        only the first 8 bytes used currently (bit 16 - 23) (max 255)
   542  *
   515  * @param p2 mode to change the order to (always set)
   543  */
   516  */
   544 int32 CmdModifyOrder(int x, int y, uint32 flags, uint32 veh_sel, uint32 mode)
   517 int32 CmdModifyOrder(int x, int y, uint32 flags, uint32 p1, uint32 p2)
   545 {
   518 {
   546 	Vehicle *v;
   519 	Vehicle *v;
   547 	byte sel = veh_sel >> 16;
       
   548 	Order *order;
   520 	Order *order;
   549 
   521 	OrderID sel_ord = p1 >> 16; // XXX - automatically truncated to 8 bits.
   550 	if (!IsVehicleIndex(veh_sel & 0xFFFF)) return CMD_ERROR;
   522 	VehicleID veh = p1 & 0xFFFF;
   551 	v = GetVehicle(veh_sel & 0xFFFF);
   523 
       
   524 	if (!IsVehicleIndex(veh)) return CMD_ERROR;
       
   525 	if (p2 != OFB_FULL_LOAD || p2 != OFB_UNLOAD || p2 != OFB_NON_STOP) return CMD_ERROR;
       
   526 
       
   527 	v = GetVehicle(veh);
   552 	if (v->type == 0 || !CheckOwnership(v->owner)) return CMD_ERROR;
   528 	if (v->type == 0 || !CheckOwnership(v->owner)) return CMD_ERROR;
   553 
   529 
   554 	/* Is it a valid order? */
   530 	/* Is it a valid order? */
   555 	if (sel >= v->num_orders)
   531 	if (sel_ord >= v->num_orders) return CMD_ERROR;
       
   532 
       
   533 	order = GetVehicleOrder(v, sel_ord);
       
   534 	if (order->type != OT_GOTO_STATION &&
       
   535 		 (order->type != OT_GOTO_DEPOT || p2 == OFB_UNLOAD) &&
       
   536 		 (order->type != OT_GOTO_WAYPOINT || p2 != OFB_NON_STOP))
   556 		return CMD_ERROR;
   537 		return CMD_ERROR;
   557 
   538 
   558 	order = GetVehicleOrder(v, sel);
       
   559 	if (order->type != OT_GOTO_STATION &&
       
   560 			(order->type != OT_GOTO_DEPOT || mode == OFB_UNLOAD) &&
       
   561 			(order->type != OT_GOTO_WAYPOINT || mode != OFB_NON_STOP))
       
   562 		return CMD_ERROR;
       
   563 
       
   564 	if (flags & DC_EXEC) {
   539 	if (flags & DC_EXEC) {
   565 		switch (mode) {
   540 		switch (p2) {
   566 		case OFB_FULL_LOAD:
   541 		case OFB_FULL_LOAD:
   567 			TOGGLEBIT(order->flags, OFB_FULL_LOAD);
   542 			TOGGLEBIT(order->flags, OFB_FULL_LOAD);
   568 			if (order->type != OT_GOTO_DEPOT)
   543 			if (order->type != OT_GOTO_DEPOT)
   569 				CLRBIT(order->flags, OFB_UNLOAD);
   544 				CLRBIT(order->flags, OFB_UNLOAD);
   570 			break;
   545 			break;
   573 			CLRBIT(order->flags, OFB_FULL_LOAD);
   548 			CLRBIT(order->flags, OFB_FULL_LOAD);
   574 			break;
   549 			break;
   575 		case OFB_NON_STOP:
   550 		case OFB_NON_STOP:
   576 			TOGGLEBIT(order->flags, OFB_NON_STOP);
   551 			TOGGLEBIT(order->flags, OFB_NON_STOP);
   577 			break;
   552 			break;
   578 
   553 		default: NOT_REACHED();
   579 			default:
       
   580 				return CMD_ERROR;
       
   581 		}
   554 		}
   582 
   555 
   583 		/* Update the windows and full load flags, also for vehicles that share the same order list */
   556 		/* Update the windows and full load flags, also for vehicles that share the same order list */
   584 		{
   557 		{
   585 			Vehicle *u = GetFirstVehicleFromSharedList(v);
   558 			Vehicle *u = GetFirstVehicleFromSharedList(v);
   586 			while (u != NULL) {
   559 			while (u != NULL) {
   587 				/* toggle u->current_order "Full load" flag if it changed */
   560 				/* toggle u->current_order "Full load" flag if it changed */
   588 				if (sel == u->cur_order_index &&
   561 				if (sel_ord == u->cur_order_index &&
   589 						HASBIT(u->current_order.flags, OFB_FULL_LOAD) != HASBIT(order->flags, OFB_FULL_LOAD))
   562 						HASBIT(u->current_order.flags, OFB_FULL_LOAD) != HASBIT(order->flags, OFB_FULL_LOAD))
   590 					TOGGLEBIT(u->current_order.flags, OFB_FULL_LOAD);
   563 					TOGGLEBIT(u->current_order.flags, OFB_FULL_LOAD);
   591 				InvalidateVehicleOrder(u);
   564 				InvalidateVehicleOrder(u);
   592 				u = u->next_shared;
   565 				u = u->next_shared;
   593 			}
   566 			}