order_cmd.c
changeset 1796 614d996f6be7
parent 1793 b9a37c98b468
child 1820 d03c56850dc2
equal deleted inserted replaced
1795:06f7b463ee52 1796:614d996f6be7
   695 				RebuildVehicleLists();
   695 				RebuildVehicleLists();
   696 			}
   696 			}
   697 		} break;
   697 		} break;
   698 
   698 
   699 		case CO_UNSHARE: return DecloneOrder(dst, flags);
   699 		case CO_UNSHARE: return DecloneOrder(dst, flags);
       
   700 		default: return CMD_ERROR;
   700 	}
   701 	}
   701 
   702 
   702 	return 0;
   703 	return 0;
   703 }
   704 }
   704 
   705 
   706  *
   707  *
   707  * Backup a vehicle order-list, so you can replace a vehicle
   708  * Backup a vehicle order-list, so you can replace a vehicle
   708  *  without loosing the order-list
   709  *  without loosing the order-list
   709  *
   710  *
   710  */
   711  */
   711 void BackupVehicleOrders(Vehicle *v, BackuppedOrders *bak)
   712 void BackupVehicleOrders(const Vehicle *v, BackuppedOrders *bak)
   712 {
   713 {
   713 	bool shared = IsOrderListShared(v);
       
   714 
       
   715 	/* Save general info */
   714 	/* Save general info */
   716 	bak->orderindex       = v->cur_order_index;
   715 	bak->orderindex       = v->cur_order_index;
   717 	bak->service_interval = v->service_interval;
   716 	bak->service_interval = v->service_interval;
   718 
   717 
   719 	/* Safe custom string, if any */
   718 	/* Safe custom string, if any */
   722 	} else {
   721 	} else {
   723 		GetName(v->string_id & 0x7FF, bak->name);
   722 		GetName(v->string_id & 0x7FF, bak->name);
   724 	}
   723 	}
   725 
   724 
   726 	/* If we have shared orders, store it on a special way */
   725 	/* If we have shared orders, store it on a special way */
   727 	if (shared) {
   726 	if (IsOrderListShared(v)) {
   728 		Vehicle *u;
   727 		const Vehicle *u = (v->next_shared) ? v->next_shared : v->prev_shared;
   729 		if (v->next_shared)
       
   730 			u = v->next_shared;
       
   731 		else
       
   732 			u = v->prev_shared;
       
   733 
   728 
   734 		bak->clone = u->index;
   729 		bak->clone = u->index;
   735 	} else {
   730 	} else {
   736 		/* Else copy the orders */
   731 		/* Else copy the orders */
   737 		Order *order, *dest;
   732 		Order *order, *dest;
   738 
   733 
   739 		dest  = bak->order;
   734 		dest = bak->order;
   740 
   735 
   741 		/* We do not have shared orders */
   736 		/* We do not have shared orders */
   742 		bak->clone = INVALID_VEHICLE;
   737 		bak->clone = INVALID_VEHICLE;
   743 
   738 
   744 		/* Copy the orders */
   739 		/* Copy the orders */
   757  * Restore vehicle orders that are backupped via BackupVehicleOrders
   752  * Restore vehicle orders that are backupped via BackupVehicleOrders
   758  *
   753  *
   759  */
   754  */
   760 void RestoreVehicleOrders(Vehicle *v, BackuppedOrders *bak)
   755 void RestoreVehicleOrders(Vehicle *v, BackuppedOrders *bak)
   761 {
   756 {
   762 	int i;
   757 	uint i;
   763 
   758 
   764 	/* If we have a custom name, process that */
   759 	/* If we have a custom name, process that */
   765 	if (bak->name[0] != 0) {
   760 	if (bak->name[0] != 0) {
   766 		strcpy((char*)_decode_parameters, bak->name);
   761 		strcpy((char*)_decode_parameters, bak->name);
   767 		DoCommandP(0, v->index, 0, NULL, CMD_NAME_VEHICLE);
   762 		DoCommandP(0, v->index, 0, NULL, CMD_NAME_VEHICLE);
   768 	}
   763 	}
   769 
   764 
   770 	/* Restore vehicle number and service interval */
       
   771 	DoCommandP(0, v->index, bak->orderindex | (bak->service_interval << 16) , NULL, CMD_RESTORE_ORDER_INDEX);
       
   772 
       
   773 	/* If we had shared orders, recover that */
   765 	/* If we had shared orders, recover that */
   774 	if (bak->clone != INVALID_VEHICLE) {
   766 	if (bak->clone != INVALID_VEHICLE) {
   775 		DoCommandP(0, v->index | (bak->clone << 16), 0, NULL, CMD_CLONE_ORDER);
   767 		DoCommandP(0, v->index | (bak->clone << 16), 0, NULL, CMD_CLONE_ORDER);
   776 		return;
   768 		return;
   777 	}
   769 	}
   778 
   770 
   779 	/* CMD_NO_TEST_IF_IN_NETWORK is used here, because CMD_INSERT_ORDER checks if the
   771 	/* CMD_NO_TEST_IF_IN_NETWORK is used here, because CMD_INSERT_ORDER checks if the
   780 	    order number is one more than the current amount of orders, and because
   772 	    order number is one more than the current amount of orders, and because
   781 	    in network the commands are queued before send, the second insert always
   773 	    in network the commands are queued before send, the second insert always
   782 	    fails in test mode. By bypassing the test-mode, that no longer is a problem. */
   774 	    fails in test mode. By bypassing the test-mode, that no longer is a problem. */
   783 	for (i = 0; bak->order[i].type != OT_NOTHING; i++)
   775 	for (i = 0; bak->order[i].type != OT_NOTHING; i++) {
   784 		if (!DoCommandP(0, v->index + (i << 16), PackOrder(&bak->order[i]), NULL, CMD_INSERT_ORDER | CMD_NO_TEST_IF_IN_NETWORK))
   776 		if (!DoCommandP(0, v->index + (i << 16), PackOrder(&bak->order[i]), NULL, CMD_INSERT_ORDER | CMD_NO_TEST_IF_IN_NETWORK))
   785 			break;
   777 			break;
   786 }
   778 	}
   787 
   779 
   788 /**
   780 	/* Restore vehicle order-index and service interval */
   789  *
   781 	DoCommandP(0, v->index, bak->orderindex | (bak->service_interval << 16) , NULL, CMD_RESTORE_ORDER_INDEX);
   790  * Restore the current-order-index of a vehicle and sets service-interval
   782 }
   791  *
   783 
   792  * @param vehicle_id The ID of the vehicle
   784 /** Restore the current order-index of a vehicle and sets service-interval.
   793  * @param data       First 16 bits are the current-order-index
   785  * @param x,y unused
   794  *                   The last 16 bits are the service-interval
   786  * @param p1 the ID of the vehicle
   795  *
   787  * @param p2 various bistuffed elements
   796  */
   788  * - p2 = (bit  0-15) - current order-index (p2 & 0xFFFF)
   797 int32 CmdRestoreOrderIndex(int x, int y, uint32 flags, uint32 vehicle_id, uint32 data)
   789  * - p2 = (bit 16-31) - service interval (p2 >> 16)
   798 {
   790  * @todo Unfortunately you cannot safely restore the unitnumber or the old vehicle
   799 	Vehicle* v;
   791  * as far as I can see. We can store it in BackuppedOrders, and restore it, but
   800 
   792  * but we have no way of seeing it has been tampered with or not, as we have no
   801 	if (!IsVehicleIndex(vehicle_id)) return CMD_ERROR;
   793  * legit way of knowing what that ID was.@n
   802 	v = GetVehicle(vehicle_id);
   794  * If we do want to backup/restore it, just add UnitID uid to BackuppedOrders, and
       
   795  * restore it as parameter 'y' (ugly hack I know) for example. "v->unitnumber = y;"
       
   796  */
       
   797 int32 CmdRestoreOrderIndex(int x, int y, uint32 flags, uint32 p1, uint32 p2)
       
   798 {
       
   799 	Vehicle *v;
       
   800 	OrderID cur_ord = p2 & 0xFFFF;
       
   801 	uint16 serv_int = p2 >> 16;
       
   802 
       
   803 	if (!IsVehicleIndex(p1)) return CMD_ERROR;
       
   804 
       
   805 	v = GetVehicle(p1);
       
   806 	/* Check the vehicle type and ownership, and if the service interval and order are in range */
   803 	if (v->type == 0 || !CheckOwnership(v->owner)) return CMD_ERROR;
   807 	if (v->type == 0 || !CheckOwnership(v->owner)) return CMD_ERROR;
       
   808 	if (serv_int != GetServiceIntervalClamped(serv_int) || cur_ord >= v->num_orders) return CMD_ERROR;
   804 
   809 
   805 	if (flags & DC_EXEC) {
   810 	if (flags & DC_EXEC) {
   806 		v->service_interval = data >> 16;
   811 		v->cur_order_index = cur_ord;
   807 		v->cur_order_index = data & 0xFFFF;
   812 		v->service_interval = serv_int;
   808 	}
   813 	}
   809 
   814 
   810 	return 0;
   815 	return 0;
   811 }
   816 }
   812 
   817