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 |
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) { |