town_cmd.c
changeset 2049 538e73c53f54
parent 1981 3c9c682f1212
child 2051 e369160ce2f3
equal deleted inserted replaced
2048:54fd558314dc 2049:538e73c53f54
    71 #include "table/town_land.h"
    71 #include "table/town_land.h"
    72 
    72 
    73 
    73 
    74 static void TownDrawTileProc1(TileInfo *ti)
    74 static void TownDrawTileProc1(TileInfo *ti)
    75 {
    75 {
    76 	AddChildSpriteScreen(0x5A3, 0xE, 0x3C - (_map_owner[ti->tile]&0x7F));
    76 	AddChildSpriteScreen(0x5A3, 0xE, 0x3C - (_m[ti->tile].owner&0x7F));
    77 }
    77 }
    78 
    78 
    79 typedef void TownDrawTileProc(TileInfo *ti);
    79 typedef void TownDrawTileProc(TileInfo *ti);
    80 static TownDrawTileProc * const _town_draw_tile_procs[1] = {
    80 static TownDrawTileProc * const _town_draw_tile_procs[1] = {
    81 	TownDrawTileProc1
    81 	TownDrawTileProc1
    89 	uint32 image;
    89 	uint32 image;
    90 
    90 
    91 	/* Retrieve pointer to the draw town tile struct */
    91 	/* Retrieve pointer to the draw town tile struct */
    92 	{
    92 	{
    93 		/* this "randomizes" on the (up to) 4 variants of a building */
    93 		/* this "randomizes" on the (up to) 4 variants of a building */
    94 		byte gfx   = (byte)_map3_hi[ti->tile];
    94 		byte gfx   = (byte)_m[ti->tile].m4;
    95 		byte stage = _map3_lo[ti->tile] >> 6;
    95 		byte stage = _m[ti->tile].m3 >> 6;
    96 		uint variant;
    96 		uint variant;
    97 		variant  = ti->x >> 4;
    97 		variant  = ti->x >> 4;
    98 		variant ^= ti->x >> 6;
    98 		variant ^= ti->x >> 6;
    99 		variant ^= ti->y >> 4;
    99 		variant ^= ti->y >> 4;
   100 		variant -= ti->y >> 6;
   100 		variant -= ti->y >> 6;
   157 	int a,b;
   157 	int a,b;
   158 
   158 
   159 	if (_tick_counter & 3)
   159 	if (_tick_counter & 3)
   160 		return;
   160 		return;
   161 
   161 
   162 	if (_map3_hi[tile] != 4 && _map3_hi[tile] != 5)
   162 	if (_m[tile].m4 != 4 && _m[tile].m4 != 5)
   163 		return;
   163 		return;
   164 
   164 
   165 	if (!((old=_map_owner[tile])&0x80)) {
   165 	if (!((old=_m[tile].owner)&0x80)) {
   166 		_map_owner[tile] |= 0x80;
   166 		_m[tile].owner |= 0x80;
   167 
   167 
   168 		do {
   168 		do {
   169 			i = (Random()&7) - 1;
   169 			i = (Random()&7) - 1;
   170 		} while (i < 0 || i == 1 || i*6==old);
   170 		} while (i < 0 || i == 1 || i*6==old);
   171 
   171 
   172 		_map5[tile] = (_map5[tile] & ~0x3F) | i;
   172 		_m[tile].m5 = (_m[tile].m5 & ~0x3F) | i;
   173 	}
   173 	}
   174 
   174 
   175 	a = _map_owner[tile]&0x7F;
   175 	a = _m[tile].owner&0x7F;
   176 	b = (_map5[tile]&0x3F) * 6;
   176 	b = (_m[tile].m5&0x3F) * 6;
   177 	a += (a < b) ? 1 : -1;
   177 	a += (a < b) ? 1 : -1;
   178 	_map_owner[tile] = (_map_owner[tile]&0x80)|a;
   178 	_m[tile].owner = (_m[tile].owner&0x80)|a;
   179 
   179 
   180 	if (a == b) {
   180 	if (a == b) {
   181 		_map5[tile] &= 0x40;
   181 		_m[tile].m5 &= 0x40;
   182 		_map_owner[tile] &= 0x7F;
   182 		_m[tile].owner &= 0x7F;
   183 		DeleteAnimatedTile(tile);
   183 		DeleteAnimatedTile(tile);
   184 	}
   184 	}
   185 
   185 
   186 	MarkTileDirtyByTile(tile);
   186 	MarkTileDirtyByTile(tile);
   187 }
   187 }
   246 {
   246 {
   247 	byte b;
   247 	byte b;
   248 
   248 
   249 	assert(IsTileType(tile, MP_HOUSE));
   249 	assert(IsTileType(tile, MP_HOUSE));
   250 
   250 
   251 	b = _map5[tile];
   251 	b = _m[tile].m5;
   252 	if (b & 0x80)
   252 	if (b & 0x80)
   253 		return;
   253 		return;
   254 
   254 
   255 	_map5[tile] = (b & 0xC0) | ((b+1)&7);
   255 	_m[tile].m5 = (b & 0xC0) | ((b+1)&7);
   256 
   256 
   257 	if ((_map5[tile]&7) != 0)
   257 	if ((_m[tile].m5&7) != 0)
   258 		return;
   258 		return;
   259 
   259 
   260 	_map3_lo[tile] = _map3_lo[tile] + 0x40;
   260 	_m[tile].m3 = _m[tile].m3 + 0x40;
   261 
   261 
   262 	if ( (_map3_lo[tile] & 0xC0) == 0xC0) {
   262 	if ( (_m[tile].m3 & 0xC0) == 0xC0) {
   263 		ChangePopulation(GetTown(_map2[tile]), _housetype_population[_map3_hi[tile]]);
   263 		ChangePopulation(GetTown(_m[tile].m2), _housetype_population[_m[tile].m4]);
   264 	}
   264 	}
   265 	MarkTileDirtyByTile(tile);
   265 	MarkTileDirtyByTile(tile);
   266 }
   266 }
   267 
   267 
   268 static void MakeTownHouseBigger(TileIndex tile)
   268 static void MakeTownHouseBigger(TileIndex tile)
   269 {
   269 {
   270 	uint flags = _house_more_flags[_map3_hi[tile]];
   270 	uint flags = _house_more_flags[_m[tile].m4];
   271 	if (flags & 8) MakeSingleHouseBigger(TILE_ADDXY(tile, 0, 0));
   271 	if (flags & 8) MakeSingleHouseBigger(TILE_ADDXY(tile, 0, 0));
   272 	if (flags & 4) MakeSingleHouseBigger(TILE_ADDXY(tile, 0, 1));
   272 	if (flags & 4) MakeSingleHouseBigger(TILE_ADDXY(tile, 0, 1));
   273 	if (flags & 2) MakeSingleHouseBigger(TILE_ADDXY(tile, 1, 0));
   273 	if (flags & 2) MakeSingleHouseBigger(TILE_ADDXY(tile, 1, 0));
   274 	if (flags & 1) MakeSingleHouseBigger(TILE_ADDXY(tile, 1, 1));
   274 	if (flags & 1) MakeSingleHouseBigger(TILE_ADDXY(tile, 1, 1));
   275 }
   275 }
   278 {
   278 {
   279 	int house;
   279 	int house;
   280 	Town *t;
   280 	Town *t;
   281 	uint32 r;
   281 	uint32 r;
   282 
   282 
   283 	if ((_map3_lo[tile] & 0xC0) != 0xC0) {
   283 	if ((_m[tile].m3 & 0xC0) != 0xC0) {
   284 		MakeTownHouseBigger(tile);
   284 		MakeTownHouseBigger(tile);
   285 		return;
   285 		return;
   286 	}
   286 	}
   287 
   287 
   288 	house = _map3_hi[tile];
   288 	house = _m[tile].m4;
   289 	if (_housetype_extra_flags[house] & 0x20 &&
   289 	if (_housetype_extra_flags[house] & 0x20 &&
   290 			!(_map5[tile] & 0x80) &&
   290 			!(_m[tile].m5 & 0x80) &&
   291 			CHANCE16(1,2) &&
   291 			CHANCE16(1,2) &&
   292 			AddAnimatedTile(tile)) {
   292 			AddAnimatedTile(tile)) {
   293 		_map5[tile] = (_map5[tile] & 0x40)|0x80;
   293 		_m[tile].m5 = (_m[tile].m5 & 0x40)|0x80;
   294 	}
   294 	}
   295 
   295 
   296 	t = GetTown(_map2[tile]);
   296 	t = GetTown(_m[tile].m2);
   297 
   297 
   298 	r = Random();
   298 	r = Random();
   299 
   299 
   300 	if ( (byte)r < _housetype_population[house] ) {
   300 	if ( (byte)r < _housetype_population[house] ) {
   301 		uint amt = ((byte)r >> 3) + 1, moved;
   301 		uint amt = ((byte)r >> 3) + 1, moved;
   343 
   343 
   344 	// safety checks
   344 	// safety checks
   345 	if (!EnsureNoVehicle(tile)) return CMD_ERROR;
   345 	if (!EnsureNoVehicle(tile)) return CMD_ERROR;
   346 	if (flags&DC_AUTO && !(flags&DC_AI_BUILDING)) return_cmd_error(STR_2004_BUILDING_MUST_BE_DEMOLISHED);
   346 	if (flags&DC_AUTO && !(flags&DC_AI_BUILDING)) return_cmd_error(STR_2004_BUILDING_MUST_BE_DEMOLISHED);
   347 
   347 
   348 	house = _map3_hi[tile];
   348 	house = _m[tile].m4;
   349 	cost = _price.remove_house * _housetype_remove_cost[house] >> 8;
   349 	cost = _price.remove_house * _housetype_remove_cost[house] >> 8;
   350 
   350 
   351 	rating = _housetype_remove_ratingmod[house];
   351 	rating = _housetype_remove_ratingmod[house];
   352 	_cleared_town_rating += rating;
   352 	_cleared_town_rating += rating;
   353 	_cleared_town = t = GetTown(_map2[tile]);
   353 	_cleared_town = t = GetTown(_m[tile].m2);
   354 
   354 
   355 	if (_current_player < MAX_PLAYERS) {
   355 	if (_current_player < MAX_PLAYERS) {
   356 		if (rating > t->ratings[_current_player] && !(flags & DC_NO_TOWN_RATING) && !_cheats.magic_bulldozer.value) {
   356 		if (rating > t->ratings[_current_player] && !(flags & DC_NO_TOWN_RATING) && !_cheats.magic_bulldozer.value) {
   357 			SetDParam(0, t->index);
   357 			SetDParam(0, t->index);
   358 			return_cmd_error(STR_2009_LOCAL_AUTHORITY_REFUSES);
   358 			return_cmd_error(STR_2009_LOCAL_AUTHORITY_REFUSES);
   367 	return cost;
   367 	return cost;
   368 }
   368 }
   369 
   369 
   370 static void GetAcceptedCargo_Town(TileIndex tile, AcceptedCargo ac)
   370 static void GetAcceptedCargo_Town(TileIndex tile, AcceptedCargo ac)
   371 {
   371 {
   372 	int type = _map3_hi[tile];
   372 	int type = _m[tile].m4;
   373 
   373 
   374 	ac[CT_PASSENGERS] = _housetype_cargo_passengers[type];
   374 	ac[CT_PASSENGERS] = _housetype_cargo_passengers[type];
   375 	ac[CT_MAIL] = _housetype_cargo_mail[type];
   375 	ac[CT_MAIL] = _housetype_cargo_mail[type];
   376 	ac[CT_GOODS] = _housetype_cargo_goods[type];
   376 	ac[CT_GOODS] = _housetype_cargo_goods[type];
   377 	ac[CT_FOOD] = _housetype_cargo_food[type];
   377 	ac[CT_FOOD] = _housetype_cargo_food[type];
   378 }
   378 }
   379 
   379 
   380 static void GetTileDesc_Town(TileIndex tile, TileDesc *td)
   380 static void GetTileDesc_Town(TileIndex tile, TileDesc *td)
   381 {
   381 {
   382 	td->str = _town_tile_names[_map3_hi[tile]];
   382 	td->str = _town_tile_names[_m[tile].m4];
   383 	if ((_map3_lo[tile] & 0xC0) != 0xC0) {
   383 	if ((_m[tile].m3 & 0xC0) != 0xC0) {
   384 		SetDParamX(td->dparam, 0, td->str);
   384 		SetDParamX(td->dparam, 0, td->str);
   385 		td->str = STR_2058_UNDER_CONSTRUCTION;
   385 		td->str = STR_2058_UNDER_CONSTRUCTION;
   386 	}
   386 	}
   387 
   387 
   388 	td->owner = OWNER_TOWN;
   388 	td->owner = OWNER_TOWN;
   556 	if (!TerraformTownTile(tile, ~ti.tileh & 0xF, 1)) {
   556 	if (!TerraformTownTile(tile, ~ti.tileh & 0xF, 1)) {
   557 		TerraformTownTile(tile, ti.tileh & 0xF, 0);
   557 		TerraformTownTile(tile, ti.tileh & 0xF, 0);
   558 	}
   558 	}
   559 }
   559 }
   560 
   560 
   561 #define IS_WATER_TILE(t) (IsTileType((t), MP_WATER) && _map5[(t)] == 0)
   561 #define IS_WATER_TILE(t) (IsTileType((t), MP_WATER) && _m[(t)].m5 == 0)
   562 
   562 
   563 static void GrowTownInTile(TileIndex *tile_ptr, uint mask, int block, Town *t1)
   563 static void GrowTownInTile(TileIndex *tile_ptr, uint mask, int block, Town *t1)
   564 {
   564 {
   565 	uint16 r;
   565 	uint16 r;
   566 	int a,b,rcmd;
   566 	int a,b,rcmd;
   614 		_grow_town_result = 0;
   614 		_grow_town_result = 0;
   615 		rcmd = 1 << (block^2);
   615 		rcmd = 1 << (block^2);
   616 	} else {
   616 	} else {
   617 
   617 
   618 		// Reached a tunnel? Then continue at the other side of it.
   618 		// Reached a tunnel? Then continue at the other side of it.
   619 		if (IsTileType(tile, MP_TUNNELBRIDGE) && (_map5[tile]& ~3) == 4) {
   619 		if (IsTileType(tile, MP_TUNNELBRIDGE) && (_m[tile].m5& ~3) == 4) {
   620 			FindLengthOfTunnelResult flotr = FindLengthOfTunnel(tile, _map5[tile]&3);
   620 			FindLengthOfTunnelResult flotr = FindLengthOfTunnel(tile, _m[tile].m5&3);
   621 			*tile_ptr = flotr.tile;
   621 			*tile_ptr = flotr.tile;
   622 			return;
   622 			return;
   623 		}
   623 		}
   624 
   624 
   625 		// For any other kind of tunnel/bridge, bail out.
   625 		// For any other kind of tunnel/bridge, bail out.
   739 		do block = Random() & 3; while (!HASBIT(mask,block));
   739 		do block = Random() & 3; while (!HASBIT(mask,block));
   740 		tile += ToTileIndexDiff(_roadblock_tileadd[block]);
   740 		tile += ToTileIndexDiff(_roadblock_tileadd[block]);
   741 
   741 
   742 		if (IsTileType(tile, MP_STREET)) {
   742 		if (IsTileType(tile, MP_STREET)) {
   743 			/* Don't allow building over roads of other cities */
   743 			/* Don't allow building over roads of other cities */
   744 			if (IsTileOwner(tile, OWNER_TOWN) && GetTown(_map2[tile]) != t)
   744 			if (IsTileOwner(tile, OWNER_TOWN) && GetTown(_m[tile].m2) != t)
   745 				_grow_town_result = -1;
   745 				_grow_town_result = -1;
   746 			else if (_game_mode == GM_EDITOR) {
   746 			else if (_game_mode == GM_EDITOR) {
   747 				/* If we are in the SE, and this road-piece has no town owner yet, it just found an
   747 				/* If we are in the SE, and this road-piece has no town owner yet, it just found an
   748 				*  owner :) (happy happy happy road now) */
   748 				*  owner :) (happy happy happy road now) */
   749 				SetTileOwner(tile, OWNER_TOWN);
   749 				SetTileOwner(tile, OWNER_TOWN);
   750 				_map2[tile] = t->index;
   750 				_m[tile].m2 = t->index;
   751 			}
   751 			}
   752 		}
   752 		}
   753 
   753 
   754 		// Max number of times is checked.
   754 		// Max number of times is checked.
   755 	} while (--_grow_town_result >= 0);
   755 	} while (--_grow_town_result >= 0);
  1380 	DeleteAnimatedTile(tile);
  1380 	DeleteAnimatedTile(tile);
  1381 }
  1381 }
  1382 
  1382 
  1383 static void ClearTownHouse(Town *t, TileIndex tile)
  1383 static void ClearTownHouse(Town *t, TileIndex tile)
  1384 {
  1384 {
  1385 	uint house = _map3_hi[tile];
  1385 	uint house = _m[tile].m4;
  1386 	uint eflags;
  1386 	uint eflags;
  1387 
  1387 
  1388 	assert(IsTileType(tile, MP_HOUSE));
  1388 	assert(IsTileType(tile, MP_HOUSE));
  1389 
  1389 
  1390 	// need to align the tile to point to the upper left corner of the house
  1390 	// need to align the tile to point to the upper left corner of the house
  1404 		}
  1404 		}
  1405 	}
  1405 	}
  1406 
  1406 
  1407 	// Remove population from the town if the
  1407 	// Remove population from the town if the
  1408 	// house is finished.
  1408 	// house is finished.
  1409 	if ((~_map3_lo[tile] & 0xC0) == 0) {
  1409 	if ((~_m[tile].m3 & 0xC0) == 0) {
  1410 		ChangePopulation(t, -_housetype_population[house]);
  1410 		ChangePopulation(t, -_housetype_population[house]);
  1411 	}
  1411 	}
  1412 
  1412 
  1413 	t->num_houses--;
  1413 	t->num_houses--;
  1414 
  1414 
  1487 
  1487 
  1488 	// Go through all tiles and delete those belonging to the town
  1488 	// Go through all tiles and delete those belonging to the town
  1489 	for (tile = 0; tile < MapSize(); ++tile) {
  1489 	for (tile = 0; tile < MapSize(); ++tile) {
  1490 		switch (GetTileType(tile)) {
  1490 		switch (GetTileType(tile)) {
  1491 			case MP_HOUSE:
  1491 			case MP_HOUSE:
  1492 				if (GetTown(_map2[tile]) == t)
  1492 				if (GetTown(_m[tile].m2) == t)
  1493 					DoCommandByTile(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
  1493 					DoCommandByTile(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
  1494 				break;
  1494 				break;
  1495 
  1495 
  1496 			case MP_STREET:
  1496 			case MP_STREET:
  1497 			case MP_TUNNELBRIDGE:
  1497 			case MP_TUNNELBRIDGE:
  1839 	Town *best_town = NULL;
  1839 	Town *best_town = NULL;
  1840 
  1840 
  1841 	// XXX - Fix this so for a given tiletype the owner of the type is in the same variable
  1841 	// XXX - Fix this so for a given tiletype the owner of the type is in the same variable
  1842 	if (IsTileType(tile, MP_HOUSE) || (
  1842 	if (IsTileType(tile, MP_HOUSE) || (
  1843 				IsTileType(tile, MP_STREET) &&
  1843 				IsTileType(tile, MP_STREET) &&
  1844 				(IsLevelCrossing(tile) ? _map3_lo[tile] : GetTileOwner(tile)) == OWNER_TOWN
  1844 				(IsLevelCrossing(tile) ? _m[tile].m3 : GetTileOwner(tile)) == OWNER_TOWN
  1845 			))
  1845 			))
  1846 		return GetTown(_map2[tile]);
  1846 		return GetTown(_m[tile].m2);
  1847 
  1847 
  1848 	FOR_ALL_TOWNS(t) {
  1848 	FOR_ALL_TOWNS(t) {
  1849 		if (t->xy != 0) {
  1849 		if (t->xy != 0) {
  1850 			dist = DistanceManhattan(tile, t->xy);
  1850 			dist = DistanceManhattan(tile, t->xy);
  1851 			if (dist < best) {
  1851 			if (dist < best) {