13 #include "industry.h" |
13 #include "industry.h" |
14 #include "newgrf_commons.h" |
14 #include "newgrf_commons.h" |
15 #include "newgrf_spritegroup.h" |
15 #include "newgrf_spritegroup.h" |
16 #include "newgrf_callbacks.h" |
16 #include "newgrf_callbacks.h" |
17 #include "newgrf_industries.h" |
17 #include "newgrf_industries.h" |
|
18 #include "newgrf_industrytiles.h" |
18 #include "newgrf_text.h" |
19 #include "newgrf_text.h" |
19 #include "industry_map.h" |
20 #include "industry_map.h" |
20 #include "clear_map.h" |
21 #include "clear_map.h" |
21 #include "table/sprites.h" |
22 #include "table/sprites.h" |
22 #include "table/strings.h" |
23 #include "table/strings.h" |
247 case 0x402: _error_message = STR_0317_CAN_ONLY_BE_BUILT_IN_RAINFOREST; return false; |
248 case 0x402: _error_message = STR_0317_CAN_ONLY_BE_BUILT_IN_RAINFOREST; return false; |
248 case 0x403: _error_message = STR_0318_CAN_ONLY_BE_BUILT_IN_DESERT; return false; |
249 case 0x403: _error_message = STR_0318_CAN_ONLY_BE_BUILT_IN_DESERT; return false; |
249 default: _error_message = GetGRFStringID(its->grf_prop.grffile->grfid, 0xD000 + callback_res); return false; |
250 default: _error_message = GetGRFStringID(its->grf_prop.grffile->grfid, 0xD000 + callback_res); return false; |
250 } |
251 } |
251 } |
252 } |
|
253 |
|
254 void AnimateNewIndustryTile(TileIndex tile) |
|
255 { |
|
256 Industry *ind = GetIndustryByTile(tile); |
|
257 IndustryGfx gfx = GetIndustryGfx(tile); |
|
258 const IndustryTileSpec *itspec = GetIndustryTileSpec(gfx); |
|
259 byte animation_speed = itspec->animation_speed; |
|
260 |
|
261 if (HASBIT(itspec->callback_flags, CBM_INDT_ANIM_SPEED)) { |
|
262 uint16 callback_res = GetIndustryTileCallback(CBID_INDTILE_ANIMATION_SPEED, 0, 0, gfx, ind, tile); |
|
263 if (callback_res != CALLBACK_FAILED) animation_speed = clamp(callback_res & 0xFF, 0, 16); |
|
264 } |
|
265 |
|
266 /* An animation speed of 2 means the animation frame changes 4 ticks, and |
|
267 * increasing this value by one doubles the wait. 0 is the minimum value |
|
268 * allowed for animation_speed, which corresponds to 30ms, and 16 is the |
|
269 * maximum, corresponding to around 33 minutes. */ |
|
270 if ((_tick_counter % (1 << animation_speed)) != 0) return; |
|
271 |
|
272 bool frame_set_by_callback = false; |
|
273 byte frame = GetIndustryAnimationState(tile); |
|
274 uint16 num_frames = GB(itspec->animation_info, 0, 8) + 1; |
|
275 |
|
276 if (HASBIT(itspec->callback_flags, CBM_INDT_ANIM_NEXT_FRAME)) { |
|
277 uint16 callback_res = GetIndustryTileCallback(CBID_INDTILE_ANIM_NEXT_FRAME, HASBIT(itspec->animation_special_flags, 0) ? Random() : 0, 0, gfx, ind, tile); |
|
278 |
|
279 if (callback_res != CALLBACK_FAILED) { |
|
280 frame_set_by_callback = true; |
|
281 |
|
282 switch (callback_res & 0xFF) { |
|
283 case 0xFF: |
|
284 DeleteAnimatedTile(tile); |
|
285 break; |
|
286 case 0xFE: |
|
287 /* Carry on as normal. */ |
|
288 frame_set_by_callback = false; |
|
289 break; |
|
290 default: |
|
291 frame = callback_res & 0xFF; |
|
292 break; |
|
293 } |
|
294 } |
|
295 } |
|
296 |
|
297 if (!frame_set_by_callback) { |
|
298 if (frame < num_frames) { |
|
299 frame++; |
|
300 } else if (frame == num_frames && GB(itspec->animation_info, 8, 8) == 1) { |
|
301 /* This animation loops, so start again from the beginning */ |
|
302 frame = 0; |
|
303 } else { |
|
304 /* This animation doesn't loop, so stay here */ |
|
305 DeleteAnimatedTile(tile); |
|
306 } |
|
307 } |
|
308 |
|
309 SetIndustryAnimationState(tile, frame); |
|
310 MarkTileDirtyByTile(tile); |
|
311 } |
|
312 |
|
313 static void ChangeIndustryTileAnimationFrame(TileIndex tile, IndustryAnimationTrigger iat, uint32 random_bits, IndustryGfx gfx, Industry *ind) |
|
314 { |
|
315 uint16 callback_res = GetIndustryTileCallback(CBID_INDTILE_ANIM_START_STOP, random_bits, iat, gfx, ind, tile); |
|
316 if (callback_res == CALLBACK_FAILED) return; |
|
317 |
|
318 switch (callback_res & 0xFF) { |
|
319 case 0xFD: /* Do nothing. */ break; |
|
320 case 0xFE: AddAnimatedTile(tile); break; |
|
321 case 0xFF: DeleteAnimatedTile(tile); break; |
|
322 default: |
|
323 SetIndustryAnimationState(tile, callback_res & 0xFF); |
|
324 AddAnimatedTile(tile); |
|
325 break; |
|
326 } |
|
327 } |
|
328 |
|
329 bool StartStopIndustryTileAnimation(TileIndex tile, IndustryAnimationTrigger iat, uint32 random) |
|
330 { |
|
331 IndustryGfx gfx = GetIndustryGfx(tile); |
|
332 const IndustryTileSpec *itspec = GetIndustryTileSpec(gfx); |
|
333 |
|
334 if (!HASBIT(itspec->animation_triggers, iat)) return false; |
|
335 |
|
336 Industry *ind = GetIndustryByTile(tile); |
|
337 ChangeIndustryTileAnimationFrame(tile, iat, random, gfx, ind); |
|
338 return true; |
|
339 } |
|
340 |
|
341 bool StartStopIndustryTileAnimation(const Industry *ind, IndustryAnimationTrigger iat) |
|
342 { |
|
343 bool ret = true; |
|
344 uint32 random = Random(); |
|
345 BEGIN_TILE_LOOP(tile, ind->width, ind->height, ind->xy) |
|
346 if (IsTileType(tile, MP_INDUSTRY) && GetIndustryIndex(tile) == ind->index) { |
|
347 ret &= StartStopIndustryTileAnimation(tile, iat, random); |
|
348 SB(random, 0, 16, Random()); |
|
349 } |
|
350 END_TILE_LOOP(tile, ind->width, ind->height, ind->xy) |
|
351 |
|
352 return ret; |
|
353 } |