tron@3319: /* $Id$ */ tron@3319: belugas@3432: /** @file town_map.h Accessors for towns */ belugas@3432: celestar@3426: #ifndef TOWN_MAP_H celestar@3426: #define TOWN_MAP_H celestar@3426: tron@3319: #include "town.h" richk@10274: #include "date_type.h" rubidium@6872: #include "tile_map.h" tron@3319: maedhros@6658: /** maedhros@6658: * Get the index of which town this house/street is attached to. maedhros@6658: * @param t the tile richk@6743: * @pre IsTileType(t, MP_HOUSE) or IsTileType(t, MP_ROAD) maedhros@6658: * @return TownID maedhros@6658: */ belugas@3432: static inline TownID GetTownIndex(TileIndex t) tron@3319: { richk@6743: assert(IsTileType(t, MP_HOUSE) || IsTileType(t, MP_ROAD)); // XXX incomplete tron@3319: return _m[t].m2; tron@3319: } tron@3319: belugas@3432: /** tron@3983: * Set the town index for a road or house tile. maedhros@6658: * @param t the tile richk@6743: * @pre IsTileType(t, MP_HOUSE) or IsTileType(t, MP_ROAD) belugas@3432: * @param index the index of the town richk@6743: * @pre IsTileType(t, MP_ROAD) || IsTileType(t, MP_HOUSE) belugas@3432: */ belugas@3432: static inline void SetTownIndex(TileIndex t, TownID index) belugas@3432: { richk@6743: assert(IsTileType(t, MP_HOUSE) || IsTileType(t, MP_ROAD)); belugas@3432: _m[t].m2 = index; belugas@3432: } belugas@3432: rubidium@6220: /** rubidium@6220: * Gets the town associated with the house or road tile rubidium@6220: * @param t the tile to get the town of rubidium@6220: * @return the town rubidium@6220: */ richk@6743: static inline Town *GetTownByTile(TileIndex t) rubidium@6220: { rubidium@6220: return GetTown(GetTownIndex(t)); rubidium@6220: } rubidium@6220: maedhros@6658: /** maedhros@6658: * Get the type of this house, which is an index into the house spec array maedhros@6658: * Since m4 is only a byte and we want to support 512 houses, we use the bit 6 maedhros@6658: * of m3 as an additional bit to house type. maedhros@6658: * @param t the tile maedhros@6658: * @pre IsTileType(t, MP_HOUSE) maedhros@6658: * @return house type maedhros@6658: */ maedhros@6658: static inline HouseID GetHouseType(TileIndex t) rubidium@6220: { rubidium@6220: assert(IsTileType(t, MP_HOUSE)); maedhros@6658: return _m[t].m4 | (GB(_m[t].m3, 6, 1) << 8); celestar@3426: } celestar@3426: maedhros@6658: /** maedhros@6658: * Set the house type. maedhros@6658: * @param t the tile maedhros@6658: * @param house_id the new house type maedhros@6658: * @pre IsTileType(t, MP_HOUSE) maedhros@6658: */ maedhros@6658: static inline void SetHouseType(TileIndex t, HouseID house_id) celestar@3426: { maedhros@6658: assert(IsTileType(t, MP_HOUSE)); maedhros@6658: _m[t].m4 = GB(house_id, 0, 8); maedhros@6658: SB(_m[t].m3, 6, 1, GB(house_id, 8, 1)); celestar@3426: } celestar@3426: maedhros@6658: /** maedhros@6658: * Check if the lift of this animated house has a destination maedhros@6658: * @param t the tile maedhros@6658: * @return has destination maedhros@6658: */ maedhros@6658: static inline bool LiftHasDestination(TileIndex t) celestar@3426: { rubidium@6871: return HasBit(_me[t].m7, 0); celestar@3426: } celestar@3426: maedhros@6658: /** maedhros@6658: * Set the new destination of the lift for this animated house, and activate maedhros@6658: * the LiftHasDestination bit. maedhros@6658: * @param t the tile maedhros@6658: * @param dest new destination maedhros@6658: */ maedhros@6658: static inline void SetLiftDestination(TileIndex t, byte dest) maedhros@6658: { rubidium@6871: SetBit(_me[t].m7, 0); maedhros@6658: SB(_me[t].m7, 1, 3, dest); maedhros@6658: } maedhros@6658: maedhros@6658: /** maedhros@6658: * Get the current destination for this lift maedhros@6658: * @param t the tile maedhros@6658: * @return destination maedhros@6658: */ maedhros@6658: static inline byte GetLiftDestination(TileIndex t) maedhros@6658: { maedhros@6658: return GB(_me[t].m7, 1, 3); maedhros@6658: } maedhros@6658: maedhros@6658: /** maedhros@6658: * Stop the lift of this animated house from moving. maedhros@6658: * Clears the first 4 bits of m7 at once, clearing the LiftHasDestination bit maedhros@6658: * and the destination. maedhros@6658: * @param t the tile maedhros@6658: */ celestar@3426: static inline void HaltLift(TileIndex t) celestar@3426: { maedhros@6658: SB(_me[t].m7, 0, 4, 0); celestar@3426: } celestar@3426: maedhros@6658: /** maedhros@6658: * Get the position of the lift on this animated house maedhros@6658: * @param t the tile maedhros@6658: * @return position, from 0 to 36 maedhros@6658: */ celestar@3426: static inline byte GetLiftPosition(TileIndex t) celestar@3426: { maedhros@6658: return GB(_m[t].m6, 2, 6); celestar@3426: } celestar@3426: maedhros@6658: /** maedhros@6658: * Set the position of the lift on this animated house maedhros@6658: * @param t the tile richk@6719: * @param pos position, from 0 to 36 maedhros@6658: */ celestar@3426: static inline void SetLiftPosition(TileIndex t, byte pos) celestar@3426: { maedhros@6658: SB(_m[t].m6, 2, 6, pos); celestar@3426: } celestar@3426: maedhros@6658: /** maedhros@6658: * Get the current animation frame for this house maedhros@6658: * @param t the tile maedhros@6658: * @pre IsTileType(t, MP_HOUSE) maedhros@6658: * @return frame number maedhros@6658: */ maedhros@6658: static inline byte GetHouseAnimationFrame(TileIndex t) maedhros@6658: { maedhros@6658: assert(IsTileType(t, MP_HOUSE)); richk@6878: return GB(_m[t].m6, 2, 6) | (GB(_m[t].m3, 5, 1) << 6); maedhros@6658: } maedhros@6658: maedhros@6658: /** maedhros@6658: * Set a new animation frame for this house maedhros@6658: * @param t the tile maedhros@6658: * @param frame the new frame number maedhros@6658: * @pre IsTileType(t, MP_HOUSE) maedhros@6658: */ maedhros@6658: static inline void SetHouseAnimationFrame(TileIndex t, byte frame) maedhros@6658: { maedhros@6658: assert(IsTileType(t, MP_HOUSE)); richk@6878: SB(_m[t].m6, 2, 6, GB(frame, 0, 6)); richk@6878: SB(_m[t].m3, 5, 1, GB(frame, 6, 1)); maedhros@6658: } maedhros@6658: maedhros@6658: /** maedhros@6658: * Get the completion of this house maedhros@6658: * @param t the tile maedhros@6658: * @return true if it is, false if it is not maedhros@6658: */ maedhros@6658: static inline bool IsHouseCompleted(TileIndex t) maedhros@6658: { maedhros@6658: assert(IsTileType(t, MP_HOUSE)); rubidium@6871: return HasBit(_m[t].m3, 7); maedhros@6658: } maedhros@6658: maedhros@6658: /** maedhros@6658: * Mark this house as been completed maedhros@6658: * @param t the tile maedhros@6658: * @param status maedhros@6658: */ maedhros@6658: static inline void SetHouseCompleted(TileIndex t, bool status) maedhros@6658: { maedhros@6658: assert(IsTileType(t, MP_HOUSE)); maedhros@6658: SB(_m[t].m3, 7, 1, !!status); maedhros@6658: } maedhros@6658: maedhros@6658: /** maedhros@6658: * Make the tile a house. maedhros@6658: * @param t tile index maedhros@6658: * @param tid Town index maedhros@6658: * @param counter of construction step maedhros@6658: * @param stage of construction (used for drawing) maedhros@6658: * @param type of house. Index into house specs array maedhros@6658: * @param random_bits required for newgrf houses maedhros@6658: * @pre IsTileType(t, MP_CLEAR) maedhros@6658: */ maedhros@6658: static inline void MakeHouseTile(TileIndex t, TownID tid, byte counter, byte stage, HouseID type, byte random_bits) celestar@3382: { celestar@3382: assert(IsTileType(t, MP_CLEAR)); celestar@3382: celestar@3382: SetTileType(t, MP_HOUSE); maedhros@6658: _m[t].m1 = random_bits; celestar@3382: _m[t].m2 = tid; maedhros@6658: _m[t].m3 = 0; maedhros@6658: SetHouseType(t, type); maedhros@6658: SetHouseCompleted(t, stage == TOWN_HOUSE_COMPLETED); maedhros@6658: _m[t].m5 = IsHouseCompleted(t) ? 0 : (stage << 3 | counter); maedhros@6658: SetHouseAnimationFrame(t, 0); maedhros@6658: _me[t].m7 = GetHouseSpecs(type)->processing_time; celestar@3382: } celestar@3382: maedhros@6658: /** belugas@3432: * House Construction Scheme. belugas@3432: * Construction counter, for buildings under construction. Incremented on every belugas@3432: * periodic tile processing. belugas@3432: * On wraparound, the stage of building in is increased. maedhros@6658: * GetHouseBuildingStage is taking care of the real stages, belugas@3432: * (as the sprite for the next phase of house building) maedhros@6658: * (Get|Inc)HouseConstructionTick is simply a tick counter between the belugas@3432: * different stages belugas@3432: */ belugas@3432: belugas@3432: /** belugas@3432: * Gets the building stage of a house maedhros@6658: * Since the stage is used for determining what sprite to use, maedhros@6658: * if the house is complete (and that stage no longuer is available), maedhros@6658: * fool the system by returning the TOWN_HOUSE_COMPLETE (3), maedhros@6658: * thus showing a beautiful complete house. maedhros@6658: * @param t the tile of the house to get the building stage of belugas@3432: * @pre IsTileType(t, MP_HOUSE) belugas@3432: * @return the building stage of the house belugas@3432: */ belugas@3432: static inline byte GetHouseBuildingStage(TileIndex t) belugas@3432: { belugas@3432: assert(IsTileType(t, MP_HOUSE)); maedhros@6658: return IsHouseCompleted(t) ? (byte)TOWN_HOUSE_COMPLETED : GB(_m[t].m5, 3, 2); belugas@3432: } belugas@3432: belugas@3432: /** belugas@3432: * Gets the construction stage of a house maedhros@6658: * @param t the tile of the house to get the construction stage of belugas@3432: * @pre IsTileType(t, MP_HOUSE) belugas@3432: * @return the construction stage of the house belugas@3432: */ belugas@3432: static inline byte GetHouseConstructionTick(TileIndex t) belugas@3432: { belugas@3432: assert(IsTileType(t, MP_HOUSE)); maedhros@6658: return IsHouseCompleted(t) ? 0 : GB(_m[t].m5, 0, 3); belugas@3432: } belugas@3432: belugas@3432: /** belugas@3432: * Sets the increment stage of a house maedhros@6658: * It is working with the whole counter + stage 5 bits, making it maedhros@6658: * easier to work: the wraparound is automatic. maedhros@6658: * @param t the tile of the house to increment the construction stage of belugas@3432: * @pre IsTileType(t, MP_HOUSE) belugas@3432: */ belugas@3432: static inline void IncHouseConstructionTick(TileIndex t) belugas@3432: { belugas@3432: assert(IsTileType(t, MP_HOUSE)); maedhros@6658: AB(_m[t].m5, 0, 5, 1); maedhros@6658: maedhros@6658: if (GB(_m[t].m5, 3, 2) == TOWN_HOUSE_COMPLETED) { maedhros@6658: /* House is now completed. maedhros@6658: * Store the year of construction as well, for newgrf house purpose */ maedhros@6658: SetHouseCompleted(t, true); maedhros@6658: } belugas@3432: } belugas@3432: maedhros@6658: /** richk@10994: * Set the year that this house was constructed. richk@10274: * @param t the tile of this house richk@10274: * @param year the year to set richk@10274: * @pre IsTileType(t, MP_HOUSE) && IsHouseCompleted(t) richk@10274: */ richk@10274: static inline void SetHouseConstructionYear(TileIndex t, Year year) richk@10274: { richk@10274: assert(IsTileType(t, MP_HOUSE) && IsHouseCompleted(t)); richk@10994: _m[t].m5 = Clamp(year - GetHouseSpecs(GetHouseType(t))->min_year, 0, 0xFF); richk@10274: } richk@10274: richk@10274: /** richk@10994: * Get the year that this house was constructed. maedhros@6658: * @param t the tile of this house maedhros@6658: * @pre IsTileType(t, MP_HOUSE) maedhros@6658: * @return year maedhros@6658: */ maedhros@6658: static inline Year GetHouseConstructionYear(TileIndex t) maedhros@6658: { maedhros@6658: assert(IsTileType(t, MP_HOUSE)); richk@10994: return IsHouseCompleted(t) ? _m[t].m5 + GetHouseSpecs(GetHouseType(t))->min_year : 0; maedhros@6658: } maedhros@6658: maedhros@6658: /** rubidium@6871: * Set the random bits for this house. rubidium@6871: * This is required for newgrf house rubidium@6871: * @param t the tile of this house rubidium@6871: * @param random the new random bits rubidium@6871: * @pre IsTileType(t, MP_HOUSE) rubidium@6871: */ rubidium@6871: static inline void SetHouseRandomBits(TileIndex t, byte random) rubidium@6871: { rubidium@6871: assert(IsTileType(t, MP_HOUSE)); rubidium@6871: _m[t].m1 = random; rubidium@6871: } rubidium@6871: rubidium@6871: /** maedhros@6658: * Get the random bits for this house. maedhros@6658: * This is required for newgrf house maedhros@6658: * @param t the tile of this house maedhros@6658: * @pre IsTileType(t, MP_HOUSE) maedhros@6658: * @return random bits maedhros@6658: */ maedhros@6658: static inline byte GetHouseRandomBits(TileIndex t) maedhros@6658: { maedhros@6658: assert(IsTileType(t, MP_HOUSE)); maedhros@6658: return _m[t].m1; maedhros@6658: } maedhros@6658: maedhros@6658: /** maedhros@6658: * Set the activated triggers bits for this house. maedhros@6658: * This is required for newgrf house richk@6719: * @param t the tile of this house richk@6719: * @param triggers the activated triggers maedhros@6658: * @pre IsTileType(t, MP_HOUSE) maedhros@6658: */ maedhros@6658: static inline void SetHouseTriggers(TileIndex t, byte triggers) maedhros@6658: { maedhros@6658: assert(IsTileType(t, MP_HOUSE)); maedhros@6658: SB(_m[t].m3, 0, 5, triggers); maedhros@6658: } maedhros@6658: maedhros@6658: /** maedhros@6658: * Get the already activated triggers bits for this house. maedhros@6658: * This is required for newgrf house maedhros@6658: * @param t the tile of this house maedhros@6658: * @pre IsTileType(t, MP_HOUSE) maedhros@6658: * @return triggers maedhros@6658: */ maedhros@6658: static inline byte GetHouseTriggers(TileIndex t) maedhros@6658: { maedhros@6658: assert(IsTileType(t, MP_HOUSE)); maedhros@6658: return GB(_m[t].m3, 0, 5); maedhros@6658: } maedhros@6658: maedhros@6658: /** maedhros@6658: * Get the amount of time remaining before the tile loop processes this tile. maedhros@6658: * @param t the house tile maedhros@6658: * @pre IsTileType(t, MP_HOUSE) maedhros@6658: * @return time remaining maedhros@6658: */ maedhros@6658: static inline byte GetHouseProcessingTime(TileIndex t) maedhros@6658: { maedhros@6658: assert(IsTileType(t, MP_HOUSE)); maedhros@6658: return _me[t].m7; maedhros@6658: } maedhros@6658: maedhros@6658: /** maedhros@6658: * Set the amount of time remaining before the tile loop processes this tile. maedhros@6658: * @param t the house tile maedhros@6658: * @param time the time to be set maedhros@6658: * @pre IsTileType(t, MP_HOUSE) maedhros@6658: */ maedhros@6658: static inline void SetHouseProcessingTime(TileIndex t, byte time) maedhros@6658: { maedhros@6658: assert(IsTileType(t, MP_HOUSE)); maedhros@6658: _me[t].m7 = time; maedhros@6658: } maedhros@6658: maedhros@6658: /** maedhros@6658: * Decrease the amount of time remaining before the tile loop processes this tile. maedhros@6658: * @param t the house tile maedhros@6658: * @pre IsTileType(t, MP_HOUSE) maedhros@6658: */ maedhros@6658: static inline void DecHouseProcessingTime(TileIndex t) maedhros@6658: { maedhros@6658: assert(IsTileType(t, MP_HOUSE)); maedhros@6658: _me[t].m7--; maedhros@6658: } belugas@3432: belugas@3432: #endif /* TOWN_MAP_H */