src/ai/api/ai_vehicle.cpp
author rubidium
Tue, 15 Apr 2008 22:34:49 +0000
branchnoai
changeset 10196 aecabd927420
parent 10189 b18d1d5b047d
child 10249 58810805030e
permissions -rw-r--r--
(svn r12728) [NoAI] -Codechange: always let functions return Money when they return something that can be quantified as money.
/* $Id$ */

/** @file ai_vehicle.cpp Implementation of AIVehicle. */

#include "ai_vehicle.hpp"
#include "ai_engine.hpp"
#include "ai_cargo.hpp"
#include "ai_order.hpp"
#include "../../depot.h"
#include "../../player_func.h"
#include "../../aircraft.h"
#include "../../string_func.h"
#include "../../strings_func.h"
#include "../../core/alloc_func.hpp"
#include "../../command_type.h"
#include "../../command_func.h"
#include "table/strings.h"

/* static */ bool AIVehicle::IsValidVehicle(VehicleID vehicle_id)
{
	return ::IsValidVehicleID(vehicle_id) && ::GetVehicle(vehicle_id)->owner == _current_player && ::GetVehicle(vehicle_id)->IsPrimaryVehicle();
}

/* static */ VehicleID AIVehicle::BuildVehicle(TileIndex depot, EngineID engine_id)
{
	EnforcePrecondition(false, AIEngine::IsValidEngine(engine_id));

	/* Reset the internal NewVehicleID in case we are in TestMode */
	AIObject::SetNewVehicleID(0);

	bool ret;
	switch (::GetEngine(engine_id)->type) {
		case VEH_ROAD: ret = AIObject::DoCommand(depot, engine_id, 0, CMD_BUILD_ROAD_VEH); break;
		case VEH_TRAIN: ret = AIObject::DoCommand(depot, engine_id, 0, CMD_BUILD_RAIL_VEHICLE); break;
		case VEH_SHIP: ret = AIObject::DoCommand(depot, engine_id, 0, CMD_BUILD_SHIP); break;
		case VEH_AIRCRAFT: ret = AIObject::DoCommand(depot, engine_id, 0, CMD_BUILD_AIRCRAFT); break;
		default: NOT_REACHED(); return INVALID_VEHICLE;
	}

	return ret ? AIObject::GetNewVehicleID() : INVALID_VEHICLE;
}

/* static */ VehicleID AIVehicle::CloneVehicle(TileIndex depot, VehicleID vehicle_id, bool share_orders)
{
	EnforcePrecondition(false, IsValidVehicle(vehicle_id));

	/* Reset the internal NewVehicleID in case we are in TestMode */
	AIObject::SetNewVehicleID(0);

	bool ret = AIObject::DoCommand(depot, vehicle_id, share_orders, CMD_CLONE_VEHICLE);
	return ret ? AIObject::GetNewVehicleID() : INVALID_VEHICLE;
}

/* static */ bool AIVehicle::RefitVehicle(VehicleID vehicle_id, CargoID cargo)
{
	EnforcePrecondition(false, IsValidVehicle(vehicle_id) && AICargo::IsValidCargo(cargo));

	switch (::GetVehicle(vehicle_id)->type) {
		case VEH_ROAD: return AIObject::DoCommand(0, vehicle_id, cargo, CMD_REFIT_ROAD_VEH);
		case VEH_TRAIN: return AIObject::DoCommand(0, vehicle_id, cargo, CMD_REFIT_RAIL_VEHICLE);
		case VEH_SHIP: return AIObject::DoCommand(0, vehicle_id, cargo, CMD_REFIT_SHIP);
		case VEH_AIRCRAFT: return AIObject::DoCommand(0, vehicle_id, cargo, CMD_REFIT_AIRCRAFT);
		default: return false;
	}
}


/* static */ bool AIVehicle::SellVehicle(VehicleID vehicle_id)
{
	EnforcePrecondition(false, IsValidVehicle(vehicle_id));

	switch (::GetVehicle(vehicle_id)->type) {
		case VEH_ROAD: return AIObject::DoCommand(0, vehicle_id, 0, CMD_SELL_ROAD_VEH);
		case VEH_TRAIN: return AIObject::DoCommand(0, vehicle_id, 0, CMD_SELL_RAIL_WAGON);
		case VEH_SHIP: return AIObject::DoCommand(0, vehicle_id, 0, CMD_SELL_SHIP);
		case VEH_AIRCRAFT: return AIObject::DoCommand(0, vehicle_id, 0, CMD_SELL_AIRCRAFT);
		default: return false;
	}
}

/* static */ bool AIVehicle::SendVehicleToDepot(VehicleID vehicle_id)
{
	EnforcePrecondition(false, IsValidVehicle(vehicle_id));

	switch (::GetVehicle(vehicle_id)->type) {
		case VEH_ROAD: return AIObject::DoCommand(0, vehicle_id, 0, CMD_SEND_ROADVEH_TO_DEPOT);
		case VEH_TRAIN: return AIObject::DoCommand(0, vehicle_id, 0, CMD_SEND_TRAIN_TO_DEPOT);
		case VEH_SHIP: return AIObject::DoCommand(0, vehicle_id, 0, CMD_SEND_SHIP_TO_DEPOT);
		case VEH_AIRCRAFT: return AIObject::DoCommand(0, vehicle_id, 0, CMD_SEND_AIRCRAFT_TO_HANGAR);
		default: return false;
	}
}

/* static */ bool AIVehicle::IsInDepot(VehicleID vehicle_id)
{
	if (!IsValidVehicle(vehicle_id)) return false;
	return ::GetVehicle(vehicle_id)->IsInDepot();
}

/* static */ bool AIVehicle::IsStoppedInDepot(VehicleID vehicle_id)
{
	if (!IsValidVehicle(vehicle_id)) return false;
	return ::GetVehicle(vehicle_id)->IsStoppedInDepot();
}

/* static */ bool AIVehicle::StartStopVehicle(VehicleID vehicle_id)
{
	EnforcePrecondition(false, IsValidVehicle(vehicle_id));

	switch (::GetVehicle(vehicle_id)->type) {
		case VEH_ROAD: return AIObject::DoCommand(0, vehicle_id, 0, CMD_START_STOP_ROADVEH);
		case VEH_TRAIN: return AIObject::DoCommand(0, vehicle_id, 0, CMD_START_STOP_TRAIN);
		case VEH_SHIP: return AIObject::DoCommand(0, vehicle_id, 0, CMD_START_STOP_SHIP);
		case VEH_AIRCRAFT: return AIObject::DoCommand(0, vehicle_id, 0, CMD_START_STOP_AIRCRAFT);
		default: return false;
	}
}

/* static */ bool AIVehicle::SkipToVehicleOrder(VehicleID vehicle_id, uint32 order_id)
{
	EnforcePrecondition(false, AIOrder::IsValidVehicleOrder(vehicle_id, order_id));

	return AIObject::DoCommand(0, vehicle_id, order_id, CMD_SKIP_TO_ORDER);
}

/* static */ bool AIVehicle::SetName(VehicleID vehicle_id, const char *name)
{
	EnforcePrecondition(false, IsValidVehicle(vehicle_id));
	EnforcePrecondition(false, !StrEmpty(name));

	_cmd_text = name;
	return AIObject::DoCommand(0, vehicle_id, 0, CMD_NAME_VEHICLE);
}

/* static */ TileIndex AIVehicle::GetLocation(VehicleID vehicle_id)
{
	if (!IsValidVehicle(vehicle_id)) return INVALID_TILE;

	return ::GetVehicle(vehicle_id)->tile;
}

/* static */ EngineID AIVehicle::GetEngineType(VehicleID vehicle_id)
{
	if (!IsValidVehicle(vehicle_id)) return INVALID_ENGINE;

	return ::GetVehicle(vehicle_id)->engine_type;
}

/* static */ int32 AIVehicle::GetUnitNumber(VehicleID vehicle_id)
{
	if (!IsValidVehicle(vehicle_id)) return -1;

	return ::GetVehicle(vehicle_id)->unitnumber;
}

/* static */ char *AIVehicle::GetName(VehicleID vehicle_id)
{
	if (!IsValidVehicle(vehicle_id)) return NULL;

	static const int len = 64;
	char *vehicle_name = MallocT<char>(len);

	::SetDParam(0, vehicle_id);
	::GetString(vehicle_name, STR_VEHICLE_NAME, &vehicle_name[len - 1]);
	return vehicle_name;
}

/* static */ int32 AIVehicle::GetAge(VehicleID vehicle_id)
{
	if (!IsValidVehicle(vehicle_id)) return -1;

	return ::GetVehicle(vehicle_id)->age;
}

/* static */ int32 AIVehicle::GetMaxAge(VehicleID vehicle_id)
{
	if (!IsValidVehicle(vehicle_id)) return -1;

	return ::GetVehicle(vehicle_id)->max_age;
}

/* static */ int32 AIVehicle::GetAgeLeft(VehicleID vehicle_id)
{
	if (!IsValidVehicle(vehicle_id)) return -1;

	return ::GetVehicle(vehicle_id)->max_age - ::GetVehicle(vehicle_id)->age;
}

/* static */ int32 AIVehicle::GetCurrentSpeed(VehicleID vehicle_id)
{
	if (!IsValidVehicle(vehicle_id)) return -1;

	return ::GetVehicle(vehicle_id)->GetDisplaySpeed();
}

/* static */ Money AIVehicle::GetRunningCost(VehicleID vehicle_id)
{
	if (!IsValidVehicle(vehicle_id)) return -1;

	return ::GetVehicle(vehicle_id)->GetRunningCost() >> 8;
}

/* static */ Money AIVehicle::GetProfitThisYear(VehicleID vehicle_id)
{
	if (!IsValidVehicle(vehicle_id)) return -1;

	return ::GetVehicle(vehicle_id)->GetDisplayProfitThisYear();
}

/* static */ Money AIVehicle::GetProfitLastYear(VehicleID vehicle_id)
{
	if (!IsValidVehicle(vehicle_id)) return -1;

	return ::GetVehicle(vehicle_id)->GetDisplayProfitLastYear();
}

/* static */ AIVehicle::VehicleType AIVehicle::GetVehicleType(VehicleID vehicle_id)
{
	if (!IsValidVehicle(vehicle_id)) return VEHICLE_INVALID;

	switch (::GetVehicle(vehicle_id)->type) {
		case VEH_ROAD:     return VEHICLE_ROAD;
		case VEH_TRAIN:    return VEHICLE_RAIL;
		case VEH_SHIP:     return VEHICLE_WATER;
		case VEH_AIRCRAFT: return VEHICLE_AIR;
		default:           return VEHICLE_INVALID;
	}
}

/* static */ int32 AIVehicle::GetCapacity(VehicleID vehicle_id, CargoID cargo)
{
	if (!IsValidVehicle(vehicle_id)) return -1;
	if (!AICargo::IsValidCargo(cargo)) return -1;

	uint32 amount = 0;
	for (const Vehicle *v = ::GetVehicle(vehicle_id); v != NULL; v = v->Next()) {
		if (v->cargo_type == cargo) amount += v->cargo_cap;
	}

	return amount;
}

/* static */ int32 AIVehicle::GetCargoLoad(VehicleID vehicle_id, CargoID cargo)
{
	if (!IsValidVehicle(vehicle_id)) return -1;
	if (!AICargo::IsValidCargo(cargo)) return -1;

	uint32 amount = 0;
	for (const Vehicle *v = ::GetVehicle(vehicle_id); v != NULL; v = v->Next()) {
		if (v->cargo_type == cargo) amount += v->cargo.Count();
	}

	return amount;
}