|
@@ -46,25 +46,24 @@
|
|
|
#include "depot_base.h"
|
|
|
#include "object_map.h"
|
|
|
#include "object_base.h"
|
|
|
#include "ai/ai.hpp"
|
|
|
#include "game/game.hpp"
|
|
|
|
|
|
#include "table/strings.h"
|
|
|
#include "table/town_land.h"
|
|
|
|
|
|
#include "safeguards.h"
|
|
|
|
|
|
TownID _new_town_id;
|
|
|
CargoTypes _town_cargoes_accepted; ///< Bitmap of all cargoes accepted by houses.
|
|
|
|
|
|
/* Initialize the town-pool */
|
|
|
TownPool _town_pool("Town");
|
|
|
INSTANTIATE_POOL_METHODS(Town)
|
|
|
|
|
|
|
|
|
TownKdtree _town_kdtree(&Kdtree_TownXYFunc);
|
|
|
|
|
|
void RebuildTownKdtree()
|
|
|
{
|
|
|
std::vector<TownID> townids;
|
|
|
for (const Town *town : Town::Iterate()) {
|
|
@@ -773,103 +772,24 @@ static void GetTileDesc_Town(TileIndex t
|
|
|
|
|
|
static TrackStatus GetTileTrackStatus_Town(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
|
|
|
{
|
|
|
/* not used */
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
static void ChangeTileOwner_Town(TileIndex tile, Owner old_owner, Owner new_owner)
|
|
|
{
|
|
|
/* not used */
|
|
|
}
|
|
|
|
|
|
/** Update the total cargo acceptance of the whole town.
|
|
|
* @param t The town to update.
|
|
|
*/
|
|
|
void UpdateTownCargoTotal(Town *t)
|
|
|
{
|
|
|
t->cargo_accepted_total = 0;
|
|
|
|
|
|
const TileArea &area = t->cargo_accepted.GetArea();
|
|
|
TILE_AREA_LOOP(tile, area) {
|
|
|
if (TileX(tile) % AcceptanceMatrix::GRID == 0 && TileY(tile) % AcceptanceMatrix::GRID == 0) {
|
|
|
t->cargo_accepted_total |= t->cargo_accepted[tile];
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Update accepted town cargoes around a specific tile.
|
|
|
* @param t The town to update.
|
|
|
* @param start Update the values around this tile.
|
|
|
* @param update_total Set to true if the total cargo acceptance should be updated.
|
|
|
*/
|
|
|
static void UpdateTownCargoes(Town *t, TileIndex start, bool update_total = true)
|
|
|
{
|
|
|
CargoArray accepted, produced;
|
|
|
CargoTypes dummy = 0;
|
|
|
|
|
|
/* Gather acceptance for all houses in an area around the start tile.
|
|
|
* The area is composed of the square the tile is in, extended one square in all
|
|
|
* directions as the coverage area of a single station is bigger than just one square. */
|
|
|
TileArea area = AcceptanceMatrix::GetAreaForTile(start, 1);
|
|
|
TILE_AREA_LOOP(tile, area) {
|
|
|
if (!IsTileType(tile, MP_HOUSE) || GetTownIndex(tile) != t->index) continue;
|
|
|
|
|
|
AddAcceptedCargo_Town(tile, accepted, &dummy);
|
|
|
AddProducedCargo_Town(tile, produced);
|
|
|
}
|
|
|
|
|
|
/* Create bitmap of produced and accepted cargoes. */
|
|
|
CargoTypes acc = 0;
|
|
|
for (uint cid = 0; cid < NUM_CARGO; cid++) {
|
|
|
if (accepted[cid] >= 8) SetBit(acc, cid);
|
|
|
if (produced[cid] > 0) SetBit(t->cargo_produced, cid);
|
|
|
}
|
|
|
t->cargo_accepted[start] = acc;
|
|
|
|
|
|
if (update_total) UpdateTownCargoTotal(t);
|
|
|
}
|
|
|
|
|
|
/** Update cargo acceptance for the complete town.
|
|
|
* @param t The town to update.
|
|
|
*/
|
|
|
void UpdateTownCargoes(Town *t)
|
|
|
{
|
|
|
t->cargo_produced = 0;
|
|
|
|
|
|
const TileArea &area = t->cargo_accepted.GetArea();
|
|
|
if (area.tile == INVALID_TILE) return;
|
|
|
|
|
|
/* Update acceptance for each grid square. */
|
|
|
TILE_AREA_LOOP(tile, area) {
|
|
|
if (TileX(tile) % AcceptanceMatrix::GRID == 0 && TileY(tile) % AcceptanceMatrix::GRID == 0) {
|
|
|
UpdateTownCargoes(t, tile, false);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* Update the total acceptance. */
|
|
|
UpdateTownCargoTotal(t);
|
|
|
}
|
|
|
|
|
|
/** Updates the bitmap of all cargoes accepted by houses. */
|
|
|
void UpdateTownCargoBitmap()
|
|
|
{
|
|
|
_town_cargoes_accepted = 0;
|
|
|
|
|
|
for (const Town *town : Town::Iterate()) {
|
|
|
_town_cargoes_accepted |= town->cargo_accepted_total;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static bool GrowTown(Town *t);
|
|
|
|
|
|
static void TownTickHandler(Town *t)
|
|
|
{
|
|
|
if (HasBit(t->flags, TOWN_IS_GROWING)) {
|
|
|
int i = (int)t->grow_counter - 1;
|
|
|
if (i < 0) {
|
|
|
if (GrowTown(t)) {
|
|
|
i = t->growth_rate;
|
|
|
} else {
|
|
|
/* If growth failed wait a bit before retrying */
|
|
|
i = min(t->growth_rate, TOWN_GROWTH_TICKS - 1);
|
|
@@ -2579,25 +2499,24 @@ static bool BuildTownHouse(Town *t, Tile
|
|
|
if (Chance16(1, 7)) construction_stage = GB(r, 0, 2);
|
|
|
|
|
|
if (construction_stage == TOWN_HOUSE_COMPLETED) {
|
|
|
ChangePopulation(t, hs->population);
|
|
|
} else {
|
|
|
construction_counter = GB(r, 2, 2);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
MakeTownHouse(tile, t, construction_counter, construction_stage, house, random_bits);
|
|
|
UpdateTownRadius(t);
|
|
|
UpdateTownGrowthRate(t);
|
|
|
UpdateTownCargoes(t, tile);
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Update data structures when a house is removed
|
|
|
* @param tile Tile of the house
|
|
|
* @param t Town owning the house
|
|
|
* @param house House type
|
|
@@ -2664,27 +2583,24 @@ void ClearTownHouse(Town *t, TileIndex t
|
|
|
ClrBit(t->flags, TOWN_HAS_STADIUM);
|
|
|
}
|
|
|
|
|
|
/* Do the actual clearing of tiles */
|
|
|
DoClearTownHouseHelper(tile, t, house);
|
|
|
if (hs->building_flags & BUILDING_2_TILES_Y) DoClearTownHouseHelper(tile + TileDiffXY(0, 1), t, ++house);
|
|
|
if (hs->building_flags & BUILDING_2_TILES_X) DoClearTownHouseHelper(tile + TileDiffXY(1, 0), t, ++house);
|
|
|
if (hs->building_flags & BUILDING_HAS_4_TILES) DoClearTownHouseHelper(tile + TileDiffXY(1, 1), t, ++house);
|
|
|
|
|
|
RemoveNearbyStations(t, tile, hs->building_flags);
|
|
|
|
|
|
UpdateTownRadius(t);
|
|
|
|
|
|
/* Update cargo acceptance. */
|
|
|
UpdateTownCargoes(t, tile);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Rename a town (server-only).
|
|
|
* @param tile unused
|
|
|
* @param flags type of operation
|
|
|
* @param p1 town ID to rename
|
|
|
* @param p2 unused
|
|
|
* @param text the new name or an empty string when resetting to the default
|
|
|
* @return the cost of this operation or an error
|
|
|
*/
|
|
|
CommandCost CmdRenameTown(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
|
@@ -3689,28 +3605,26 @@ void TownsMonthlyLoop()
|
|
|
{
|
|
|
for (Town *t : Town::Iterate()) {
|
|
|
if (t->road_build_months != 0) t->road_build_months--;
|
|
|
|
|
|
if (t->exclusive_counter != 0) {
|
|
|
if (--t->exclusive_counter == 0) t->exclusivity = INVALID_COMPANY;
|
|
|
}
|
|
|
|
|
|
UpdateTownAmounts(t);
|
|
|
UpdateTownGrowth(t);
|
|
|
UpdateTownRating(t);
|
|
|
UpdateTownUnwanted(t);
|
|
|
UpdateTownCargoes(t);
|
|
|
}
|
|
|
|
|
|
UpdateTownCargoBitmap();
|
|
|
}
|
|
|
|
|
|
void TownsYearlyLoop()
|
|
|
{
|
|
|
/* Increment house ages */
|
|
|
for (TileIndex t = 0; t < MapSize(); t++) {
|
|
|
if (!IsTileType(t, MP_HOUSE)) continue;
|
|
|
IncrementHouseAge(t);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static CommandCost TerraformTile_Town(TileIndex tile, DoCommandFlag flags, int z_new, Slope tileh_new)
|