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 */ |