src/town_cmd.cpp
branchnoai
changeset 9694 e72987579514
parent 9641 855e32c08c9b
child 9701 d1ac22c62f64
equal deleted inserted replaced
9693:31fcaa5375a1 9694:e72987579514
    38 #include "newgrf.h"
    38 #include "newgrf.h"
    39 #include "newgrf_callbacks.h"
    39 #include "newgrf_callbacks.h"
    40 #include "newgrf_house.h"
    40 #include "newgrf_house.h"
    41 #include "newgrf_commons.h"
    41 #include "newgrf_commons.h"
    42 #include "newgrf_townname.h"
    42 #include "newgrf_townname.h"
    43 
    43 #include "misc/autoptr.hpp"
    44 /**
       
    45  * Called if a new block is added to the town-pool
       
    46  */
       
    47 static void TownPoolNewBlock(uint start_item)
       
    48 {
       
    49 	Town *t;
       
    50 
       
    51 	/* We don't use FOR_ALL here, because FOR_ALL skips invalid items.
       
    52 	 * TODO - This is just a temporary stage, this will be removed. */
       
    53 	for (t = GetTown(start_item); t != NULL; t = (t->index + 1U < GetTownPoolSize()) ? GetTown(t->index + 1U) : NULL) t->index = start_item++;
       
    54 }
       
    55 
    44 
    56 /* Initialize the town-pool */
    45 /* Initialize the town-pool */
    57 DEFINE_OLD_POOL(Town, Town, TownPoolNewBlock, NULL)
    46 DEFINE_OLD_POOL_GENERIC(Town, Town)
    58 
    47 
    59 /**
    48 Town::Town(TileIndex tile)
    60  * Removes a specific town as well as all industries
    49 {
    61  * under its "juridiction"
    50 	this->xy = tile;
    62  * @param t Town to remove
    51 }
    63  */
    52 
    64 void DestroyTown(Town *t)
    53 Town::~Town()
    65 {
    54 {
    66 	Industry *i;
    55 	Industry *i;
    67 	TileIndex tile;
       
    68 
    56 
    69 	/* Delete town authority window
    57 	/* Delete town authority window
    70 	 * and remove from list of sorted towns */
    58 	 * and remove from list of sorted towns */
    71 	DeleteWindowById(WC_TOWN_VIEW, t->index);
    59 	DeleteWindowById(WC_TOWN_VIEW, this->index);
    72 	_town_sort_dirty = true;
    60 	_town_sort_dirty = true;
    73 	_total_towns--;
    61 	_total_towns--;
    74 
    62 
    75 	/* Delete all industries belonging to the town */
    63 	/* Delete all industries belonging to the town */
    76 	FOR_ALL_INDUSTRIES(i) if (i->town == t) DeleteIndustry(i);
    64 	FOR_ALL_INDUSTRIES(i) if (i->town == this) delete i;
    77 
    65 
    78 	/* Go through all tiles and delete those belonging to the town */
    66 	/* Go through all tiles and delete those belonging to the town */
    79 	for (tile = 0; tile < MapSize(); ++tile) {
    67 	for (TileIndex tile = 0; tile < MapSize(); ++tile) {
    80 		switch (GetTileType(tile)) {
    68 		switch (GetTileType(tile)) {
    81 			case MP_HOUSE:
    69 			case MP_HOUSE:
    82 				if (GetTownByTile(tile) == t) DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
    70 				if (GetTownByTile(tile) == this) DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
    83 				break;
    71 				break;
    84 
    72 
    85 			case MP_STREET:
    73 			case MP_ROAD:
    86 			case MP_TUNNELBRIDGE:
    74 			case MP_TUNNELBRIDGE:
    87 				if (IsTileOwner(tile, OWNER_TOWN) &&
    75 				if (IsTileOwner(tile, OWNER_TOWN) &&
    88 						ClosestTownFromTile(tile, (uint)-1) == t)
    76 						ClosestTownFromTile(tile, (uint)-1) == this)
    89 					DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
    77 					DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
    90 				break;
    78 				break;
    91 
    79 
    92 			default:
    80 			default:
    93 				break;
    81 				break;
    94 		}
    82 		}
    95 	}
    83 	}
    96 
    84 
    97 	DeleteName(t->townnametype);
    85 	DeleteSubsidyWithTown(this->index);
    98 	DeleteSubsidyWithTown(t->index);
       
    99 
    86 
   100 	MarkWholeScreenDirty();
    87 	MarkWholeScreenDirty();
       
    88 
       
    89 	this->QuickFree();
       
    90 	this->xy = 0;
       
    91 }
       
    92 
       
    93 void Town::QuickFree()
       
    94 {
       
    95 	DeleteName(this->townnametype);
   101 }
    96 }
   102 
    97 
   103 // Local
    98 // Local
   104 static int _grow_town_result;
    99 static int _grow_town_result;
   105 
   100 
   152 	}
   147 	}
   153 
   148 
   154 	/* Retrieve pointer to the draw town tile struct */
   149 	/* Retrieve pointer to the draw town tile struct */
   155 	dcts = &_town_draw_tile_data[house_id << 4 | OriginalTileRandomiser(ti->x, ti->y) << 2 | GetHouseBuildingStage(ti->tile)];
   150 	dcts = &_town_draw_tile_data[house_id << 4 | OriginalTileRandomiser(ti->x, ti->y) << 2 | GetHouseBuildingStage(ti->tile)];
   156 
   151 
   157 	if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, ti->tileh);
   152 	if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, FOUNDATION_LEVELED);
   158 
   153 
   159 	image = dcts->ground.sprite;
   154 	image = dcts->ground.sprite;
   160 	pal   = dcts->ground.pal;
   155 	pal   = dcts->ground.pal;
   161 	DrawGroundSprite(image, pal);
   156 	DrawGroundSprite(image, pal);
   162 
   157 
   163 	/* Add a house on top of the ground? */
   158 	/* Add a house on top of the ground? */
   164 	image = dcts->building.sprite;
   159 	image = dcts->building.sprite;
   165 	if (image != 0) {
   160 	if (image != 0) {
   166 		if (HASBIT(_transparent_opt, TO_HOUSES)) {
   161 		AddSortableSpriteToDraw(image, dcts->building.pal,
   167 			SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
       
   168 			pal = PALETTE_TO_TRANSPARENT;
       
   169 		} else {
       
   170 			pal = dcts->building.pal;
       
   171 		}
       
   172 
       
   173 		AddSortableSpriteToDraw(image, pal,
       
   174 			ti->x + dcts->subtile_x,
   162 			ti->x + dcts->subtile_x,
   175 			ti->y + dcts->subtile_y,
   163 			ti->y + dcts->subtile_y,
   176 			dcts->width + 1,
   164 			dcts->width + 1,
   177 			dcts->height + 1,
   165 			dcts->height + 1,
   178 			dcts->dz,
   166 			dcts->dz,
   179 			ti->z
   167 			ti->z,
       
   168 			HASBIT(_transparent_opt, TO_HOUSES)
   180 		);
   169 		);
   181 
   170 
   182 		if (HASBIT(_transparent_opt, TO_HOUSES)) return;
   171 		if (HASBIT(_transparent_opt, TO_HOUSES)) return;
   183 	}
   172 	}
   184 
   173 
   192 static uint GetSlopeZ_Town(TileIndex tile, uint x, uint y)
   181 static uint GetSlopeZ_Town(TileIndex tile, uint x, uint y)
   193 {
   182 {
   194 	return GetTileMaxZ(tile);
   183 	return GetTileMaxZ(tile);
   195 }
   184 }
   196 
   185 
   197 static Slope GetSlopeTileh_Town(TileIndex tile, Slope tileh)
   186 static Foundation GetFoundation_Town(TileIndex tile, Slope tileh)
   198 {
   187 {
   199 	return SLOPE_FLAT;
   188 	return FlatteningFoundation(tileh);
   200 }
   189 }
   201 
   190 
   202 /**
   191 /**
   203  * Animate a tile for a town
   192  * Animate a tile for a town
   204  * Only certain houses can be animated
   193  * Only certain houses can be animated
  1155 		/* Select a random bit from the blockmask, walk a step
  1144 		/* Select a random bit from the blockmask, walk a step
  1156 		 * and continue the search from there. */
  1145 		 * and continue the search from there. */
  1157 		do block = Random() & 3; while (!HASBIT(mask, block));
  1146 		do block = Random() & 3; while (!HASBIT(mask, block));
  1158 		tile += ToTileIndexDiff(_roadblock_tileadd[block]);
  1147 		tile += ToTileIndexDiff(_roadblock_tileadd[block]);
  1159 
  1148 
  1160 		if (IsTileType(tile, MP_STREET)) {
  1149 		if (IsTileType(tile, MP_ROAD)) {
  1161 			/* Don't allow building over roads of other cities */
  1150 			/* Don't allow building over roads of other cities */
  1162 			if (IsTileOwner(tile, OWNER_TOWN) && GetTownByTile(tile) != t) {
  1151 			if (IsTileOwner(tile, OWNER_TOWN) && GetTownByTile(tile) != t) {
  1163 				_grow_town_result = -1;
  1152 				_grow_town_result = -1;
  1164 			} else if (_game_mode == GM_EDITOR) {
  1153 			} else if (_game_mode == GM_EDITOR) {
  1165 				/* If we are in the SE, and this road-piece has no town owner yet, it just found an
  1154 				/* If we are in the SE, and this road-piece has no town owner yet, it just found an
  1363 static void DoCreateTown(Town *t, TileIndex tile, uint32 townnameparts, TownSizeMode size_mode, uint size)
  1352 static void DoCreateTown(Town *t, TileIndex tile, uint32 townnameparts, TownSizeMode size_mode, uint size)
  1364 {
  1353 {
  1365 	extern int _nb_orig_names;
  1354 	extern int _nb_orig_names;
  1366 	int x, i;
  1355 	int x, i;
  1367 
  1356 
  1368 	/* clear the town struct */
       
  1369 	i = t->index;
       
  1370 	memset(t, 0, sizeof(Town));
       
  1371 	t->index = i;
       
  1372 	_total_towns++;
  1357 	_total_towns++;
  1373 
  1358 
  1374 	t->xy = tile;
  1359 	t->xy = tile;
  1375 	t->num_houses = 0;
  1360 	t->num_houses = 0;
  1376 	t->time_until_rebuild = 10;
  1361 	t->time_until_rebuild = 10;
  1450 	t->num_houses -= x;
  1435 	t->num_houses -= x;
  1451 	UpdateTownRadius(t);
  1436 	UpdateTownRadius(t);
  1452 	UpdateTownMaxPass(t);
  1437 	UpdateTownMaxPass(t);
  1453 }
  1438 }
  1454 
  1439 
  1455 static Town *AllocateTown()
       
  1456 {
       
  1457 	Town *t;
       
  1458 
       
  1459 	/* We don't use FOR_ALL here, because FOR_ALL skips invalid items.
       
  1460 	 * TODO - This is just a temporary stage, this will be removed. */
       
  1461 	for (t = GetTown(0); t != NULL; t = (t->index + 1U < GetTownPoolSize()) ? GetTown(t->index + 1U) : NULL) {
       
  1462 		if (!IsValidTown(t)) {
       
  1463 			TownID index = t->index;
       
  1464 
       
  1465 			memset(t, 0, sizeof(Town));
       
  1466 			t->index = index;
       
  1467 
       
  1468 			return t;
       
  1469 		}
       
  1470 	}
       
  1471 
       
  1472 	/* Check if we can add a block to the pool */
       
  1473 	if (AddBlockToPool(&_Town_pool))
       
  1474 		return AllocateTown();
       
  1475 
       
  1476 	return NULL;
       
  1477 }
       
  1478 
       
  1479 /** Create a new town.
  1440 /** Create a new town.
  1480  * This obviously only works in the scenario editor. Function not removed
  1441  * This obviously only works in the scenario editor. Function not removed
  1481  * as it might be possible in the future to fund your own town :)
  1442  * as it might be possible in the future to fund your own town :)
  1482  * @param tile coordinates where town is built
  1443  * @param tile coordinates where town is built
  1483  * @param flags type of operation
  1444  * @param flags type of operation
  1484  * @param p1 size of the town (0 = small, 1 = medium, 2 = large)
  1445  * @param p1 size of the town (0 = small, 1 = medium, 2 = large)
  1485  * @param p2 size mode (@see TownSizeMode)
  1446  * @param p2 size mode (@see TownSizeMode)
  1486  */
  1447  */
  1487 CommandCost CmdBuildTown(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1448 CommandCost CmdBuildTown(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1488 {
  1449 {
  1489 	Town *t;
       
  1490 	uint32 townnameparts;
  1450 	uint32 townnameparts;
  1491 
  1451 
  1492 	/* Only in the scenario editor */
  1452 	/* Only in the scenario editor */
  1493 	if (_game_mode != GM_EDITOR) return CMD_ERROR;
  1453 	if (_game_mode != GM_EDITOR) return CMD_ERROR;
  1494 	if (p2 > TSM_CITY) return CMD_ERROR;
  1454 	if (p2 > TSM_CITY) return CMD_ERROR;
  1511 	/* Get a unique name for the town. */
  1471 	/* Get a unique name for the town. */
  1512 	if (!CreateTownName(&townnameparts))
  1472 	if (!CreateTownName(&townnameparts))
  1513 		return_cmd_error(STR_023A_TOO_MANY_TOWNS);
  1473 		return_cmd_error(STR_023A_TOO_MANY_TOWNS);
  1514 
  1474 
  1515 	/* Allocate town struct */
  1475 	/* Allocate town struct */
  1516 	t = AllocateTown();
  1476 	Town *t = new Town(tile);
  1517 	if (t == NULL) return_cmd_error(STR_023A_TOO_MANY_TOWNS);
  1477 	if (t == NULL) return_cmd_error(STR_023A_TOO_MANY_TOWNS);
       
  1478 	AutoPtrT<Town> t_auto_delete = t;
  1518 
  1479 
  1519 	/* Create the town */
  1480 	/* Create the town */
  1520 	if (flags & DC_EXEC) {
  1481 	if (flags & DC_EXEC) {
  1521 		_generating_world = true;
  1482 		_generating_world = true;
  1522 		DoCreateTown(t, tile, townnameparts, (TownSizeMode)p2, p1);
  1483 		DoCreateTown(t, tile, townnameparts, (TownSizeMode)p2, p1);
  1523 		_generating_world = false;
  1484 		_generating_world = false;
       
  1485 		t_auto_delete.Detach();
  1524 	}
  1486 	}
  1525 	return CommandCost();
  1487 	return CommandCost();
  1526 }
  1488 }
  1527 
  1489 
  1528 Town *CreateRandomTown(uint attempts, TownSizeMode mode, uint size)
  1490 Town *CreateRandomTown(uint attempts, TownSizeMode mode, uint size)
  1544 
  1506 
  1545 		/* Get a unique name for the town. */
  1507 		/* Get a unique name for the town. */
  1546 		if (!CreateTownName(&townnameparts)) break;
  1508 		if (!CreateTownName(&townnameparts)) break;
  1547 
  1509 
  1548 		/* Allocate a town struct */
  1510 		/* Allocate a town struct */
  1549 		t = AllocateTown();
  1511 		t = new Town(tile);
  1550 		if (t == NULL) break;
  1512 		if (t == NULL) break;
  1551 
  1513 
  1552 		DoCreateTown(t, tile, townnameparts, mode, size);
  1514 		DoCreateTown(t, tile, townnameparts, mode, size);
  1553 		return t;
  1515 		return t;
  1554 	} while (--attempts);
  1516 	} while (--attempts);
  2237 
  2199 
  2238 
  2200 
  2239 Town *ClosestTownFromTile(TileIndex tile, uint threshold)
  2201 Town *ClosestTownFromTile(TileIndex tile, uint threshold)
  2240 {
  2202 {
  2241 	if (IsTileType(tile, MP_HOUSE) || (
  2203 	if (IsTileType(tile, MP_HOUSE) || (
  2242 				IsTileType(tile, MP_STREET) &&
  2204 				IsTileType(tile, MP_ROAD) &&
  2243 				GetRoadOwner(tile, ROADTYPE_ROAD) == OWNER_TOWN
  2205 				GetRoadOwner(tile, ROADTYPE_ROAD) == OWNER_TOWN
  2244 			)) {
  2206 			)) {
  2245 		return GetTownByTile(tile);
  2207 		return GetTownByTile(tile);
  2246 	} else {
  2208 	} else {
  2247 		return CalcClosestTownFromTile(tile, threshold);
  2209 		return CalcClosestTownFromTile(tile, threshold);
  2328 void InitializeTowns()
  2290 void InitializeTowns()
  2329 {
  2291 {
  2330 	Subsidy *s;
  2292 	Subsidy *s;
  2331 
  2293 
  2332 	/* Clean the town pool and create 1 block in it */
  2294 	/* Clean the town pool and create 1 block in it */
  2333 	CleanPool(&_Town_pool);
  2295 	_Town_pool.CleanPool();
  2334 	AddBlockToPool(&_Town_pool);
  2296 	_Town_pool.AddBlockToPool();
  2335 
  2297 
  2336 	memset(_subsidies, 0, sizeof(_subsidies));
  2298 	memset(_subsidies, 0, sizeof(_subsidies));
  2337 	for (s=_subsidies; s != endof(_subsidies); s++)
  2299 	for (s=_subsidies; s != endof(_subsidies); s++)
  2338 		s->cargo_type = CT_INVALID;
  2300 		s->cargo_type = CT_INVALID;
  2339 
  2301 
  2354 	AnimateTile_Town,        /* animate_tile_proc */
  2316 	AnimateTile_Town,        /* animate_tile_proc */
  2355 	TileLoop_Town,           /* tile_loop_clear */
  2317 	TileLoop_Town,           /* tile_loop_clear */
  2356 	ChangeTileOwner_Town,    /* change_tile_owner_clear */
  2318 	ChangeTileOwner_Town,    /* change_tile_owner_clear */
  2357 	NULL,                    /* get_produced_cargo_proc */
  2319 	NULL,                    /* get_produced_cargo_proc */
  2358 	NULL,                    /* vehicle_enter_tile_proc */
  2320 	NULL,                    /* vehicle_enter_tile_proc */
  2359 	GetSlopeTileh_Town,      /* get_slope_tileh_proc */
  2321 	GetFoundation_Town,      /* get_foundation_proc */
  2360 };
  2322 };
  2361 
  2323 
  2362 
  2324 
  2363 /** Save and load of towns. */
  2325 /** Save and load of towns. */
  2364 static const SaveLoad _town_desc[] = {
  2326 static const SaveLoad _town_desc[] = {
  2480 	int index;
  2442 	int index;
  2481 
  2443 
  2482 	_total_towns = 0;
  2444 	_total_towns = 0;
  2483 
  2445 
  2484 	while ((index = SlIterateArray()) != -1) {
  2446 	while ((index = SlIterateArray()) != -1) {
  2485 		Town *t;
  2447 		Town *t = new (index) Town();
  2486 
       
  2487 		if (!AddBlockIfNeeded(&_Town_pool, index))
       
  2488 			error("Towns: failed loading savegame: too many towns");
       
  2489 
       
  2490 		t = GetTown(index);
       
  2491 		SlObject(t, _town_desc);
  2448 		SlObject(t, _town_desc);
  2492 
  2449 
  2493 		_total_towns++;
  2450 		_total_towns++;
  2494 	}
  2451 	}
  2495 
  2452