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