File diff r11916:e3a8d08bf479 → r11917:612c11f7ab47
src/ai/api/ai_order.cpp
Show inline comments
 
@@ -40,23 +40,23 @@ static OrderType GetOrderTypeByTile(Tile
 

	
 
	return OT_END;
 
}
 

	
 
/* static */ bool AIOrder::IsValidVehicleOrder(VehicleID vehicle_id, OrderPosition order_position)
 
{
 
	return AIVehicle::IsValidVehicle(vehicle_id) && order_position >= 0 && (order_position < ::GetVehicle(vehicle_id)->GetNumOrders() || order_position == ORDER_CURRENT);
 
	return AIVehicle::IsValidVehicle(vehicle_id) && order_position >= 0 && (order_position < ::Vehicle::Get(vehicle_id)->GetNumOrders() || order_position == ORDER_CURRENT);
 
}
 

	
 
/**
 
 * Get the current order the vehicle is executing. If the current order is in
 
 *  the order list, return the order from the orderlist. If the current order
 
 *  was a manual order, return the current order.
 
 */
 
static const Order *ResolveOrder(VehicleID vehicle_id, AIOrder::OrderPosition order_position)
 
{
 
	const Vehicle *v = ::GetVehicle(vehicle_id);
 
	const Vehicle *v = ::Vehicle::Get(vehicle_id);
 
	if (order_position == AIOrder::ORDER_CURRENT) {
 
		const Order *order = &v->current_order;
 
		if (order->GetType() == OT_GOTO_DEPOT && !(order->GetDepotOrderType() & ODTFB_PART_OF_ORDERS)) return order;
 
		order_position = AIOrder::ResolveOrderPosition(vehicle_id, order_position);
 
		if (order_position == AIOrder::ORDER_INVALID) return NULL;
 
	}
 
@@ -89,32 +89,32 @@ static const Order *ResolveOrder(Vehicle
 

	
 
/* static */ bool AIOrder::IsConditionalOrder(VehicleID vehicle_id, OrderPosition order_position)
 
{
 
	if (order_position == ORDER_CURRENT) return false;
 
	if (!IsValidVehicleOrder(vehicle_id, order_position)) return false;
 

	
 
	const Order *order = ::GetVehicleOrder(GetVehicle(vehicle_id), order_position);
 
	const Order *order = ::GetVehicleOrder(Vehicle::Get(vehicle_id), order_position);
 
	return order->GetType() == OT_CONDITIONAL;
 
}
 

	
 
/* static */ bool AIOrder::IsCurrentOrderPartOfOrderList(VehicleID vehicle_id)
 
{
 
	if (AIVehicle::IsValidVehicle(vehicle_id)) return false;
 
	if (GetOrderCount(vehicle_id) == 0) return false;
 

	
 
	const Order *order = &::GetVehicle(vehicle_id)->current_order;
 
	const Order *order = &::Vehicle::Get(vehicle_id)->current_order;
 
	if (order->GetType() != OT_GOTO_DEPOT) return true;
 
	return (order->GetDepotOrderType() & ODTFB_PART_OF_ORDERS) != 0;
 
}
 

	
 
/* static */ AIOrder::OrderPosition AIOrder::ResolveOrderPosition(VehicleID vehicle_id, OrderPosition order_position)
 
{
 
	if (!AIVehicle::IsValidVehicle(vehicle_id)) return ORDER_INVALID;
 

	
 
	if (order_position == ORDER_CURRENT) return (AIOrder::OrderPosition)::GetVehicle(vehicle_id)->cur_order_index;
 
	return (order_position >= 0 && order_position < ::GetVehicle(vehicle_id)->GetNumOrders()) ? order_position : ORDER_INVALID;
 
	if (order_position == ORDER_CURRENT) return (AIOrder::OrderPosition)::Vehicle::Get(vehicle_id)->cur_order_index;
 
	return (order_position >= 0 && order_position < ::Vehicle::Get(vehicle_id)->GetNumOrders()) ? order_position : ORDER_INVALID;
 
}
 

	
 

	
 
/* static */ bool AIOrder::AreOrderFlagsValid(TileIndex destination, AIOrderFlags order_flags)
 
{
 
	switch (::GetOrderTypeByTile(destination)) {
 
@@ -155,35 +155,35 @@ static const Order *ResolveOrder(Vehicle
 
		default: return false;
 
	}
 
}
 

	
 
/* static */ int32 AIOrder::GetOrderCount(VehicleID vehicle_id)
 
{
 
	return AIVehicle::IsValidVehicle(vehicle_id) ? ::GetVehicle(vehicle_id)->GetNumOrders() : -1;
 
	return AIVehicle::IsValidVehicle(vehicle_id) ? ::Vehicle::Get(vehicle_id)->GetNumOrders() : -1;
 
}
 

	
 
/* static */ TileIndex AIOrder::GetOrderDestination(VehicleID vehicle_id, OrderPosition order_position)
 
{
 
	if (!IsValidVehicleOrder(vehicle_id, order_position)) return INVALID_TILE;
 

	
 
	const Order *order = ::ResolveOrder(vehicle_id, order_position);
 
	if (order == NULL || order->GetType() == OT_CONDITIONAL) return INVALID_TILE;
 
	const Vehicle *v = ::GetVehicle(vehicle_id);
 
	const Vehicle *v = ::Vehicle::Get(vehicle_id);
 

	
 
	switch (order->GetType()) {
 
		case OT_GOTO_DEPOT: {
 
			if (v->type != VEH_AIRCRAFT) return ::GetDepot(order->GetDestination())->xy;
 
			if (v->type != VEH_AIRCRAFT) return ::Depot::Get(order->GetDestination())->xy;
 
			/* Aircraft's hangars are referenced by StationID, not DepotID */
 
			const Station *st = ::GetStation(order->GetDestination());
 
			const Station *st = ::Station::Get(order->GetDestination());
 
			const AirportFTAClass *airport = st->Airport();
 
			if (airport == NULL || airport->nof_depots == 0) return INVALID_TILE;
 
			return st->airport_tile + ::ToTileIndexDiff(st->Airport()->airport_depots[0]);
 
		}
 

	
 
		case OT_GOTO_STATION: {
 
			const Station *st = ::GetStation(order->GetDestination());
 
			const Station *st = ::Station::Get(order->GetDestination());
 
			if (st->train_tile != INVALID_TILE) {
 
				for (uint i = 0; i < st->trainst_w; i++) {
 
					TileIndex t = st->train_tile + TileDiffXY(i, 0);
 
					if (st->TileBelongsToRailStation(t)) return t;
 
				}
 
			} else if (st->dock_tile != INVALID_TILE) {
 
@@ -197,13 +197,13 @@ static const Order *ResolveOrder(Vehicle
 
				BEGIN_TILE_LOOP(tile, fta->size_x, fta->size_y, st->airport_tile) {
 
					if (!::IsHangar(tile)) return tile;
 
				} END_TILE_LOOP(tile, fta->size_x, fta->size_y, st->airport_tile)
 
			}
 
			return INVALID_TILE;
 
		}
 
		case OT_GOTO_WAYPOINT: return ::GetWaypoint(order->GetDestination())->xy;
 
		case OT_GOTO_WAYPOINT: return ::Waypoint::Get(order->GetDestination())->xy;
 
		default:               return INVALID_TILE;
 
	}
 
}
 

	
 
/* static */ AIOrder::AIOrderFlags AIOrder::GetOrderFlags(VehicleID vehicle_id, OrderPosition order_position)
 
{
 
@@ -233,40 +233,40 @@ static const Order *ResolveOrder(Vehicle
 

	
 
/* static */ AIOrder::OrderPosition AIOrder::GetOrderJumpTo(VehicleID vehicle_id, OrderPosition order_position)
 
{
 
	if (!IsValidVehicleOrder(vehicle_id, order_position)) return ORDER_INVALID;
 
	if (order_position == ORDER_CURRENT || !IsConditionalOrder(vehicle_id, order_position)) return ORDER_INVALID;
 

	
 
	const Order *order = ::GetVehicleOrder(GetVehicle(vehicle_id), order_position);
 
	const Order *order = ::GetVehicleOrder(Vehicle::Get(vehicle_id), order_position);
 
	return (OrderPosition)order->GetConditionSkipToOrder();
 
}
 

	
 
/* static */ AIOrder::OrderCondition AIOrder::GetOrderCondition(VehicleID vehicle_id, OrderPosition order_position)
 
{
 
	if (!IsValidVehicleOrder(vehicle_id, order_position)) return OC_INVALID;
 
	if (order_position == ORDER_CURRENT || !IsConditionalOrder(vehicle_id, order_position)) return OC_INVALID;
 

	
 
	const Order *order = ::GetVehicleOrder(GetVehicle(vehicle_id), order_position);
 
	const Order *order = ::GetVehicleOrder(Vehicle::Get(vehicle_id), order_position);
 
	return (OrderCondition)order->GetConditionVariable();
 
}
 

	
 
/* static */ AIOrder::CompareFunction AIOrder::GetOrderCompareFunction(VehicleID vehicle_id, OrderPosition order_position)
 
{
 
	if (!IsValidVehicleOrder(vehicle_id, order_position)) return CF_INVALID;
 
	if (order_position == ORDER_CURRENT || !IsConditionalOrder(vehicle_id, order_position)) return CF_INVALID;
 

	
 
	const Order *order = ::GetVehicleOrder(GetVehicle(vehicle_id), order_position);
 
	const Order *order = ::GetVehicleOrder(Vehicle::Get(vehicle_id), order_position);
 
	return (CompareFunction)order->GetConditionComparator();
 
}
 

	
 
/* static */ int32 AIOrder::GetOrderCompareValue(VehicleID vehicle_id, OrderPosition order_position)
 
{
 
	if (!IsValidVehicleOrder(vehicle_id, order_position)) return -1;
 
	if (order_position == ORDER_CURRENT || !IsConditionalOrder(vehicle_id, order_position)) return -1;
 

	
 
	const Order *order = ::GetVehicleOrder(GetVehicle(vehicle_id), order_position);
 
	const Order *order = ::GetVehicleOrder(Vehicle::Get(vehicle_id), order_position);
 
	int32 value = order->GetConditionValue();
 
	if (order->GetConditionVariable() == OCV_MAX_SPEED) value = value * 16 / 10;
 
	return value;
 
}
 

	
 
/* static */ bool AIOrder::SetOrderJumpTo(VehicleID vehicle_id, OrderPosition order_position, OrderPosition jump_to)
 
@@ -308,41 +308,41 @@ static const Order *ResolveOrder(Vehicle
 

	
 
/* static */ bool AIOrder::AppendOrder(VehicleID vehicle_id, TileIndex destination, AIOrderFlags order_flags)
 
{
 
	EnforcePrecondition(false, AIVehicle::IsValidVehicle(vehicle_id));
 
	EnforcePrecondition(false, AreOrderFlagsValid(destination, order_flags));
 

	
 
	return InsertOrder(vehicle_id, (AIOrder::OrderPosition)::GetVehicle(vehicle_id)->GetNumOrders(), destination, order_flags);
 
	return InsertOrder(vehicle_id, (AIOrder::OrderPosition)::Vehicle::Get(vehicle_id)->GetNumOrders(), destination, order_flags);
 
}
 

	
 
/* static */ bool AIOrder::AppendConditionalOrder(VehicleID vehicle_id, OrderPosition jump_to)
 
{
 
	EnforcePrecondition(false, AIVehicle::IsValidVehicle(vehicle_id));
 
	EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, jump_to));
 

	
 
	return InsertConditionalOrder(vehicle_id, (AIOrder::OrderPosition)::GetVehicle(vehicle_id)->GetNumOrders(), jump_to);
 
	return InsertConditionalOrder(vehicle_id, (AIOrder::OrderPosition)::Vehicle::Get(vehicle_id)->GetNumOrders(), jump_to);
 
}
 

	
 
/* static */ bool AIOrder::InsertOrder(VehicleID vehicle_id, OrderPosition order_position, TileIndex destination, AIOrder::AIOrderFlags order_flags)
 
{
 
	/* IsValidVehicleOrder is not good enough because it does not allow appending. */
 
	if (order_position == ORDER_CURRENT) order_position = AIOrder::ResolveOrderPosition(vehicle_id, order_position);
 

	
 
	EnforcePrecondition(false, AIVehicle::IsValidVehicle(vehicle_id));
 
	EnforcePrecondition(false, order_position >= 0 && order_position <= ::GetVehicle(vehicle_id)->GetNumOrders());
 
	EnforcePrecondition(false, order_position >= 0 && order_position <= ::Vehicle::Get(vehicle_id)->GetNumOrders());
 
	EnforcePrecondition(false, AreOrderFlagsValid(destination, order_flags));
 

	
 
	Order order;
 
	switch (::GetOrderTypeByTile(destination)) {
 
		case OT_GOTO_DEPOT: {
 
			OrderDepotTypeFlags odtf = (OrderDepotTypeFlags)(ODTFB_PART_OF_ORDERS | ((order_flags & AIOF_SERVICE_IF_NEEDED) ? ODTFB_SERVICE : 0));
 
			OrderDepotActionFlags odaf = (OrderDepotActionFlags)(ODATF_SERVICE_ONLY | ((order_flags & AIOF_STOP_IN_DEPOT) ? ODATFB_HALT : 0));
 
			OrderNonStopFlags onsf = (OrderNonStopFlags)((order_flags & AIOF_NON_STOP_INTERMEDIATE) ? ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS : ONSF_STOP_EVERYWHERE);
 
			/* Check explicitly if the order is to a station (for aircraft) or
 
			 * to a depot (other vehicle types). */
 
			if (::GetVehicle(vehicle_id)->type == VEH_AIRCRAFT) {
 
			if (::Vehicle::Get(vehicle_id)->type == VEH_AIRCRAFT) {
 
				if (!::IsTileType(destination, MP_STATION)) return false;
 
				order.MakeGoToDepot(::GetStationIndex(destination), odtf, onsf, odaf);
 
			} else {
 
				if (::IsTileType(destination, MP_STATION)) return false;
 
				order.MakeGoToDepot(::GetDepotByTile(destination)->index, odtf, onsf, odaf);
 
			}
 
@@ -429,13 +429,13 @@ static void _DoCommandReturnSetOrderFlag
 

	
 
	order_position = AIOrder::ResolveOrderPosition(vehicle_id, order_position);
 

	
 
	EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, order_position));
 
	EnforcePrecondition(false, AreOrderFlagsValid(GetOrderDestination(vehicle_id, order_position), order_flags));
 

	
 
	const Order *order = ::GetVehicleOrder(GetVehicle(vehicle_id), order_position);
 
	const Order *order = ::GetVehicleOrder(Vehicle::Get(vehicle_id), order_position);
 

	
 
	AIOrderFlags current = GetOrderFlags(vehicle_id, order_position);
 

	
 
	if ((current & AIOF_NON_STOP_FLAGS) != (order_flags & AIOF_NON_STOP_FLAGS)) {
 
		return AIObject::DoCommand(0, vehicle_id | (order_position << 16), (order_flags & AIOF_NON_STOP_FLAGS) << 4 | MOF_NON_STOP, CMD_MODIFY_ORDER, NULL, &_DoCommandReturnSetOrderFlags);
 
	}