src/newgrf_industrytiles.cpp
changeset 7229 a5f262f6df1b
parent 7216 2bb13ff061b1
child 7233 aadfbb505671
equal deleted inserted replaced
7228:24f0a19ca622 7229:a5f262f6df1b
    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 }