Index: town_cmd.c =================================================================== --- town_cmd.c (revision 3328) +++ town_cmd.c (working copy) @@ -49,6 +49,8 @@ * are then scaled based on that. */ #define TOWN_GROWTH_FREQUENCY 23 +#define BUILDINDSTAGE_COMPLETED 0x03 + enum { TOWN_HAS_CHURCH = 0x02, TOWN_HAS_STADIUM = 0x04 @@ -87,6 +89,32 @@ }; +static byte NewHouseIDFromMap( TileIndex tile ) +{ + return _m[tile].m4; /*Standard ID*/ +} + +static byte BuildingStage(TileIndex tile) +{ + return GB(_m[tile].m3, 6,2); +} + +static void IncBuildingStage( TileIndex tile ) +{ + AB(_m[tile].m3, 6, 2, 1); /*increase construction stage of one more step*/ +} + +static inline Town *GetTownByTile(TileIndex tile) +{ + return GetTown(_m[tile].m2 ); +} + +static bool HouseLiftIsMoving( TileIndex tile ) +{ + return HASBIT(_m[tile].m5,7); +} + + static void DrawTile_Town(TileInfo *ti) { const DrawTownTileStruct *dcts; @@ -96,8 +124,8 @@ /* Retrieve pointer to the draw town tile struct */ { /* this "randomizes" on the (up to) 4 variants of a building */ - byte gfx = _m[ti->tile].m4; - byte stage = GB(_m[ti->tile].m3, 6, 2); + byte gfx = NewHouseIDFromMap(ti->tile);//pointer to house type*/ + byte stage = BuildingStage(ti->tile); uint variant; variant = ti->x >> 4; variant ^= ti->x >> 6; @@ -165,7 +193,7 @@ // Not exactly sure when this happens, but probably when a house changes. // Before this was just a return...so it'd leak animated tiles.. // That bug seems to have been here since day 1?? - if (!(_housetype_extra_flags[_m[tile].m4] & 0x20)) { + if (!(_housetype_extra_flags[NewHouseIDFromMap(tile)] & 0x20)) { DeleteAnimatedTile(tile); return; } @@ -254,22 +282,26 @@ { assert(IsTileType(tile, MP_HOUSE)); - if (_m[tile].m5 & 0x80) return; + if (HouseLiftIsMoving(tile)) return; //house with a moving lift is indeed finished AB(_m[tile].m5, 0, 3, 1); if (GB(_m[tile].m5, 0, 3) != 0) return; + /*m5 bits 2..0: + Construction counter, for buildings under construction. Incremented on every + periodic tile processing. On wraparound, the stage of construction in m3 is increased*/ - _m[tile].m3 = _m[tile].m3 + 0x40; + IncBuildingStage( tile ); /*increase construction stage of one more step*/ - if ((_m[tile].m3 & 0xC0) == 0xC0) { - ChangePopulation(GetTown(_m[tile].m2), _housetype_population[_m[tile].m4]); + if (BuildingStage(tile) == BUILDINDSTAGE_COMPLETED) { //House is completed + /*Now, construction is completed. Can add population of building to the town*/ + ChangePopulation(GetTownByTile(tile), _housetype_population[NewHouseIDFromMap(tile)]); } MarkTileDirtyByTile(tile); } static void MakeTownHouseBigger(TileIndex tile) { - uint flags = _house_more_flags[_m[tile].m4]; + uint flags = _house_more_flags[NewHouseIDFromMap(tile)]; if (flags & 8) MakeSingleHouseBigger(TILE_ADDXY(tile, 0, 0)); if (flags & 4) MakeSingleHouseBigger(TILE_ADDXY(tile, 0, 1)); if (flags & 2) MakeSingleHouseBigger(TILE_ADDXY(tile, 1, 0)); @@ -282,20 +314,22 @@ Town *t; uint32 r; - if ((_m[tile].m3 & 0xC0) != 0xC0) { + + if (BuildingStage(tile) != BUILDINDSTAGE_COMPLETED) { + /*Construction is not completed. See if we can go further in construction*/ MakeTownHouseBigger(tile); return; } - house = _m[tile].m4; + house = NewHouseIDFromMap(tile); if (_housetype_extra_flags[house] & 0x20 && - !(_m[tile].m5 & 0x80) && + !HouseLiftIsMoving( tile ) && CHANCE16(1, 2) && AddAnimatedTile(tile)) { _m[tile].m5 = (_m[tile].m5 & 0x40) | 0x80; } - t = GetTown(_m[tile].m2); + t = GetTownByTile(tile); r = Random(); @@ -348,12 +382,12 @@ if (!EnsureNoVehicle(tile)) return CMD_ERROR; if (flags&DC_AUTO && !(flags&DC_AI_BUILDING)) return_cmd_error(STR_2004_BUILDING_MUST_BE_DEMOLISHED); - house = _m[tile].m4; + house = NewHouseIDFromMap(tile); cost = _price.remove_house * _housetype_remove_cost[house] >> 8; rating = _housetype_remove_ratingmod[house]; _cleared_town_rating += rating; - _cleared_town = t = GetTown(_m[tile].m2); + _cleared_town = t = GetTownByTile(tile); if (_current_player < MAX_PLAYERS) { if (rating > t->ratings[_current_player] && !(flags & DC_NO_TOWN_RATING) && !_cheats.magic_bulldozer.value) { @@ -372,7 +406,7 @@ static void GetAcceptedCargo_Town(TileIndex tile, AcceptedCargo ac) { - byte type = _m[tile].m4; + byte type = NewHouseIDFromMap(tile); ac[CT_PASSENGERS] = _housetype_cargo_passengers[type]; ac[CT_MAIL] = _housetype_cargo_mail[type]; @@ -382,8 +416,8 @@ static void GetTileDesc_Town(TileIndex tile, TileDesc *td) { - td->str = _town_tile_names[_m[tile].m4]; - if ((_m[tile].m3 & 0xC0) != 0xC0) { + td->str = _town_tile_names[NewHouseIDFromMap(tile)]; + if ((BuildingStage(tile) != BUILDINDSTAGE_COMPLETED)) { SetDParamX(td->dparam, 0, td->str); td->str = STR_2058_UNDER_CONSTRUCTION; } @@ -733,7 +767,7 @@ if (IsTileType(tile, MP_STREET)) { /* Don't allow building over roads of other cities */ - if (IsTileOwner(tile, OWNER_TOWN) && GetTown(_m[tile].m2) != t) + if (IsTileOwner(tile, OWNER_TOWN) && GetTownByTile(tile) != t) _grow_town_result = -1; else if (_game_mode == GM_EDITOR) { /* If we are in the SE, and this road-piece has no town owner yet, it just found an @@ -1377,7 +1411,7 @@ static void ClearTownHouse(Town *t, TileIndex tile) { - uint house = _m[tile].m4; + uint house = NewHouseIDFromMap(tile); uint eflags; assert(IsTileType(tile, MP_HOUSE)); @@ -1399,9 +1433,8 @@ } } - // Remove population from the town if the - // house is finished. - if ((~_m[tile].m3 & 0xC0) == 0) { + // Remove population from the town if the house is finished. + if (BuildingStage(tile) == BUILDINDSTAGE_COMPLETED) { ChangePopulation(t, -_housetype_population[house]); } @@ -1484,7 +1517,7 @@ for (tile = 0; tile < MapSize(); ++tile) { switch (GetTileType(tile)) { case MP_HOUSE: - if (GetTown(_m[tile].m2) == t) + if (GetTownByTile(tile) == t) DoCommandByTile(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR); break; @@ -1833,7 +1866,7 @@ IsTileType(tile, MP_STREET) && (IsLevelCrossing(tile) ? _m[tile].m3 : GetTileOwner(tile)) == OWNER_TOWN )) - return GetTown(_m[tile].m2); + return GetTownByTile(tile); FOR_ALL_TOWNS(t) { if (t->xy != 0) {