2009-01-12 17:11:45 +00:00
|
|
|
/* $Id$ */
|
|
|
|
|
2009-08-21 20:21:05 +00:00
|
|
|
/*
|
|
|
|
* This file is part of OpenTTD.
|
|
|
|
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
|
|
|
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2009-01-12 17:11:45 +00:00
|
|
|
/** @file ai_town.cpp Implementation of AITown. */
|
|
|
|
|
|
|
|
#include "ai_town.hpp"
|
|
|
|
#include "ai_map.hpp"
|
|
|
|
#include "ai_cargo.hpp"
|
|
|
|
#include "ai_error.hpp"
|
|
|
|
#include "../../town.h"
|
|
|
|
#include "../../strings_func.h"
|
|
|
|
#include "../../company_func.h"
|
|
|
|
#include "../../station_base.h"
|
|
|
|
#include "table/strings.h"
|
|
|
|
|
|
|
|
/* static */ int32 AITown::GetTownCount()
|
|
|
|
{
|
2009-05-22 15:23:47 +00:00
|
|
|
return (int32)::Town::GetNumItems();
|
2009-01-12 17:11:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* static */ bool AITown::IsValidTown(TownID town_id)
|
|
|
|
{
|
2009-05-17 01:00:56 +00:00
|
|
|
return ::Town::IsValidID(town_id);
|
2009-01-12 17:11:45 +00:00
|
|
|
}
|
|
|
|
|
2009-01-17 15:31:30 +00:00
|
|
|
/* static */ char *AITown::GetName(TownID town_id)
|
2009-01-12 17:11:45 +00:00
|
|
|
{
|
|
|
|
if (!IsValidTown(town_id)) return NULL;
|
|
|
|
static const int len = 64;
|
|
|
|
char *town_name = MallocT<char>(len);
|
|
|
|
|
|
|
|
::SetDParam(0, town_id);
|
2009-07-20 11:21:57 +00:00
|
|
|
::GetString(town_name, STR_TOWN_NAME, &town_name[len - 1]);
|
2009-01-12 17:11:45 +00:00
|
|
|
|
|
|
|
return town_name;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* static */ int32 AITown::GetPopulation(TownID town_id)
|
|
|
|
{
|
|
|
|
if (!IsValidTown(town_id)) return -1;
|
2009-05-16 23:34:14 +00:00
|
|
|
const Town *t = ::Town::Get(town_id);
|
2009-01-12 17:11:45 +00:00
|
|
|
return t->population;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* static */ int32 AITown::GetHouseCount(TownID town_id)
|
|
|
|
{
|
|
|
|
if (!IsValidTown(town_id)) return -1;
|
2009-05-16 23:34:14 +00:00
|
|
|
const Town *t = ::Town::Get(town_id);
|
2009-01-12 17:11:45 +00:00
|
|
|
return t->num_houses;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* static */ TileIndex AITown::GetLocation(TownID town_id)
|
|
|
|
{
|
|
|
|
if (!IsValidTown(town_id)) return INVALID_TILE;
|
2009-05-16 23:34:14 +00:00
|
|
|
const Town *t = ::Town::Get(town_id);
|
2009-01-12 17:11:45 +00:00
|
|
|
return t->xy;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* static */ int32 AITown::GetLastMonthProduction(TownID town_id, CargoID cargo_id)
|
|
|
|
{
|
|
|
|
if (!IsValidTown(town_id)) return -1;
|
|
|
|
if (!AICargo::IsValidCargo(cargo_id)) return -1;
|
|
|
|
|
2009-05-16 23:34:14 +00:00
|
|
|
const Town *t = ::Town::Get(town_id);
|
2009-01-12 17:11:45 +00:00
|
|
|
|
2009-08-09 14:40:34 +00:00
|
|
|
switch (AICargo::GetTownEffect(cargo_id)) {
|
2009-08-27 13:47:03 +00:00
|
|
|
case AICargo::TE_PASSENGERS: return t->max_pass;
|
|
|
|
case AICargo::TE_MAIL: return t->max_mail;
|
2009-01-12 17:11:45 +00:00
|
|
|
default: return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* static */ int32 AITown::GetLastMonthTransported(TownID town_id, CargoID cargo_id)
|
|
|
|
{
|
|
|
|
if (!IsValidTown(town_id)) return -1;
|
|
|
|
if (!AICargo::IsValidCargo(cargo_id)) return -1;
|
|
|
|
|
2009-05-16 23:34:14 +00:00
|
|
|
const Town *t = ::Town::Get(town_id);
|
2009-01-12 17:11:45 +00:00
|
|
|
|
2009-08-09 14:40:34 +00:00
|
|
|
switch (AICargo::GetTownEffect(cargo_id)) {
|
2009-08-27 13:47:03 +00:00
|
|
|
case AICargo::TE_PASSENGERS: return t->act_pass;
|
|
|
|
case AICargo::TE_MAIL: return t->act_mail;
|
2009-01-12 17:11:45 +00:00
|
|
|
default: return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-08-27 13:50:07 +00:00
|
|
|
/* static */ int32 AITown::GetLastMonthTransportedPercentage(TownID town_id, CargoID cargo_id)
|
|
|
|
{
|
|
|
|
if (!IsValidTown(town_id)) return -1;
|
|
|
|
if (!AICargo::IsValidCargo(cargo_id)) return -1;
|
|
|
|
|
|
|
|
const Town *t = ::Town::Get(town_id);
|
|
|
|
|
|
|
|
switch (AICargo::GetTownEffect(cargo_id)) {
|
|
|
|
case AICargo::TE_PASSENGERS: return ::ToPercent8(t->pct_pass_transported);
|
|
|
|
case AICargo::TE_MAIL: return ::ToPercent8(t->pct_mail_transported);
|
|
|
|
default: return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-01-12 17:11:45 +00:00
|
|
|
/* static */ int32 AITown::GetDistanceManhattanToTile(TownID town_id, TileIndex tile)
|
|
|
|
{
|
|
|
|
return AIMap::DistanceManhattan(tile, GetLocation(town_id));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* static */ int32 AITown::GetDistanceSquareToTile(TownID town_id, TileIndex tile)
|
|
|
|
{
|
|
|
|
return AIMap::DistanceSquare(tile, GetLocation(town_id));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* static */ bool AITown::IsWithinTownInfluence(TownID town_id, TileIndex tile)
|
|
|
|
{
|
|
|
|
if (!IsValidTown(town_id)) return false;
|
|
|
|
|
2009-05-16 23:34:14 +00:00
|
|
|
const Town *t = ::Town::Get(town_id);
|
2009-01-12 17:11:45 +00:00
|
|
|
return ((uint32)GetDistanceSquareToTile(town_id, tile) <= t->squared_town_zone_radius[0]);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* static */ bool AITown::HasStatue(TownID town_id)
|
|
|
|
{
|
|
|
|
if (!IsValidTown(town_id)) return false;
|
|
|
|
|
2009-05-16 23:34:14 +00:00
|
|
|
return ::HasBit(::Town::Get(town_id)->statues, _current_company);
|
2009-01-12 17:11:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* static */ int AITown::GetRoadReworkDuration(TownID town_id)
|
|
|
|
{
|
|
|
|
if (!IsValidTown(town_id)) return -1;
|
|
|
|
|
2009-05-16 23:34:14 +00:00
|
|
|
return ::Town::Get(town_id)->road_build_months;
|
2009-01-12 17:11:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* static */ AICompany::CompanyID AITown::GetExclusiveRightsCompany(TownID town_id)
|
|
|
|
{
|
2009-01-16 00:05:26 +00:00
|
|
|
if (!IsValidTown(town_id)) return AICompany::COMPANY_INVALID;
|
2009-01-12 17:11:45 +00:00
|
|
|
|
2009-05-16 23:34:14 +00:00
|
|
|
return (AICompany::CompanyID)(int8)::Town::Get(town_id)->exclusivity;
|
2009-01-12 17:11:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* static */ int32 AITown::GetExclusiveRightsDuration(TownID town_id)
|
|
|
|
{
|
|
|
|
if (!IsValidTown(town_id)) return -1;
|
|
|
|
|
2009-05-16 23:34:14 +00:00
|
|
|
return ::Town::Get(town_id)->exclusive_counter;
|
2009-01-12 17:11:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* static */ bool AITown::IsActionAvailable(TownID town_id, TownAction town_action)
|
|
|
|
{
|
|
|
|
if (!IsValidTown(town_id)) return false;
|
|
|
|
|
2009-05-16 23:34:14 +00:00
|
|
|
return HasBit(::GetMaskOfTownActions(NULL, _current_company, ::Town::Get(town_id)), town_action);
|
2009-01-12 17:11:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* static */ bool AITown::PerformTownAction(TownID town_id, TownAction town_action)
|
|
|
|
{
|
|
|
|
EnforcePrecondition(false, IsValidTown(town_id));
|
|
|
|
EnforcePrecondition(false, IsActionAvailable(town_id, town_action));
|
|
|
|
|
2009-05-16 23:34:14 +00:00
|
|
|
return AIObject::DoCommand(::Town::Get(town_id)->xy, town_id, town_action, CMD_DO_TOWN_ACTION);
|
2009-01-12 17:11:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* static */ AITown::TownRating AITown::GetRating(TownID town_id, AICompany::CompanyID company_id)
|
|
|
|
{
|
2009-01-16 00:05:26 +00:00
|
|
|
if (!IsValidTown(town_id)) return TOWN_RATING_INVALID;
|
2009-01-12 17:11:45 +00:00
|
|
|
AICompany::CompanyID company = AICompany::ResolveCompanyID(company_id);
|
2009-01-16 00:05:26 +00:00
|
|
|
if (company == AICompany::COMPANY_INVALID) return TOWN_RATING_INVALID;
|
2009-01-12 17:11:45 +00:00
|
|
|
|
2009-05-16 23:34:14 +00:00
|
|
|
const Town *t = ::Town::Get(town_id);
|
2009-01-12 17:11:45 +00:00
|
|
|
if (!HasBit(t->have_ratings, company)) return TOWN_RATING_NONE;
|
|
|
|
return max(TOWN_RATING_APPALLING, (TownRating)((t->ratings[company] / 200) + 3));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* static */ int AITown::GetAllowedNoise(TownID town_id)
|
|
|
|
{
|
|
|
|
if (!IsValidTown(town_id)) return -1;
|
|
|
|
|
2009-05-16 23:34:14 +00:00
|
|
|
const Town *t = ::Town::Get(town_id);
|
2009-01-12 17:11:45 +00:00
|
|
|
if (_settings_game.economy.station_noise_level) {
|
|
|
|
return t->MaxTownNoise() - t->noise_reached;
|
|
|
|
}
|
|
|
|
|
|
|
|
int num = 0;
|
|
|
|
const Station *st;
|
|
|
|
FOR_ALL_STATIONS(st) {
|
2009-06-01 11:43:36 +00:00
|
|
|
if (st->town == t && (st->facilities & FACIL_AIRPORT) && st->airport_type != AT_OILRIG) num++;
|
2009-01-12 17:11:45 +00:00
|
|
|
}
|
|
|
|
return max(0, 2 - num);
|
|
|
|
}
|
2009-02-04 23:26:21 +00:00
|
|
|
|
|
|
|
/* static */ AITown::RoadLayout AITown::GetRoadLayout(TownID town_id)
|
|
|
|
{
|
|
|
|
if (!IsValidTown(town_id)) return ROAD_LAYOUT_INVALID;
|
|
|
|
|
2009-05-16 23:34:14 +00:00
|
|
|
return (AITown::RoadLayout)((TownLayout)::Town::Get(town_id)->layout);
|
2009-02-04 23:26:21 +00:00
|
|
|
}
|