src/town_map.h
branchcpp_gui
changeset 6303 84c215fc8eb8
parent 6220 0c2371b1edda
child 6307 f40e88cff863
child 6914 3ba37b6fa39b
equal deleted inserted replaced
6302:bd80897189ba 6303:84c215fc8eb8
     4 
     4 
     5 #ifndef TOWN_MAP_H
     5 #ifndef TOWN_MAP_H
     6 #define TOWN_MAP_H
     6 #define TOWN_MAP_H
     7 
     7 
     8 #include "town.h"
     8 #include "town.h"
     9 
     9 #include "date.h"
       
    10 
       
    11 /**
       
    12  * Get the index of which town this house/street is attached to.
       
    13  * @param t the tile
       
    14  * @pre IsTileType(t, MP_HOUSE) or IsTileType(t, MP_STREET)
       
    15  * @return TownID
       
    16  */
    10 static inline TownID GetTownIndex(TileIndex t)
    17 static inline TownID GetTownIndex(TileIndex t)
    11 {
    18 {
    12 	assert(IsTileType(t, MP_HOUSE) || IsTileType(t, MP_STREET)); // XXX incomplete
    19 	assert(IsTileType(t, MP_HOUSE) || IsTileType(t, MP_STREET)); // XXX incomplete
    13 	return _m[t].m2;
    20 	return _m[t].m2;
    14 }
    21 }
    15 
    22 
    16 /**
    23 /**
    17  * Set the town index for a road or house tile.
    24  * Set the town index for a road or house tile.
    18  * @param tile the tile
    25  * @param t the tile
       
    26  * @pre IsTileType(t, MP_HOUSE) or IsTileType(t, MP_STREET)
    19  * @param index the index of the town
    27  * @param index the index of the town
    20  * @pre IsTileType(t, MP_STREET) || IsTileType(t, MP_HOUSE)
    28  * @pre IsTileType(t, MP_STREET) || IsTileType(t, MP_HOUSE)
    21  */
    29  */
    22 static inline void SetTownIndex(TileIndex t, TownID index)
    30 static inline void SetTownIndex(TileIndex t, TownID index)
    23 {
    31 {
    24 	assert(IsTileType(t, MP_STREET) || IsTileType(t, MP_HOUSE));
    32 	assert(IsTileType(t, MP_HOUSE) || IsTileType(t, MP_STREET));
    25 	_m[t].m2 = index;
    33 	_m[t].m2 = index;
    26 }
    34 }
    27 
    35 
    28 /**
    36 /**
    29  * Gets the town associated with the house or road tile
    37  * Gets the town associated with the house or road tile
    33 static inline Town* GetTownByTile(TileIndex t)
    41 static inline Town* GetTownByTile(TileIndex t)
    34 {
    42 {
    35 	return GetTown(GetTownIndex(t));
    43 	return GetTown(GetTownIndex(t));
    36 }
    44 }
    37 
    45 
    38 
    46 /**
    39 static inline int GetHouseType(TileIndex t)
    47  * Get the type of this house, which is an index into the house spec array
    40 {
    48  * Since m4 is only a byte and we want to support 512 houses, we use the bit 6
    41 	assert(IsTileType(t, MP_HOUSE));
    49  * of m3 as an additional bit to house type.
    42 	return _m[t].m4;
    50  * @param t the tile
    43 }
    51  * @pre IsTileType(t, MP_HOUSE)
    44 
    52  * @return house type
       
    53  */
       
    54 static inline HouseID GetHouseType(TileIndex t)
       
    55 {
       
    56 	assert(IsTileType(t, MP_HOUSE));
       
    57 	return _m[t].m4 | (GB(_m[t].m3, 6, 1) << 8);
       
    58 }
       
    59 
       
    60 /**
       
    61  * Set the house type.
       
    62  * @param t the tile
       
    63  * @param house_id the new house type
       
    64  * @pre IsTileType(t, MP_HOUSE)
       
    65  */
       
    66 static inline void SetHouseType(TileIndex t, HouseID house_id)
       
    67 {
       
    68 	assert(IsTileType(t, MP_HOUSE));
       
    69 	_m[t].m4 = GB(house_id, 0, 8);
       
    70 	SB(_m[t].m3, 6, 1, GB(house_id, 8, 1));
       
    71 }
       
    72 
       
    73 /**
       
    74  * Check if the lift of this animated house has a destination
       
    75  * @param t the tile
       
    76  * @return has destination
       
    77  */
    45 static inline bool LiftHasDestination(TileIndex t)
    78 static inline bool LiftHasDestination(TileIndex t)
    46 {
    79 {
    47 	return HASBIT(_m[t].m5, 7);
    80 	return HASBIT(_me[t].m7, 0);
    48 }
    81 }
    49 
    82 
       
    83 /**
       
    84  * Set the new destination of the lift for this animated house, and activate
       
    85  * the LiftHasDestination bit.
       
    86  * @param t the tile
       
    87  * @param dest new destination
       
    88  */
    50 static inline void SetLiftDestination(TileIndex t, byte dest)
    89 static inline void SetLiftDestination(TileIndex t, byte dest)
    51 {
    90 {
    52 	SB(_m[t].m5, 0, 6, dest);
    91 	SETBIT(_me[t].m7, 0);
    53 	SETBIT(_m[t].m1, 7); /* Start moving */
    92 	SB(_me[t].m7, 1, 3, dest);
    54 }
    93 }
    55 
    94 
       
    95 /**
       
    96  * Get the current destination for this lift
       
    97  * @param t the tile
       
    98  * @return destination
       
    99  */
    56 static inline byte GetLiftDestination(TileIndex t)
   100 static inline byte GetLiftDestination(TileIndex t)
    57 {
   101 {
    58 	return GB(_m[t].m5, 0, 6);
   102 	return GB(_me[t].m7, 1, 3);
    59 }
   103 }
    60 
   104 
    61 static inline bool IsLiftMoving(TileIndex t)
   105 /**
    62 {
   106  * Stop the lift of this animated house from moving.
    63 	return HASBIT(_m[t].m1, 7);
   107  * Clears the first 4 bits of m7 at once, clearing the LiftHasDestination bit
    64 }
   108  * and the destination.
    65 
   109  * @param t the tile
    66 static inline void BeginLiftMovement(TileIndex t)
   110  */
    67 {
       
    68 	SETBIT(_m[t].m5, 7);
       
    69 }
       
    70 
       
    71 static inline void HaltLift(TileIndex t)
   111 static inline void HaltLift(TileIndex t)
    72 {
   112 {
    73 	CLRBIT(_m[t].m1, 7);
   113 	SB(_me[t].m7, 0, 4, 0);
    74 	CLRBIT(_m[t].m5, 7);
       
    75 	SB(_m[t].m5, 0, 6, 0);
       
    76 
       
    77 	DeleteAnimatedTile(t);
   114 	DeleteAnimatedTile(t);
    78 }
   115 }
    79 
   116 
       
   117 /**
       
   118  * Get the position of the lift on this animated house
       
   119  * @param t the tile
       
   120  * @return position, from 0 to 36
       
   121  */
    80 static inline byte GetLiftPosition(TileIndex t)
   122 static inline byte GetLiftPosition(TileIndex t)
    81 {
   123 {
    82 	return GB(_m[t].m1, 0, 7);
   124 	return GB(_m[t].m6, 2, 6);
    83 }
   125 }
    84 
   126 
       
   127 /**
       
   128  * Set the position of the lift on this animated house
       
   129  * @param t the tile
       
   130  * @param pos, from 0 to 36
       
   131  */
    85 static inline void SetLiftPosition(TileIndex t, byte pos)
   132 static inline void SetLiftPosition(TileIndex t, byte pos)
    86 {
   133 {
    87 	SB(_m[t].m1, 0, 7, pos);
   134 	SB(_m[t].m6, 2, 6, pos);
    88 }
   135 }
    89 
   136 
    90 static inline void MakeHouseTile(TileIndex t, TownID tid, byte counter, byte stage, byte type)
   137 /**
       
   138  * Get the current animation frame for this house
       
   139  * @param t the tile
       
   140  * @pre IsTileType(t, MP_HOUSE)
       
   141  * @return frame number
       
   142  */
       
   143 static inline byte GetHouseAnimationFrame(TileIndex t)
       
   144 {
       
   145 	assert(IsTileType(t, MP_HOUSE));
       
   146 	return GB(_m[t].m6, 3, 5);
       
   147 }
       
   148 
       
   149 /**
       
   150  * Set a new animation frame for this house
       
   151  * @param t the tile
       
   152  * @param frame the new frame number
       
   153  * @pre IsTileType(t, MP_HOUSE)
       
   154  */
       
   155 static inline void SetHouseAnimationFrame(TileIndex t, byte frame)
       
   156 {
       
   157 	assert(IsTileType(t, MP_HOUSE));
       
   158 	SB(_m[t].m6, 3, 5, frame);
       
   159 }
       
   160 
       
   161 /**
       
   162  * Get the completion of this house
       
   163  * @param t the tile
       
   164  * @return true if it is, false if it is not
       
   165  */
       
   166 static inline bool IsHouseCompleted(TileIndex t)
       
   167 {
       
   168 	assert(IsTileType(t, MP_HOUSE));
       
   169 	return HASBIT(_m[t].m3, 7);
       
   170 }
       
   171 
       
   172 /**
       
   173  * Mark this house as been completed
       
   174  * @param t the tile
       
   175  * @param status
       
   176  */
       
   177 static inline void SetHouseCompleted(TileIndex t, bool status)
       
   178 {
       
   179 	assert(IsTileType(t, MP_HOUSE));
       
   180 	SB(_m[t].m3, 7, 1, !!status);
       
   181 }
       
   182 
       
   183 /**
       
   184  * Make the tile a house.
       
   185  * @param t tile index
       
   186  * @param tid Town index
       
   187  * @param counter of construction step
       
   188  * @param stage of construction (used for drawing)
       
   189  * @param type of house.  Index into house specs array
       
   190  * @param random_bits required for newgrf houses
       
   191  * @pre IsTileType(t, MP_CLEAR)
       
   192  */
       
   193 static inline void MakeHouseTile(TileIndex t, TownID tid, byte counter, byte stage, HouseID type, byte random_bits)
    91 {
   194 {
    92 	assert(IsTileType(t, MP_CLEAR));
   195 	assert(IsTileType(t, MP_CLEAR));
    93 
   196 
    94 	SetTileType(t, MP_HOUSE);
   197 	SetTileType(t, MP_HOUSE);
    95 	_m[t].m1 = 0;
   198 	_m[t].m1 = random_bits;
    96 	_m[t].m2 = tid;
   199 	_m[t].m2 = tid;
    97 	SB(_m[t].m3, 6, 2, stage);
   200 	_m[t].m3 = 0;
    98 	_m[t].m4 = type;
   201 	SetHouseType(t, type);
    99 	SB(_m[t].m5, 0, 2, counter);
   202 	SetHouseCompleted(t, stage == TOWN_HOUSE_COMPLETED);
   100 
   203 	_m[t].m5 = IsHouseCompleted(t) ? 0 : (stage << 3 | counter);
       
   204 	SetHouseAnimationFrame(t, 0);
       
   205 	_me[t].m7 = GetHouseSpecs(type)->processing_time;
       
   206 
       
   207 	if (GetHouseSpecs(type)->building_flags & BUILDING_IS_ANIMATED) AddAnimatedTile(t);
   101 	MarkTileDirtyByTile(t);
   208 	MarkTileDirtyByTile(t);
   102 }
   209 }
   103 
   210 
   104 enum {
   211 /**
   105 	TWO_BY_TWO_BIT = 2, ///< House is two tiles in X and Y directions
   212  * Helper function for MakeHouseTile.
   106 	ONE_BY_TWO_BIT = 1, ///< House is two tiles in Y direction
   213  * It is called  for each tile of a multi-tile house.
   107 	TWO_BY_ONE_BIT = 0, ///< House is two tiles in X direction
   214  * Parametes are the same.
   108 };
   215  * @param t tile index
   109 
   216  * @param tid Town index
   110 static inline void MakeTownHouse(TileIndex t, TownID tid, byte counter, byte stage, byte size, byte type)
   217  * @param counter of construction step
   111 {
   218  * @param stage of construction (used for drawing)
   112 	MakeHouseTile(t, tid, counter, stage, type);
   219  * @param type of house.  Index into house specs array
   113 	if (HASBIT(size, TWO_BY_TWO_BIT) || HASBIT(size, ONE_BY_TWO_BIT)) MakeHouseTile(t + TileDiffXY(0, 1), tid, counter, stage, ++type);
   220  * @param random_bits required for newgrf houses
   114 	if (HASBIT(size, TWO_BY_TWO_BIT) || HASBIT(size, TWO_BY_ONE_BIT)) MakeHouseTile(t + TileDiffXY(1, 0), tid, counter, stage, ++type);
   221  */
   115 	if (HASBIT(size, TWO_BY_TWO_BIT)) MakeHouseTile(t + TileDiffXY(1, 1), tid, counter, stage, ++type);
   222 static inline void MakeTownHouse(TileIndex t, TownID tid, byte counter, byte stage, HouseID type, byte random_bits)
       
   223 {
       
   224 	BuildingFlags size = GetHouseSpecs(type)->building_flags;
       
   225 	MakeHouseTile(t, tid, counter, stage, type, random_bits);
       
   226 	if (size & BUILDING_2_TILES_Y)   MakeHouseTile(t + TileDiffXY(0, 1), tid, counter, stage, ++type, random_bits);
       
   227 	if (size & BUILDING_2_TILES_X)   MakeHouseTile(t + TileDiffXY(1, 0), tid, counter, stage, ++type, random_bits);
       
   228 	if (size & BUILDING_HAS_4_TILES) MakeHouseTile(t + TileDiffXY(1, 1), tid, counter, stage, ++type, random_bits);
   116 }
   229 }
   117 
   230 
   118 /**
   231 /**
   119  * House Construction Scheme.
   232  * House Construction Scheme.
   120  *  Construction counter, for buildings under construction. Incremented on every
   233  *  Construction counter, for buildings under construction. Incremented on every
   121  *  periodic tile processing.
   234  *  periodic tile processing.
   122  *  On wraparound, the stage of building in is increased.
   235  *  On wraparound, the stage of building in is increased.
   123  *  (Get|Set|Inc)HouseBuildingStage are taking care of the real stages,
   236  *  GetHouseBuildingStage is taking care of the real stages,
   124  *  (as the sprite for the next phase of house building)
   237  *  (as the sprite for the next phase of house building)
   125  *  (Get|Set|Inc)HouseConstructionTick is simply a tick counter between the
   238  *  (Get|Inc)HouseConstructionTick is simply a tick counter between the
   126  *  different stages
   239  *  different stages
   127  */
   240  */
   128 
   241 
   129 /**
   242 /**
   130  * Gets the building stage of a house
   243  * Gets the building stage of a house
   131  * @param tile the tile of the house to get the building stage of
   244  * Since the stage is used for determining what sprite to use,
       
   245  * if the house is complete (and that stage no longuer is available),
       
   246  * fool the system by returning the TOWN_HOUSE_COMPLETE (3),
       
   247  * thus showing a beautiful complete house.
       
   248  * @param t the tile of the house to get the building stage of
   132  * @pre IsTileType(t, MP_HOUSE)
   249  * @pre IsTileType(t, MP_HOUSE)
   133  * @return the building stage of the house
   250  * @return the building stage of the house
   134  */
   251  */
   135 static inline byte GetHouseBuildingStage(TileIndex t)
   252 static inline byte GetHouseBuildingStage(TileIndex t)
   136 {
   253 {
   137 	assert(IsTileType(t, MP_HOUSE));
   254 	assert(IsTileType(t, MP_HOUSE));
   138 	return GB(_m[t].m3, 6, 2);
   255 	return IsHouseCompleted(t) ? (byte)TOWN_HOUSE_COMPLETED : GB(_m[t].m5, 3, 2);
   139 }
       
   140 
       
   141 /**
       
   142  * Sets the building stage of a house
       
   143  * @param tile the tile of the house to set the building stage of
       
   144  * @param stage the new stage
       
   145  * @pre IsTileType(t, MP_HOUSE)
       
   146  */
       
   147 static inline void SetHouseBuildingStage(TileIndex t, byte stage)
       
   148 {
       
   149 	assert(IsTileType(t, MP_HOUSE));
       
   150 	SB(_m[t].m3, 6, 2, stage);
       
   151 }
       
   152 
       
   153 /**
       
   154  * Increments the building stage of a house
       
   155  * @param tile the tile of the house to increment the building stage of
       
   156  * @pre IsTileType(t, MP_HOUSE)
       
   157  */
       
   158 static inline void IncHouseBuildingStage( TileIndex t )
       
   159 {
       
   160 	assert(IsTileType(t, MP_HOUSE));
       
   161 	AB(_m[t].m3, 6, 2, 1);
       
   162 }
   256 }
   163 
   257 
   164 /**
   258 /**
   165  * Gets the construction stage of a house
   259  * Gets the construction stage of a house
   166  * @param tile the tile of the house to get the construction stage of
   260  * @param t the tile of the house to get the construction stage of
   167  * @pre IsTileType(t, MP_HOUSE)
   261  * @pre IsTileType(t, MP_HOUSE)
   168  * @return the construction stage of the house
   262  * @return the construction stage of the house
   169  */
   263  */
   170 static inline byte GetHouseConstructionTick(TileIndex t)
   264 static inline byte GetHouseConstructionTick(TileIndex t)
   171 {
   265 {
   172 	assert(IsTileType(t, MP_HOUSE));
   266 	assert(IsTileType(t, MP_HOUSE));
   173 	return GB(_m[t].m5, 0, 3);
   267 	return IsHouseCompleted(t) ? 0 : GB(_m[t].m5, 0, 3);
   174 }
       
   175 
       
   176 /**
       
   177  * Sets the construction stage of a house
       
   178  * @param tile the tile of the house to set the construction stage of
       
   179  * @param stage the new stage
       
   180  * @pre IsTileType(t, MP_HOUSE)
       
   181  */
       
   182 static inline void SetHouseConstructionTick(TileIndex t, byte stage)
       
   183 {
       
   184 	assert(IsTileType(t, MP_HOUSE));
       
   185 	SB(_m[t].m5, 0, 3, stage);
       
   186 }
   268 }
   187 
   269 
   188 /**
   270 /**
   189  * Sets the increment stage of a house
   271  * Sets the increment stage of a house
   190  * @param tile the tile of the house to increment the construction stage of
   272  * It is working with the whole counter + stage 5 bits, making it
       
   273  * easier to work:  the wraparound is automatic.
       
   274  * @param t the tile of the house to increment the construction stage of
   191  * @pre IsTileType(t, MP_HOUSE)
   275  * @pre IsTileType(t, MP_HOUSE)
   192  */
   276  */
   193 static inline void IncHouseConstructionTick(TileIndex t)
   277 static inline void IncHouseConstructionTick(TileIndex t)
   194 {
   278 {
   195 	assert(IsTileType(t, MP_HOUSE));
   279 	assert(IsTileType(t, MP_HOUSE));
   196 	AB(_m[t].m5, 0, 3, 1);
   280 	AB(_m[t].m5, 0, 5, 1);
   197 }
   281 
   198 
   282 	if (GB(_m[t].m5, 3, 2) == TOWN_HOUSE_COMPLETED) {
       
   283 		/* House is now completed.
       
   284 		 * Store the year of construction as well, for newgrf house purpose */
       
   285 		SetHouseCompleted(t, true);
       
   286 		_m[t].m5 = clamp(_cur_year - ORIGINAL_BASE_YEAR, 0, 0xFF);
       
   287 	}
       
   288 }
       
   289 
       
   290 /**
       
   291  * Get the year that this house was constructed (between 1920 and 2175).
       
   292  * @param t the tile of this house
       
   293  * @pre IsTileType(t, MP_HOUSE)
       
   294  * @return year
       
   295  */
       
   296 static inline Year GetHouseConstructionYear(TileIndex t)
       
   297 {
       
   298 	assert(IsTileType(t, MP_HOUSE));
       
   299 	return IsHouseCompleted(t) ? _m[t].m5 + ORIGINAL_BASE_YEAR : 0;
       
   300 }
       
   301 
       
   302 /**
       
   303  * Get the random bits for this house.
       
   304  * This is required for newgrf house
       
   305  * @param t the tile of this house
       
   306  * @pre IsTileType(t, MP_HOUSE)
       
   307  * @return random bits
       
   308  */
       
   309 static inline byte GetHouseRandomBits(TileIndex t)
       
   310 {
       
   311 	assert(IsTileType(t, MP_HOUSE));
       
   312 	return _m[t].m1;
       
   313 }
       
   314 
       
   315 /**
       
   316  * Set the activated triggers bits for this house.
       
   317  * This is required for newgrf house
       
   318  * @param t the tile of this house
       
   319  * @pre IsTileType(t, MP_HOUSE)
       
   320  */
       
   321 static inline void SetHouseTriggers(TileIndex t, byte triggers)
       
   322 {
       
   323 	assert(IsTileType(t, MP_HOUSE));
       
   324 	SB(_m[t].m3, 0, 5, triggers);
       
   325 }
       
   326 
       
   327 /**
       
   328  * Get the already activated triggers bits for this house.
       
   329  * This is required for newgrf house
       
   330  * @param t the tile of this house
       
   331  * @pre IsTileType(t, MP_HOUSE)
       
   332  * @return triggers
       
   333  */
       
   334 static inline byte GetHouseTriggers(TileIndex t)
       
   335 {
       
   336 	assert(IsTileType(t, MP_HOUSE));
       
   337 	return GB(_m[t].m3, 0, 5);
       
   338 }
       
   339 
       
   340 /**
       
   341  * Get the amount of time remaining before the tile loop processes this tile.
       
   342  * @param t the house tile
       
   343  * @pre IsTileType(t, MP_HOUSE)
       
   344  * @return time remaining
       
   345  */
       
   346 static inline byte GetHouseProcessingTime(TileIndex t)
       
   347 {
       
   348 	assert(IsTileType(t, MP_HOUSE));
       
   349 	return _me[t].m7;
       
   350 }
       
   351 
       
   352 /**
       
   353  * Set the amount of time remaining before the tile loop processes this tile.
       
   354  * @param t the house tile
       
   355  * @param time the time to be set
       
   356  * @pre IsTileType(t, MP_HOUSE)
       
   357  */
       
   358 static inline void SetHouseProcessingTime(TileIndex t, byte time)
       
   359 {
       
   360 	assert(IsTileType(t, MP_HOUSE));
       
   361 	_me[t].m7 = time;
       
   362 }
       
   363 
       
   364 /**
       
   365  * Decrease the amount of time remaining before the tile loop processes this tile.
       
   366  * @param t the house tile
       
   367  * @pre IsTileType(t, MP_HOUSE)
       
   368  */
       
   369 static inline void DecHouseProcessingTime(TileIndex t)
       
   370 {
       
   371 	assert(IsTileType(t, MP_HOUSE));
       
   372 	_me[t].m7--;
       
   373 }
   199 
   374 
   200 #endif /* TOWN_MAP_H */
   375 #endif /* TOWN_MAP_H */