(svn r4261) CodeChange : Add and Use Accessor for Houses Construction. And cleaning on town.flags12 too

This commit is contained in:
belugas 2006-04-03 14:56:07 +00:00
parent 5931b34aff
commit f4bbce2c39
3 changed files with 165 additions and 52 deletions

24
town.h
View File

@ -21,6 +21,9 @@ struct Town {
ViewportSign sign; ViewportSign sign;
// Makes sure we don't build certain house types twice. // Makes sure we don't build certain house types twice.
// bit 0 = Building funds received
// bit 1 = CHURCH
// bit 2 = STADIUM
byte flags12; byte flags12;
// Which players have a statue? // Which players have a statue?
@ -125,6 +128,27 @@ enum {
RATING_BRIBE_DOWN_TO = -50 // XXX SHOULD BE SOMETHING LOWER? RATING_BRIBE_DOWN_TO = -50 // XXX SHOULD BE SOMETHING LOWER?
}; };
enum {
/* This is the base "normal" number of towns on the 8x8 map, when
* one town should get grown per tick. The other numbers of towns
* are then scaled based on that. */
TOWN_GROWTH_FREQUENCY = 23,
/* Simple value that indicates the house has reached final stage of construction*/
TOWN_HOUSE_COMPLETED = 3,
};
/* This enum is used in conjonction with town->flags12.
* IT simply states what bit is used for.
* It is pretty unrealistic (IMHO) to only have one church/stadium
* per town, NO MATTER the population of it.
* And there are 5 more bits available on flags12...
*/
enum {
TOWN_IS_FUNDED = 0, // Town has received some funds for
TOWN_HAS_CHURCH = 1, // There can be only one church by town.
TOWN_HAS_STADIUM = 2 // There can be only one stadium by town.
};
bool CheckforTownRating(uint32 flags, Town *t, byte type); bool CheckforTownRating(uint32 flags, Town *t, byte type);
VARDEF TownID *_town_sort; VARDEF TownID *_town_sort;

View File

@ -46,17 +46,6 @@ static void TownPoolNewBlock(uint start_item)
/* Initialize the town-pool */ /* Initialize the town-pool */
MemoryPool _town_pool = { "Towns", TOWN_POOL_MAX_BLOCKS, TOWN_POOL_BLOCK_SIZE_BITS, sizeof(Town), &TownPoolNewBlock, 0, 0, NULL }; MemoryPool _town_pool = { "Towns", TOWN_POOL_MAX_BLOCKS, TOWN_POOL_BLOCK_SIZE_BITS, sizeof(Town), &TownPoolNewBlock, 0, 0, NULL };
/* This is the base "normal" number of towns on the 8x8 map, when
* one town should get grown per tick. The other numbers of towns
* are then scaled based on that. */
#define TOWN_GROWTH_FREQUENCY 23
enum {
TOWN_HAS_CHURCH = 0x02,
TOWN_HAS_STADIUM = 0x04
};
// Local // Local
static int _grow_town_result; static int _grow_town_result;
@ -100,7 +89,7 @@ static void DrawTile_Town(TileInfo *ti)
{ {
/* this "randomizes" on the (up to) 4 variants of a building */ /* this "randomizes" on the (up to) 4 variants of a building */
byte gfx = GetHouseType(ti->tile); byte gfx = GetHouseType(ti->tile);
byte stage = GB(_m[ti->tile].m3, 6, 2); byte stage = GetHouseBuildingStage(ti->tile);
uint variant; uint variant;
variant = ti->x >> 4; variant = ti->x >> 4;
variant ^= ti->x >> 6; variant ^= ti->x >> 6;
@ -115,7 +104,7 @@ static void DrawTile_Town(TileInfo *ti)
/* Add bricks below the house? */ /* Add bricks below the house? */
if (ti->tileh) { if (ti->tileh) {
AddSortableSpriteToDraw(SPR_FOUNDATION_BASE + ti->tileh, ti->x, ti->y, 16, 16, 7, z); AddSortableSpriteToDraw(SPR_FOUNDATION_BASE + ti->tileh, ti->x, ti->y, 16, 16, 7, z);
AddChildSpriteScreen(dcts->sprite_1, 0x1F, 1); AddChildSpriteScreen(dcts->sprite_1, 31, 1);
z += 8; z += 8;
} else { } else {
/* Else draw regular ground */ /* Else draw regular ground */
@ -254,12 +243,13 @@ static void MakeSingleHouseBigger(TileIndex tile)
if (LiftHasDestination(tile)) return; if (LiftHasDestination(tile)) return;
AB(_m[tile].m5, 0, 3, 1); IncHouseConstructionTick(tile);
if (GB(_m[tile].m5, 0, 3) != 0) return; if (GetHouseConstructionTick(tile) != 0) return;
_m[tile].m3 = _m[tile].m3 + 0x40; IncHouseBuildingStage(tile); /*increase construction stage of one more step*/
if ((_m[tile].m3 & 0xC0) == 0xC0) { if (GetHouseBuildingStage(tile) == TOWN_HOUSE_COMPLETED){
/*Now, construction is completed. Can add population of building to the town*/
ChangePopulation(GetTownByTile(tile), _housetype_population[GetHouseType(tile)]); ChangePopulation(GetTownByTile(tile), _housetype_population[GetHouseType(tile)]);
} }
MarkTileDirtyByTile(tile); MarkTileDirtyByTile(tile);
@ -280,7 +270,8 @@ static void TileLoop_Town(TileIndex tile)
Town *t; Town *t;
uint32 r; uint32 r;
if ((_m[tile].m3 & 0xC0) != 0xC0) { if (GetHouseBuildingStage(tile) != TOWN_HOUSE_COMPLETED) {
/*Construction is not completed. See if we can go further in construction*/
MakeTownHouseBigger(tile); MakeTownHouseBigger(tile);
return; return;
} }
@ -312,7 +303,7 @@ static void TileLoop_Town(TileIndex tile)
t->new_act_mail += moved; t->new_act_mail += moved;
} }
if (_house_more_flags[house] & 8 && (t->flags12 & 1) && --t->time_until_rebuild == 0) { if (_house_more_flags[house] & 8 && HASBIT(t->flags12, TOWN_IS_FUNDED) && --t->time_until_rebuild == 0) {
t->time_until_rebuild = GB(r, 16, 6) + 130; t->time_until_rebuild = GB(r, 16, 6) + 130;
_current_player = OWNER_TOWN; _current_player = OWNER_TOWN;
@ -376,7 +367,7 @@ static void GetAcceptedCargo_Town(TileIndex tile, AcceptedCargo ac)
static void GetTileDesc_Town(TileIndex tile, TileDesc *td) static void GetTileDesc_Town(TileIndex tile, TileDesc *td)
{ {
td->str = _town_tile_names[GetHouseType(tile)]; td->str = _town_tile_names[GetHouseType(tile)];
if ((_m[tile].m3 & 0xC0) != 0xC0) { if (GetHouseBuildingStage(tile) != TOWN_HOUSE_COMPLETED) {
SetDParamX(td->dparam, 0, td->str); SetDParamX(td->dparam, 0, td->str);
td->str = STR_2058_UNDER_CONSTRUCTION; td->str = STR_2058_UNDER_CONSTRUCTION;
} }
@ -414,7 +405,7 @@ static bool GrowTown(Town *t);
static void TownTickHandler(Town *t) static void TownTickHandler(Town *t)
{ {
if (t->flags12&1) { if (HASBIT(t->flags12, TOWN_IS_FUNDED)) {
int i = t->grow_counter - 1; int i = t->grow_counter - 1;
if (i < 0) { if (i < 0) {
if (GrowTown(t)) { if (GrowTown(t)) {
@ -739,7 +730,7 @@ static int GrowTownAtRoad(Town *t, TileIndex tile)
/* If we are in the SE, and this road-piece has no town owner yet, it just found an /* If we are in the SE, and this road-piece has no town owner yet, it just found an
* owner :) (happy happy happy road now) */ * owner :) (happy happy happy road now) */
SetTileOwner(tile, OWNER_TOWN); SetTileOwner(tile, OWNER_TOWN);
_m[tile].m2 = t->index; SetTownIndex(tile, t->index);
} }
} }
@ -804,8 +795,8 @@ static bool GrowTown(Town *t)
// clearing some land and then building a road there. // clearing some land and then building a road there.
tile = t->xy; tile = t->xy;
for (ptr = _town_coord_mod; ptr != endof(_town_coord_mod); ++ptr) { for (ptr = _town_coord_mod; ptr != endof(_town_coord_mod); ++ptr) {
// Only work with plain land that not already has a house with map5=0 // Only work with plain land that not already has a house with GetHouseConstructionTick=0
if ((!IsTileType(tile, MP_HOUSE) || _m[tile].m5 != 0) && if ((!IsTileType(tile, MP_HOUSE) || GetHouseConstructionTick(tile) != 0) &&
GetTileSlope(tile, NULL) == 0) { GetTileSlope(tile, NULL) == 0) {
if (!CmdFailed(DoCommandByTile(tile, 0, 0, DC_AUTO, CMD_LANDSCAPE_CLEAR))) { if (!CmdFailed(DoCommandByTile(tile, 0, 0, DC_AUTO, CMD_LANDSCAPE_CLEAR))) {
DoCommandByTile(tile, GenRandomRoadBits(), t->index, DC_EXEC | DC_AUTO, CMD_BUILD_ROAD); DoCommandByTile(tile, GenRandomRoadBits(), t->index, DC_EXEC | DC_AUTO, CMD_BUILD_ROAD);
@ -1177,7 +1168,7 @@ static void DoBuildTownHouse(Town *t, TileIndex tile)
int house; int house;
uint slope; uint slope;
uint z; uint z;
uint oneof; uint oneof = 0;
// Above snow? // Above snow?
slope = GetTileSlope(tile, &z); slope = GetTileSlope(tile, &z);
@ -1219,18 +1210,18 @@ static void DoBuildTownHouse(Town *t, TileIndex tile)
case HOUSE_SNOW_CHURCH: case HOUSE_SNOW_CHURCH:
case HOUSE_TROP_CHURCH: case HOUSE_TROP_CHURCH:
case HOUSE_TOY_CHURCH: case HOUSE_TOY_CHURCH:
oneof = TOWN_HAS_CHURCH; SETBIT(oneof, TOWN_HAS_CHURCH);
break; break;
case HOUSE_STADIUM: case HOUSE_STADIUM:
case HOUSE_MODERN_STADIUM: case HOUSE_MODERN_STADIUM:
oneof = TOWN_HAS_STADIUM; SETBIT(oneof, TOWN_HAS_STADIUM);
break; break;
default: default:
oneof = 0; oneof = 0;
break; break;
} }
if (t->flags12 & oneof) continue; if (HASBITS(t->flags12 , oneof)) continue;
// Make sure there is no slope? // Make sure there is no slope?
if (_housetype_extra_flags[house] & 0x12 && slope) continue; if (_housetype_extra_flags[house] & 0x12 && slope) continue;
@ -1274,10 +1265,10 @@ static void DoBuildTownHouse(Town *t, TileIndex tile)
if (_generating_world) { if (_generating_world) {
uint32 r = Random(); uint32 r = Random();
construction_stage = 3; /* House is finished */ construction_stage = TOWN_HOUSE_COMPLETED;
if (CHANCE16(1, 7)) construction_stage = GB(r, 0, 2); if (CHANCE16(1, 7)) construction_stage = GB(r, 0, 2);
if (construction_stage == 3) { if (construction_stage == TOWN_HOUSE_COMPLETED) {
ChangePopulation(t, _housetype_population[house]); ChangePopulation(t, _housetype_population[house]);
} else { } else {
construction_counter = GB(r, 2, 2); construction_counter = GB(r, 2, 2);
@ -1337,9 +1328,8 @@ static void ClearTownHouse(Town *t, TileIndex tile)
} }
} }
// Remove population from the town if the // Remove population from the town if the house is finished.
// house is finished. if (GetHouseBuildingStage(tile) == TOWN_HOUSE_COMPLETED) {
if ((~_m[tile].m3 & 0xC0) == 0) {
ChangePopulation(t, -_housetype_population[house]); ChangePopulation(t, -_housetype_population[house]);
} }
@ -1352,11 +1342,11 @@ static void ClearTownHouse(Town *t, TileIndex tile)
case HOUSE_SNOW_CHURCH: case HOUSE_SNOW_CHURCH:
case HOUSE_TROP_CHURCH: case HOUSE_TROP_CHURCH:
case HOUSE_TOY_CHURCH: case HOUSE_TOY_CHURCH:
t->flags12 &= ~TOWN_HAS_CHURCH; CLRBIT(t->flags12, TOWN_HAS_CHURCH);
break; break;
case HOUSE_STADIUM: case HOUSE_STADIUM:
case HOUSE_MODERN_STADIUM: case HOUSE_MODERN_STADIUM:
t->flags12 &= ~TOWN_HAS_STADIUM; CLRBIT(t->flags12, TOWN_HAS_STADIUM);
break; break;
default: default:
break; break;
@ -1559,8 +1549,11 @@ static void TownActionBuildStatue(Town *t, int action)
static void TownActionFundBuildings(Town *t, int action) static void TownActionFundBuildings(Town *t, int action)
{ {
// Build next tick
t->grow_counter = 1; t->grow_counter = 1;
t->flags12 |= 1; // If we were not already growing
SETBIT(t->flags12, TOWN_IS_FUNDED);
// And grow for 3 months
t->fund_buildings_months = 3; t->fund_buildings_months = 3;
} }
@ -1676,7 +1669,7 @@ static void UpdateTownGrowRate(Town *t)
} }
} }
t->flags12 &= ~1; CLRBIT(t->flags12, TOWN_IS_FUNDED);
if (t->fund_buildings_months != 0) { if (t->fund_buildings_months != 0) {
static const byte _grow_count_values[6] = { static const byte _grow_count_values[6] = {
@ -1707,7 +1700,7 @@ static void UpdateTownGrowRate(Town *t)
if (m <= t->grow_counter) if (m <= t->grow_counter)
t->grow_counter = m; t->grow_counter = m;
t->flags12 |= 1; SETBIT(t->flags12, TOWN_IS_FUNDED);
} }
static void UpdateTownAmounts(Town *t) static void UpdateTownAmounts(Town *t)

View File

@ -1,5 +1,7 @@
/* $Id$ */ /* $Id$ */
/** @file town_map.h Accessors for towns */
#ifndef TOWN_MAP_H #ifndef TOWN_MAP_H
#define TOWN_MAP_H #define TOWN_MAP_H
@ -11,12 +13,24 @@ static inline int GetHouseType(TileIndex t)
return _m[t].m4; return _m[t].m4;
} }
static inline uint GetTownIndex(TileIndex t) static inline TownID GetTownIndex(TileIndex t)
{ {
assert(IsTileType(t, MP_HOUSE) || IsTileType(t, MP_STREET)); // XXX incomplete assert(IsTileType(t, MP_HOUSE) || IsTileType(t, MP_STREET)); // XXX incomplete
return _m[t].m2; return _m[t].m2;
} }
/**
* Set the town index for a street tile.
* @param tile the tile
* @param index the index of the town
* @pre IsTileType(tile, MP_STREET)
*/
static inline void SetTownIndex(TileIndex t, TownID index)
{
assert(IsTileType(t, MP_STREET));
_m[t].m2 = index;
}
static inline bool LiftHasDestination(TileIndex t) static inline bool LiftHasDestination(TileIndex t)
{ {
return HASBIT(_m[t].m5, 7); return HASBIT(_m[t].m5, 7);
@ -67,7 +81,6 @@ static inline Town* GetTownByTile(TileIndex t)
return GetTown(GetTownIndex(t)); return GetTown(GetTownIndex(t));
} }
static inline void MakeHouseTile(TileIndex t, TownID tid, byte counter, byte stage, byte type) static inline void MakeHouseTile(TileIndex t, TownID tid, byte counter, byte stage, byte type)
{ {
assert(IsTileType(t, MP_CLEAR)); assert(IsTileType(t, MP_CLEAR));
@ -95,4 +108,87 @@ static inline void MakeTownHouse(TileIndex t, TownID tid, byte counter, byte sta
if (HASBIT(size, TWO_BY_TWO_BIT) || HASBIT(size, TWO_BY_ONE_BIT)) MakeHouseTile(t + TileDiffXY(1, 0), tid, counter, stage, ++type); if (HASBIT(size, TWO_BY_TWO_BIT) || HASBIT(size, TWO_BY_ONE_BIT)) MakeHouseTile(t + TileDiffXY(1, 0), tid, counter, stage, ++type);
if (HASBIT(size, TWO_BY_TWO_BIT)) MakeHouseTile(t + TileDiffXY(1, 1), tid, counter, stage, ++type); if (HASBIT(size, TWO_BY_TWO_BIT)) MakeHouseTile(t + TileDiffXY(1, 1), tid, counter, stage, ++type);
} }
#endif
/**
* House Construction Scheme.
* Construction counter, for buildings under construction. Incremented on every
* periodic tile processing.
* On wraparound, the stage of building in is increased.
* (Get|Set|Inc)HouseBuildingStage are taking care of the real stages,
* (as the sprite for the next phase of house building)
* (Get|Set|Inc)HouseConstructionTick is simply a tick counter between the
* different stages
*/
/**
* Gets the building stage of a house
* @param tile the tile of the house to get the building stage of
* @pre IsTileType(t, MP_HOUSE)
* @return the building stage of the house
*/
static inline byte GetHouseBuildingStage(TileIndex t)
{
assert(IsTileType(t, MP_HOUSE));
return GB(_m[t].m3, 6, 2);
}
/**
* Sets the building stage of a house
* @param tile the tile of the house to set the building stage of
* @param stage the new stage
* @pre IsTileType(t, MP_HOUSE)
*/
static inline void SetHouseBuildingStage(TileIndex t, byte stage)
{
assert(IsTileType(t, MP_HOUSE));
SB(_m[t].m3, 6, 2, stage);
}
/**
* Increments the building stage of a house
* @param tile the tile of the house to increment the building stage of
* @pre IsTileType(t, MP_HOUSE)
*/
static inline void IncHouseBuildingStage( TileIndex t )
{
assert(IsTileType(t, MP_HOUSE));
AB(_m[t].m3, 6, 2, 1);
}
/**
* Gets the construction stage of a house
* @param tile the tile of the house to get the construction stage of
* @pre IsTileType(t, MP_HOUSE)
* @return the construction stage of the house
*/
static inline byte GetHouseConstructionTick(TileIndex t)
{
assert(IsTileType(t, MP_HOUSE));
return GB(_m[t].m5, 0, 3);
}
/**
* Sets the construction stage of a house
* @param tile the tile of the house to set the construction stage of
* @param stage the new stage
* @pre IsTileType(t, MP_HOUSE)
*/
static inline void SetHouseConstructionTick(TileIndex t, byte stage)
{
assert(IsTileType(t, MP_HOUSE));
SB(_m[t].m5, 0, 3, stage);
}
/**
* Sets the increment stage of a house
* @param tile the tile of the house to increment the construction stage of
* @pre IsTileType(t, MP_HOUSE)
*/
static inline void IncHouseConstructionTick(TileIndex t)
{
assert(IsTileType(t, MP_HOUSE));
AB(_m[t].m5, 0, 3, 1);
}
#endif /* TOWN_MAP_H */