83 uint32 image; |
83 uint32 image; |
84 |
84 |
85 /* Retrieve pointer to the draw town tile struct */ |
85 /* Retrieve pointer to the draw town tile struct */ |
86 { |
86 { |
87 /* this "randomizes" on the (up to) 4 variants of a building */ |
87 /* this "randomizes" on the (up to) 4 variants of a building */ |
88 byte gfx = (byte)_map2[ti->tile]; |
88 byte gfx = (byte)_map3_hi[ti->tile]; |
89 byte stage = _map3_lo[ti->tile] >> 6; |
89 byte stage = _map3_lo[ti->tile] >> 6; |
90 uint variant; |
90 uint variant; |
91 variant = ti->x >> 4; |
91 variant = ti->x >> 4; |
92 variant ^= ti->x >> 6; |
92 variant ^= ti->x >> 6; |
93 variant ^= ti->y >> 4; |
93 variant ^= ti->y >> 4; |
253 |
253 |
254 _map3_lo[tile] = _map3_lo[tile] + 0x40; |
254 _map3_lo[tile] = _map3_lo[tile] + 0x40; |
255 |
255 |
256 if ( (_map3_lo[tile] & 0xC0) == 0xC0) { |
256 if ( (_map3_lo[tile] & 0xC0) == 0xC0) { |
257 Town *t = ClosestTownFromTile(tile, (uint)-1); |
257 Town *t = ClosestTownFromTile(tile, (uint)-1); |
258 ChangePopulation(t, _housetype_population[_map2[tile]]); |
258 ChangePopulation(t, _housetype_population[_map3_hi[tile]]); |
259 } |
259 } |
260 MarkTileDirtyByTile(tile); |
260 MarkTileDirtyByTile(tile); |
261 } |
261 } |
262 |
262 |
263 static void MakeTownHouseBigger(uint tile) |
263 static void MakeTownHouseBigger(uint tile) |
264 { |
264 { |
265 uint flags = _house_more_flags[_map2[tile]]; |
265 uint flags = _house_more_flags[_map3_hi[tile]]; |
266 if (flags & 8) MakeSingleHouseBigger(TILE_ADDXY(tile, 0, 0)); |
266 if (flags & 8) MakeSingleHouseBigger(TILE_ADDXY(tile, 0, 0)); |
267 if (flags & 4) MakeSingleHouseBigger(TILE_ADDXY(tile, 0, 1)); |
267 if (flags & 4) MakeSingleHouseBigger(TILE_ADDXY(tile, 0, 1)); |
268 if (flags & 2) MakeSingleHouseBigger(TILE_ADDXY(tile, 1, 0)); |
268 if (flags & 2) MakeSingleHouseBigger(TILE_ADDXY(tile, 1, 0)); |
269 if (flags & 1) MakeSingleHouseBigger(TILE_ADDXY(tile, 1, 1)); |
269 if (flags & 1) MakeSingleHouseBigger(TILE_ADDXY(tile, 1, 1)); |
270 } |
270 } |
278 if ((_map3_lo[tile] & 0xC0) != 0xC0) { |
278 if ((_map3_lo[tile] & 0xC0) != 0xC0) { |
279 MakeTownHouseBigger(tile); |
279 MakeTownHouseBigger(tile); |
280 return; |
280 return; |
281 } |
281 } |
282 |
282 |
283 house = _map2[tile]; |
283 house = _map3_hi[tile]; |
284 if (_housetype_extra_flags[house] & 0x20 && |
284 if (_housetype_extra_flags[house] & 0x20 && |
285 !(_map5[tile] & 0x80) && |
285 !(_map5[tile] & 0x80) && |
286 CHANCE16(1,2) && |
286 CHANCE16(1,2) && |
287 AddAnimatedTile(tile)) { |
287 AddAnimatedTile(tile)) { |
288 _map5[tile] = (_map5[tile] & 0x40)|0x80; |
288 _map5[tile] = (_map5[tile] & 0x40)|0x80; |
338 |
338 |
339 // safety checks |
339 // safety checks |
340 if (!EnsureNoVehicle(tile)) return CMD_ERROR; |
340 if (!EnsureNoVehicle(tile)) return CMD_ERROR; |
341 if (flags&DC_AUTO && !(flags&DC_AI_BUILDING)) return_cmd_error(STR_2004_BUILDING_MUST_BE_DEMOLISHED); |
341 if (flags&DC_AUTO && !(flags&DC_AI_BUILDING)) return_cmd_error(STR_2004_BUILDING_MUST_BE_DEMOLISHED); |
342 |
342 |
343 house = _map2[tile]; |
343 house = _map3_hi[tile]; |
344 cost = _price.remove_house * _housetype_remove_cost[house] >> 8; |
344 cost = _price.remove_house * _housetype_remove_cost[house] >> 8; |
345 |
345 |
346 rating = _housetype_remove_ratingmod[house]; |
346 rating = _housetype_remove_ratingmod[house]; |
347 _cleared_town_rating += rating; |
347 _cleared_town_rating += rating; |
348 _cleared_town = t = ClosestTownFromTile(tile, (uint)-1); |
348 _cleared_town = t = ClosestTownFromTile(tile, (uint)-1); |
362 return cost; |
362 return cost; |
363 } |
363 } |
364 |
364 |
365 static void GetAcceptedCargo_Town(uint tile, AcceptedCargo ac) |
365 static void GetAcceptedCargo_Town(uint tile, AcceptedCargo ac) |
366 { |
366 { |
367 int type = _map2[tile]; |
367 int type = _map3_hi[tile]; |
368 |
368 |
369 ac[CT_PASSENGERS] = _housetype_cargo_passengers[type]; |
369 ac[CT_PASSENGERS] = _housetype_cargo_passengers[type]; |
370 ac[CT_MAIL] = _housetype_cargo_mail[type]; |
370 ac[CT_MAIL] = _housetype_cargo_mail[type]; |
371 ac[CT_GOODS] = _housetype_cargo_goods[type]; |
371 ac[CT_GOODS] = _housetype_cargo_goods[type]; |
372 ac[CT_FOOD] = _housetype_cargo_food[type]; |
372 ac[CT_FOOD] = _housetype_cargo_food[type]; |
373 } |
373 } |
374 |
374 |
375 static void GetTileDesc_Town(uint tile, TileDesc *td) |
375 static void GetTileDesc_Town(uint tile, TileDesc *td) |
376 { |
376 { |
377 td->str = _town_tile_names[_map2[tile]]; |
377 td->str = _town_tile_names[_map3_hi[tile]]; |
378 if ((_map3_lo[tile] & 0xC0) != 0xC0) { |
378 if ((_map3_lo[tile] & 0xC0) != 0xC0) { |
379 SetDParamX(td->dparam, 0, td->str); |
379 SetDParamX(td->dparam, 0, td->str); |
380 td->str = STR_2058_UNDER_CONSTRUCTION; |
380 td->str = STR_2058_UNDER_CONSTRUCTION; |
381 } |
381 } |
382 |
382 |
674 if ((i=0,ti.tileh != 3) && |
674 if ((i=0,ti.tileh != 3) && |
675 (i++,ti.tileh != 9) && |
675 (i++,ti.tileh != 9) && |
676 (i++,ti.tileh != 12) && |
676 (i++,ti.tileh != 12) && |
677 (i++,ti.tileh != 6)) { |
677 (i++,ti.tileh != 6)) { |
678 build_road_and_exit: |
678 build_road_and_exit: |
679 if (DoCommandByTile(tile, rcmd, 0, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD) != CMD_ERROR) |
679 if (DoCommandByTile(tile, rcmd, t1->index, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD) != CMD_ERROR) |
680 _grow_town_result = -1; |
680 _grow_town_result = -1; |
681 return; |
681 return; |
682 } |
682 } |
683 |
683 |
684 tmptile = tile; |
684 tmptile = tile; |
807 FindLandscapeHeightByTile(&ti, tile); |
807 FindLandscapeHeightByTile(&ti, tile); |
808 |
808 |
809 // Only work with plain land that not already has a house with map5=0 |
809 // Only work with plain land that not already has a house with map5=0 |
810 if (ti.tileh == 0 && !(ti.type==MP_HOUSE && ti.map5==0)) { |
810 if (ti.tileh == 0 && !(ti.type==MP_HOUSE && ti.map5==0)) { |
811 if (DoCommandByTile(tile, 0, 0, DC_AUTO, CMD_LANDSCAPE_CLEAR) != CMD_ERROR) { |
811 if (DoCommandByTile(tile, 0, 0, DC_AUTO, CMD_LANDSCAPE_CLEAR) != CMD_ERROR) { |
812 DoCommandByTile(tile, GenRandomRoadBits(), 0, DC_EXEC | DC_AUTO, CMD_BUILD_ROAD); |
812 DoCommandByTile(tile, GenRandomRoadBits(), t->index, DC_EXEC | DC_AUTO, CMD_BUILD_ROAD); |
813 _current_player = old_player; |
813 _current_player = old_player; |
814 return true; |
814 return true; |
815 } |
815 } |
816 } |
816 } |
817 tile = TILE_ADD(tile, ToTileIndexDiff(*ptr)); |
817 tile = TILE_ADD(tile, ToTileIndexDiff(*ptr)); |
1270 } |
1270 } |
1271 |
1271 |
1272 assert(IsTileType(tile, MP_CLEAR)); |
1272 assert(IsTileType(tile, MP_CLEAR)); |
1273 |
1273 |
1274 ModifyTile(tile, |
1274 ModifyTile(tile, |
1275 MP_SETTYPE(MP_HOUSE) | MP_MAP2 | MP_MAP3LO | MP_MAP3HI_CLEAR | MP_MAP5 | MP_MAPOWNER, |
1275 MP_SETTYPE(MP_HOUSE) | MP_MAP3HI | MP_MAP3LO | MP_MAP2 | MP_MAP5 | MP_MAPOWNER, |
1276 house, /* map2 */ |
1276 t->index, |
1277 m3lo, /* map3_lo */ |
1277 m3lo, /* map3_lo */ |
|
1278 house, /* map3_hi */ |
1278 0, /* map_owner */ |
1279 0, /* map_owner */ |
1279 m5 /* map5 */ |
1280 m5 /* map5 */ |
1280 ); |
1281 ); |
1281 |
1282 |
1282 eflags = _housetype_extra_flags[house]; |
1283 eflags = _housetype_extra_flags[house]; |
1283 |
1284 |
1284 if (eflags&0x18) { |
1285 if (eflags&0x18) { |
1285 assert(IsTileType(tile + TILE_XY(0,1), MP_CLEAR)); |
1286 assert(IsTileType(tile + TILE_XY(0,1), MP_CLEAR)); |
1286 ModifyTile(tile + TILE_XY(0,1), |
1287 ModifyTile(tile + TILE_XY(0,1), |
1287 MP_SETTYPE(MP_HOUSE) | MP_MAP2 | MP_MAP3LO | MP_MAP3HI_CLEAR | MP_MAP5 | MP_MAPOWNER, |
1288 MP_SETTYPE(MP_HOUSE) | MP_MAP2 | MP_MAP3LO | MP_MAP3HI | MP_MAP5 | MP_MAPOWNER, |
1288 ++house, /* map2 */ |
1289 t->index, |
1289 m3lo, /* map3_lo */ |
1290 m3lo, /* map3_lo */ |
|
1291 ++house, /* map3_hi */ |
1290 0, /* map_owner */ |
1292 0, /* map_owner */ |
1291 m5 /* map5 */ |
1293 m5 /* map5 */ |
1292 ); |
1294 ); |
1293 } |
1295 } |
1294 |
1296 |
1295 if (eflags&0x14) { |
1297 if (eflags&0x14) { |
1296 assert(IsTileType(tile + TILE_XY(1,0), MP_CLEAR)); |
1298 assert(IsTileType(tile + TILE_XY(1,0), MP_CLEAR)); |
1297 ModifyTile(tile + TILE_XY(1,0), |
1299 ModifyTile(tile + TILE_XY(1,0), |
1298 MP_SETTYPE(MP_HOUSE) | MP_MAP2 | MP_MAP3LO | MP_MAP3HI_CLEAR | MP_MAP5 | MP_MAPOWNER, |
1300 MP_SETTYPE(MP_HOUSE) | MP_MAP2 | MP_MAP3LO | MP_MAP3HI | MP_MAP5 | MP_MAPOWNER, |
1299 ++house, /* map2 */ |
1301 t->index, |
1300 m3lo, /* map3_lo */ |
1302 m3lo, /* map3_lo */ |
|
1303 ++house, /* map3_hi */ |
1301 0, /* map_owner */ |
1304 0, /* map_owner */ |
1302 m5 /* map5 */ |
1305 m5 /* map5 */ |
1303 ); |
1306 ); |
1304 } |
1307 } |
1305 |
1308 |
1306 if (eflags&0x10) { |
1309 if (eflags&0x10) { |
1307 assert(IsTileType(tile + TILE_XY(1,1), MP_CLEAR)); |
1310 assert(IsTileType(tile + TILE_XY(1,1), MP_CLEAR)); |
1308 ModifyTile(tile + TILE_XY(1,1), |
1311 ModifyTile(tile + TILE_XY(1,1), |
1309 MP_SETTYPE(MP_HOUSE) | MP_MAP2 | MP_MAP3LO | MP_MAP3HI_CLEAR | MP_MAP5 | MP_MAPOWNER, |
1312 MP_SETTYPE(MP_HOUSE) | MP_MAP2 | MP_MAP3LO | MP_MAP3HI | MP_MAP5 | MP_MAPOWNER, |
1310 ++house, /* map2 */ |
1313 t->index, |
1311 m3lo, /* map3_lo */ |
1314 m3lo, /* map3_lo */ |
|
1315 ++house, /* map3_hi */ |
1312 0, /* map_owner */ |
1316 0, /* map_owner */ |
1313 m5 /* map5 */ |
1317 m5 /* map5 */ |
1314 ); |
1318 ); |
1315 } |
1319 } |
1316 } |
1320 } |
1340 DoClearSquare(tile); |
1344 DoClearSquare(tile); |
1341 DeleteAnimatedTile(tile); |
1345 DeleteAnimatedTile(tile); |
1342 } |
1346 } |
1343 |
1347 |
1344 static void ClearTownHouse(Town *t, uint tile) { |
1348 static void ClearTownHouse(Town *t, uint tile) { |
1345 uint house = _map2[tile]; |
1349 uint house = _map3_hi[tile]; |
1346 uint eflags; |
1350 uint eflags; |
1347 |
1351 |
1348 assert(IsTileType(tile, MP_HOUSE)); |
1352 assert(IsTileType(tile, MP_HOUSE)); |
1349 |
1353 |
1350 // need to align the tile to point to the upper left corner of the house |
1354 // need to align the tile to point to the upper left corner of the house |
1775 { |
1779 { |
1776 Town *t; |
1780 Town *t; |
1777 uint dist, best = threshold; |
1781 uint dist, best = threshold; |
1778 Town *best_town = NULL; |
1782 Town *best_town = NULL; |
1779 |
1783 |
|
1784 if ((IsTileType(tile, MP_STREET) && _map_owner[tile] == OWNER_TOWN) || IsTileType(tile, MP_HOUSE)) |
|
1785 return GetTown(_map2[tile]); |
|
1786 |
1780 FOR_ALL_TOWNS(t) { |
1787 FOR_ALL_TOWNS(t) { |
1781 if (t->xy != 0) { |
1788 if (t->xy != 0) { |
1782 dist = DistanceManhattan(tile, t->xy); |
1789 dist = DistanceManhattan(tile, t->xy); |
1783 if (dist < best) { |
1790 if (dist < best) { |
1784 best = dist; |
1791 best = dist; |