src/town_cmd.cpp
branchNewGRF_ports
changeset 10184 fcf5fb2548eb
parent 6878 7d1ff2f621c7
child 10211 c1391c8ed5c6
equal deleted inserted replaced
10179:eec5a7dcbf61 10184:fcf5fb2548eb
    13 #include "tunnel_map.h"
    13 #include "tunnel_map.h"
    14 #include "viewport_func.h"
    14 #include "viewport_func.h"
    15 #include "town.h"
    15 #include "town.h"
    16 #include "command_func.h"
    16 #include "command_func.h"
    17 #include "industry.h"
    17 #include "industry.h"
    18 #include "station.h"
    18 #include "station_base.h"
    19 #include "player_base.h"
    19 #include "player_base.h"
    20 #include "news.h"
    20 #include "news_func.h"
    21 #include "saveload.h"
    21 #include "saveload.h"
    22 #include "gui.h"
    22 #include "gui.h"
    23 #include "unmovable_map.h"
    23 #include "unmovable_map.h"
    24 #include "water_map.h"
    24 #include "water_map.h"
    25 #include "variables.h"
    25 #include "variables.h"
    37 #include "transparency.h"
    37 #include "transparency.h"
    38 #include "tunnelbridge_map.h"
    38 #include "tunnelbridge_map.h"
    39 #include "strings_func.h"
    39 #include "strings_func.h"
    40 #include "window_func.h"
    40 #include "window_func.h"
    41 #include "string_func.h"
    41 #include "string_func.h"
       
    42 #include "newgrf_cargo.h"
       
    43 #include "oldpool_func.h"
    42 
    44 
    43 #include "table/strings.h"
    45 #include "table/strings.h"
    44 #include "table/sprites.h"
    46 #include "table/sprites.h"
    45 #include "table/town_land.h"
    47 #include "table/town_land.h"
    46 
    48 
   104 	MarkWholeScreenDirty();
   106 	MarkWholeScreenDirty();
   105 
   107 
   106 	this->xy = 0;
   108 	this->xy = 0;
   107 }
   109 }
   108 
   110 
       
   111 /**
       
   112  * Generate a random town road layout.
       
   113  *
       
   114  * The layout is based on the TileHash.
       
   115  */
       
   116 void Town::InitializeLayout()
       
   117 {
       
   118 	this->layout = (TownLayout)(TileHash(TileX(this->xy), TileY(this->xy)) % NUM_TLS);
       
   119 
       
   120 	/* Set invalid layouts to valid ones */
       
   121 	switch (this->layout) {
       
   122 		default: break;
       
   123 		case TL_RANDOM: this->layout = TL_ORIGINAL; break;
       
   124 		case TL_NO_ROADS: this->layout = TL_BETTER_ROADS; break;
       
   125 	}
       
   126 }
       
   127 
   109 // Local
   128 // Local
   110 static int _grow_town_result;
   129 static int _grow_town_result;
   111 
   130 
   112 /* Describe the possible states */
   131 /* Describe the possible states */
   113 enum TownGrowthResult {
   132 enum TownGrowthResult {
   122 {
   141 {
   123 	AddChildSpriteScreen(SPR_LIFT, PAL_NONE, 14, 60 - GetLiftPosition(ti->tile));
   142 	AddChildSpriteScreen(SPR_LIFT, PAL_NONE, 14, 60 - GetLiftPosition(ti->tile));
   124 }
   143 }
   125 
   144 
   126 typedef void TownDrawTileProc(const TileInfo *ti);
   145 typedef void TownDrawTileProc(const TileInfo *ti);
   127 static TownDrawTileProc * const _town_draw_tile_procs[1] = {
   146 static TownDrawTileProc *const _town_draw_tile_procs[1] = {
   128 	TownDrawHouseLift
   147 	TownDrawHouseLift
   129 };
   148 };
   130 
       
   131 uint OriginalTileRandomiser(uint x, uint y)
       
   132 {
       
   133 	uint variant;
       
   134 	variant  = x >> 4;
       
   135 	variant ^= x >> 6;
       
   136 	variant ^= y >> 4;
       
   137 	variant -= y >> 6;
       
   138 	variant &= 3;
       
   139 	return variant;
       
   140 }
       
   141 
   149 
   142 /**
   150 /**
   143  * Return a random direction
   151  * Return a random direction
   144  *
   152  *
   145  * @return a random direction
   153  * @return a random direction
   154  * Part of the tile loop process
   162  * Part of the tile loop process
   155  * @param ti TileInfo of the tile to draw
   163  * @param ti TileInfo of the tile to draw
   156  */
   164  */
   157 static void DrawTile_Town(TileInfo *ti)
   165 static void DrawTile_Town(TileInfo *ti)
   158 {
   166 {
   159 	const DrawBuildingsTileStruct *dcts;
       
   160 	SpriteID image;
       
   161 	SpriteID pal;
       
   162 	HouseID house_id = GetHouseType(ti->tile);
   167 	HouseID house_id = GetHouseType(ti->tile);
   163 
   168 
   164 	if (house_id >= NEW_HOUSE_OFFSET) {
   169 	if (house_id >= NEW_HOUSE_OFFSET) {
   165 		/* Houses don't necessarily need new graphics. If they don't have a
   170 		/* Houses don't necessarily need new graphics. If they don't have a
   166 		 * spritegroup associated with them, then the sprite for the substitute
   171 		 * spritegroup associated with them, then the sprite for the substitute
   172 			house_id = GetHouseSpecs(house_id)->substitute_id;
   177 			house_id = GetHouseSpecs(house_id)->substitute_id;
   173 		}
   178 		}
   174 	}
   179 	}
   175 
   180 
   176 	/* Retrieve pointer to the draw town tile struct */
   181 	/* Retrieve pointer to the draw town tile struct */
   177 	dcts = &_town_draw_tile_data[house_id << 4 | OriginalTileRandomiser(ti->x, ti->y) << 2 | GetHouseBuildingStage(ti->tile)];
   182 	const DrawBuildingsTileStruct *dcts = &_town_draw_tile_data[house_id << 4 | TileHash2Bit(ti->x, ti->y) << 2 | GetHouseBuildingStage(ti->tile)];
   178 
   183 
   179 	if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, FOUNDATION_LEVELED);
   184 	if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, FOUNDATION_LEVELED);
   180 
   185 
   181 	image = dcts->ground.sprite;
   186 	DrawGroundSprite(dcts->ground.sprite, dcts->ground.pal);
   182 	pal   = dcts->ground.pal;
   187 
   183 	DrawGroundSprite(image, pal);
   188 	/* If houses are invisible, do not draw the upper part */
       
   189 	if (IsInvisibilitySet(TO_HOUSES)) return;
   184 
   190 
   185 	/* Add a house on top of the ground? */
   191 	/* Add a house on top of the ground? */
   186 	image = dcts->building.sprite;
   192 	SpriteID image = dcts->building.sprite;
   187 	if (image != 0) {
   193 	if (image != 0) {
   188 		AddSortableSpriteToDraw(image, dcts->building.pal,
   194 		AddSortableSpriteToDraw(image, dcts->building.pal,
   189 			ti->x + dcts->subtile_x,
   195 			ti->x + dcts->subtile_x,
   190 			ti->y + dcts->subtile_y,
   196 			ti->y + dcts->subtile_y,
   191 			dcts->width,
   197 			dcts->width,
   221  * The newhouses animation superseeds regular ones
   227  * The newhouses animation superseeds regular ones
   222  * @param tile TileIndex of the house to animate
   228  * @param tile TileIndex of the house to animate
   223  */
   229  */
   224 static void AnimateTile_Town(TileIndex tile)
   230 static void AnimateTile_Town(TileIndex tile)
   225 {
   231 {
   226 	int pos, dest;
       
   227 
       
   228 	if (GetHouseType(tile) >= NEW_HOUSE_OFFSET) {
   232 	if (GetHouseType(tile) >= NEW_HOUSE_OFFSET) {
   229 		AnimateNewHouseTile(tile);
   233 		AnimateNewHouseTile(tile);
   230 		return;
   234 		return;
   231 	}
   235 	}
   232 
   236 
   240 		DeleteAnimatedTile(tile);
   244 		DeleteAnimatedTile(tile);
   241 		return;
   245 		return;
   242 	}
   246 	}
   243 
   247 
   244 	if (!LiftHasDestination(tile)) {
   248 	if (!LiftHasDestination(tile)) {
   245 		int i;
   249 		uint i;
   246 
   250 
   247 		/*  Building has 6 floors, number 0 .. 6, where 1 is illegal.
   251 		/* Building has 6 floors, number 0 .. 6, where 1 is illegal.
   248 		 *  This is due to the fact that the first floor is, in the graphics,
   252 		 * This is due to the fact that the first floor is, in the graphics,
   249 		 *  the height of 2 'normal' floors.
   253 		 *  the height of 2 'normal' floors.
   250 		 *  Furthermore, there are 6 lift positions from floor N (incl) to floor N + 1 (excl) */
   254 		 * Furthermore, there are 6 lift positions from floor N (incl) to floor N + 1 (excl) */
   251 		do {
   255 		do {
   252 			i = (Random() & 7) - 1;
   256 			i = RandomRange(7);
   253 		} while (i < 0 || i == 1 || i * 6 == GetLiftPosition(tile));
   257 		} while (i == 1 || i * 6 == GetLiftPosition(tile));
   254 
   258 
   255 		SetLiftDestination(tile, i);
   259 		SetLiftDestination(tile, i);
   256 	}
   260 	}
   257 
   261 
   258 	pos = GetLiftPosition(tile);
   262 	int pos = GetLiftPosition(tile);
   259 	dest = GetLiftDestination(tile) * 6;
   263 	int dest = GetLiftDestination(tile) * 6;
   260 	pos += (pos < dest) ? 1 : -1;
   264 	pos += (pos < dest) ? 1 : -1;
   261 	SetLiftPosition(tile, pos);
   265 	SetLiftPosition(tile, pos);
   262 
   266 
   263 	if (pos == dest) HaltLift(tile);
   267 	if (pos == dest) HaltLift(tile);
   264 
   268 
   265 	MarkTileDirtyByTile(tile);
   269 	MarkTileDirtyByTile(tile);
   266 }
   270 }
   267 
       
   268 static void UpdateTownRadius(Town *t);
       
   269 
   271 
   270 /**
   272 /**
   271  * Determines if a town is close to a tile
   273  * Determines if a town is close to a tile
   272  * @param tile TileIndex of the tile to query
   274  * @param tile TileIndex of the tile to query
   273  * @param dist maximum distance to be accepted
   275  * @param dist maximum distance to be accepted
   274  * @returns true if the tile correspond to the distance criteria
   276  * @returns true if the tile correspond to the distance criteria
   275  */
   277  */
   276 static bool IsCloseToTown(TileIndex tile, uint dist)
   278 static bool IsCloseToTown(TileIndex tile, uint dist)
   277 {
   279 {
   278 	const Town* t;
   280 	const Town *t;
   279 
   281 
   280 	FOR_ALL_TOWNS(t) {
   282 	FOR_ALL_TOWNS(t) {
   281 		if (DistanceManhattan(tile, t->xy) < dist) return true;
   283 		if (DistanceManhattan(tile, t->xy) < dist) return true;
   282 	}
   284 	}
   283 	return false;
   285 	return false;
   306  * population (creation or growth or else)
   308  * population (creation or growth or else)
   307  * @param t Town to update
   309  * @param t Town to update
   308  */
   310  */
   309 void UpdateTownVirtCoord(Town *t)
   311 void UpdateTownVirtCoord(Town *t)
   310 {
   312 {
   311 	Point pt;
       
   312 
       
   313 	MarkTownSignDirty(t);
   313 	MarkTownSignDirty(t);
   314 	pt = RemapCoords2(TileX(t->xy) * TILE_SIZE, TileY(t->xy) * TILE_SIZE);
   314 	Point pt = RemapCoords2(TileX(t->xy) * TILE_SIZE, TileY(t->xy) * TILE_SIZE);
   315 	SetDParam(0, t->index);
   315 	SetDParam(0, t->index);
   316 	SetDParam(1, t->population);
   316 	SetDParam(1, t->population);
   317 	UpdateViewportSignPos(&t->sign, pt.x, pt.y - 24,
   317 	UpdateViewportSignPos(&t->sign, pt.x, pt.y - 24,
   318 		_patches.population_in_label ? STR_TOWN_LABEL_POP : STR_TOWN_LABEL);
   318 		_patches.population_in_label ? STR_TOWN_LABEL_POP : STR_TOWN_LABEL);
   319 	MarkTownSignDirty(t);
   319 	MarkTownSignDirty(t);
   347  * Basically, count population of all towns, one by one
   347  * Basically, count population of all towns, one by one
   348  * @return uint32 the calculated population of the world
   348  * @return uint32 the calculated population of the world
   349  */
   349  */
   350 uint32 GetWorldPopulation()
   350 uint32 GetWorldPopulation()
   351 {
   351 {
   352 	uint32 pop;
   352 	uint32 pop = 0;
   353 	const Town* t;
   353 	const Town *t;
   354 
   354 
   355 	pop = 0;
       
   356 	FOR_ALL_TOWNS(t) pop += t->population;
   355 	FOR_ALL_TOWNS(t) pop += t->population;
   357 	return pop;
   356 	return pop;
   358 }
   357 }
   359 
   358 
   360 /**
   359 /**
   402  * Periodic tic handler for houses and town
   401  * Periodic tic handler for houses and town
   403  * @param tile been asked to do its stuff
   402  * @param tile been asked to do its stuff
   404  */
   403  */
   405 static void TileLoop_Town(TileIndex tile)
   404 static void TileLoop_Town(TileIndex tile)
   406 {
   405 {
   407 	Town *t;
       
   408 	uint32 r;
       
   409 	HouseID house_id = GetHouseType(tile);
   406 	HouseID house_id = GetHouseType(tile);
   410 	HouseSpec *hs = GetHouseSpecs(house_id);
       
   411 
   407 
   412 	/* NewHouseTileLoop returns false if Callback 21 succeeded, i.e. the house
   408 	/* NewHouseTileLoop returns false if Callback 21 succeeded, i.e. the house
   413 	 * doesn't exist any more, so don't continue here. */
   409 	 * doesn't exist any more, so don't continue here. */
   414 	if (house_id >= NEW_HOUSE_OFFSET && !NewHouseTileLoop(tile)) return;
   410 	if (house_id >= NEW_HOUSE_OFFSET && !NewHouseTileLoop(tile)) return;
   415 
   411 
   417 		/* Construction is not completed. See if we can go further in construction*/
   413 		/* Construction is not completed. See if we can go further in construction*/
   418 		MakeTownHouseBigger(tile);
   414 		MakeTownHouseBigger(tile);
   419 		return;
   415 		return;
   420 	}
   416 	}
   421 
   417 
       
   418 	const HouseSpec *hs = GetHouseSpecs(house_id);
       
   419 
   422 	/* If the lift has a destination, it is already an animated tile. */
   420 	/* If the lift has a destination, it is already an animated tile. */
   423 	if ((hs->building_flags & BUILDING_IS_ANIMATED) &&
   421 	if ((hs->building_flags & BUILDING_IS_ANIMATED) &&
   424 			house_id < NEW_HOUSE_OFFSET &&
   422 			house_id < NEW_HOUSE_OFFSET &&
   425 			!LiftHasDestination(tile) &&
   423 			!LiftHasDestination(tile) &&
   426 			Chance16(1, 2))
   424 			Chance16(1, 2)) {
   427 		AddAnimatedTile(tile);
   425 		AddAnimatedTile(tile);
   428 
   426 	}
   429 	t = GetTownByTile(tile);
   427 
   430 
   428 	Town *t = GetTownByTile(tile);
   431 	r = Random();
   429 	uint32 r = Random();
   432 
   430 
   433 	if (HasBit(hs->callback_mask, CBM_HOUSE_PRODUCE_CARGO)) {
   431 	if (HasBit(hs->callback_mask, CBM_HOUSE_PRODUCE_CARGO)) {
   434 		for (uint i = 0; i < 256; i++) {
   432 		for (uint i = 0; i < 256; i++) {
   435 			uint16 callback = GetHouseCallback(CBID_HOUSE_PRODUCE_CARGO, i, r, house_id, t, tile);
   433 			uint16 callback = GetHouseCallback(CBID_HOUSE_PRODUCE_CARGO, i, r, house_id, t, tile);
   436 
   434 
   459 			}
   457 			}
   460 		}
   458 		}
   461 	} else {
   459 	} else {
   462 		if (GB(r, 0, 8) < hs->population) {
   460 		if (GB(r, 0, 8) < hs->population) {
   463 			uint amt = GB(r, 0, 8) / 8 + 1;
   461 			uint amt = GB(r, 0, 8) / 8 + 1;
   464 			uint moved;
       
   465 
   462 
   466 			if (_economy.fluct <= 0) amt = (amt + 1) >> 1;
   463 			if (_economy.fluct <= 0) amt = (amt + 1) >> 1;
   467 			t->new_max_pass += amt;
   464 			t->new_max_pass += amt;
   468 			moved = MoveGoodsToStation(tile, 1, 1, CT_PASSENGERS, amt);
   465 			t->new_act_pass += MoveGoodsToStation(tile, 1, 1, CT_PASSENGERS, amt);
   469 			t->new_act_pass += moved;
       
   470 		}
   466 		}
   471 
   467 
   472 		if (GB(r, 8, 8) < hs->mail_generation) {
   468 		if (GB(r, 8, 8) < hs->mail_generation) {
   473 			uint amt = GB(r, 8, 8) / 8 + 1;
   469 			uint amt = GB(r, 8, 8) / 8 + 1;
   474 			uint moved;
       
   475 
   470 
   476 			if (_economy.fluct <= 0) amt = (amt + 1) >> 1;
   471 			if (_economy.fluct <= 0) amt = (amt + 1) >> 1;
   477 			t->new_max_mail += amt;
   472 			t->new_max_mail += amt;
   478 			moved = MoveGoodsToStation(tile, 1, 1, CT_MAIL, amt);
   473 			t->new_act_mail += MoveGoodsToStation(tile, 1, 1, CT_MAIL, amt);
   479 			t->new_act_mail += moved;
       
   480 		}
   474 		}
   481 	}
   475 	}
   482 
   476 
   483 	_current_player = OWNER_TOWN;
   477 	_current_player = OWNER_TOWN;
   484 
   478 
   507 	/* not used */
   501 	/* not used */
   508 }
   502 }
   509 
   503 
   510 static CommandCost ClearTile_Town(TileIndex tile, byte flags)
   504 static CommandCost ClearTile_Town(TileIndex tile, byte flags)
   511 {
   505 {
   512 	int rating;
   506 	if ((flags & DC_AUTO) && !(flags & DC_AI_BUILDING)) return_cmd_error(STR_2004_BUILDING_MUST_BE_DEMOLISHED);
       
   507 	if (!CanDeleteHouse(tile)) return CMD_ERROR;
       
   508 
       
   509 	const HouseSpec *hs = GetHouseSpecs(GetHouseType(tile));
       
   510 
   513 	CommandCost cost(EXPENSES_CONSTRUCTION);
   511 	CommandCost cost(EXPENSES_CONSTRUCTION);
   514 	Town *t;
       
   515 	HouseSpec *hs = GetHouseSpecs(GetHouseType(tile));
       
   516 
       
   517 	if (flags&DC_AUTO && !(flags&DC_AI_BUILDING)) return_cmd_error(STR_2004_BUILDING_MUST_BE_DEMOLISHED);
       
   518 	if (!CanDeleteHouse(tile)) return CMD_ERROR;
       
   519 
       
   520 	cost.AddCost(_price.remove_house * hs->removal_cost >> 8);
   512 	cost.AddCost(_price.remove_house * hs->removal_cost >> 8);
   521 
   513 
   522 	rating = hs->remove_rating_decrease;
   514 	int rating = hs->remove_rating_decrease;
   523 	_cleared_town_rating += rating;
   515 	_cleared_town_rating += rating;
   524 	_cleared_town = t = GetTownByTile(tile);
   516 	Town *t = _cleared_town = GetTownByTile(tile);
   525 
   517 
   526 	if (IsValidPlayer(_current_player)) {
   518 	if (IsValidPlayer(_current_player)) {
   527 		if (rating > t->ratings[_current_player] && !(flags & DC_NO_TOWN_RATING) && !_cheats.magic_bulldozer.value) {
   519 		if (rating > t->ratings[_current_player] && !(flags & DC_NO_TOWN_RATING) && !_cheats.magic_bulldozer.value) {
   528 			SetDParam(0, t->index);
   520 			SetDParam(0, t->index);
   529 			return_cmd_error(STR_2009_LOCAL_AUTHORITY_REFUSES);
   521 			return_cmd_error(STR_2009_LOCAL_AUTHORITY_REFUSES);
   536 	}
   528 	}
   537 
   529 
   538 	return cost;
   530 	return cost;
   539 }
   531 }
   540 
   532 
       
   533 static void GetProducedCargo_Town(TileIndex tile, CargoID *b)
       
   534 {
       
   535 	HouseID house_id = GetHouseType(tile);
       
   536 	const HouseSpec *hs = GetHouseSpecs(house_id);
       
   537 	Town *t = GetTownByTile(tile);
       
   538 
       
   539 	if (HasBit(hs->callback_mask, CBM_HOUSE_PRODUCE_CARGO)) {
       
   540 		for (uint i = 0; i < 256; i++) {
       
   541 			uint16 callback = GetHouseCallback(CBID_HOUSE_PRODUCE_CARGO, i, 0, house_id, t, tile);
       
   542 
       
   543 			if (callback == CALLBACK_FAILED || callback == CALLBACK_HOUSEPRODCARGO_END) break;
       
   544 
       
   545 			CargoID cargo = GetCargoTranslation(GB(callback, 8, 7), hs->grffile);
       
   546 
       
   547 			if (cargo == CT_INVALID) continue;
       
   548 			*(b++) = cargo;
       
   549 		}
       
   550 	} else {
       
   551 		if (hs->population > 0) {
       
   552 			*(b++) = CT_PASSENGERS;
       
   553 		}
       
   554 		if (hs->mail_generation > 0) {
       
   555 			*(b++) = CT_MAIL;
       
   556 		}
       
   557 	}
       
   558 }
       
   559 
   541 static void GetAcceptedCargo_Town(TileIndex tile, AcceptedCargo ac)
   560 static void GetAcceptedCargo_Town(TileIndex tile, AcceptedCargo ac)
   542 {
   561 {
   543 	HouseSpec *hs = GetHouseSpecs(GetHouseType(tile));
   562 	const HouseSpec *hs = GetHouseSpecs(GetHouseType(tile));
   544 	CargoID accepts[3];
   563 	CargoID accepts[3];
   545 
   564 
   546 	/* Set the initial accepted cargo types */
   565 	/* Set the initial accepted cargo types */
   547 	for (uint8 i = 0; i < lengthof(accepts); i++) {
   566 	for (uint8 i = 0; i < lengthof(accepts); i++) {
   548 		accepts[i] = hs->accepts_cargo[i];
   567 		accepts[i] = hs->accepts_cargo[i];
   701 }
   720 }
   702 
   721 
   703 /**
   722 /**
   704  * Check if a Road is allowed on a given tile
   723  * Check if a Road is allowed on a given tile
   705  *
   724  *
       
   725  * @param t The current town
   706  * @param tile The target tile
   726  * @param tile The target tile
   707  * @param dir The direction in which we want to extend the town
   727  * @param dir The direction in which we want to extend the town
   708  * @return true if it is allowed else false
   728  * @return true if it is allowed else false
   709  */
   729  */
   710 static bool IsRoadAllowedHere(TileIndex tile, DiagDirection dir)
   730 static bool IsRoadAllowedHere(Town *t, TileIndex tile, DiagDirection dir)
   711 {
   731 {
   712 	if (TileX(tile) < 2 || TileX(tile) >= MapMaxX() || TileY(tile) < 2 || TileY(tile) >= MapMaxY()) return false;
   732 	if (TileX(tile) < 2 || TileX(tile) >= MapMaxX() || TileY(tile) < 2 || TileY(tile) >= MapMaxY()) return false;
   713 
   733 
   714 	Slope cur_slope, desired_slope;
   734 	Slope cur_slope, desired_slope;
   715 
   735 
   726 
   746 
   727 		cur_slope = GetTileSlope(tile, NULL);
   747 		cur_slope = GetTileSlope(tile, NULL);
   728 		if (cur_slope == SLOPE_FLAT) {
   748 		if (cur_slope == SLOPE_FLAT) {
   729 no_slope:
   749 no_slope:
   730 			/* Tile has no slope */
   750 			/* Tile has no slope */
   731 			switch (_patches.town_layout) {
   751 			switch (t->GetActiveLayout()) {
   732 				default: NOT_REACHED();
   752 				default: NOT_REACHED();
   733 
   753 
   734 				case TL_ORIGINAL: // Disallow the road if any neighboring tile has a road (distance: 1)
   754 				case TL_ORIGINAL: // Disallow the road if any neighboring tile has a road (distance: 1)
   735 					return !IsNeighborRoadTile(tile, dir, 1);
   755 					return !IsNeighborRoadTile(tile, dir, 1);
   736 
   756 
   761 	}
   781 	}
   762 }
   782 }
   763 
   783 
   764 static bool TerraformTownTile(TileIndex tile, int edges, int dir)
   784 static bool TerraformTownTile(TileIndex tile, int edges, int dir)
   765 {
   785 {
   766 	CommandCost r;
       
   767 
       
   768 	TILE_ASSERT(tile);
   786 	TILE_ASSERT(tile);
   769 
   787 
   770 	r = DoCommand(tile, edges, dir, DC_AUTO | DC_NO_WATER, CMD_TERRAFORM_LAND);
   788 	CommandCost r = DoCommand(tile, edges, dir, DC_AUTO | DC_NO_WATER, CMD_TERRAFORM_LAND);
   771 	if (CmdFailed(r) || r.GetCost() >= 126 * 16) return false;
   789 	if (CmdFailed(r) || r.GetCost() >= (_price.terraform + 2) * 8) return false;
   772 	DoCommand(tile, edges, dir, DC_AUTO | DC_NO_WATER | DC_EXEC, CMD_TERRAFORM_LAND);
   790 	DoCommand(tile, edges, dir, DC_AUTO | DC_NO_WATER | DC_EXEC, CMD_TERRAFORM_LAND);
   773 	return true;
   791 	return true;
   774 }
   792 }
   775 
   793 
   776 static void LevelTownLand(TileIndex tile)
   794 static void LevelTownLand(TileIndex tile)
   777 {
   795 {
   778 	Slope tileh;
       
   779 
       
   780 	TILE_ASSERT(tile);
   796 	TILE_ASSERT(tile);
   781 
   797 
   782 	/* Don't terraform if land is plain or if there's a house there. */
   798 	/* Don't terraform if land is plain or if there's a house there. */
   783 	if (IsTileType(tile, MP_HOUSE)) return;
   799 	if (IsTileType(tile, MP_HOUSE)) return;
   784 	tileh = GetTileSlope(tile, NULL);
   800 	Slope tileh = GetTileSlope(tile, NULL);
   785 	if (tileh == SLOPE_FLAT) return;
   801 	if (tileh == SLOPE_FLAT) return;
   786 
   802 
   787 	/* First try up, then down */
   803 	/* First try up, then down */
   788 	if (!TerraformTownTile(tile, ~tileh & SLOPE_ELEVATED, 1)) {
   804 	if (!TerraformTownTile(tile, ~tileh & SLOPE_ELEVATED, 1)) {
   789 		TerraformTownTile(tile, tileh & SLOPE_ELEVATED, 0);
   805 		TerraformTownTile(tile, tileh & SLOPE_ELEVATED, 0);
   797  * @param tile tile in reference to the town
   813  * @param tile tile in reference to the town
   798  * @param dir The direction to which we are growing ATM
   814  * @param dir The direction to which we are growing ATM
   799  * @return the RoadBit of the current tile regarding
   815  * @return the RoadBit of the current tile regarding
   800  *  the selected town layout
   816  *  the selected town layout
   801  */
   817  */
   802 static RoadBits GetTownRoadGridElement(Town* t, TileIndex tile, DiagDirection dir)
   818 static RoadBits GetTownRoadGridElement(Town *t, TileIndex tile, DiagDirection dir)
   803 {
   819 {
   804 	/* align the grid to the downtown */
   820 	/* align the grid to the downtown */
   805 	TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile); // Vector from downtown to the tile
   821 	TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile); // Vector from downtown to the tile
   806 	RoadBits rcmd = ROAD_NONE;
   822 	RoadBits rcmd = ROAD_NONE;
   807 
   823 
   808 	switch (_patches.town_layout) {
   824 	switch (t->GetActiveLayout()) {
   809 		default: NOT_REACHED();
   825 		default: NOT_REACHED();
   810 
   826 
   811 		case TL_2X2_GRID:
   827 		case TL_2X2_GRID:
   812 			if ((grid_pos.x % 3) == 0) rcmd |= ROAD_Y;
   828 			if ((grid_pos.x % 3) == 0) rcmd |= ROAD_Y;
   813 			if ((grid_pos.y % 3) == 0) rcmd |= ROAD_X;
   829 			if ((grid_pos.y % 3) == 0) rcmd |= ROAD_X;
   986 
  1002 
   987 		/* Remove hills etc */
  1003 		/* Remove hills etc */
   988 		LevelTownLand(tile);
  1004 		LevelTownLand(tile);
   989 
  1005 
   990 		/* Is a road allowed here? */
  1006 		/* Is a road allowed here? */
   991 		switch (_patches.town_layout) {
  1007 		switch (t1->GetActiveLayout()) {
   992 			default: NOT_REACHED();
  1008 			default: NOT_REACHED();
   993 
  1009 
   994 			case TL_NO_ROADS: /* Disallow Roads */
  1010 			case TL_NO_ROADS: /* Disallow Roads */
   995 				return;
  1011 				return;
   996 
  1012 
  1000 				if (rcmd == ROAD_NONE) return;
  1016 				if (rcmd == ROAD_NONE) return;
  1001 				break;
  1017 				break;
  1002 
  1018 
  1003 			case TL_BETTER_ROADS:
  1019 			case TL_BETTER_ROADS:
  1004 			case TL_ORIGINAL:
  1020 			case TL_ORIGINAL:
  1005 				if (!IsRoadAllowedHere(tile, target_dir)) return;
  1021 				if (!IsRoadAllowedHere(t1, tile, target_dir)) return;
  1006 
  1022 
  1007 				DiagDirection source_dir = ReverseDiagDir(target_dir);
  1023 				DiagDirection source_dir = ReverseDiagDir(target_dir);
  1008 
  1024 
  1009 				if (Chance16(1, 4)) {
  1025 				if (Chance16(1, 4)) {
  1010 					/* Randomize a new target dir */
  1026 					/* Randomize a new target dir */
  1011 					do target_dir = RandomDiagDir(); while (target_dir == source_dir);
  1027 					do target_dir = RandomDiagDir(); while (target_dir == source_dir);
  1012 				}
  1028 				}
  1013 
  1029 
  1014 				if (!IsRoadAllowedHere(TileAddByDiagDir(tile, target_dir), target_dir)) {
  1030 				if (!IsRoadAllowedHere(t1, TileAddByDiagDir(tile, target_dir), target_dir)) {
  1015 					/* A road is not allowed to continue the randomized road,
  1031 					/* A road is not allowed to continue the randomized road,
  1016 					 *  return if the road we're trying to build is curved. */
  1032 					 *  return if the road we're trying to build is curved. */
  1017 					if (target_dir != ReverseDiagDir(source_dir)) return;
  1033 					if (target_dir != ReverseDiagDir(source_dir)) return;
  1018 
  1034 
  1019 					/* Return if neither side of the new road is a house */
  1035 					/* Return if neither side of the new road is a house */
  1034 		/* Continue building on a partial road.
  1050 		/* Continue building on a partial road.
  1035 		 * Should be allways OK, so we only generate
  1051 		 * Should be allways OK, so we only generate
  1036 		 * the fitting RoadBits */
  1052 		 * the fitting RoadBits */
  1037 		_grow_town_result = GROWTH_SEARCH_STOPPED;
  1053 		_grow_town_result = GROWTH_SEARCH_STOPPED;
  1038 
  1054 
  1039 		switch (_patches.town_layout) {
  1055 		switch (t1->GetActiveLayout()) {
  1040 			default: NOT_REACHED();
  1056 			default: NOT_REACHED();
  1041 
  1057 
  1042 			case TL_NO_ROADS: /* Disallow Roads */
  1058 			case TL_NO_ROADS: /* Disallow Roads */
  1043 				return;
  1059 				return;
  1044 
  1060 
  1072 		TileIndex house_tile = TileAddByDiagDir(tile, target_dir); // position of a possible house
  1088 		TileIndex house_tile = TileAddByDiagDir(tile, target_dir); // position of a possible house
  1073 
  1089 
  1074 		/* Don't walk into water. */
  1090 		/* Don't walk into water. */
  1075 		if (IsWaterTile(house_tile)) return;
  1091 		if (IsWaterTile(house_tile)) return;
  1076 
  1092 
  1077 		switch (_patches.town_layout) {
  1093 		switch (t1->GetActiveLayout()) {
  1078 			default: NOT_REACHED();
  1094 			default: NOT_REACHED();
  1079 
  1095 
  1080 			case TL_NO_ROADS:
  1096 			case TL_NO_ROADS:
  1081 				allow_house = true;
  1097 				allow_house = true;
  1082 				break;
  1098 				break;
  1096 
  1112 
  1097 			case TL_ORIGINAL:
  1113 			case TL_ORIGINAL:
  1098 				 /* Allow a house at the edge. 60% chance or
  1114 				 /* Allow a house at the edge. 60% chance or
  1099 				  * always ok if no road allowed. */
  1115 				  * always ok if no road allowed. */
  1100 				rcmd = DiagDirToRoadBits(target_dir);
  1116 				rcmd = DiagDirToRoadBits(target_dir);
  1101 				allow_house = (!IsRoadAllowedHere(house_tile, target_dir) || Chance16(6, 10));
  1117 				allow_house = (!IsRoadAllowedHere(t1, house_tile, target_dir) || Chance16(6, 10));
  1102 				break;
  1118 				break;
  1103 		}
  1119 		}
  1104 
  1120 
  1105 		if (allow_house) {
  1121 		if (allow_house) {
  1106 			/* Build a house, but not if there already is a house there. */
  1122 			/* Build a house, but not if there already is a house there. */
  1150 	TILE_ASSERT(tile);
  1166 	TILE_ASSERT(tile);
  1151 
  1167 
  1152 	/* Number of times to search.
  1168 	/* Number of times to search.
  1153 	 * Better roads, 2X2 and 3X3 grid grow quite fast so we give
  1169 	 * Better roads, 2X2 and 3X3 grid grow quite fast so we give
  1154 	 * them a little handicap. */
  1170 	 * them a little handicap. */
  1155 	switch (_patches.town_layout) {
  1171 	switch (t->GetActiveLayout()) {
  1156 		case TL_BETTER_ROADS:
  1172 		case TL_BETTER_ROADS:
  1157 			_grow_town_result = 10 + t->num_houses * 2 / 9;
  1173 			_grow_town_result = 10 + t->num_houses * 2 / 9;
  1158 			break;
  1174 			break;
  1159 
  1175 
  1160 		case TL_3X3_GRID:
  1176 		case TL_3X3_GRID:
  1217 	if (a == b) b ^= 2;
  1233 	if (a == b) b ^= 2;
  1218 	return (RoadBits)((ROAD_NW << a) + (ROAD_NW << b));
  1234 	return (RoadBits)((ROAD_NW << a) + (ROAD_NW << b));
  1219 }
  1235 }
  1220 
  1236 
  1221 /** Grow the town
  1237 /** Grow the town
  1222  * @Return true if a house was built, or no if the build failed. */
  1238  * @param t town to grow
       
  1239  * @return true iff a house was built
       
  1240  */
  1223 static bool GrowTown(Town *t)
  1241 static bool GrowTown(Town *t)
  1224 {
  1242 {
  1225 
       
  1226 	/* Let the town be a ghost town
  1243 	/* Let the town be a ghost town
  1227 	 * The player wanted it in such a way. Thus there he has it. ;)
  1244 	 * The player wanted it in such a way. Thus there he has it. ;)
  1228 	 * Never reached in editor mode. */
  1245 	 * Never reached in editor mode. */
  1229 	if (_patches.town_layout == TL_NO_ROADS && _generating_world) {
  1246 	if (_patches.town_layout == TL_NO_ROADS && _generating_world) {
  1230 		return false;
  1247 		return false;
  1243 		{-2,  2},
  1260 		{-2,  2},
  1244 		{ 2,  2},
  1261 		{ 2,  2},
  1245 		{ 2, -2},
  1262 		{ 2, -2},
  1246 		{ 0,  0}
  1263 		{ 0,  0}
  1247 	};
  1264 	};
  1248 	const TileIndexDiffC *ptr;
       
  1249 
  1265 
  1250 	/* Current player is a town */
  1266 	/* Current player is a town */
  1251 	PlayerID old_player = _current_player;
  1267 	PlayerID old_player = _current_player;
  1252 	_current_player = OWNER_TOWN;
  1268 	_current_player = OWNER_TOWN;
  1253 
  1269 
  1254 	TileIndex tile = t->xy; // The tile we are working with ATM
  1270 	TileIndex tile = t->xy; // The tile we are working with ATM
  1255 
  1271 
  1256 	/* Find a road that we can base the construction on. */
  1272 	/* Find a road that we can base the construction on. */
       
  1273 	const TileIndexDiffC *ptr;
  1257 	for (ptr = _town_coord_mod; ptr != endof(_town_coord_mod); ++ptr) {
  1274 	for (ptr = _town_coord_mod; ptr != endof(_town_coord_mod); ++ptr) {
  1258 		if (GetTownRoadBits(tile) != ROAD_NONE) {
  1275 		if (GetTownRoadBits(tile) != ROAD_NONE) {
  1259 			int r = GrowTownAtRoad(t, tile);
  1276 			int r = GrowTownAtRoad(t, tile);
  1260 			_current_player = old_player;
  1277 			_current_player = old_player;
  1261 			return r != 0;
  1278 			return r != 0;
  1280 
  1297 
  1281 	_current_player = old_player;
  1298 	_current_player = old_player;
  1282 	return false;
  1299 	return false;
  1283 }
  1300 }
  1284 
  1301 
  1285 static void UpdateTownRadius(Town *t)
  1302 void UpdateTownRadius(Town *t)
  1286 {
  1303 {
  1287 	static const uint16 _town_radius_data[23][5] = {
  1304 	static const uint16 _town_radius_data[23][5] = {
  1288 		{  4,  0,  0,  0,  0}, // 0
  1305 		{  4,  0,  0,  0,  0}, // 0
  1289 		{ 16,  0,  0,  0,  0},
  1306 		{ 16,  0,  0,  0,  0},
  1290 		{ 25,  0,  0,  0,  0},
  1307 		{ 25,  0,  0,  0,  0},
  1342 	int tries = 1000;
  1359 	int tries = 1000;
  1343 	bool grf = (_opt.town_name >= _nb_orig_names);
  1360 	bool grf = (_opt.town_name >= _nb_orig_names);
  1344 	uint32 grfid = grf ? GetGRFTownNameId(_opt.town_name - _nb_orig_names) : 0;
  1361 	uint32 grfid = grf ? GetGRFTownNameId(_opt.town_name - _nb_orig_names) : 0;
  1345 	uint16 townnametype = grf ? GetGRFTownNameType(_opt.town_name - _nb_orig_names) : SPECSTR_TOWNNAME_START + _opt.town_name;
  1362 	uint16 townnametype = grf ? GetGRFTownNameType(_opt.town_name - _nb_orig_names) : SPECSTR_TOWNNAME_START + _opt.town_name;
  1346 
  1363 
  1347 	assert(townnameparts);
  1364 	assert(townnameparts != NULL);
  1348 
  1365 
  1349 	for (;;) {
  1366 	for (;;) {
  1350 restart:
  1367 restart:
  1351 		r = Random();
  1368 		r = Random();
  1352 
  1369 
  1391  * @param size Parameter for size determination
  1408  * @param size Parameter for size determination
  1392  */
  1409  */
  1393 static void DoCreateTown(Town *t, TileIndex tile, uint32 townnameparts, TownSizeMode size_mode, uint size)
  1410 static void DoCreateTown(Town *t, TileIndex tile, uint32 townnameparts, TownSizeMode size_mode, uint size)
  1394 {
  1411 {
  1395 	extern int _nb_orig_names;
  1412 	extern int _nb_orig_names;
  1396 	int x, i;
       
  1397 
  1413 
  1398 	t->xy = tile;
  1414 	t->xy = tile;
  1399 	t->num_houses = 0;
  1415 	t->num_houses = 0;
  1400 	t->time_until_rebuild = 10;
  1416 	t->time_until_rebuild = 10;
  1401 	UpdateTownRadius(t);
  1417 	UpdateTownRadius(t);
  1418 	t->new_act_food = 0;
  1434 	t->new_act_food = 0;
  1419 	t->new_act_water = 0;
  1435 	t->new_act_water = 0;
  1420 	t->act_food = 0;
  1436 	t->act_food = 0;
  1421 	t->act_water = 0;
  1437 	t->act_water = 0;
  1422 
  1438 
  1423 	for (i = 0; i != MAX_PLAYERS; i++)
  1439 	for (uint i = 0; i != MAX_PLAYERS; i++) t->ratings[i] = RATING_INITIAL;
  1424 		t->ratings[i] = 500;
       
  1425 
  1440 
  1426 	t->have_ratings = 0;
  1441 	t->have_ratings = 0;
  1427 	t->exclusivity = INVALID_PLAYER;
  1442 	t->exclusivity = INVALID_PLAYER;
  1428 	t->exclusive_counter = 0;
  1443 	t->exclusive_counter = 0;
  1429 	t->statues = 0;
  1444 	t->statues = 0;
  1440 	t->townnameparts = townnameparts;
  1455 	t->townnameparts = townnameparts;
  1441 
  1456 
  1442 	UpdateTownVirtCoord(t);
  1457 	UpdateTownVirtCoord(t);
  1443 	_town_sort_dirty = true;
  1458 	_town_sort_dirty = true;
  1444 
  1459 
       
  1460 	t->InitializeLayout();
       
  1461 
  1445 	/* Random town size. */
  1462 	/* Random town size. */
  1446 	x = (Random() & 0xF) + 8;
  1463 	int x = (Random() & 0xF) + 8;
  1447 
  1464 
  1448 	switch (size_mode) {
  1465 	switch (size_mode) {
  1449 		default: NOT_REACHED();
  1466 		default: NOT_REACHED();
  1450 
  1467 
  1451 		case TSM_RANDOM:
  1468 		case TSM_RANDOM:
  1464 	}
  1481 	}
  1465 
  1482 
  1466 	t->num_houses += x;
  1483 	t->num_houses += x;
  1467 	UpdateTownRadius(t);
  1484 	UpdateTownRadius(t);
  1468 
  1485 
  1469 	i = x * 4;
  1486 	int i = x * 4;
  1470 	do {
  1487 	do {
  1471 		GrowTown(t);
  1488 		GrowTown(t);
  1472 	} while (--i);
  1489 	} while (--i);
  1473 
  1490 
  1474 	t->num_houses -= x;
  1491 	t->num_houses -= x;
  1484  * @param p1 size of the town (0 = small, 1 = medium, 2 = large)
  1501  * @param p1 size of the town (0 = small, 1 = medium, 2 = large)
  1485  * @param p2 size mode (@see TownSizeMode)
  1502  * @param p2 size mode (@see TownSizeMode)
  1486  */
  1503  */
  1487 CommandCost CmdBuildTown(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1504 CommandCost CmdBuildTown(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1488 {
  1505 {
  1489 	uint32 townnameparts;
       
  1490 
       
  1491 	/* Only in the scenario editor */
  1506 	/* Only in the scenario editor */
  1492 	if (_game_mode != GM_EDITOR) return CMD_ERROR;
  1507 	if (_game_mode != GM_EDITOR) return CMD_ERROR;
  1493 	if (p2 > TSM_CITY) return CMD_ERROR;
  1508 	if (p2 > TSM_CITY) return CMD_ERROR;
  1494 
  1509 
  1495 	/* Check if too close to the edge of map */
  1510 	/* Check if too close to the edge of map */
  1502 	}
  1517 	}
  1503 
  1518 
  1504 	/* Check distance to all other towns. */
  1519 	/* Check distance to all other towns. */
  1505 	if (IsCloseToTown(tile, 20))
  1520 	if (IsCloseToTown(tile, 20))
  1506 		return_cmd_error(STR_0238_TOO_CLOSE_TO_ANOTHER_TOWN);
  1521 		return_cmd_error(STR_0238_TOO_CLOSE_TO_ANOTHER_TOWN);
       
  1522 
       
  1523 	uint32 townnameparts;
  1507 
  1524 
  1508 	/* Get a unique name for the town. */
  1525 	/* Get a unique name for the town. */
  1509 	if (!CreateTownName(&townnameparts))
  1526 	if (!CreateTownName(&townnameparts))
  1510 		return_cmd_error(STR_023A_TOO_MANY_TOWNS);
  1527 		return_cmd_error(STR_023A_TOO_MANY_TOWNS);
  1511 
  1528 
  1524 	return CommandCost();
  1541 	return CommandCost();
  1525 }
  1542 }
  1526 
  1543 
  1527 Town *CreateRandomTown(uint attempts, TownSizeMode mode, uint size)
  1544 Town *CreateRandomTown(uint attempts, TownSizeMode mode, uint size)
  1528 {
  1545 {
  1529 	TileIndex tile;
       
  1530 	Town *t;
       
  1531 	uint32 townnameparts;
       
  1532 
       
  1533 	do {
  1546 	do {
  1534 		/* Generate a tile index not too close from the edge */
  1547 		/* Generate a tile index not too close from the edge */
  1535 		tile = RandomTile();
  1548 		TileIndex tile = RandomTile();
  1536 		if (DistanceFromEdge(tile) < 20) continue;
  1549 		if (DistanceFromEdge(tile) < 20) continue;
  1537 
  1550 
  1538 		/* Make sure the tile is plain */
  1551 		/* Make sure the tile is plain */
  1539 		if (!IsTileType(tile, MP_CLEAR) || GetTileSlope(tile, NULL) != SLOPE_FLAT) continue;
  1552 		if (!IsTileType(tile, MP_CLEAR) || GetTileSlope(tile, NULL) != SLOPE_FLAT) continue;
  1540 
  1553 
  1541 		/* Check not too close to a town */
  1554 		/* Check not too close to a town */
  1542 		if (IsCloseToTown(tile, 20)) continue;
  1555 		if (IsCloseToTown(tile, 20)) continue;
  1543 
  1556 
       
  1557 		uint32 townnameparts;
       
  1558 
  1544 		/* Get a unique name for the town. */
  1559 		/* Get a unique name for the town. */
  1545 		if (!CreateTownName(&townnameparts)) break;
  1560 		if (!CreateTownName(&townnameparts)) break;
  1546 
  1561 
  1547 		/* Allocate a town struct */
  1562 		/* Allocate a town struct */
  1548 		t = new Town(tile);
  1563 		Town *t = new Town(tile);
  1549 		if (t == NULL) break;
  1564 		if (t == NULL) break;
  1550 
  1565 
  1551 		DoCreateTown(t, tile, townnameparts, mode, size);
  1566 		DoCreateTown(t, tile, townnameparts, mode, size);
  1552 		return t;
  1567 		return t;
  1553 	} while (--attempts);
  1568 	} while (--attempts != 0);
       
  1569 
  1554 	return NULL;
  1570 	return NULL;
  1555 }
  1571 }
  1556 
  1572 
  1557 static const byte _num_initial_towns[4] = {5, 11, 23, 46};
  1573 static const byte _num_initial_towns[4] = {5, 11, 23, 46};
  1558 
  1574 
  1589 /** Returns the bit corresponding to the town zone of the specified tile
  1605 /** Returns the bit corresponding to the town zone of the specified tile
  1590  * @param t Town on which radius is to be found
  1606  * @param t Town on which radius is to be found
  1591  * @param tile TileIndex where radius needs to be found
  1607  * @param tile TileIndex where radius needs to be found
  1592  * @return the bit position of the given zone, as defined in HouseZones
  1608  * @return the bit position of the given zone, as defined in HouseZones
  1593  */
  1609  */
  1594 HouseZonesBits GetTownRadiusGroup(const Town* t, TileIndex tile)
  1610 HouseZonesBits GetTownRadiusGroup(const Town *t, TileIndex tile)
  1595 {
  1611 {
  1596 	uint dist = DistanceSquare(tile, t->xy);
  1612 	uint dist = DistanceSquare(tile, t->xy);
  1597 	HouseZonesBits smallest;
       
  1598 	uint i;
       
  1599 
  1613 
  1600 	if (t->fund_buildings_months && dist <= 25) return HZB_TOWN_CENTRE;
  1614 	if (t->fund_buildings_months && dist <= 25) return HZB_TOWN_CENTRE;
  1601 
  1615 
  1602 	smallest = HZB_TOWN_EDGE;
  1616 	HouseZonesBits smallest = HZB_TOWN_EDGE;
  1603 	for (i = 0; i != lengthof(t->radius); i++) {
  1617 	for (HouseZonesBits i = HZB_BEGIN; i < HZB_END; i++) {
  1604 		if (dist < t->radius[i]) smallest = (HouseZonesBits)i;
  1618 		if (dist < t->radius[i]) smallest = i;
  1605 	}
  1619 	}
  1606 
  1620 
  1607 	return smallest;
  1621 	return smallest;
  1608 }
  1622 }
  1609 
  1623 
  1729  */
  1743  */
  1730 static inline bool TownLayoutAllowsHouseHere(Town *t, TileIndex tile)
  1744 static inline bool TownLayoutAllowsHouseHere(Town *t, TileIndex tile)
  1731 {
  1745 {
  1732 	TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile);
  1746 	TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile);
  1733 
  1747 
  1734 	switch (_patches.town_layout) {
  1748 	switch (t->GetActiveLayout()) {
  1735 		case TL_2X2_GRID:
  1749 		case TL_2X2_GRID:
  1736 			if ((grid_pos.x % 3) == 0 || (grid_pos.y % 3) == 0) return false;
  1750 			if ((grid_pos.x % 3) == 0 || (grid_pos.y % 3) == 0) return false;
  1737 			break;
  1751 			break;
  1738 
  1752 
  1739 		case TL_3X3_GRID:
  1753 		case TL_3X3_GRID:
  1760 	/* MapSize() is sure dividable by both MapSizeX() and MapSizeY(),
  1774 	/* MapSize() is sure dividable by both MapSizeX() and MapSizeY(),
  1761 	 * so to do only one memory access, use MapSize() */
  1775 	 * so to do only one memory access, use MapSize() */
  1762 	uint dx = MapSize() + TileX(t->xy) - TileX(tile);
  1776 	uint dx = MapSize() + TileX(t->xy) - TileX(tile);
  1763 	uint dy = MapSize() + TileY(t->xy) - TileY(tile);
  1777 	uint dy = MapSize() + TileY(t->xy) - TileY(tile);
  1764 
  1778 
  1765 	switch (_patches.town_layout) {
  1779 	switch (t->GetActiveLayout()) {
  1766 		case TL_2X2_GRID:
  1780 		case TL_2X2_GRID:
  1767 			if ((dx % 3) != 0 || (dy % 3) != 0) return false;
  1781 			if ((dx % 3) != 0 || (dy % 3) != 0) return false;
  1768 			break;
  1782 			break;
  1769 
  1783 
  1770 		case TL_3X3_GRID:
  1784 		case TL_3X3_GRID:
  1865 	uint probs[HOUSE_MAX];
  1879 	uint probs[HOUSE_MAX];
  1866 	uint probability_max = 0;
  1880 	uint probability_max = 0;
  1867 
  1881 
  1868 	/* Generate a list of all possible houses that can be built. */
  1882 	/* Generate a list of all possible houses that can be built. */
  1869 	for (uint i = 0; i < HOUSE_MAX; i++) {
  1883 	for (uint i = 0; i < HOUSE_MAX; i++) {
  1870 		HouseSpec *hs = GetHouseSpecs(i);
  1884 		const HouseSpec *hs = GetHouseSpecs(i);
  1871 		/* Verify that the candidate house spec matches the current tile status */
  1885 		/* Verify that the candidate house spec matches the current tile status */
  1872 		if ((~hs->building_availability & bitmask) == 0 && hs->enabled) {
  1886 		if ((~hs->building_availability & bitmask) == 0 && hs->enabled) {
  1873 			/* Without NewHouses, all houses have probability '1' */
  1887 			/* Without NewHouses, all houses have probability '1' */
  1874 			uint cur_prob = (_loaded_newgrf_features.has_newhouses ? hs->probability : 1);
  1888 			uint cur_prob = (_loaded_newgrf_features.has_newhouses ? hs->probability : 1);
  1875 			probability_max += cur_prob;
  1889 			probability_max += cur_prob;
  1894 		/* remove tested house from the set */
  1908 		/* remove tested house from the set */
  1895 		num--;
  1909 		num--;
  1896 		houses[i] = houses[num];
  1910 		houses[i] = houses[num];
  1897 		probs[i] = probs[num];
  1911 		probs[i] = probs[num];
  1898 
  1912 
  1899 		HouseSpec *hs = GetHouseSpecs(house);
  1913 		const HouseSpec *hs = GetHouseSpecs(house);
  1900 
  1914 
  1901 		if (_loaded_newgrf_features.has_newhouses) {
  1915 		if (_loaded_newgrf_features.has_newhouses) {
  1902 			if (hs->override != 0) {
  1916 			if (hs->override != 0) {
  1903 				house = hs->override;
  1917 				house = hs->override;
  1904 				hs = GetHouseSpecs(house);
  1918 				hs = GetHouseSpecs(house);
  1978 	DeleteAnimatedTile(tile);
  1992 	DeleteAnimatedTile(tile);
  1979 }
  1993 }
  1980 
  1994 
  1981 void ClearTownHouse(Town *t, TileIndex tile)
  1995 void ClearTownHouse(Town *t, TileIndex tile)
  1982 {
  1996 {
       
  1997 	assert(IsTileType(tile, MP_HOUSE));
       
  1998 
  1983 	HouseID house = GetHouseType(tile);
  1999 	HouseID house = GetHouseType(tile);
  1984 	uint eflags;
       
  1985 	HouseSpec *hs;
       
  1986 
       
  1987 	assert(IsTileType(tile, MP_HOUSE));
       
  1988 
  2000 
  1989 	/* need to align the tile to point to the upper left corner of the house */
  2001 	/* need to align the tile to point to the upper left corner of the house */
  1990 	if (house >= 3) { // house id 0,1,2 MUST be single tile houses, or this code breaks.
  2002 	if (house >= 3) { // house id 0,1,2 MUST be single tile houses, or this code breaks.
  1991 		if (GetHouseSpecs(house-1)->building_flags & TILE_SIZE_2x1) {
  2003 		if (GetHouseSpecs(house-1)->building_flags & TILE_SIZE_2x1) {
  1992 			house--;
  2004 			house--;
  2001 			house-=3;
  2013 			house-=3;
  2002 			tile += TileDiffXY(-1, -1);
  2014 			tile += TileDiffXY(-1, -1);
  2003 		}
  2015 		}
  2004 	}
  2016 	}
  2005 
  2017 
  2006 	hs = GetHouseSpecs(house);
  2018 	const HouseSpec *hs = GetHouseSpecs(house);
  2007 
  2019 
  2008 	/* Remove population from the town if the house is finished. */
  2020 	/* Remove population from the town if the house is finished. */
  2009 	if (IsHouseCompleted(tile)) {
  2021 	if (IsHouseCompleted(tile)) {
  2010 		ChangePopulation(t, -hs->population);
  2022 		ChangePopulation(t, -hs->population);
  2011 	}
  2023 	}
  2019 	} else if (hs->building_flags & BUILDING_IS_STADIUM) {
  2031 	} else if (hs->building_flags & BUILDING_IS_STADIUM) {
  2020 		ClrBit(t->flags12, TOWN_HAS_STADIUM);
  2032 		ClrBit(t->flags12, TOWN_HAS_STADIUM);
  2021 	}
  2033 	}
  2022 
  2034 
  2023 	/* Do the actual clearing of tiles */
  2035 	/* Do the actual clearing of tiles */
  2024 	eflags = hs->building_flags;
  2036 	uint eflags = hs->building_flags;
  2025 	DoClearTownHouseHelper(tile);
  2037 	DoClearTownHouseHelper(tile);
  2026 	if (eflags & BUILDING_2_TILES_X)   DoClearTownHouseHelper(tile + TileDiffXY(1, 0));
  2038 	if (eflags & BUILDING_2_TILES_X)   DoClearTownHouseHelper(tile + TileDiffXY(1, 0));
  2027 	if (eflags & BUILDING_2_TILES_Y)   DoClearTownHouseHelper(tile + TileDiffXY(0, 1));
  2039 	if (eflags & BUILDING_2_TILES_Y)   DoClearTownHouseHelper(tile + TileDiffXY(0, 1));
  2028 	if (eflags & BUILDING_HAS_4_TILES) DoClearTownHouseHelper(tile + TileDiffXY(1, 1));
  2040 	if (eflags & BUILDING_HAS_4_TILES) DoClearTownHouseHelper(tile + TileDiffXY(1, 1));
  2029 }
  2041 }
  2048  * @param p1 town ID to rename
  2060  * @param p1 town ID to rename
  2049  * @param p2 unused
  2061  * @param p2 unused
  2050  */
  2062  */
  2051 CommandCost CmdRenameTown(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  2063 CommandCost CmdRenameTown(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  2052 {
  2064 {
  2053 	Town *t;
       
  2054 
       
  2055 	if (!IsValidTownID(p1) || StrEmpty(_cmd_text)) return CMD_ERROR;
  2065 	if (!IsValidTownID(p1) || StrEmpty(_cmd_text)) return CMD_ERROR;
  2056 
  2066 
  2057 	t = GetTown(p1);
       
  2058 
       
  2059 	if (!IsUniqueTownName(_cmd_text)) return_cmd_error(STR_NAME_MUST_BE_UNIQUE);
  2067 	if (!IsUniqueTownName(_cmd_text)) return_cmd_error(STR_NAME_MUST_BE_UNIQUE);
  2060 
  2068 
  2061 	if (flags & DC_EXEC) {
  2069 	if (flags & DC_EXEC) {
       
  2070 		Town *t = GetTown(p1);
       
  2071 
  2062 		free(t->name);
  2072 		free(t->name);
  2063 		t->name = strdup(_cmd_text);
  2073 		t->name = strdup(_cmd_text);
  2064 
  2074 
  2065 		UpdateTownVirtCoord(t);
  2075 		UpdateTownVirtCoord(t);
  2066 		_town_sort_dirty = true;
  2076 		_town_sort_dirty = true;
  2072 }
  2082 }
  2073 
  2083 
  2074 /** Called from GUI */
  2084 /** Called from GUI */
  2075 void ExpandTown(Town *t)
  2085 void ExpandTown(Town *t)
  2076 {
  2086 {
  2077 	int amount, n;
       
  2078 
       
  2079 	_generating_world = true;
  2087 	_generating_world = true;
  2080 
  2088 
  2081 	/* The more houses, the faster we grow */
  2089 	/* The more houses, the faster we grow */
  2082 	amount = RandomRange(t->num_houses / 10) + 3;
  2090 	uint amount = RandomRange(ClampToU16(t->num_houses / 10)) + 3;
  2083 	t->num_houses += amount;
  2091 	t->num_houses += amount;
  2084 	UpdateTownRadius(t);
  2092 	UpdateTownRadius(t);
  2085 
  2093 
  2086 	n = amount * 10;
  2094 	uint n = amount * 10;
  2087 	do GrowTown(t); while (--n);
  2095 	do GrowTown(t); while (--n);
  2088 
  2096 
  2089 	t->num_houses -= amount;
  2097 	t->num_houses -= amount;
  2090 	UpdateTownRadius(t);
  2098 	UpdateTownRadius(t);
  2091 
  2099 
  2095 
  2103 
  2096 extern const byte _town_action_costs[8] = {
  2104 extern const byte _town_action_costs[8] = {
  2097 	2, 4, 9, 35, 48, 53, 117, 175
  2105 	2, 4, 9, 35, 48, 53, 117, 175
  2098 };
  2106 };
  2099 
  2107 
  2100 static void TownActionAdvertiseSmall(Town* t)
  2108 static void TownActionAdvertiseSmall(Town *t)
  2101 {
  2109 {
  2102 	ModifyStationRatingAround(t->xy, _current_player, 0x40, 10);
  2110 	ModifyStationRatingAround(t->xy, _current_player, 0x40, 10);
  2103 }
  2111 }
  2104 
  2112 
  2105 static void TownActionAdvertiseMedium(Town* t)
  2113 static void TownActionAdvertiseMedium(Town *t)
  2106 {
  2114 {
  2107 	ModifyStationRatingAround(t->xy, _current_player, 0x70, 15);
  2115 	ModifyStationRatingAround(t->xy, _current_player, 0x70, 15);
  2108 }
  2116 }
  2109 
  2117 
  2110 static void TownActionAdvertiseLarge(Town* t)
  2118 static void TownActionAdvertiseLarge(Town *t)
  2111 {
  2119 {
  2112 	ModifyStationRatingAround(t->xy, _current_player, 0xA0, 20);
  2120 	ModifyStationRatingAround(t->xy, _current_player, 0xA0, 20);
  2113 }
  2121 }
  2114 
  2122 
  2115 static void TownActionRoadRebuild(Town* t)
  2123 static void TownActionRoadRebuild(Town *t)
  2116 {
  2124 {
  2117 	t->road_build_months = 6;
  2125 	t->road_build_months = 6;
  2118 
  2126 
  2119 	SetDParam(0, t->index);
  2127 	SetDParam(0, t->index);
  2120 	SetDParam(1, _current_player);
  2128 	SetDParam(1, _current_player);
  2121 
  2129 
  2122 	AddNewsItem(STR_2055_TRAFFIC_CHAOS_IN_ROAD_REBUILDING,
  2130 	AddNewsItem(STR_2055_TRAFFIC_CHAOS_IN_ROAD_REBUILDING,
  2123 		NEWS_FLAGS(NM_NORMAL, NF_TILE, NT_GENERAL, 0), t->xy, 0);
  2131 		NM_NORMAL, NF_TILE, NT_GENERAL, DNC_NONE, t->xy, 0);
  2124 }
  2132 }
  2125 
  2133 
  2126 static bool DoBuildStatueOfCompany(TileIndex tile, TownID town_id)
  2134 static bool DoBuildStatueOfCompany(TileIndex tile, TownID town_id)
  2127 {
  2135 {
  2128 	PlayerID old;
       
  2129 	CommandCost r;
       
  2130 
       
  2131 	/* Statues can be build on slopes, just like houses. Only the steep slopes is a no go. */
  2136 	/* Statues can be build on slopes, just like houses. Only the steep slopes is a no go. */
  2132 	if (IsSteepSlope(GetTileSlope(tile, NULL))) return false;
  2137 	if (IsSteepSlope(GetTileSlope(tile, NULL))) return false;
  2133 
  2138 
  2134 	if (!IsTileType(tile, MP_HOUSE) &&
  2139 	if (!IsTileType(tile, MP_HOUSE) &&
  2135 			!IsTileType(tile, MP_CLEAR) &&
  2140 			!IsTileType(tile, MP_CLEAR) &&
  2136 			!IsTileType(tile, MP_TREES)) {
  2141 			!IsTileType(tile, MP_TREES)) {
  2137 		return false;
  2142 		return false;
  2138 	}
  2143 	}
  2139 
  2144 
  2140 	old = _current_player;
  2145 	PlayerID old = _current_player;
  2141 	_current_player = OWNER_NONE;
  2146 	_current_player = OWNER_NONE;
  2142 	r = DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
  2147 	CommandCost r = DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
  2143 	_current_player = old;
  2148 	_current_player = old;
  2144 
  2149 
  2145 	if (CmdFailed(r)) return false;
  2150 	if (CmdFailed(r)) return false;
  2146 
  2151 
  2147 	MakeStatue(tile, _current_player, town_id);
  2152 	MakeStatue(tile, _current_player, town_id);
  2164 /**
  2169 /**
  2165  * Perform a 9x9 tiles circular search from the center of the town
  2170  * Perform a 9x9 tiles circular search from the center of the town
  2166  * in order to find a free tile to place a statue
  2171  * in order to find a free tile to place a statue
  2167  * @param t town to search in
  2172  * @param t town to search in
  2168  */
  2173  */
  2169 static void TownActionBuildStatue(Town* t)
  2174 static void TownActionBuildStatue(Town *t)
  2170 {
  2175 {
  2171 	TileIndex tile = t->xy;
  2176 	TileIndex tile = t->xy;
  2172 
  2177 
  2173 	if (CircularTileSearch(tile, 9, SearchTileForStatue, t->index))
  2178 	if (CircularTileSearch(tile, 9, SearchTileForStatue, t->index)) {
  2174 		SetBit(t->statues, _current_player); // Once found and built, "inform" the Town
  2179 		SetBit(t->statues, _current_player); // Once found and built, "inform" the Town
  2175 }
  2180 	}
  2176 
  2181 }
  2177 static void TownActionFundBuildings(Town* t)
  2182 
       
  2183 static void TownActionFundBuildings(Town *t)
  2178 {
  2184 {
  2179 	/* Build next tick */
  2185 	/* Build next tick */
  2180 	t->grow_counter = 1;
  2186 	t->grow_counter = 1;
  2181 	/* If we were not already growing */
  2187 	/* If we were not already growing */
  2182 	SetBit(t->flags12, TOWN_IS_FUNDED);
  2188 	SetBit(t->flags12, TOWN_IS_FUNDED);
  2183 	/* And grow for 3 months */
  2189 	/* And grow for 3 months */
  2184 	t->fund_buildings_months = 3;
  2190 	t->fund_buildings_months = 3;
  2185 }
  2191 }
  2186 
  2192 
  2187 static void TownActionBuyRights(Town* t)
  2193 static void TownActionBuyRights(Town *t)
  2188 {
  2194 {
  2189 	/* Check if it's allowed to by the rights */
  2195 	/* Check if it's allowed to by the rights */
  2190 	if (!_patches.exclusive_rights) return;
  2196 	if (!_patches.exclusive_rights) return;
  2191 
  2197 
  2192 	t->exclusive_counter = 12;
  2198 	t->exclusive_counter = 12;
  2193 	t->exclusivity = _current_player;
  2199 	t->exclusivity = _current_player;
  2194 
  2200 
  2195 	ModifyStationRatingAround(t->xy, _current_player, 130, 17);
  2201 	ModifyStationRatingAround(t->xy, _current_player, 130, 17);
  2196 }
  2202 }
  2197 
  2203 
  2198 static void TownActionBribe(Town* t)
  2204 static void TownActionBribe(Town *t)
  2199 {
  2205 {
  2200 	if (!RandomRange(15)) {
  2206 	if (Chance16(1, 14)) {
  2201 		Station *st;
       
  2202 
       
  2203 		/* set as unwanted for 6 months */
  2207 		/* set as unwanted for 6 months */
  2204 		t->unwanted[_current_player] = 6;
  2208 		t->unwanted[_current_player] = 6;
  2205 
  2209 
  2206 		/* set all close by station ratings to 0 */
  2210 		/* set all close by station ratings to 0 */
       
  2211 		Station *st;
  2207 		FOR_ALL_STATIONS(st) {
  2212 		FOR_ALL_STATIONS(st) {
  2208 			if (st->town == t && st->owner == _current_player) {
  2213 			if (st->town == t && st->owner == _current_player) {
  2209 				for (CargoID i = 0; i < NUM_CARGO; i++) st->goods[i].rating = 0;
  2214 				for (CargoID i = 0; i < NUM_CARGO; i++) st->goods[i].rating = 0;
  2210 			}
  2215 			}
  2211 		}
  2216 		}
  2224 	} else {
  2229 	} else {
  2225 		ChangeTownRating(t, RATING_BRIBE_UP_STEP, RATING_BRIBE_MAXIMUM);
  2230 		ChangeTownRating(t, RATING_BRIBE_UP_STEP, RATING_BRIBE_MAXIMUM);
  2226 	}
  2231 	}
  2227 }
  2232 }
  2228 
  2233 
  2229 typedef void TownActionProc(Town* t);
  2234 typedef void TownActionProc(Town *t);
  2230 static TownActionProc * const _town_action_proc[] = {
  2235 static TownActionProc *const _town_action_proc[] = {
  2231 	TownActionAdvertiseSmall,
  2236 	TownActionAdvertiseSmall,
  2232 	TownActionAdvertiseMedium,
  2237 	TownActionAdvertiseMedium,
  2233 	TownActionAdvertiseLarge,
  2238 	TownActionAdvertiseLarge,
  2234 	TownActionRoadRebuild,
  2239 	TownActionRoadRebuild,
  2235 	TownActionBuildStatue,
  2240 	TownActionBuildStatue,
  2248  * @param p1 town to do the action at
  2253  * @param p1 town to do the action at
  2249  * @param p2 action to perform, @see _town_action_proc for the list of available actions
  2254  * @param p2 action to perform, @see _town_action_proc for the list of available actions
  2250  */
  2255  */
  2251 CommandCost CmdDoTownAction(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  2256 CommandCost CmdDoTownAction(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  2252 {
  2257 {
  2253 	Town *t;
       
  2254 
       
  2255 	if (!IsValidTownID(p1) || p2 > lengthof(_town_action_proc)) return CMD_ERROR;
  2258 	if (!IsValidTownID(p1) || p2 > lengthof(_town_action_proc)) return CMD_ERROR;
  2256 
  2259 
  2257 	t = GetTown(p1);
  2260 	Town *t = GetTown(p1);
  2258 
  2261 
  2259 	if (!HasBit(GetMaskOfTownActions(NULL, _current_player, t), p2)) return CMD_ERROR;
  2262 	if (!HasBit(GetMaskOfTownActions(NULL, _current_player, t), p2)) return CMD_ERROR;
  2260 
  2263 
  2261 	CommandCost cost(EXPENSES_OTHER, (_price.build_industry >> 8) * _town_action_costs[p2]);
  2264 	CommandCost cost(EXPENSES_OTHER, (_price.build_industry >> 8) * _town_action_costs[p2]);
  2262 
  2265 
  2268 	return cost;
  2271 	return cost;
  2269 }
  2272 }
  2270 
  2273 
  2271 static void UpdateTownGrowRate(Town *t)
  2274 static void UpdateTownGrowRate(Town *t)
  2272 {
  2275 {
  2273 	int n;
  2276 	/* Increase player ratings if they're low */
  2274 	Station *st;
  2277 	const Player *p;
  2275 	uint16 m;
       
  2276 	Player *p;
       
  2277 
       
  2278 	/* Reset player ratings if they're low */
       
  2279 	FOR_ALL_PLAYERS(p) {
  2278 	FOR_ALL_PLAYERS(p) {
  2280 		if (p->is_active && t->ratings[p->index] <= 200) {
  2279 		if (p->is_active) {
  2281 			t->ratings[p->index] += 5;
  2280 			t->ratings[p->index] = min((int)RATING_GROWTH_MAXIMUM, t->ratings[p->index] + RATING_GROWTH_UP_STEP);
  2282 		}
  2281 		}
  2283 	}
  2282 	}
  2284 
  2283 
  2285 	n = 0;
  2284 	int n = 0;
       
  2285 
       
  2286 	const Station *st;
  2286 	FOR_ALL_STATIONS(st) {
  2287 	FOR_ALL_STATIONS(st) {
  2287 		if (DistanceSquare(st->xy, t->xy) <= t->radius[0]) {
  2288 		if (DistanceSquare(st->xy, t->xy) <= t->radius[0]) {
  2288 			if (st->time_since_load <= 20 || st->time_since_unload <= 20) {
  2289 			if (st->time_since_load <= 20 || st->time_since_unload <= 20) {
  2289 				n++;
  2290 				n++;
  2290 				if (IsValidPlayer(st->owner) && t->ratings[st->owner] <= 1000-12)
  2291 				if (IsValidPlayer(st->owner)) {
  2291 					t->ratings[st->owner] += 12;
  2292 					int new_rating = t->ratings[st->owner] + RATING_STATION_UP_STEP;
       
  2293 					t->ratings[st->owner] = min(new_rating, INT16_MAX); // do not let it overflow
       
  2294 				}
  2292 			} else {
  2295 			} else {
  2293 				if (IsValidPlayer(st->owner) && t->ratings[st->owner] >= -1000+15)
  2296 				if (IsValidPlayer(st->owner)) {
  2294 					t->ratings[st->owner] -= 15;
  2297 					int new_rating = t->ratings[st->owner] + RATING_STATION_DOWN_STEP;
       
  2298 					t->ratings[st->owner] = max(new_rating, INT16_MIN);
       
  2299 				}
  2295 			}
  2300 			}
  2296 		}
  2301 		}
       
  2302 	}
       
  2303 
       
  2304 	/* clamp all ratings to valid values */
       
  2305 	for (uint i = 0; i < MAX_PLAYERS; i++) {
       
  2306 		t->ratings[i] = Clamp(t->ratings[i], RATING_MINIMUM, RATING_MAXIMUM);
  2297 	}
  2307 	}
  2298 
  2308 
  2299 	ClrBit(t->flags12, TOWN_IS_FUNDED);
  2309 	ClrBit(t->flags12, TOWN_IS_FUNDED);
  2300 	if (_patches.town_growth_rate == 0 && t->fund_buildings_months == 0) return;
  2310 	if (_patches.town_growth_rate == 0 && t->fund_buildings_months == 0) return;
  2301 
  2311 
  2304 	static const uint16 _grow_count_values[2][6] = {
  2314 	static const uint16 _grow_count_values[2][6] = {
  2305 		{ 120, 120, 120, 100,  80,  60 }, // Fund new buildings has been activated
  2315 		{ 120, 120, 120, 100,  80,  60 }, // Fund new buildings has been activated
  2306 		{ 320, 420, 300, 220, 160, 100 }  // Normal values
  2316 		{ 320, 420, 300, 220, 160, 100 }  // Normal values
  2307 	};
  2317 	};
  2308 
  2318 
       
  2319 	uint16 m;
       
  2320 
  2309 	if (t->fund_buildings_months != 0) {
  2321 	if (t->fund_buildings_months != 0) {
  2310 		m = _grow_count_values[0][min(n, 5)];
  2322 		m = _grow_count_values[0][min(n, 5)];
  2311 		t->fund_buildings_months--;
  2323 		t->fund_buildings_months--;
  2312 	} else {
  2324 	} else {
  2313 		m = _grow_count_values[1][min(n, 5)];
  2325 		m = _grow_count_values[1][min(n, 5)];
  2354 	InvalidateWindow(WC_TOWN_VIEW, t->index);
  2366 	InvalidateWindow(WC_TOWN_VIEW, t->index);
  2355 }
  2367 }
  2356 
  2368 
  2357 static void UpdateTownUnwanted(Town *t)
  2369 static void UpdateTownUnwanted(Town *t)
  2358 {
  2370 {
  2359 	const Player* p;
  2371 	const Player *p;
  2360 
  2372 
  2361 	FOR_ALL_PLAYERS(p) {
  2373 	FOR_ALL_PLAYERS(p) {
  2362 		if (t->unwanted[p->index] > 0) t->unwanted[p->index]--;
  2374 		if (t->unwanted[p->index] > 0) t->unwanted[p->index]--;
  2363 	}
  2375 	}
  2364 }
  2376 }
  2365 
  2377 
  2366 bool CheckIfAuthorityAllows(TileIndex tile)
  2378 bool CheckIfAuthorityAllows(TileIndex tile)
  2367 {
  2379 {
  2368 	Town *t;
       
  2369 
       
  2370 	if (!IsValidPlayer(_current_player)) return true;
  2380 	if (!IsValidPlayer(_current_player)) return true;
  2371 
  2381 
  2372 	t = ClosestTownFromTile(tile, _patches.dist_local_authority);
  2382 	Town *t = ClosestTownFromTile(tile, _patches.dist_local_authority);
  2373 	if (t == NULL) return true;
  2383 	if (t == NULL) return true;
  2374 
  2384 
  2375 	if (t->ratings[_current_player] > -200) return true;
  2385 	if (t->ratings[_current_player] > RATING_VERYPOOR) return true;
  2376 
  2386 
  2377 	_error_message = STR_2009_LOCAL_AUTHORITY_REFUSES;
  2387 	_error_message = STR_2009_LOCAL_AUTHORITY_REFUSES;
  2378 	SetDParam(0, t->index);
  2388 	SetDParam(0, t->index);
  2379 
  2389 
  2380 	return false;
  2390 	return false;
  2381 }
  2391 }
  2382 
  2392 
  2383 
  2393 
  2384 Town* CalcClosestTownFromTile(TileIndex tile, uint threshold)
  2394 Town *CalcClosestTownFromTile(TileIndex tile, uint threshold)
  2385 {
  2395 {
  2386 	Town *t;
  2396 	Town *t;
  2387 	uint dist, best = threshold;
  2397 	uint best = threshold;
  2388 	Town *best_town = NULL;
  2398 	Town *best_town = NULL;
  2389 
  2399 
  2390 	FOR_ALL_TOWNS(t) {
  2400 	FOR_ALL_TOWNS(t) {
  2391 		dist = DistanceManhattan(tile, t->xy);
  2401 		uint dist = DistanceManhattan(tile, t->xy);
  2392 		if (dist < best) {
  2402 		if (dist < best) {
  2393 			best = dist;
  2403 			best = dist;
  2394 			best_town = t;
  2404 			best_town = t;
  2395 		}
  2405 		}
  2396 	}
  2406 	}
  2429 	_town_rating_test = !(ref_count == 0);
  2439 	_town_rating_test = !(ref_count == 0);
  2430 }
  2440 }
  2431 
  2441 
  2432 void ChangeTownRating(Town *t, int add, int max)
  2442 void ChangeTownRating(Town *t, int add, int max)
  2433 {
  2443 {
  2434 	int rating;
       
  2435 
       
  2436 	/* if magic_bulldozer cheat is active, town doesn't penaltize for removing stuff */
  2444 	/* if magic_bulldozer cheat is active, town doesn't penaltize for removing stuff */
  2437 	if (t == NULL ||
  2445 	if (t == NULL ||
  2438 			!IsValidPlayer(_current_player) ||
  2446 			!IsValidPlayer(_current_player) ||
  2439 			(_cheats.magic_bulldozer.value && add < 0)) {
  2447 			(_cheats.magic_bulldozer.value && add < 0)) {
  2440 		return;
  2448 		return;
  2441 	}
  2449 	}
  2442 
  2450 
  2443 	SetBit(t->have_ratings, _current_player);
  2451 	SetBit(t->have_ratings, _current_player);
  2444 
  2452 
  2445 	rating = _town_rating_test ? t->test_rating : t->ratings[_current_player];
  2453 	int rating = _town_rating_test ? t->test_rating : t->ratings[_current_player];
  2446 
  2454 
  2447 	if (add < 0) {
  2455 	if (add < 0) {
  2448 		if (rating > max) {
  2456 		if (rating > max) {
  2449 			rating += add;
  2457 			rating += add;
  2450 			if (rating < max) rating = max;
  2458 			if (rating < max) rating = max;
  2470 	{ 96, 384, 768}, // Hostile
  2478 	{ 96, 384, 768}, // Hostile
  2471 };
  2479 };
  2472 
  2480 
  2473 bool CheckforTownRating(uint32 flags, Town *t, byte type)
  2481 bool CheckforTownRating(uint32 flags, Town *t, byte type)
  2474 {
  2482 {
  2475 	int modemod;
       
  2476 
       
  2477 	/* if magic_bulldozer cheat is active, town doesn't restrict your destructive actions */
  2483 	/* if magic_bulldozer cheat is active, town doesn't restrict your destructive actions */
  2478 	if (t == NULL || !IsValidPlayer(_current_player) || _cheats.magic_bulldozer.value)
  2484 	if (t == NULL || !IsValidPlayer(_current_player) || _cheats.magic_bulldozer.value)
  2479 		return true;
  2485 		return true;
  2480 
  2486 
  2481 	/* check if you're allowed to remove the street/bridge/tunnel/industry
  2487 	/* check if you're allowed to remove the street/bridge/tunnel/industry
  2482 	 * owned by a town no removal if rating is lower than ... depends now on
  2488 	 * owned by a town no removal if rating is lower than ... depends now on
  2483 	 * difficulty setting. Minimum town rating selected by difficulty level
  2489 	 * difficulty setting. Minimum town rating selected by difficulty level
  2484 	 */
  2490 	 */
  2485 	modemod = _default_rating_settings[_opt.diff.town_council_tolerance][type];
  2491 	int modemod = _default_rating_settings[_opt.diff.town_council_tolerance][type];
  2486 
  2492 
  2487 	if ((_town_rating_test ? t->test_rating : t->ratings[_current_player]) < 16 + modemod && !(flags & DC_NO_TOWN_RATING)) {
  2493 	if ((_town_rating_test ? t->test_rating : t->ratings[_current_player]) < 16 + modemod && !(flags & DC_NO_TOWN_RATING)) {
  2488 		SetDParam(0, t->index);
  2494 		SetDParam(0, t->index);
  2489 		_error_message = STR_2009_LOCAL_AUTHORITY_REFUSES;
  2495 		_error_message = STR_2009_LOCAL_AUTHORITY_REFUSES;
  2490 		return false;
  2496 		return false;
  2509 	}
  2515 	}
  2510 }
  2516 }
  2511 
  2517 
  2512 void InitializeTowns()
  2518 void InitializeTowns()
  2513 {
  2519 {
  2514 	Subsidy *s;
       
  2515 
       
  2516 	/* Clean the town pool and create 1 block in it */
  2520 	/* Clean the town pool and create 1 block in it */
  2517 	_Town_pool.CleanPool();
  2521 	_Town_pool.CleanPool();
  2518 	_Town_pool.AddBlockToPool();
  2522 	_Town_pool.AddBlockToPool();
  2519 
  2523 
  2520 	memset(_subsidies, 0, sizeof(_subsidies));
  2524 	memset(_subsidies, 0, sizeof(_subsidies));
  2521 	for (s=_subsidies; s != endof(_subsidies); s++)
  2525 	for (Subsidy *s = _subsidies; s != endof(_subsidies); s++) {
  2522 		s->cargo_type = CT_INVALID;
  2526 		s->cargo_type = CT_INVALID;
       
  2527 	}
  2523 
  2528 
  2524 	_cur_town_ctr = 0;
  2529 	_cur_town_ctr = 0;
  2525 	_cur_town_iter = 0;
  2530 	_cur_town_iter = 0;
  2526 	_total_towns = 0;
  2531 	_total_towns = 0;
  2527 	_town_sort_dirty = true;
  2532 	_town_sort_dirty = true;
  2529 
  2534 
  2530 static CommandCost TerraformTile_Town(TileIndex tile, uint32 flags, uint z_new, Slope tileh_new)
  2535 static CommandCost TerraformTile_Town(TileIndex tile, uint32 flags, uint z_new, Slope tileh_new)
  2531 {
  2536 {
  2532 	if (AutoslopeEnabled()) {
  2537 	if (AutoslopeEnabled()) {
  2533 		HouseID house = GetHouseType(tile);
  2538 		HouseID house = GetHouseType(tile);
  2534 		HouseSpec *hs = GetHouseSpecs(house);
  2539 		const HouseSpec *hs = GetHouseSpecs(house);
  2535 
  2540 
  2536 		/* Here we differ from TTDP by checking TILE_NOT_SLOPED */
  2541 		/* Here we differ from TTDP by checking TILE_NOT_SLOPED */
  2537 		if (((hs->building_flags & TILE_NOT_SLOPED) == 0) && !IsSteepSlope(tileh_new) &&
  2542 		if (((hs->building_flags & TILE_NOT_SLOPED) == 0) && !IsSteepSlope(tileh_new) &&
  2538 			(GetTileMaxZ(tile) == z_new + GetSlopeMaxZ(tileh_new))) return CommandCost(EXPENSES_CONSTRUCTION, _price.terraform);
  2543 			(GetTileMaxZ(tile) == z_new + GetSlopeMaxZ(tileh_new))) return CommandCost(EXPENSES_CONSTRUCTION, _price.terraform);
  2539 	}
  2544 	}
  2550 	GetTileTrackStatus_Town, /* get_tile_track_status_proc */
  2555 	GetTileTrackStatus_Town, /* get_tile_track_status_proc */
  2551 	ClickTile_Town,          /* click_tile_proc */
  2556 	ClickTile_Town,          /* click_tile_proc */
  2552 	AnimateTile_Town,        /* animate_tile_proc */
  2557 	AnimateTile_Town,        /* animate_tile_proc */
  2553 	TileLoop_Town,           /* tile_loop_clear */
  2558 	TileLoop_Town,           /* tile_loop_clear */
  2554 	ChangeTileOwner_Town,    /* change_tile_owner_clear */
  2559 	ChangeTileOwner_Town,    /* change_tile_owner_clear */
  2555 	NULL,                    /* get_produced_cargo_proc */
  2560 	GetProducedCargo_Town,   /* get_produced_cargo_proc */
  2556 	NULL,                    /* vehicle_enter_tile_proc */
  2561 	NULL,                    /* vehicle_enter_tile_proc */
  2557 	GetFoundation_Town,      /* get_foundation_proc */
  2562 	GetFoundation_Town,      /* get_foundation_proc */
  2558 	TerraformTile_Town,      /* terraform_tile_proc */
  2563 	TerraformTile_Town,      /* terraform_tile_proc */
  2559 };
  2564 };
  2560 
  2565 
  2562 /** Save and load of towns. */
  2567 /** Save and load of towns. */
  2563 static const SaveLoad _town_desc[] = {
  2568 static const SaveLoad _town_desc[] = {
  2564 	SLE_CONDVAR(Town, xy,                    SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
  2569 	SLE_CONDVAR(Town, xy,                    SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
  2565 	SLE_CONDVAR(Town, xy,                    SLE_UINT32,                 6, SL_MAX_VERSION),
  2570 	SLE_CONDVAR(Town, xy,                    SLE_UINT32,                 6, SL_MAX_VERSION),
  2566 
  2571 
  2567 	SLE_CONDNULL(2, 0, 2),
  2572 	SLE_CONDNULL(2, 0, 2),                   ///< population, no longer in use
  2568 	SLE_CONDNULL(4, 3, 84),
  2573 	SLE_CONDNULL(4, 3, 84),                  ///< population, no longer in use
  2569 
  2574 	SLE_CONDNULL(2, 0, 91),                  ///< num_houses, no longer in use
  2570 	    SLE_VAR(Town, num_houses,            SLE_UINT16),
  2575 
  2571 	SLE_CONDVAR(Town, townnamegrfid,         SLE_UINT32, 66, SL_MAX_VERSION),
  2576 	SLE_CONDVAR(Town, townnamegrfid,         SLE_UINT32, 66, SL_MAX_VERSION),
  2572 	    SLE_VAR(Town, townnametype,          SLE_UINT16),
  2577 	    SLE_VAR(Town, townnametype,          SLE_UINT16),
  2573 	    SLE_VAR(Town, townnameparts,         SLE_UINT32),
  2578 	    SLE_VAR(Town, townnameparts,         SLE_UINT32),
  2574 	SLE_CONDSTR(Town, name,                  SLE_STR, 0, 84, SL_MAX_VERSION),
  2579 	SLE_CONDSTR(Town, name,                  SLE_STR, 0, 84, SL_MAX_VERSION),
  2575 
  2580 
  2576 	    SLE_VAR(Town, flags12,               SLE_UINT8),
  2581 	    SLE_VAR(Town, flags12,               SLE_UINT8),
  2577 	    SLE_VAR(Town, statues,               SLE_UINT8),
  2582 	    SLE_VAR(Town, statues,               SLE_UINT8),
  2578 
  2583 
  2579 	/* sort_index_obsolete was stored here in savegame format 0 - 1 */
  2584 	SLE_CONDNULL(1, 0, 1),                   ///< sort_index, no longer in use
  2580 	SLE_CONDNULL(1, 0, 1),
       
  2581 
  2585 
  2582 	    SLE_VAR(Town, have_ratings,          SLE_UINT8),
  2586 	    SLE_VAR(Town, have_ratings,          SLE_UINT8),
  2583 	    SLE_ARR(Town, ratings,               SLE_INT16, 8),
  2587 	    SLE_ARR(Town, ratings,               SLE_INT16, 8),
  2584 	/* failed bribe attempts are stored since savegame format 4 */
  2588 	/* failed bribe attempts are stored since savegame format 4 */
  2585 	SLE_CONDARR(Town, unwanted,              SLE_INT8, 8, 4,SL_MAX_VERSION),
  2589 	SLE_CONDARR(Town, unwanted,              SLE_INT8, 8, 4, SL_MAX_VERSION),
  2586 
  2590 
  2587 	SLE_CONDVAR(Town, max_pass,              SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
  2591 	SLE_CONDVAR(Town, max_pass,              SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
  2588 	SLE_CONDVAR(Town, max_mail,              SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
  2592 	SLE_CONDVAR(Town, max_mail,              SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
  2589 	SLE_CONDVAR(Town, new_max_pass,          SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
  2593 	SLE_CONDVAR(Town, new_max_pass,          SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
  2590 	SLE_CONDVAR(Town, new_max_mail,          SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
  2594 	SLE_CONDVAR(Town, new_max_mail,          SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
  2693 		_cur_town_ctr = 0;
  2697 		_cur_town_ctr = 0;
  2694 }
  2698 }
  2695 
  2699 
  2696 void AfterLoadTown()
  2700 void AfterLoadTown()
  2697 {
  2701 {
       
  2702 	_town_sort_dirty = true;
       
  2703 
  2698 	Town *t;
  2704 	Town *t;
  2699 	FOR_ALL_TOWNS(t) {
  2705 	FOR_ALL_TOWNS(t) t->InitializeLayout();
  2700 		UpdateTownRadius(t);
       
  2701 	}
       
  2702 	_town_sort_dirty = true;
       
  2703 }
  2706 }
  2704 
  2707 
  2705 extern const ChunkHandler _town_chunk_handlers[] = {
  2708 extern const ChunkHandler _town_chunk_handlers[] = {
  2706 	{ 'HIDS', Save_HOUSEIDS, Load_HOUSEIDS, CH_ARRAY },
  2709 	{ 'HIDS', Save_HOUSEIDS, Load_HOUSEIDS, CH_ARRAY },
  2707 	{ 'CITY', Save_TOWN,     Load_TOWN,     CH_ARRAY | CH_LAST},
  2710 	{ 'CITY', Save_TOWN,     Load_TOWN,     CH_ARRAY | CH_LAST},