town_cmd.c
changeset 193 0a7025304867
parent 159 139cf78bfb28
child 260 4819bcce8389
equal deleted inserted replaced
192:614bba52258d 193:0a7025304867
    74 
    74 
    75 	/* Add a house on top of the ground? */
    75 	/* Add a house on top of the ground? */
    76 	if ((image = dcts->sprite_2) != 0) {
    76 	if ((image = dcts->sprite_2) != 0) {
    77 		if (!(_display_opt & DO_TRANS_BUILDINGS))
    77 		if (!(_display_opt & DO_TRANS_BUILDINGS))
    78 			image = (image & 0x3FFF) | 0x3224000;
    78 			image = (image & 0x3FFF) | 0x3224000;
    79 		
    79 
    80 		AddSortableSpriteToDraw(image, 
    80 		AddSortableSpriteToDraw(image,
    81 			ti->x | (dcts->subtile_xy>>4),
    81 			ti->x | (dcts->subtile_xy>>4),
    82 			ti->y | (dcts->subtile_xy&0xF),
    82 			ti->y | (dcts->subtile_xy&0xF),
    83 			(dcts->width_height>>4)+1,
    83 			(dcts->width_height>>4)+1,
    84 			(dcts->width_height&0xF)+1,
    84 			(dcts->width_height&0xF)+1,
    85 			dcts->dz,
    85 			dcts->dz,
    98 
    98 
    99 static uint GetSlopeZ_Town(TileInfo *ti)
    99 static uint GetSlopeZ_Town(TileInfo *ti)
   100 {
   100 {
   101 	uint z = GetPartialZ(ti->x&0xF, ti->y&0xF, ti->tileh) + ti->z;
   101 	uint z = GetPartialZ(ti->x&0xF, ti->y&0xF, ti->tileh) + ti->z;
   102 	if (ti->tileh != 0) z = (z & ~7) + 4;
   102 	if (ti->tileh != 0) z = (z & ~7) + 4;
   103 	return (uint16) z;	
   103 	return (uint16) z;
   104 }
   104 }
   105 
   105 
   106 static uint GetSlopeTileh_Town(TileInfo *ti)
   106 static uint GetSlopeTileh_Town(TileInfo *ti)
   107 {
   107 {
   108 	return ti->tileh;
   108 	return ti->tileh;
   138 	if (a == b) {
   138 	if (a == b) {
   139 		_map5[tile] &= 0x40;
   139 		_map5[tile] &= 0x40;
   140 		_map_owner[tile] &= 0x7F;
   140 		_map_owner[tile] &= 0x7F;
   141 		DeleteAnimatedTile(tile);
   141 		DeleteAnimatedTile(tile);
   142 	}
   142 	}
   143 	
   143 
   144 	MarkTileDirtyByTile(tile);
   144 	MarkTileDirtyByTile(tile);
   145 }
   145 }
   146 
   146 
   147 static void UpdateTownRadius(Town *t);
   147 static void UpdateTownRadius(Town *t);
   148 
   148 
   167 }
   167 }
   168 
   168 
   169 static void MakeSingleHouseBigger(uint tile)
   169 static void MakeSingleHouseBigger(uint tile)
   170 {
   170 {
   171 	byte b;
   171 	byte b;
   172 	
   172 
   173 	assert(IS_TILETYPE(tile, MP_HOUSE));
   173 	assert(IS_TILETYPE(tile, MP_HOUSE));
   174 	
   174 
   175 	b = _map5[tile];
   175 	b = _map5[tile];
   176 	if (b & 0x80)
   176 	if (b & 0x80)
   177 		return;
   177 		return;
   178 
   178 
   179 	_map5[tile] = (b & 0xC0) | ((b+1)&7);
   179 	_map5[tile] = (b & 0xC0) | ((b+1)&7);
   183 
   183 
   184 	_map3_lo[tile] = _map3_lo[tile] + 0x40;
   184 	_map3_lo[tile] = _map3_lo[tile] + 0x40;
   185 
   185 
   186 	if ( (_map3_lo[tile] & 0xC0) == 0xC0) {
   186 	if ( (_map3_lo[tile] & 0xC0) == 0xC0) {
   187 		Town *t = ClosestTownFromTile(tile, (uint)-1);
   187 		Town *t = ClosestTownFromTile(tile, (uint)-1);
   188 		ChangePopulation(t, _housetype_population[_map2[tile]]); 
   188 		ChangePopulation(t, _housetype_population[_map2[tile]]);
   189 	}
   189 	}
   190 	MarkTileDirtyByTile(tile);
   190 	MarkTileDirtyByTile(tile);
   191 }
   191 }
   192 
   192 
   193 static void MakeTownHouseBigger(uint tile)
   193 static void MakeTownHouseBigger(uint tile)
   194 {
   194 {
   195 	uint flags = _house_more_flags[_map2[tile]]; 
   195 	uint flags = _house_more_flags[_map2[tile]];
   196 	if (flags & 8) MakeSingleHouseBigger(TILE_ADDXY(tile, 0, 0));
   196 	if (flags & 8) MakeSingleHouseBigger(TILE_ADDXY(tile, 0, 0));
   197 	if (flags & 4) MakeSingleHouseBigger(TILE_ADDXY(tile, 0, 1));
   197 	if (flags & 4) MakeSingleHouseBigger(TILE_ADDXY(tile, 0, 1));
   198 	if (flags & 2) MakeSingleHouseBigger(TILE_ADDXY(tile, 1, 0));
   198 	if (flags & 2) MakeSingleHouseBigger(TILE_ADDXY(tile, 1, 0));
   199 	if (flags & 1) MakeSingleHouseBigger(TILE_ADDXY(tile, 1, 1));
   199 	if (flags & 1) MakeSingleHouseBigger(TILE_ADDXY(tile, 1, 1));
   200 }
   200 }
   243 		t->time_until_rebuild = (r & 63) + 130;
   243 		t->time_until_rebuild = (r & 63) + 130;
   244 
   244 
   245 		_current_player = OWNER_TOWN;
   245 		_current_player = OWNER_TOWN;
   246 
   246 
   247 		ClearTownHouse(t, tile);
   247 		ClearTownHouse(t, tile);
   248 		
   248 
   249 		// rebuild with another house?
   249 		// rebuild with another house?
   250 		if ( (byte) (r >> 8) >= 12) {
   250 		if ( (byte) (r >> 8) >= 12) {
   251 			DoBuildTownHouse(t, tile);
   251 			DoBuildTownHouse(t, tile);
   252 		}
   252 		}
   253 	}
   253 	}
   272 	cost = _price.remove_house * _housetype_remove_cost[house] >> 8;
   272 	cost = _price.remove_house * _housetype_remove_cost[house] >> 8;
   273 
   273 
   274 	rating = _housetype_remove_ratingmod[house];
   274 	rating = _housetype_remove_ratingmod[house];
   275 	_cleared_town_rating += rating;
   275 	_cleared_town_rating += rating;
   276 	_cleared_town = t = ClosestTownFromTile(tile, (uint)-1);
   276 	_cleared_town = t = ClosestTownFromTile(tile, (uint)-1);
   277 	
   277 
   278 	if (_current_player < MAX_PLAYERS) {
   278 	if (_current_player < MAX_PLAYERS) {
   279 		if (rating > t->ratings[_current_player] && !(flags & DC_NO_TOWN_RATING) && !_cheats.magic_bulldozer.value) {
   279 		if (rating > t->ratings[_current_player] && !(flags & DC_NO_TOWN_RATING) && !_cheats.magic_bulldozer.value) {
   280 			SET_DPARAM16(0, t->index);
   280 			SET_DPARAM16(0, t->index);
   281 			return_cmd_error(STR_2009_LOCAL_AUTHORITY_REFUSES);
   281 			return_cmd_error(STR_2009_LOCAL_AUTHORITY_REFUSES);
   282 		}	
   282 		}
   283 	}
   283 	}
   284 
   284 
   285 	if (flags & DC_EXEC) {
   285 	if (flags & DC_EXEC) {
   286 		ChangeTownRating(t, -rating, -1000);
   286 		ChangeTownRating(t, -rating, -1000);
   287 		ClearTownHouse(t, tile);
   287 		ClearTownHouse(t, tile);
   291 }
   291 }
   292 
   292 
   293 static void GetAcceptedCargo_Town(uint tile, AcceptedCargo *ac)
   293 static void GetAcceptedCargo_Town(uint tile, AcceptedCargo *ac)
   294 {
   294 {
   295 	int type = _map2[tile];
   295 	int type = _map2[tile];
   296 	
   296 
   297 	ac->type_1 = CT_PASSENGERS;
   297 	ac->type_1 = CT_PASSENGERS;
   298 	ac->amount_1 = _housetype_cargo_passengers[type];
   298 	ac->amount_1 = _housetype_cargo_passengers[type];
   299 
   299 
   300 	ac->type_2 = CT_GOODS;
   300 	ac->type_2 = CT_GOODS;
   301 	ac->amount_2 = _housetype_cargo_goods[type];
   301 	ac->amount_2 = _housetype_cargo_goods[type];
   334 static const TileIndexDiff _roadblock_tileadd[4+3] = {
   334 static const TileIndexDiff _roadblock_tileadd[4+3] = {
   335 	TILE_XY(0,-1),
   335 	TILE_XY(0,-1),
   336 	TILE_XY(1,0),
   336 	TILE_XY(1,0),
   337 	TILE_XY(0,1),
   337 	TILE_XY(0,1),
   338 	TILE_XY(-1,0),
   338 	TILE_XY(-1,0),
   339 	
   339 
   340 	// Store the first 3 elements again.
   340 	// Store the first 3 elements again.
   341 	// Lets us rotate without using &3.
   341 	// Lets us rotate without using &3.
   342 	TILE_XY(0,-1),
   342 	TILE_XY(0,-1),
   343 	TILE_XY(1,0),
   343 	TILE_XY(1,0),
   344 	TILE_XY(0,1),
   344 	TILE_XY(0,1),
   350 		int i = t->grow_counter - 1;
   350 		int i = t->grow_counter - 1;
   351 		if (i < 0) {
   351 		if (i < 0) {
   352 			if (GrowTown(t)) {
   352 			if (GrowTown(t)) {
   353 				i = t->growth_rate;
   353 				i = t->growth_rate;
   354 			} else {
   354 			} else {
   355 				i = 0;	
   355 				i = 0;
   356 			}
   356 			}
   357 		}
   357 		}
   358 		t->grow_counter = i;
   358 		t->grow_counter = i;
   359 	}
   359 	}
   360 
   360 
   398 	uint slope;
   398 	uint slope;
   399 
   399 
   400 	// If this assertion fails, it might be because the world contains
   400 	// If this assertion fails, it might be because the world contains
   401 	//  land at the edges. This is not ok.
   401 	//  land at the edges. This is not ok.
   402 	TILE_ASSERT(tile);
   402 	TILE_ASSERT(tile);
   403 	
   403 
   404 	for(;;) {
   404 	for(;;) {
   405 		// Check if there already is a road at this point?
   405 		// Check if there already is a road at this point?
   406 		if (GetRoadBitsByTile(tile) == 0) {
   406 		if (GetRoadBitsByTile(tile) == 0) {
   407 			// No, try to build one in the direction.
   407 			// No, try to build one in the direction.
   408 			// if that fails clear the land, and if that fails exit.
   408 			// if that fails clear the land, and if that fails exit.
   419 			if (HASBIT(GetTownRoadMask(TILE_ADD(tile, _roadblock_tileadd[dir+1])), dir^2) ||
   419 			if (HASBIT(GetTownRoadMask(TILE_ADD(tile, _roadblock_tileadd[dir+1])), dir^2) ||
   420 					HASBIT(GetTownRoadMask(TILE_ADD(tile, _roadblock_tileadd[dir+3])), dir^2) ||
   420 					HASBIT(GetTownRoadMask(TILE_ADD(tile, _roadblock_tileadd[dir+3])), dir^2) ||
   421 					HASBIT(GetTownRoadMask(TILE_ADD(tile, _roadblock_tileadd[dir+1] + _roadblock_tileadd[dir+2])), dir) ||
   421 					HASBIT(GetTownRoadMask(TILE_ADD(tile, _roadblock_tileadd[dir+1] + _roadblock_tileadd[dir+2])), dir) ||
   422 					HASBIT(GetTownRoadMask(TILE_ADD(tile, _roadblock_tileadd[dir+3] + _roadblock_tileadd[dir+2])), dir))
   422 					HASBIT(GetTownRoadMask(TILE_ADD(tile, _roadblock_tileadd[dir+3] + _roadblock_tileadd[dir+2])), dir))
   423 				return false;
   423 				return false;
   424 			
   424 
   425 			// Otherwise allow
   425 			// Otherwise allow
   426 			return true;
   426 			return true;
   427 		}
   427 		}
   428 		
   428 
   429 		// If the tile is not a slope in the right direction, then
   429 		// If the tile is not a slope in the right direction, then
   430 		// maybe terraform some.
   430 		// maybe terraform some.
   431 		if ((k = (dir&1)?0xC:0x9) != slope && (k^0xF) != slope) {
   431 		if ((k = (dir&1)?0xC:0x9) != slope && (k^0xF) != slope) {
   432 			uint32 r = Random();
   432 			uint32 r = Random();
   433 
   433 
   445 }
   445 }
   446 
   446 
   447 static bool TerraformTownTile(uint tile, int edges, int dir)
   447 static bool TerraformTownTile(uint tile, int edges, int dir)
   448 {
   448 {
   449 	int32 r;
   449 	int32 r;
   450 	
   450 
   451 	TILE_ASSERT(tile);
   451 	TILE_ASSERT(tile);
   452 
   452 
   453 	r = DoCommandByTile(tile, edges, dir, DC_AUTO | DC_NO_WATER, CMD_TERRAFORM_LAND);
   453 	r = DoCommandByTile(tile, edges, dir, DC_AUTO | DC_NO_WATER, CMD_TERRAFORM_LAND);
   454 	if (r == CMD_ERROR || r >= 126*16)
   454 	if (r == CMD_ERROR || r >= 126*16)
   455 		return false;
   455 		return false;
   489 
   489 
   490 	TILE_ASSERT(tile);
   490 	TILE_ASSERT(tile);
   491 
   491 
   492 	if (mask == 0) {
   492 	if (mask == 0) {
   493 		// Tile has no road. First reset the status counter
   493 		// Tile has no road. First reset the status counter
   494 		// to say that this is the last iteration.	
   494 		// to say that this is the last iteration.
   495 		_grow_town_result = 0;
   495 		_grow_town_result = 0;
   496 
   496 
   497 		// Then check if the tile we are at belongs to the town,
   497 		// Then check if the tile we are at belongs to the town,
   498 		// if not, bail out.
   498 		// if not, bail out.
   499 		t2 = ClosestTownFromTile(tile, (uint)-1);
   499 		t2 = ClosestTownFromTile(tile, (uint)-1);
   518 		if (!IsRoadAllowedHere(TILE_ADD(tile,_roadblock_tileadd[a]), a)) {
   518 		if (!IsRoadAllowedHere(TILE_ADD(tile,_roadblock_tileadd[a]), a)) {
   519 			// A road is not allowed to continue the randomized road,
   519 			// A road is not allowed to continue the randomized road,
   520 			//   return if the road we're trying to build is curved.
   520 			//   return if the road we're trying to build is curved.
   521 			if ( a != (b^2))
   521 			if ( a != (b^2))
   522 				return;
   522 				return;
   523 			
   523 
   524 			// Return if neither side of the new road is a house
   524 			// Return if neither side of the new road is a house
   525 			if (!IS_TILETYPE(TILE_ADD(tile,_roadblock_tileadd[a+1]), MP_HOUSE) &&
   525 			if (!IS_TILETYPE(TILE_ADD(tile,_roadblock_tileadd[a+1]), MP_HOUSE) &&
   526 					!IS_TILETYPE(TILE_ADD(tile,_roadblock_tileadd[a+3]), MP_HOUSE))
   526 					!IS_TILETYPE(TILE_ADD(tile,_roadblock_tileadd[a+3]), MP_HOUSE))
   527 				return;
   527 				return;
   528 
   528 
   542 		if (IS_TILETYPE(tile, MP_TUNNELBRIDGE) && (_map5[tile]&~3)==4) {
   542 		if (IS_TILETYPE(tile, MP_TUNNELBRIDGE) && (_map5[tile]&~3)==4) {
   543 			FindLengthOfTunnelResult flotr = FindLengthOfTunnel(tile, _map5[tile]&3);
   543 			FindLengthOfTunnelResult flotr = FindLengthOfTunnel(tile, _map5[tile]&3);
   544 			*tile_ptr = flotr.tile;
   544 			*tile_ptr = flotr.tile;
   545 			return;
   545 			return;
   546 		}
   546 		}
   547 		
   547 
   548 		// For any other kind of tunnel/bridge, bail out.
   548 		// For any other kind of tunnel/bridge, bail out.
   549 		if (IS_TILETYPE(tile, MP_TUNNELBRIDGE))
   549 		if (IS_TILETYPE(tile, MP_TUNNELBRIDGE))
   550 			return;
   550 			return;
   551 
   551 
   552 		// Possibly extend the road in a direction.
   552 		// Possibly extend the road in a direction.
   555 		if (HASBIT(mask, i))
   555 		if (HASBIT(mask, i))
   556 			return;
   556 			return;
   557 
   557 
   558 		// This is the tile we will reach if we extend to this direction.
   558 		// This is the tile we will reach if we extend to this direction.
   559 		tmptile = TILE_ADD(tile,_roadblock_tileadd[i]);
   559 		tmptile = TILE_ADD(tile,_roadblock_tileadd[i]);
   560 		
   560 
   561 		// Don't do it if it reaches to water.
   561 		// Don't do it if it reaches to water.
   562 		if (IS_WATER_TILE(tmptile))
   562 		if (IS_WATER_TILE(tmptile))
   563 			return;
   563 			return;
   564 
   564 
   565 		// If the new tile belongs to another town,
   565 		// If the new tile belongs to another town,
   567 		if (ClosestTownFromTile(tmptile, (uint)-1) != t1) {
   567 		if (ClosestTownFromTile(tmptile, (uint)-1) != t1) {
   568 			_grow_town_result = 0;
   568 			_grow_town_result = 0;
   569 			return;
   569 			return;
   570 		}
   570 		}
   571 
   571 
   572 		// Build a house at the edge. 60% chance or 
   572 		// Build a house at the edge. 60% chance or
   573 		//  always ok if no road allowed.
   573 		//  always ok if no road allowed.
   574 		if (!IsRoadAllowedHere(tmptile, i) || CHANCE16(6,10)) {
   574 		if (!IsRoadAllowedHere(tmptile, i) || CHANCE16(6,10)) {
   575 			// But not if there already is a house there.
   575 			// But not if there already is a house there.
   576 			if (!IS_TILETYPE(tmptile, MP_HOUSE)) {
   576 			if (!IS_TILETYPE(tmptile, MP_HOUSE)) {
   577 				// Level the land if possible
   577 				// Level the land if possible
   720 	do {
   720 	do {
   721 		if (GetRoadBitsByTile(tile) != 0) {
   721 		if (GetRoadBitsByTile(tile) != 0) {
   722 			return GrowTownAtRoad(t, tile);
   722 			return GrowTownAtRoad(t, tile);
   723 		}
   723 		}
   724 		offs = *ptr++;
   724 		offs = *ptr++;
   725 		
   725 
   726 		tile = TILE_ADD(tile, offs);
   726 		tile = TILE_ADD(tile, offs);
   727 	} while (offs);
   727 	} while (offs);
   728 
   728 
   729 	// No road available, try to build a random road block by
   729 	// No road available, try to build a random road block by
   730 	// clearing some land and then building a road there.
   730 	// clearing some land and then building a road there.
   731 	tile = t->xy;
   731 	tile = t->xy;
   732 	ptr = _town_coord_mod;
   732 	ptr = _town_coord_mod;
   733 	do {
   733 	do {
   734 		FindLandscapeHeightByTile(&ti, tile);
   734 		FindLandscapeHeightByTile(&ti, tile);
   735 		
   735 
   736 		// Only work with plain land that not already has a house with map5=0
   736 		// Only work with plain land that not already has a house with map5=0
   737 		if (ti.tileh == 0 && !(ti.type==MP_HOUSE && ti.map5==0)) {
   737 		if (ti.tileh == 0 && !(ti.type==MP_HOUSE && ti.map5==0)) {
   738 			if (DoCommandByTile(tile, 0, 0, DC_AUTO, CMD_LANDSCAPE_CLEAR) != CMD_ERROR) {
   738 			if (DoCommandByTile(tile, 0, 0, DC_AUTO, CMD_LANDSCAPE_CLEAR) != CMD_ERROR) {
   739 				DoCommandByTile(tile, GenRandomRoadBits(), 0, DC_EXEC | DC_AUTO, CMD_BUILD_ROAD);
   739 				DoCommandByTile(tile, GenRandomRoadBits(), 0, DC_EXEC | DC_AUTO, CMD_BUILD_ROAD);
   740 				return true;
   740 				return true;
   798 restart:
   798 restart:
   799 		r = Random();
   799 		r = Random();
   800 
   800 
   801 		SET_DPARAM32(0, r);
   801 		SET_DPARAM32(0, r);
   802 		GetString(buf1, t1->townnametype);
   802 		GetString(buf1, t1->townnametype);
   803 			
   803 
   804 		// Check size and width
   804 		// Check size and width
   805 		if (strlen(buf1) >= 31 || GetStringWidth(buf1) > 130)
   805 		if (strlen(buf1) >= 31 || GetStringWidth(buf1) > 130)
   806 			continue;
   806 			continue;
   807 
   807 
   808 		FOR_ALL_TOWNS(t2) {
   808 		FOR_ALL_TOWNS(t2) {
   812 				if (str_eq(buf1, buf2))
   812 				if (str_eq(buf1, buf2))
   813 					goto restart;
   813 					goto restart;
   814 			}
   814 			}
   815 		}
   815 		}
   816 		t1->townnameparts = r;
   816 		t1->townnameparts = r;
   817 		
   817 
   818 		return;
   818 		return;
   819 	}
   819 	}
   820 }
   820 }
   821 
   821 
   822 static void UpdateTownMaxPass(Town *t)
   822 static void UpdateTownMaxPass(Town *t)
   866 	t->exclusivity = (byte)-1;
   866 	t->exclusivity = (byte)-1;
   867 	t->exclusive_counter = 0;
   867 	t->exclusive_counter = 0;
   868 	t->statues = 0;
   868 	t->statues = 0;
   869 
   869 
   870 	CreateTownName(t);
   870 	CreateTownName(t);
   871 		
   871 
   872 	UpdateTownVirtCoord(t);
   872 	UpdateTownVirtCoord(t);
   873 	_town_sort_dirty = true;
   873 	_town_sort_dirty = true;
   874 
   874 
   875 	x = (Random() & 0xF) + 8;
   875 	x = (Random() & 0xF) + 8;
   876 	if (_game_mode == GM_EDITOR)
   876 	if (_game_mode == GM_EDITOR)
   904 int32 CmdBuildTown(int x, int y, uint32 flags, uint32 p1, uint32 p2)
   904 int32 CmdBuildTown(int x, int y, uint32 flags, uint32 p1, uint32 p2)
   905 {
   905 {
   906 	uint tile = TILE_FROM_XY(x,y);
   906 	uint tile = TILE_FROM_XY(x,y);
   907 	TileInfo ti;
   907 	TileInfo ti;
   908 	Town *t;
   908 	Town *t;
   909 	
   909 
   910 	SET_EXPENSES_TYPE(EXPENSES_OTHER);
   910 	SET_EXPENSES_TYPE(EXPENSES_OTHER);
   911 
   911 
   912 	// Check if too close to the edge of map
   912 	// Check if too close to the edge of map
   913 	if (!CheckDistanceFromEdge(tile, 12))
   913 	if (!CheckDistanceFromEdge(tile, 12))
   914 		return_cmd_error(STR_0237_TOO_CLOSE_TO_EDGE_OF_MAP);
   914 		return_cmd_error(STR_0237_TOO_CLOSE_TO_EDGE_OF_MAP);
   923 		return_cmd_error(STR_0238_TOO_CLOSE_TO_ANOTHER_TOWN);
   923 		return_cmd_error(STR_0238_TOO_CLOSE_TO_ANOTHER_TOWN);
   924 
   924 
   925 	// Allocate town struct
   925 	// Allocate town struct
   926 	t = AllocateTown();
   926 	t = AllocateTown();
   927 	if (t == NULL)
   927 	if (t == NULL)
   928 		return_cmd_error(STR_023A_TOO_MANY_TOWNS);	
   928 		return_cmd_error(STR_023A_TOO_MANY_TOWNS);
   929 
   929 
   930 	// Create the town
   930 	// Create the town
   931 	if (flags & DC_EXEC) {
   931 	if (flags & DC_EXEC) {
   932 		_generating_world = true;
   932 		_generating_world = true;
   933 		DoCreateTown(t, tile);
   933 		DoCreateTown(t, tile);
   957 			continue;
   957 			continue;
   958 
   958 
   959 		// Check not too close to a town
   959 		// Check not too close to a town
   960 		if (IsCloseToTown(tile, 20))
   960 		if (IsCloseToTown(tile, 20))
   961 			continue;
   961 			continue;
   962 		
   962 
   963 		// Allocate a town struct
   963 		// Allocate a town struct
   964 		t = AllocateTown();
   964 		t = AllocateTown();
   965 		if (t == NULL)
   965 		if (t == NULL)
   966 			break;
   966 			break;
   967 
   967 
  1040 
  1040 
  1041 	for(i=0; i!=4; i++) {
  1041 	for(i=0; i!=4; i++) {
  1042 		tile += _tile_add[i];
  1042 		tile += _tile_add[i];
  1043 
  1043 
  1044 		t = ClosestTownFromTile(tile, (uint)-1);
  1044 		t = ClosestTownFromTile(tile, (uint)-1);
  1045 		if (t1 != t) 
  1045 		if (t1 != t)
  1046 			return false;
  1046 			return false;
  1047 
  1047 
  1048 		if (GetTileSlope(tile, NULL))
  1048 		if (GetTileSlope(tile, NULL))
  1049 			return false;
  1049 			return false;
  1050 
  1050 
  1061 	uint bitmask;
  1061 	uint bitmask;
  1062 	int house;
  1062 	int house;
  1063 	uint slope;
  1063 	uint slope;
  1064 	int z;
  1064 	int z;
  1065 	uint oneof;
  1065 	uint oneof;
  1066 	
  1066 
  1067 	// Above snow?
  1067 	// Above snow?
  1068 	slope = GetTileSlope(tile, &z);
  1068 	slope = GetTileSlope(tile, &z);
  1069 
  1069 
  1070 	// Get the town zone type
  1070 	// Get the town zone type
  1071 	{
  1071 	{
  1108 				continue;
  1108 				continue;
  1109 
  1109 
  1110 			// Make sure there is no slope?
  1110 			// Make sure there is no slope?
  1111 			if (_housetype_extra_flags[house]&0x12 && slope)
  1111 			if (_housetype_extra_flags[house]&0x12 && slope)
  1112 				continue;
  1112 				continue;
  1113 			
  1113 
  1114 			if (_housetype_extra_flags[house]&0x10) {
  1114 			if (_housetype_extra_flags[house]&0x10) {
  1115 				if (CheckFree2x2Area(t,tile) ||
  1115 				if (CheckFree2x2Area(t,tile) ||
  1116 						CheckFree2x2Area(t,(tile+=TILE_XY(-1,0))) ||
  1116 						CheckFree2x2Area(t,(tile+=TILE_XY(-1,0))) ||
  1117 						CheckFree2x2Area(t,(tile+=TILE_XY(0,-1))) ||
  1117 						CheckFree2x2Area(t,(tile+=TILE_XY(0,-1))) ||
  1118 						CheckFree2x2Area(t,(tile+=TILE_XY(1,0))))
  1118 						CheckFree2x2Area(t,(tile+=TILE_XY(1,0))))
  1119 							break;
  1119 							break;
  1120 				tile += TILE_XY(0,1);
  1120 				tile += TILE_XY(0,1);
  1121 			} else if (_housetype_extra_flags[house]&4) {
  1121 			} else if (_housetype_extra_flags[house]&4) {
  1122 				if (CheckBuildHouseMode(t, tile+TILE_XY(1,0), slope, 0))
  1122 				if (CheckBuildHouseMode(t, tile+TILE_XY(1,0), slope, 0))
  1123 					break;
  1123 					break;
  1124 				
  1124 
  1125 				if (CheckBuildHouseMode(t, tile+TILE_XY(-1,0), slope, 1)) {
  1125 				if (CheckBuildHouseMode(t, tile+TILE_XY(-1,0), slope, 1)) {
  1126 					tile += TILE_XY(-1,0);
  1126 					tile += TILE_XY(-1,0);
  1127 					break;
  1127 					break;
  1128 				}
  1128 				}
  1129 			} else if (_housetype_extra_flags[house]&8) {
  1129 			} else if (_housetype_extra_flags[house]&8) {
  1141 
  1141 
  1142 	t->num_houses++;
  1142 	t->num_houses++;
  1143 
  1143 
  1144 	// Special houses that there can be only one of.
  1144 	// Special houses that there can be only one of.
  1145 	t->flags12 |= oneof;
  1145 	t->flags12 |= oneof;
  1146 	
  1146 
  1147 	{
  1147 	{
  1148 		int m3lo,m5,eflags;
  1148 		int m3lo,m5,eflags;
  1149 
  1149 
  1150 		// ENDING_2
  1150 		// ENDING_2
  1151 		m3lo = 0;
  1151 		m3lo = 0;
  1152 		m5 = 0;
  1152 		m5 = 0;
  1153 		if (_generating_world) {
  1153 		if (_generating_world) {
  1154 			uint32 r = Random();
  1154 			uint32 r = Random();
  1155 			
  1155 
  1156 			// Value for map3lo
  1156 			// Value for map3lo
  1157 			m3lo = 0xC0;
  1157 			m3lo = 0xC0;
  1158 			if ((byte)r >= 220) m3lo &= (r>>8);
  1158 			if ((byte)r >= 220) m3lo &= (r>>8);
  1159 
  1159 
  1160 			if (m3lo == 0xC0)
  1160 			if (m3lo == 0xC0)
  1161 				ChangePopulation(t, _housetype_population[house]);
  1161 				ChangePopulation(t, _housetype_population[house]);
  1162 			
  1162 
  1163 			// Initial value for map5.
  1163 			// Initial value for map5.
  1164 			m5 = (r >> 16) & 0x3F;
  1164 			m5 = (r >> 16) & 0x3F;
  1165 		}
  1165 		}
  1166 		
  1166 
  1167 		assert(IS_TILETYPE(tile, MP_CLEAR));
  1167 		assert(IS_TILETYPE(tile, MP_CLEAR));
  1168 
  1168 
  1169 		ModifyTile(tile, 
  1169 		ModifyTile(tile,
  1170 			MP_SETTYPE(MP_HOUSE) | MP_MAP2 | MP_MAP3LO | MP_MAP3HI_CLEAR | MP_MAP5 | MP_MAPOWNER,
  1170 			MP_SETTYPE(MP_HOUSE) | MP_MAP2 | MP_MAP3LO | MP_MAP3HI_CLEAR | MP_MAP5 | MP_MAPOWNER,
  1171 			house, /* map2 */
  1171 			house, /* map2 */
  1172 			m3lo,  /* map3_lo */
  1172 			m3lo,  /* map3_lo */
  1173 			0,     /* map_owner */
  1173 			0,     /* map_owner */
  1174 			m5		 /* map5 */
  1174 			m5		 /* map5 */
  1214 }
  1214 }
  1215 
  1215 
  1216 static bool BuildTownHouse(Town *t, uint tile)
  1216 static bool BuildTownHouse(Town *t, uint tile)
  1217 {
  1217 {
  1218 	int32 r;
  1218 	int32 r;
  1219 		
  1219 
  1220 	// make sure it's possible
  1220 	// make sure it's possible
  1221 	if (!EnsureNoVehicle(tile)) return false;
  1221 	if (!EnsureNoVehicle(tile)) return false;
  1222 	if (GetTileSlope(tile, NULL) & 0x10) return false;
  1222 	if (GetTileSlope(tile, NULL) & 0x10) return false;
  1223 
  1223 
  1224 	r = DoCommandByTile(tile, 0, 0, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_LANDSCAPE_CLEAR);
  1224 	r = DoCommandByTile(tile, 0, 0, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_LANDSCAPE_CLEAR);
  1256 		} else if (_housetype_extra_flags[house-3] & 0x10) {
  1256 		} else if (_housetype_extra_flags[house-3] & 0x10) {
  1257 			house-=3;
  1257 			house-=3;
  1258 			tile += TILE_XY(-1,-1);
  1258 			tile += TILE_XY(-1,-1);
  1259 		}
  1259 		}
  1260 	}
  1260 	}
  1261 		
  1261 
  1262 	// Remove population from the town if the
  1262 	// Remove population from the town if the
  1263 	// house is finished.
  1263 	// house is finished.
  1264 	if ((~_map3_lo[tile] & 0xC0) == 0) {
  1264 	if ((~_map3_lo[tile] & 0xC0) == 0) {
  1265 		ChangePopulation(t, -_housetype_population[house]);
  1265 		ChangePopulation(t, -_housetype_population[house]);
  1266 	}
  1266 	}
  1271 	if (house == 0x5B || house == 0x53 || house == 0x3C ||
  1271 	if (house == 0x5B || house == 0x53 || house == 0x3C ||
  1272 			house == 0x3D || house == 0x03)
  1272 			house == 0x3D || house == 0x03)
  1273 		t->flags12 &= ~2;
  1273 		t->flags12 &= ~2;
  1274 	if (house == 0x14 || house == 0x20)
  1274 	if (house == 0x14 || house == 0x20)
  1275 		t->flags12 &= ~4;
  1275 		t->flags12 &= ~4;
  1276 	
  1276 
  1277 	// Do the actual clearing of tiles
  1277 	// Do the actual clearing of tiles
  1278 	eflags = _housetype_extra_flags[house];
  1278 	eflags = _housetype_extra_flags[house];
  1279 	DoClearTownHouseHelper(tile);
  1279 	DoClearTownHouseHelper(tile);
  1280 	if (eflags & 0x14) DoClearTownHouseHelper(tile + TILE_XY(1,0));
  1280 	if (eflags & 0x14) DoClearTownHouseHelper(tile + TILE_XY(1,0));
  1281 	if (eflags & 0x18) DoClearTownHouseHelper(tile + TILE_XY(0,1));
  1281 	if (eflags & 0x18) DoClearTownHouseHelper(tile + TILE_XY(0,1));
  1284 
  1284 
  1285 int32 CmdRenameTown(int x, int y, uint32 flags, uint32 p1, uint32 p2)
  1285 int32 CmdRenameTown(int x, int y, uint32 flags, uint32 p1, uint32 p2)
  1286 {
  1286 {
  1287 	StringID str;
  1287 	StringID str;
  1288 	Town *t = DEREF_TOWN(p1);
  1288 	Town *t = DEREF_TOWN(p1);
  1289 		
  1289 
  1290 	str = AllocateName((byte*)_decode_parameters, 4);
  1290 	str = AllocateName((byte*)_decode_parameters, 4);
  1291 	if (str == 0)
  1291 	if (str == 0)
  1292 		return CMD_ERROR;
  1292 		return CMD_ERROR;
  1293 
  1293 
  1294 	if (flags & DC_EXEC) {
  1294 	if (flags & DC_EXEC) {
  1347 void ExpandTown(Town *t)
  1347 void ExpandTown(Town *t)
  1348 {
  1348 {
  1349 	int amount, n;
  1349 	int amount, n;
  1350 
  1350 
  1351 	_generating_world = true;
  1351 	_generating_world = true;
  1352 	
  1352 
  1353 	amount = ((int)Random()&3) + 3;
  1353 	amount = ((int)Random()&3) + 3;
  1354 	t->num_houses += amount;
  1354 	t->num_houses += amount;
  1355 	UpdateTownRadius(t);
  1355 	UpdateTownRadius(t);
  1356 
  1356 
  1357 	n = amount * 4;
  1357 	n = amount * 4;
  1372 
  1372 
  1373 static void TownActionAdvertise(Town *t, int action)
  1373 static void TownActionAdvertise(Town *t, int action)
  1374 {
  1374 {
  1375 	static const byte _advertising_amount[3] = {0x40, 0x70, 0xA0};
  1375 	static const byte _advertising_amount[3] = {0x40, 0x70, 0xA0};
  1376 	static const byte _advertising_radius[3] = {10,15,20};
  1376 	static const byte _advertising_radius[3] = {10,15,20};
  1377 	ModifyStationRatingAround(t->xy, _current_player, 
  1377 	ModifyStationRatingAround(t->xy, _current_player,
  1378 		_advertising_amount[action],
  1378 		_advertising_amount[action],
  1379 		_advertising_radius[action]);
  1379 		_advertising_radius[action]);
  1380 }
  1380 }
  1381 
  1381 
  1382 static void TownActionRoadRebuild(Town *t, int action)
  1382 static void TownActionRoadRebuild(Town *t, int action)
  1383 {
  1383 {
  1384 	Player *p;
  1384 	Player *p;
  1385 
  1385 
  1386 	t->road_build_months = 6;
  1386 	t->road_build_months = 6;
  1387 	
  1387 
  1388 	SET_DPARAM16(0, t->index);
  1388 	SET_DPARAM16(0, t->index);
  1389 
  1389 
  1390 	p = DEREF_PLAYER(_current_player);
  1390 	p = DEREF_PLAYER(_current_player);
  1391 	SET_DPARAM16(1, p->name_1);
  1391 	SET_DPARAM16(1, p->name_1);
  1392 	SET_DPARAM32(2, p->name_2);
  1392 	SET_DPARAM32(2, p->name_2);
  1393 
  1393 
  1394 	AddNewsItem(STR_2055_TRAFFIC_CHAOS_IN_ROAD_REBUILDING, 
  1394 	AddNewsItem(STR_2055_TRAFFIC_CHAOS_IN_ROAD_REBUILDING,
  1395 		NEWS_FLAGS(NM_NORMAL, NF_TILE, NT_GENERAL, 0), t->xy, 0);
  1395 		NEWS_FLAGS(NM_NORMAL, NF_TILE, NT_GENERAL, 0), t->xy, 0);
  1396 }
  1396 }
  1397 
  1397 
  1398 static bool DoBuildStatueOfCompany(uint tile)
  1398 static bool DoBuildStatueOfCompany(uint tile)
  1399 {
  1399 {
  1427 static void TownActionBuildStatue(Town *t, int action)
  1427 static void TownActionBuildStatue(Town *t, int action)
  1428 {
  1428 {
  1429 	// Layouted as an outward spiral
  1429 	// Layouted as an outward spiral
  1430 	static const TileIndexDiff _statue_tiles[] = {
  1430 	static const TileIndexDiff _statue_tiles[] = {
  1431 	  TILE_XY(-1,0), TILE_XY(0,1),  TILE_XY(1,0),  TILE_XY(1,0),
  1431 	  TILE_XY(-1,0), TILE_XY(0,1),  TILE_XY(1,0),  TILE_XY(1,0),
  1432 	  TILE_XY(0,-1), TILE_XY(0,-1), TILE_XY(-1,0), TILE_XY(-1,0), 
  1432 	  TILE_XY(0,-1), TILE_XY(0,-1), TILE_XY(-1,0), TILE_XY(-1,0),
  1433 	  TILE_XY(-1,0), TILE_XY(0,1),  TILE_XY(0,1),  TILE_XY(0,1),
  1433 	  TILE_XY(-1,0), TILE_XY(0,1),  TILE_XY(0,1),  TILE_XY(0,1),
  1434 	  TILE_XY(1,0),  TILE_XY(1,0),  TILE_XY(1,0),  TILE_XY(1,0),
  1434 	  TILE_XY(1,0),  TILE_XY(1,0),  TILE_XY(1,0),  TILE_XY(1,0),
  1435 	  TILE_XY(0,-1), TILE_XY(0,-1), TILE_XY(0,-1), TILE_XY(0,-1),
  1435 	  TILE_XY(0,-1), TILE_XY(0,-1), TILE_XY(0,-1), TILE_XY(0,-1),
  1436 	  TILE_XY(-1,0), TILE_XY(-1,0), TILE_XY(-1,0), TILE_XY(-1,0),
  1436 	  TILE_XY(-1,0), TILE_XY(-1,0), TILE_XY(-1,0), TILE_XY(-1,0),
  1437 	  TILE_XY(-1,0), TILE_XY(0,1),  TILE_XY(0,1),  TILE_XY(0,1),
  1437 	  TILE_XY(-1,0), TILE_XY(0,1),  TILE_XY(0,1),  TILE_XY(0,1),
  1438 	  TILE_XY(0,1),  TILE_XY(0,1),  TILE_XY(1,0),  TILE_XY(1,0),
  1438 	  TILE_XY(0,1),  TILE_XY(0,1),  TILE_XY(1,0),  TILE_XY(1,0),
  1439 	  TILE_XY(1,0),  TILE_XY(1,0),  TILE_XY(1,0),  TILE_XY(1,0),
  1439 	  TILE_XY(1,0),  TILE_XY(1,0),  TILE_XY(1,0),  TILE_XY(1,0),
  1440 	  TILE_XY(0,-1), TILE_XY(0,-1), TILE_XY(0,-1), TILE_XY(0,-1), 
  1440 	  TILE_XY(0,-1), TILE_XY(0,-1), TILE_XY(0,-1), TILE_XY(0,-1),
  1441 	  TILE_XY(0,-1), TILE_XY(0,-1), TILE_XY(-1,0), TILE_XY(-1,0),
  1441 	  TILE_XY(0,-1), TILE_XY(0,-1), TILE_XY(-1,0), TILE_XY(-1,0),
  1442 	  TILE_XY(-1,0), TILE_XY(-1,0), TILE_XY(-1,0), TILE_XY(-1,0),
  1442 	  TILE_XY(-1,0), TILE_XY(-1,0), TILE_XY(-1,0), TILE_XY(-1,0),
  1443 	  TILE_XY(-1,0), TILE_XY(0,1),  TILE_XY(0,1),  TILE_XY(0,1),
  1443 	  TILE_XY(-1,0), TILE_XY(0,1),  TILE_XY(0,1),  TILE_XY(0,1),
  1444 	  TILE_XY(0,1),  TILE_XY(0,1),  TILE_XY(0,1),  TILE_XY(0,1),
  1444 	  TILE_XY(0,1),  TILE_XY(0,1),  TILE_XY(0,1),  TILE_XY(0,1),
  1445 	  TILE_XY(1,0),  TILE_XY(1,0),  TILE_XY(1,0),  TILE_XY(1,0),
  1445 	  TILE_XY(1,0),  TILE_XY(1,0),  TILE_XY(1,0),  TILE_XY(1,0),
  1446 	  TILE_XY(1,0),  TILE_XY(1,0),  TILE_XY(1,0),  TILE_XY(1,0),
  1446 	  TILE_XY(1,0),  TILE_XY(1,0),  TILE_XY(1,0),  TILE_XY(1,0),
  1447 	  TILE_XY(0,-1), TILE_XY(0,-1), TILE_XY(0,-1), TILE_XY(0,-1),
  1447 	  TILE_XY(0,-1), TILE_XY(0,-1), TILE_XY(0,-1), TILE_XY(0,-1),
  1448 	  TILE_XY(0,-1), TILE_XY(0,-1), TILE_XY(0,-1), TILE_XY(0,-1), 
  1448 	  TILE_XY(0,-1), TILE_XY(0,-1), TILE_XY(0,-1), TILE_XY(0,-1),
  1449 	  TILE_XY(-1,0), TILE_XY(-1,0), TILE_XY(-1,0), TILE_XY(-1,0),
  1449 	  TILE_XY(-1,0), TILE_XY(-1,0), TILE_XY(-1,0), TILE_XY(-1,0),
  1450 	  TILE_XY(-1,0), TILE_XY(-1,0), TILE_XY(-1,0), TILE_XY(-1,0),
  1450 	  TILE_XY(-1,0), TILE_XY(-1,0), TILE_XY(-1,0), TILE_XY(-1,0),
  1451 	  0,
  1451 	  0,
  1452     };
  1452     };
  1453 	int offs;
  1453 	int offs;
  1655 Town *ClosestTownFromTile(uint tile, uint threshold)
  1655 Town *ClosestTownFromTile(uint tile, uint threshold)
  1656 {
  1656 {
  1657 	Town *t;
  1657 	Town *t;
  1658 	uint dist, best = threshold;
  1658 	uint dist, best = threshold;
  1659 	Town *best_town = NULL;
  1659 	Town *best_town = NULL;
  1660 	
  1660 
  1661 	FOR_ALL_TOWNS(t) {
  1661 	FOR_ALL_TOWNS(t) {
  1662 		if (t->xy != 0) {
  1662 		if (t->xy != 0) {
  1663 			dist = GetTileDist(tile, t->xy);
  1663 			dist = GetTileDist(tile, t->xy);
  1664 			if (dist < best) {
  1664 			if (dist < best) {
  1665 				best = dist;
  1665 				best = dist;
  1678 	//	if magic_bulldozer cheat is active, town doesn't penaltize for removing stuff
  1678 	//	if magic_bulldozer cheat is active, town doesn't penaltize for removing stuff
  1679 	if (t == NULL || _current_player >= MAX_PLAYERS || (_cheats.magic_bulldozer.value && add < 0)	)
  1679 	if (t == NULL || _current_player >= MAX_PLAYERS || (_cheats.magic_bulldozer.value && add < 0)	)
  1680 		return;
  1680 		return;
  1681 
  1681 
  1682 	SETBIT(t->have_ratings, _current_player);
  1682 	SETBIT(t->have_ratings, _current_player);
  1683 	
  1683 
  1684 	rating = t->ratings[_current_player];
  1684 	rating = t->ratings[_current_player];
  1685 	
  1685 
  1686 	if (add < 0) {
  1686 	if (add < 0) {
  1687 		if (rating > max) {
  1687 		if (rating > max) {
  1688 			rating += add;
  1688 			rating += add;
  1689 			if (rating < max) rating = max;
  1689 			if (rating < max) rating = max;
  1690 		}
  1690 		}
  1712 	//	if magic_bulldozer cheat is active, town doesn't restrict your destructive actions
  1712 	//	if magic_bulldozer cheat is active, town doesn't restrict your destructive actions
  1713 	if (t == NULL || _current_player >= MAX_PLAYERS || _cheats.magic_bulldozer.value)
  1713 	if (t == NULL || _current_player >= MAX_PLAYERS || _cheats.magic_bulldozer.value)
  1714 		return true;
  1714 		return true;
  1715 
  1715 
  1716 	/*	check if you're allowed to remove the street/bridge/tunnel/industry
  1716 	/*	check if you're allowed to remove the street/bridge/tunnel/industry
  1717 	 *	owned by a town	no removal if rating is lower than ... depends now on 
  1717 	 *	owned by a town	no removal if rating is lower than ... depends now on
  1718 	 *	difficulty setting. Minimum town rating selected by difficulty level
  1718 	 *	difficulty setting. Minimum town rating selected by difficulty level
  1719 	 */
  1719 	 */
  1720 	modemod = _default_rating_settings[_opt_mod_ptr->diff.town_council_tolerance][type];
  1720 	modemod = _default_rating_settings[_opt_mod_ptr->diff.town_council_tolerance][type];
  1721 
  1721 
  1722 	if (t->ratings[_current_player] < 16 + modemod && !(flags & DC_NO_TOWN_RATING)) {
  1722 	if (t->ratings[_current_player] < 16 + modemod && !(flags & DC_NO_TOWN_RATING)) {
  1783 
  1783 
  1784 
  1784 
  1785 // Save and load of towns.
  1785 // Save and load of towns.
  1786 static const byte _town_desc[] = {
  1786 static const byte _town_desc[] = {
  1787 	SLE_VAR(Town,xy,					SLE_UINT16),
  1787 	SLE_VAR(Town,xy,					SLE_UINT16),
  1788 	
  1788 
  1789 	SLE_CONDVAR(Town,population,	SLE_FILE_U16 | SLE_VAR_U32, 0, 2),
  1789 	SLE_CONDVAR(Town,population,	SLE_FILE_U16 | SLE_VAR_U32, 0, 2),
  1790 	SLE_CONDVAR(Town,population,	SLE_UINT32, 3, 255),
  1790 	SLE_CONDVAR(Town,population,	SLE_UINT32, 3, 255),
  1791 
  1791 
  1792 
  1792 
  1793 	SLE_VAR(Town,num_houses,	SLE_UINT16),
  1793 	SLE_VAR(Town,num_houses,	SLE_UINT16),