/* $Id */
/** @file */
#include "stdafx.h"
#include "openttd.h"
#include "road_map.h"
#include "town.h"
#include "town_map.h"
/* static */
int64 Town::GetTilePrice(TileIndex tile)
{
uint rad;
const Town *t = GetRadiusGroupForTile(tile, rad);
FixedT<int64, 16> price = t->GetActivity();
DEBUG(eco, 6, "Getting price for tile 0x%x at %f (authority at 0x%x)", tile, (double)price, t->xy);
price *= _eco->GetPrice(CEconomy::PURCHASE_LAND) * rad * rad * 10;
return price;
}
/* static */
const Town *Town::GetRadiusGroupForTile(TileIndex tile, uint &group)
{
const Town *t;
group = 0;
const Town *best_town = NULL;
DEBUG(eco, 7, "Obtaining highest town radius for tile 0x%x", tile);
/* We do have a tile that directly belongs to a town */
if (IsTileType(tile, MP_HOUSE) ||
(IsTileType(tile, MP_STREET) &&
(GetTileOwner(tile)) == OWNER_TOWN)) { /** @todo check this for level crossings, trams, etc */
t = GetTownByTile(tile);
group = t->GetRadiusGroup(tile, true) + 1;
DEBUG(eco, 6, "Tile 0x%x belongs to town at 0x%x, level %d", tile, t->xy, group);
return t;
}
uint best_dist = UINT_MAX;
FOR_ALL_TOWNS(t) {
if (1 + t->GetRadiusGroup(tile, true) > group) {
group = t->GetRadiusGroup(tile, true) + 1;
DEBUG(eco, 7, "Higher group (%d) found for town at 0x%x", group, t->xy);
best_town = t;
if (best_dist > DistanceSquare(tile, t->xy)) best_dist = DistanceSquare(tile, t->xy);
} else if (1 + t->GetRadiusGroup(tile, true) == group) {
DEBUG(eco, 7, "Same group found town at 0x%x is closer", t->xy);
if (best_dist > DistanceSquare(tile, t->xy)) {
best_dist = DistanceSquare(tile, t->xy);
best_town = t;
}
}
}
assert(best_town != NULL);
return best_town;
}
uint Town::GetRadiusGroup(TileIndex tile, bool ignore_funding) const
{
uint dist = DistanceSquare(tile, xy);
uint smallest = 0;
if (!ignore_funding && fund_buildings_months > 0 && dist < 25) return 4;
for (uint i = 0; i != lengthof(radius); i++) if (dist < radius[i]) smallest = i;
return smallest;
}
void Town::UpdateActivity()
{
if (new_act_pass == 0 && act_pass == 0) {
DEBUG(eco, 7, "Town is not connected, bailing out");
return;
}
static const FixedT<int, 12> max_activity_change (1, 400);
static const FixedT<int, 12> min_activity_change = -max_activity_change;
FixedT<int, 12> activity_change (1, 200);
activity_change *= act_pass;
activity_change /= max_pass;
activity_change -= max_activity_change;
DEBUG(eco, 6, "Raw EAL change for town at 0x%x is %f", xy, (double)activity_change);
if (activity_change > max_activity_change) activity_change = max_activity_change;
if (activity_change < min_activity_change) activity_change = min_activity_change;
this->SetActivity(this->GetActivity() + activity_change);
DEBUG(eco, 5, "Modifying EAL for town at 0x%x by %f to %f", xy, (double)activity_change, (double)this->GetActivity());
}