order_cmd.c
changeset 1718 96d76767ea93
parent 1680 2d69b69f7b17
child 1733 7b74d376b184
equal deleted inserted replaced
1717:44bff152f15f 1718:96d76767ea93
     1 #include "stdafx.h"
     1 #include "stdafx.h"
     2 #include "ttd.h"
     2 #include "ttd.h"
       
     3 #include "airport.h"
       
     4 #include "depot.h"
     3 #include "table/strings.h"
     5 #include "table/strings.h"
     4 #include "vehicle.h"
     6 #include "vehicle.h"
       
     7 #include "waypoint.h"
     5 #include "command.h"
     8 #include "command.h"
     6 #include "station.h"
     9 #include "station.h"
     7 #include "player.h"
    10 #include "player.h"
     8 #include "news.h"
    11 #include "news.h"
     9 #include "saveload.h"
    12 #include "saveload.h"
   145  * @param packed_order Packed order to insert
   148  * @param packed_order Packed order to insert
   146  *
   149  *
   147  */
   150  */
   148 int32 CmdInsertOrder(int x, int y, uint32 flags, uint32 veh_sel, uint32 packed_order)
   151 int32 CmdInsertOrder(int x, int y, uint32 flags, uint32 veh_sel, uint32 packed_order)
   149 {
   152 {
   150 	Vehicle *v      = GetVehicle(veh_sel & 0xFFFF);
   153 	Vehicle *v;
   151 	int sel         = veh_sel >> 16;
   154 	int sel         = veh_sel >> 16;
   152 	Order new_order = UnpackOrder(packed_order);
   155 	Order new_order = UnpackOrder(packed_order);
       
   156 
       
   157 	if (!IsVehicleIndex(veh_sel & 0xFFFF)) return CMD_ERROR;
       
   158 	v = GetVehicle(veh_sel & 0xFFFF);
       
   159 	if (v->type == 0 || !CheckOwnership(v->owner)) return CMD_ERROR;
       
   160 
       
   161 	switch (new_order.type) {
       
   162 		case OT_GOTO_STATION: {
       
   163 			const Station* st;
       
   164 
       
   165 			if (!IsStationIndex(new_order.station)) return CMD_ERROR;
       
   166 			st = GetStation(new_order.station);
       
   167 
       
   168 			if (!IsValidStation(st) ||
       
   169 					(st->airport_type != AT_OILRIG && !CheckOwnership(st->owner))) {
       
   170 				return CMD_ERROR;
       
   171 			}
       
   172 
       
   173 			switch (v->type) {
       
   174 				case VEH_Train:
       
   175 					if (!(st->facilities & FACIL_TRAIN)) return CMD_ERROR;
       
   176 					break;
       
   177 
       
   178 				case VEH_Road:
       
   179 					if (v->cargo_type == CT_PASSENGERS) {
       
   180 						if (!(st->facilities & FACIL_BUS_STOP)) return CMD_ERROR;
       
   181 					} else {
       
   182 						if (!(st->facilities & FACIL_TRUCK_STOP)) return CMD_ERROR;
       
   183 					}
       
   184 					break;
       
   185 
       
   186 				case VEH_Ship:
       
   187 					if (!(st->facilities & FACIL_DOCK)) return CMD_ERROR;
       
   188 					break;
       
   189 
       
   190 				case VEH_Aircraft:
       
   191 					if (!(st->facilities & FACIL_AIRPORT)) return CMD_ERROR;
       
   192 					break;
       
   193 
       
   194 				default:
       
   195 					return CMD_ERROR;
       
   196 			}
       
   197 
       
   198 			switch (new_order.flags) {
       
   199 				case 0:
       
   200 				case OF_FULL_LOAD:
       
   201 				case OF_UNLOAD:
       
   202 				case OF_NON_STOP:
       
   203 				case OF_NON_STOP | OF_FULL_LOAD:
       
   204 				case OF_NON_STOP | OF_UNLOAD:
       
   205 					break;
       
   206 
       
   207 				default:
       
   208 					return CMD_ERROR;
       
   209 			}
       
   210 			break;
       
   211 		}
       
   212 
       
   213 		case OT_GOTO_DEPOT: {
       
   214 			if (v->type == VEH_Aircraft) {
       
   215 				const Station* st;
       
   216 
       
   217 				if (!IsStationIndex(new_order.station)) return CMD_ERROR;
       
   218 				st = GetStation(new_order.station);
       
   219 
       
   220 				if (!IsValidStation(st) ||
       
   221 						(st->airport_type != AT_OILRIG && !CheckOwnership(st->owner)) ||
       
   222 						!(st->facilities & FACIL_AIRPORT) ||
       
   223 						GetAirport(st->airport_type)->nof_depots == 0) {
       
   224 					return CMD_ERROR;
       
   225 				}
       
   226 			} else {
       
   227 				const Depot* dp;
       
   228 
       
   229 				if (!IsDepotIndex(new_order.station)) return CMD_ERROR;
       
   230 				dp = GetDepot(new_order.station);
       
   231 
       
   232 				if (!IsValidDepot(dp) ||
       
   233 						!CheckOwnership(GetTileOwner(dp->xy))) {
       
   234 					return CMD_ERROR;
       
   235 				}
       
   236 
       
   237 				switch (v->type) {
       
   238 					case VEH_Train:
       
   239 						if (!IsTileDepotType(dp->xy, TRANSPORT_RAIL)) return CMD_ERROR;
       
   240 						break;
       
   241 
       
   242 					case VEH_Road:
       
   243 						if (!IsTileDepotType(dp->xy, TRANSPORT_ROAD)) return CMD_ERROR;
       
   244 						break;
       
   245 
       
   246 					case VEH_Ship:
       
   247 						if (!IsTileDepotType(dp->xy, TRANSPORT_WATER)) return CMD_ERROR;
       
   248 						break;
       
   249 
       
   250 					default:
       
   251 						return CMD_ERROR;
       
   252 				}
       
   253 			}
       
   254 
       
   255 			switch (new_order.flags) {
       
   256 				case OF_PART_OF_ORDERS:
       
   257 				case OF_PART_OF_ORDERS | OF_HALT_IN_DEPOT:
       
   258 				case OF_NON_STOP | OF_PART_OF_ORDERS:
       
   259 				case OF_NON_STOP | OF_PART_OF_ORDERS | OF_HALT_IN_DEPOT:
       
   260 					break;
       
   261 
       
   262 				default:
       
   263 					return CMD_ERROR;
       
   264 			}
       
   265 			break;
       
   266 		}
       
   267 
       
   268 		case OT_GOTO_WAYPOINT: {
       
   269 			const Waypoint* wp;
       
   270 
       
   271 			if (v->type != VEH_Train) return CMD_ERROR;
       
   272 
       
   273 			if (!IsWaypointIndex(new_order.station)) return CMD_ERROR;
       
   274 			wp = GetWaypoint(new_order.station);
       
   275 
       
   276 			if (!CheckOwnership(GetTileOwner(wp->xy))) return CMD_ERROR;
       
   277 
       
   278 			switch (new_order.flags) {
       
   279 				case 0:
       
   280 				case OF_NON_STOP:
       
   281 					break;
       
   282 
       
   283 				default:
       
   284 					return CMD_ERROR;
       
   285 			}
       
   286 			break;
       
   287 		}
       
   288 
       
   289 		default:
       
   290 			return CMD_ERROR;
       
   291 	}
   153 
   292 
   154 	if (sel > v->num_orders)
   293 	if (sel > v->num_orders)
   155 		return_cmd_error(STR_EMPTY);
   294 		return_cmd_error(STR_EMPTY);
   156 
   295 
   157 	if (IsOrderPoolFull())
   296 	if (IsOrderPoolFull())
   168 		sel != 0 && GetVehicleOrder(v, sel - 1)->type == OT_GOTO_STATION
   307 		sel != 0 && GetVehicleOrder(v, sel - 1)->type == OT_GOTO_STATION
   169 		&& !_patches.new_pathfinding_all) {
   308 		&& !_patches.new_pathfinding_all) {
   170 
   309 
   171 		int dist = DistanceManhattan(
   310 		int dist = DistanceManhattan(
   172 			GetStation(GetVehicleOrder(v, sel - 1)->station)->xy,
   311 			GetStation(GetVehicleOrder(v, sel - 1)->station)->xy,
   173 			GetStation(new_order.station)->xy
   312 			GetStation(new_order.station)->xy // XXX type != OT_GOTO_STATION?
   174 		);
   313 		);
   175 		if (dist >= 130)
   314 		if (dist >= 130)
   176 			return_cmd_error(STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO);
   315 			return_cmd_error(STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO);
   177 	}
   316 	}
   178 
   317 
   267  * @param selected   The order to delete
   406  * @param selected   The order to delete
   268  *
   407  *
   269  */
   408  */
   270 int32 CmdDeleteOrder(int x, int y, uint32 flags, uint32 vehicle_id, uint32 selected)
   409 int32 CmdDeleteOrder(int x, int y, uint32 flags, uint32 vehicle_id, uint32 selected)
   271 {
   410 {
   272 	Vehicle *v = GetVehicle(vehicle_id), *u;
   411 	Vehicle *v;
       
   412 	Vehicle *u;
   273 	uint sel   = selected;
   413 	uint sel   = selected;
   274 	Order *order;
   414 	Order *order;
       
   415 
       
   416 	if (!IsVehicleIndex(vehicle_id)) return CMD_ERROR;
       
   417 	v = GetVehicle(vehicle_id);
       
   418 	if (v->type == 0 || !CheckOwnership(v->owner)) return CMD_ERROR;
   275 
   419 
   276 	/* XXX -- Why is this here? :s */
   420 	/* XXX -- Why is this here? :s */
   277 	_error_message = STR_EMPTY;
   421 	_error_message = STR_EMPTY;
   278 
   422 
   279 	/* If we did not select an order, we maybe want to de-clone the orders */
   423 	/* If we did not select an order, we maybe want to de-clone the orders */
   345  * @param vehicle_id The ID of the vehicle
   489  * @param vehicle_id The ID of the vehicle
   346  *
   490  *
   347  */
   491  */
   348 int32 CmdSkipOrder(int x, int y, uint32 flags, uint32 vehicle_id, uint32 not_used)
   492 int32 CmdSkipOrder(int x, int y, uint32 flags, uint32 vehicle_id, uint32 not_used)
   349 {
   493 {
   350 	Vehicle *v = GetVehicle(vehicle_id);
   494 	Vehicle *v;
       
   495 
       
   496 	if (!IsVehicleIndex(vehicle_id)) return CMD_ERROR;
       
   497 	v = GetVehicle(vehicle_id);
       
   498 	if (v->type == 0 || !CheckOwnership(v->owner)) return CMD_ERROR;
   351 
   499 
   352 	if (flags & DC_EXEC) {
   500 	if (flags & DC_EXEC) {
   353 		/* Goto next order */
   501 		/* Goto next order */
   354 		{
   502 		{
   355 			byte b = v->cur_order_index + 1;
   503 			byte b = v->cur_order_index + 1;
   392  * @param mode         Mode to change the order to
   540  * @param mode         Mode to change the order to
   393  *
   541  *
   394  */
   542  */
   395 int32 CmdModifyOrder(int x, int y, uint32 flags, uint32 veh_sel, uint32 mode)
   543 int32 CmdModifyOrder(int x, int y, uint32 flags, uint32 veh_sel, uint32 mode)
   396 {
   544 {
   397 	Vehicle *v = GetVehicle(veh_sel & 0xFFFF);
   545 	Vehicle *v;
   398 	byte sel = veh_sel >> 16;
   546 	byte sel = veh_sel >> 16;
   399 	Order *order;
   547 	Order *order;
       
   548 
       
   549 	if (!IsVehicleIndex(veh_sel & 0xFFFF)) return CMD_ERROR;
       
   550 	v = GetVehicle(veh_sel & 0xFFFF);
       
   551 	if (v->type == 0 || !CheckOwnership(v->owner)) return CMD_ERROR;
   400 
   552 
   401 	/* Is it a valid order? */
   553 	/* Is it a valid order? */
   402 	if (sel >= v->num_orders)
   554 	if (sel >= v->num_orders)
   403 		return CMD_ERROR;
   555 		return CMD_ERROR;
   404 
   556 
   420 			CLRBIT(order->flags, OFB_FULL_LOAD);
   572 			CLRBIT(order->flags, OFB_FULL_LOAD);
   421 			break;
   573 			break;
   422 		case OFB_NON_STOP:
   574 		case OFB_NON_STOP:
   423 			TOGGLEBIT(order->flags, OFB_NON_STOP);
   575 			TOGGLEBIT(order->flags, OFB_NON_STOP);
   424 			break;
   576 			break;
       
   577 
       
   578 			default:
       
   579 				return CMD_ERROR;
   425 		}
   580 		}
   426 
   581 
   427 		/* Update the windows, also for vehicles that share the same order list */
   582 		/* Update the windows, also for vehicles that share the same order list */
   428 		{
   583 		{
   429 			Vehicle *u = GetFirstVehicleFromSharedList(v);
   584 			Vehicle *u = GetFirstVehicleFromSharedList(v);
   651  *                   The last 16 bits are the service-interval
   806  *                   The last 16 bits are the service-interval
   652  *
   807  *
   653  */
   808  */
   654 int32 CmdRestoreOrderIndex(int x, int y, uint32 flags, uint32 vehicle_id, uint32 data)
   809 int32 CmdRestoreOrderIndex(int x, int y, uint32 flags, uint32 vehicle_id, uint32 data)
   655 {
   810 {
       
   811 	Vehicle* v;
       
   812 
       
   813 	if (!IsVehicleIndex(vehicle_id)) return CMD_ERROR;
       
   814 	v = GetVehicle(vehicle_id);
       
   815 	if (v->type == 0 || !CheckOwnership(v->owner)) return CMD_ERROR;
       
   816 
   656 	if (flags & DC_EXEC) {
   817 	if (flags & DC_EXEC) {
   657 		Vehicle *v = GetVehicle(vehicle_id);
       
   658 		v->service_interval = data >> 16;
   818 		v->service_interval = data >> 16;
   659 		v->cur_order_index = data & 0xFFFF;
   819 		v->cur_order_index = data & 0xFFFF;
   660 	}
   820 	}
   661 
   821 
   662 	return 0;
   822 	return 0;