src/industry_cmd.cpp
branchnoai
changeset 9722 ebf0ece7d8f6
parent 9718 f82a4facea8b
child 9723 eee46cb39750
equal deleted inserted replaced
9721:9a27928bcd5e 9722:ebf0ece7d8f6
    11 #include "table/strings.h"
    11 #include "table/strings.h"
    12 #include "strings.h"
    12 #include "strings.h"
    13 #include "table/sprites.h"
    13 #include "table/sprites.h"
    14 #include "map.h"
    14 #include "map.h"
    15 #include "tile.h"
    15 #include "tile.h"
       
    16 #include "train.h"
    16 #include "landscape.h"
    17 #include "landscape.h"
    17 #include "viewport.h"
    18 #include "viewport.h"
    18 #include "command.h"
    19 #include "command.h"
    19 #include "industry.h"
    20 #include "industry.h"
    20 #include "town.h"
    21 #include "town.h"
    36 #include "newgrf_industries.h"
    37 #include "newgrf_industries.h"
    37 #include "newgrf_industrytiles.h"
    38 #include "newgrf_industrytiles.h"
    38 #include "newgrf_callbacks.h"
    39 #include "newgrf_callbacks.h"
    39 #include "misc/autoptr.hpp"
    40 #include "misc/autoptr.hpp"
    40 #include "autoslope.h"
    41 #include "autoslope.h"
       
    42 #include "transparency.h"
    41 
    43 
    42 void ShowIndustryViewWindow(int industry);
    44 void ShowIndustryViewWindow(int industry);
    43 void BuildOilRig(TileIndex tile);
    45 void BuildOilRig(TileIndex tile);
    44 
    46 
    45 static byte _industry_sound_ctr;
    47 static byte _industry_sound_ctr;
    64 	memcpy(&_industry_specs, &_origin_industry_specs, sizeof(_origin_industry_specs));
    66 	memcpy(&_industry_specs, &_origin_industry_specs, sizeof(_origin_industry_specs));
    65 
    67 
    66 	/* once performed, enable only the current climate industries */
    68 	/* once performed, enable only the current climate industries */
    67 	for (IndustryType i = 0; i < NUM_INDUSTRYTYPES; i++) {
    69 	for (IndustryType i = 0; i < NUM_INDUSTRYTYPES; i++) {
    68 		_industry_specs[i].enabled = i < NEW_INDUSTRYOFFSET &&
    70 		_industry_specs[i].enabled = i < NEW_INDUSTRYOFFSET &&
    69 				HASBIT(_origin_industry_specs[i].climate_availability, _opt.landscape);
    71 				HasBit(_origin_industry_specs[i].climate_availability, _opt.landscape);
    70 	}
    72 	}
    71 
    73 
    72 	memset(&_industry_tile_specs, 0, sizeof(_industry_tile_specs));
    74 	memset(&_industry_tile_specs, 0, sizeof(_industry_tile_specs));
    73 	memcpy(&_industry_tile_specs, &_origin_industry_tile_specs, sizeof(_origin_industry_tile_specs));
    75 	memcpy(&_industry_tile_specs, &_origin_industry_tile_specs, sizeof(_origin_industry_tile_specs));
    74 
    76 
   286 	dits = &_industry_draw_tile_data[gfx << 2 | (indts->anim_state ?
   288 	dits = &_industry_draw_tile_data[gfx << 2 | (indts->anim_state ?
   287 			GetIndustryAnimationState(ti->tile) & INDUSTRY_COMPLETED :
   289 			GetIndustryAnimationState(ti->tile) & INDUSTRY_COMPLETED :
   288 			GetIndustryConstructionStage(ti->tile))];
   290 			GetIndustryConstructionStage(ti->tile))];
   289 
   291 
   290 	image = dits->ground.sprite;
   292 	image = dits->ground.sprite;
   291 	if (HASBIT(image, PALETTE_MODIFIER_COLOR) && dits->ground.pal == PAL_NONE) {
   293 	if (HasBit(image, PALETTE_MODIFIER_COLOR) && dits->ground.pal == PAL_NONE) {
   292 		pal = GENERAL_SPRITE_COLOR(ind->random_color);
   294 		pal = GENERAL_SPRITE_COLOR(ind->random_color);
   293 	} else {
   295 	} else {
   294 		pal = dits->ground.pal;
   296 		pal = dits->ground.pal;
   295 	}
   297 	}
   296 
   298 
   301 
   303 
   302 	/* Add industry on top of the ground? */
   304 	/* Add industry on top of the ground? */
   303 	image = dits->building.sprite;
   305 	image = dits->building.sprite;
   304 	if (image != 0) {
   306 	if (image != 0) {
   305 		AddSortableSpriteToDraw(image,
   307 		AddSortableSpriteToDraw(image,
   306 			(HASBIT(image, PALETTE_MODIFIER_COLOR) && dits->building.pal == PAL_NONE) ? GENERAL_SPRITE_COLOR(ind->random_color) : dits->building.pal,
   308 			(HasBit(image, PALETTE_MODIFIER_COLOR) && dits->building.pal == PAL_NONE) ? GENERAL_SPRITE_COLOR(ind->random_color) : dits->building.pal,
   307 			ti->x + dits->subtile_x,
   309 			ti->x + dits->subtile_x,
   308 			ti->y + dits->subtile_y,
   310 			ti->y + dits->subtile_y,
   309 			dits->width,
   311 			dits->width,
   310 			dits->height,
   312 			dits->height,
   311 			dits->dz,
   313 			dits->dz,
   312 			ti->z,
   314 			ti->z,
   313 			HASBIT(_transparent_opt, TO_INDUSTRIES));
   315 			IsTransparencySet(TO_INDUSTRIES));
   314 
   316 
   315 		if (HASBIT(_transparent_opt, TO_INDUSTRIES)) return;
   317 		if (IsTransparencySet(TO_INDUSTRIES)) return;
   316 	}
   318 	}
   317 
   319 
   318 	{
   320 	{
   319 		int proc = dits->draw_proc - 1;
   321 		int proc = dits->draw_proc - 1;
   320 		if (proc >= 0) _industry_draw_tile_procs[proc](ti);
   322 		if (proc >= 0) _industry_draw_tile_procs[proc](ti);
   342 
   344 
   343 	/* And then these will always point to a same sized array with the required data */
   345 	/* And then these will always point to a same sized array with the required data */
   344 	const CargoID *accepts_cargo = itspec->accepts_cargo;
   346 	const CargoID *accepts_cargo = itspec->accepts_cargo;
   345 	const uint8 *acceptance = itspec->acceptance;
   347 	const uint8 *acceptance = itspec->acceptance;
   346 
   348 
   347 	if (HASBIT(itspec->callback_flags, CBM_INDT_ACCEPT_CARGO)) {
   349 	if (HasBit(itspec->callback_flags, CBM_INDT_ACCEPT_CARGO)) {
   348 		uint16 res = GetIndustryTileCallback(CBID_INDTILE_ACCEPT_CARGO, 0, 0, gfx, GetIndustryByTile(tile), tile);
   350 		uint16 res = GetIndustryTileCallback(CBID_INDTILE_ACCEPT_CARGO, 0, 0, gfx, GetIndustryByTile(tile), tile);
   349 		if (res != CALLBACK_FAILED) {
   351 		if (res != CALLBACK_FAILED) {
   350 			accepts_cargo = raw_accepts_cargo;
   352 			accepts_cargo = raw_accepts_cargo;
   351 			for (uint i = 0; i < lengthof(itspec->accepts_cargo); i++) raw_accepts_cargo[i] = GetCargoTranslation(GB(res, i * 5, 5), itspec->grf_prop.grffile);
   353 			for (uint i = 0; i < lengthof(itspec->accepts_cargo); i++) raw_accepts_cargo[i] = GetCargoTranslation(GB(res, i * 5, 5), itspec->grf_prop.grffile);
   352 		}
   354 		}
   353 	}
   355 	}
   354 
   356 
   355 	if (HASBIT(itspec->callback_flags, CBM_INDT_CARGO_ACCEPTANCE)) {
   357 	if (HasBit(itspec->callback_flags, CBM_INDT_CARGO_ACCEPTANCE)) {
   356 		uint16 res = GetIndustryTileCallback(CBID_INDTILE_CARGO_ACCEPTANCE, 0, 0, gfx, GetIndustryByTile(tile), tile);
   358 		uint16 res = GetIndustryTileCallback(CBID_INDTILE_CARGO_ACCEPTANCE, 0, 0, gfx, GetIndustryByTile(tile), tile);
   357 		if (res != CALLBACK_FAILED) {
   359 		if (res != CALLBACK_FAILED) {
   358 			acceptance = raw_acceptance;
   360 			acceptance = raw_acceptance;
   359 			for (uint i = 0; i < lengthof(itspec->accepts_cargo); i++) raw_acceptance[i] = GB(res, i * 4, 4);
   361 			for (uint i = 0; i < lengthof(itspec->accepts_cargo); i++) raw_acceptance[i] = GB(res, i * 4, 4);
   360 		}
   362 		}
   403 
   405 
   404 static void TransportIndustryGoods(TileIndex tile)
   406 static void TransportIndustryGoods(TileIndex tile)
   405 {
   407 {
   406 	Industry *i = GetIndustryByTile(tile);
   408 	Industry *i = GetIndustryByTile(tile);
   407 	const IndustrySpec *indspec = GetIndustrySpec(i->type);
   409 	const IndustrySpec *indspec = GetIndustrySpec(i->type);
   408 	uint cw, am;
   410 	bool moved_cargo = false;
   409 
   411 
   410 	cw = min(i->produced_cargo_waiting[0], 255);
   412 	for (uint j = 0; j < lengthof(i->produced_cargo_waiting); j++) {
   411 	if (cw > indspec->minimal_cargo/* && i->produced_cargo[0] != 0xFF*/) {
   413 		uint cw = min(i->produced_cargo_waiting[j], 255);
   412 		i->produced_cargo_waiting[0] -= cw;
   414 		if (cw > indspec->minimal_cargo && i->produced_cargo[j] != CT_INVALID) {
   413 
   415 			i->produced_cargo_waiting[j] -= cw;
   414 		/* fluctuating economy? */
   416 
   415 		if (_economy.fluct <= 0) cw = (cw + 1) / 2;
   417 			/* fluctuating economy? */
   416 
   418 			if (_economy.fluct <= 0) cw = (cw + 1) / 2;
   417 		i->this_month_production[0] += cw;
   419 
   418 
   420 			i->this_month_production[j] += cw;
   419 		am = MoveGoodsToStation(i->xy, i->width, i->height, i->produced_cargo[0], cw);
   421 
   420 		i->this_month_transported[0] += am;
   422 			uint am = MoveGoodsToStation(i->xy, i->width, i->height, i->produced_cargo[j], cw);
   421 		if (am != 0 && !StartStopIndustryTileAnimation(i, IAT_INDUSTRY_DISTRIBUTES_CARGO)) {
   423 			i->this_month_transported[j] += am;
   422 			uint newgfx = GetIndustryTileSpec(GetIndustryGfx(tile))->anim_production;
   424 
   423 
   425 			moved_cargo |= (am != 0);
   424 			if (newgfx != INDUSTRYTILE_NOANIM) {
   426 		}
   425 				ResetIndustryConstructionStage(tile);
   427 	}
   426 				SetIndustryCompleted(tile, true);
   428 
   427 				SetIndustryGfx(tile, newgfx);
   429 	if (moved_cargo && !StartStopIndustryTileAnimation(i, IAT_INDUSTRY_DISTRIBUTES_CARGO)) {
   428 				MarkTileDirtyByTile(tile);
   430 		uint newgfx = GetIndustryTileSpec(GetIndustryGfx(tile))->anim_production;
   429 			}
   431 
   430 		}
   432 		if (newgfx != INDUSTRYTILE_NOANIM) {
   431 	}
   433 			ResetIndustryConstructionStage(tile);
   432 
   434 			SetIndustryCompleted(tile, true);
   433 	cw = min(i->produced_cargo_waiting[1], 255);
   435 			SetIndustryGfx(tile, newgfx);
   434 	if (cw > indspec->minimal_cargo) {
   436 			MarkTileDirtyByTile(tile);
   435 		i->produced_cargo_waiting[1] -= cw;
   437 		}
   436 
       
   437 		if (_economy.fluct <= 0) cw = (cw + 1) / 2;
       
   438 
       
   439 		i->this_month_production[1] += cw;
       
   440 
       
   441 		am = MoveGoodsToStation(i->xy, i->width, i->height, i->produced_cargo[1], cw);
       
   442 		i->this_month_transported[1] += am;
       
   443 	}
   438 	}
   444 }
   439 }
   445 
   440 
   446 
   441 
   447 static void AnimateTile_Industry(TileIndex tile)
   442 static void AnimateTile_Industry(TileIndex tile)
   647 
   642 
   648 	if (!IsIndustryCompleted(tile)) return;
   643 	if (!IsIndustryCompleted(tile)) return;
   649 
   644 
   650 	IndustryGfx gfx = GetIndustryGfx(tile);
   645 	IndustryGfx gfx = GetIndustryGfx(tile);
   651 	if (gfx >= NEW_INDUSTRYTILEOFFSET) {
   646 	if (gfx >= NEW_INDUSTRYTILEOFFSET) {
   652 		/* New industry */
   647 		/* New industries are already animated on construction. */
   653 		const IndustryTileSpec *its = GetIndustryTileSpec(gfx);
       
   654 		if (its->animation_info != 0xFFFF) AddAnimatedTile(tile);
       
   655 		return;
   648 		return;
   656 	}
   649 	}
   657 
   650 
   658 	switch (gfx) {
   651 	switch (gfx) {
   659 	case GFX_POWERPLANT_CHIMNEY:
   652 	case GFX_POWERPLANT_CHIMNEY:
   706 
   699 
   707 static void TileLoop_Industry(TileIndex tile)
   700 static void TileLoop_Industry(TileIndex tile)
   708 {
   701 {
   709 	IndustryGfx newgfx;
   702 	IndustryGfx newgfx;
   710 	IndustryGfx gfx;
   703 	IndustryGfx gfx;
       
   704 
       
   705 	TriggerIndustryTile(tile, INDTILE_TRIGGER_TILE_LOOP);
   711 
   706 
   712 	if (!IsIndustryCompleted(tile)) {
   707 	if (!IsIndustryCompleted(tile)) {
   713 		MakeIndustryTileBigger(tile);
   708 		MakeIndustryTileBigger(tile);
   714 		return;
   709 		return;
   715 	}
   710 	}
  1003 
   998 
  1004 	i->counter--;
   999 	i->counter--;
  1005 
  1000 
  1006 	/* produce some cargo */
  1001 	/* produce some cargo */
  1007 	if ((i->counter & 0xFF) == 0) {
  1002 	if ((i->counter & 0xFF) == 0) {
  1008 		if (HASBIT(indsp->callback_flags, CBM_IND_PRODUCTION_256_TICKS)) IndustryProductionCallback(i, 1);
  1003 		if (HasBit(indsp->callback_flags, CBM_IND_PRODUCTION_256_TICKS)) IndustryProductionCallback(i, 1);
  1009 
  1004 
  1010 		IndustryBehaviour indbehav = indsp->behaviour;
  1005 		IndustryBehaviour indbehav = indsp->behaviour;
  1011 		i->produced_cargo_waiting[0] = min(0xffff, i->produced_cargo_waiting[0] + i->production_rate[0]);
  1006 		i->produced_cargo_waiting[0] = min(0xffff, i->produced_cargo_waiting[0] + i->production_rate[0]);
  1012 		i->produced_cargo_waiting[1] = min(0xffff, i->produced_cargo_waiting[1] + i->production_rate[1]);
  1007 		i->produced_cargo_waiting[1] = min(0xffff, i->produced_cargo_waiting[1] + i->production_rate[1]);
  1013 
  1008 
  1014 		if ((indbehav & INDUSTRYBEH_PLANT_FIELDS) != 0) {
  1009 		if ((indbehav & INDUSTRYBEH_PLANT_FIELDS) != 0) {
  1015 			bool plant;
  1010 			bool plant;
  1016 			if (HASBIT(indsp->callback_flags, CBM_IND_SPECIAL_EFFECT)) {
  1011 			if (HasBit(indsp->callback_flags, CBM_IND_SPECIAL_EFFECT)) {
  1017 				plant = (GetIndustryCallback(CBID_INDUSTRY_SPECIAL_EFFECT, Random(), 0, i, i->type, i->xy) != 0);
  1012 				plant = (GetIndustryCallback(CBID_INDUSTRY_SPECIAL_EFFECT, Random(), 0, i, i->type, i->xy) != 0);
  1018 			} else {
  1013 			} else {
  1019 				plant = CHANCE16(1, 8);
  1014 				plant = CHANCE16(1, 8);
  1020 			}
  1015 			}
  1021 
  1016 
  1022 			if (plant) PlantRandomFarmField(i);
  1017 			if (plant) PlantRandomFarmField(i);
  1023 		}
  1018 		}
  1024 		if ((indbehav & INDUSTRYBEH_CUT_TREES) != 0) {
  1019 		if ((indbehav & INDUSTRYBEH_CUT_TREES) != 0) {
  1025 			bool cut = ((i->counter & 0x1FF) == 0);
  1020 			bool cut = ((i->counter & 0x1FF) == 0);
  1026 			if (HASBIT(indsp->callback_flags, CBM_IND_SPECIAL_EFFECT)) {
  1021 			if (HasBit(indsp->callback_flags, CBM_IND_SPECIAL_EFFECT)) {
  1027 				cut = (GetIndustryCallback(CBID_INDUSTRY_SPECIAL_EFFECT, 0, 1, i, i->type, i->xy) != 0);
  1022 				cut = (GetIndustryCallback(CBID_INDUSTRY_SPECIAL_EFFECT, 0, 1, i, i->type, i->xy) != 0);
  1028 			}
  1023 			}
  1029 
  1024 
  1030 			if (cut) ChopLumberMillTrees(i);
  1025 			if (cut) ChopLumberMillTrees(i);
  1031 		}
  1026 		}
  1048 	}
  1043 	}
  1049 
  1044 
  1050 	if (_game_mode == GM_EDITOR) return;
  1045 	if (_game_mode == GM_EDITOR) return;
  1051 
  1046 
  1052 	FOR_ALL_INDUSTRIES(i) {
  1047 	FOR_ALL_INDUSTRIES(i) {
       
  1048 		TriggerIndustry(i, INDUSTRY_TRIGGER_INDUSTRY_TICK);
  1053 		StartStopIndustryTileAnimation(i, IAT_INDUSTRY_TICK);
  1049 		StartStopIndustryTileAnimation(i, IAT_INDUSTRY_TICK);
  1054 		ProduceIndustryGoods(i);
  1050 		ProduceIndustryGoods(i);
  1055 	}
  1051 	}
  1056 }
  1052 }
  1057 
  1053 
  1227 			const IndustryTileSpec *its = GetIndustryTileSpec(gfx);
  1223 			const IndustryTileSpec *its = GetIndustryTileSpec(gfx);
  1228 
  1224 
  1229 			IndustryBehaviour ind_behav = GetIndustrySpec(type)->behaviour;
  1225 			IndustryBehaviour ind_behav = GetIndustrySpec(type)->behaviour;
  1230 
  1226 
  1231 			/* Perform land/water check if not disabled */
  1227 			/* Perform land/water check if not disabled */
  1232 			if (!HASBIT(its->slopes_refused, 5) && (IsWaterTile(cur_tile) == !(ind_behav & INDUSTRYBEH_BUILT_ONWATER))) return false;
  1228 			if (!HasBit(its->slopes_refused, 5) && (IsWaterTile(cur_tile) == !(ind_behav & INDUSTRYBEH_BUILT_ONWATER))) return false;
  1233 
  1229 
  1234 			if (HASBIT(its->callback_flags, CBM_INDT_SHAPE_CHECK)) {
  1230 			if (HasBit(its->callback_flags, CBM_INDT_SHAPE_CHECK)) {
  1235 				custom_shape = true;
  1231 				custom_shape = true;
  1236 				if (!PerformIndustryTileSlopeCheck(tile, cur_tile, its, type, gfx, itspec_index)) return false;
  1232 				if (!PerformIndustryTileSlopeCheck(tile, cur_tile, its, type, gfx, itspec_index)) return false;
  1237 			} else {
  1233 			} else {
  1238 				Slope tileh = GetTileSlope(cur_tile, NULL);
  1234 				Slope tileh = GetTileSlope(cur_tile, NULL);
  1239 				refused_slope |= IsSlopeRefused(tileh, its->slopes_refused);
  1235 				refused_slope |= IsSlopeRefused(tileh, its->slopes_refused);
  1240 			}
  1236 			}
  1241 
  1237 
  1242 			if (ind_behav & INDUSTRYBEH_ONLY_INTOWN) {
  1238 			if (ind_behav & (INDUSTRYBEH_ONLY_INTOWN | INDUSTRYBEH_TOWN1200_MORE)) {
  1243 				if (!IsTileType(cur_tile, MP_HOUSE)) {
  1239 				if (!IsTileType(cur_tile, MP_HOUSE)) {
  1244 					_error_message = STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS;
  1240 					_error_message = STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS;
  1245 					return false;
  1241 					return false;
  1246 				}
  1242 				}
  1247 				if (CmdFailed(DoCommand(cur_tile, 0, 0, 0, CMD_LANDSCAPE_CLEAR))) return false;
  1243 				if (CmdFailed(DoCommand(cur_tile, 0, 0, 0, CMD_LANDSCAPE_CLEAR))) return false;
  1430 	i->accepts_cargo[1] = indspec->accepts_cargo[1];
  1426 	i->accepts_cargo[1] = indspec->accepts_cargo[1];
  1431 	i->accepts_cargo[2] = indspec->accepts_cargo[2];
  1427 	i->accepts_cargo[2] = indspec->accepts_cargo[2];
  1432 	i->production_rate[0] = indspec->production_rate[0];
  1428 	i->production_rate[0] = indspec->production_rate[0];
  1433 	i->production_rate[1] = indspec->production_rate[1];
  1429 	i->production_rate[1] = indspec->production_rate[1];
  1434 
  1430 
  1435 	/* don't use smooth economy for industries using production callbacks */
  1431 	/* don't use smooth economy for industries using production related callbacks */
  1436 	if (_patches.smooth_economy  && !(HASBIT(indspec->callback_flags, CBM_IND_PRODUCTION_256_TICKS) || HASBIT(indspec->callback_flags, CBM_IND_PRODUCTION_CARGO_ARRIVAL))) {
  1432 	if (_patches.smooth_economy &&
       
  1433 	    !(HasBit(indspec->callback_flags, CBM_IND_PRODUCTION_256_TICKS) || HasBit(indspec->callback_flags, CBM_IND_PRODUCTION_CARGO_ARRIVAL)) && // production callbacks
       
  1434 	    !(HasBit(indspec->callback_flags, CBM_IND_MONTHLYPROD_CHANGE) || HasBit(indspec->callback_flags, CBM_IND_PRODUCTION_CHANGE))             // production change callbacks
       
  1435 	) {
  1437 		i->production_rate[0] = min((RandomRange(256) + 128) * i->production_rate[0] >> 8 , 255);
  1436 		i->production_rate[0] = min((RandomRange(256) + 128) * i->production_rate[0] >> 8 , 255);
  1438 		i->production_rate[1] = min((RandomRange(256) + 128) * i->production_rate[1] >> 8 , 255);
  1437 		i->production_rate[1] = min((RandomRange(256) + 128) * i->production_rate[1] >> 8 , 255);
  1439 	}
  1438 	}
  1440 
  1439 
  1441 	i->town = t;
  1440 	i->town = t;
  1442 	i->owner = owner;
  1441 	i->owner = owner;
  1443 
  1442 
  1444 	r = Random();
  1443 	r = Random();
  1445 	i->random_color = GB(r, 8, 4);
  1444 	i->random_color = GB(r, 0, 4);
  1446 	i->counter = GB(r, 0, 12);
  1445 	i->counter = GB(r, 4, 12);
       
  1446 	i->random = GB(r, 16, 16);
  1447 	i->produced_cargo_waiting[0] = 0;
  1447 	i->produced_cargo_waiting[0] = 0;
  1448 	i->produced_cargo_waiting[1] = 0;
  1448 	i->produced_cargo_waiting[1] = 0;
  1449 	i->incoming_cargo_waiting[0] = 0;
  1449 	i->incoming_cargo_waiting[0] = 0;
  1450 	i->incoming_cargo_waiting[1] = 0;
  1450 	i->incoming_cargo_waiting[1] = 0;
  1451 	i->incoming_cargo_waiting[2] = 0;
  1451 	i->incoming_cargo_waiting[2] = 0;
  1461 	i->last_prod_year = _cur_year;
  1461 	i->last_prod_year = _cur_year;
  1462 	i->last_month_production[0] = i->production_rate[0] * 8;
  1462 	i->last_month_production[0] = i->production_rate[0] * 8;
  1463 	i->last_month_production[1] = i->production_rate[1] * 8;
  1463 	i->last_month_production[1] = i->production_rate[1] * 8;
  1464 	i->founder = _current_player;
  1464 	i->founder = _current_player;
  1465 
  1465 
  1466 	if (HASBIT(indspec->callback_flags, CBM_IND_DECIDE_COLOUR)) {
  1466 	if (HasBit(indspec->callback_flags, CBM_IND_DECIDE_COLOUR)) {
  1467 		uint16 res = GetIndustryCallback(CBID_INDUSTRY_DECIDE_COLOUR, 0, 0, i, type, INVALID_TILE);
  1467 		uint16 res = GetIndustryCallback(CBID_INDUSTRY_DECIDE_COLOUR, 0, 0, i, type, INVALID_TILE);
  1468 		if (res != CALLBACK_FAILED) i->random_color = GB(res, 0, 4);
  1468 		if (res != CALLBACK_FAILED) i->random_color = GB(res, 0, 4);
  1469 	}
  1469 	}
  1470 
  1470 
  1471 	if (HASBIT(indspec->callback_flags, CBM_IND_INPUT_CARGO_TYPES)) {
  1471 	if (HasBit(indspec->callback_flags, CBM_IND_INPUT_CARGO_TYPES)) {
  1472 		for (j = 0; j < lengthof(i->accepts_cargo); j++) i->accepts_cargo[j] = CT_INVALID;
  1472 		for (j = 0; j < lengthof(i->accepts_cargo); j++) i->accepts_cargo[j] = CT_INVALID;
  1473 		for (j = 0; j < lengthof(i->accepts_cargo); j++) {
  1473 		for (j = 0; j < lengthof(i->accepts_cargo); j++) {
  1474 			uint16 res = GetIndustryCallback(CBID_INDUSTRY_INPUT_CARGO_TYPES, j, 0, i, type, INVALID_TILE);
  1474 			uint16 res = GetIndustryCallback(CBID_INDUSTRY_INPUT_CARGO_TYPES, j, 0, i, type, INVALID_TILE);
  1475 			if (res == CALLBACK_FAILED || GB(res, 0, 8) == CT_INVALID) break;
  1475 			if (res == CALLBACK_FAILED || GB(res, 0, 8) == CT_INVALID) break;
  1476 			i->accepts_cargo[j] = GetCargoTranslation(GB(res, 0, 8), indspec->grf_prop.grffile);
  1476 			i->accepts_cargo[j] = GetCargoTranslation(GB(res, 0, 8), indspec->grf_prop.grffile);
  1477 		}
  1477 		}
  1478 	}
  1478 	}
  1479 
  1479 
  1480 	if (HASBIT(indspec->callback_flags, CBM_IND_OUTPUT_CARGO_TYPES)) {
  1480 	if (HasBit(indspec->callback_flags, CBM_IND_OUTPUT_CARGO_TYPES)) {
  1481 		for (j = 0; j < lengthof(i->produced_cargo); j++) i->produced_cargo[j] = CT_INVALID;
  1481 		for (j = 0; j < lengthof(i->produced_cargo); j++) i->produced_cargo[j] = CT_INVALID;
  1482 		for (j = 0; j < lengthof(i->produced_cargo); j++) {
  1482 		for (j = 0; j < lengthof(i->produced_cargo); j++) {
  1483 			uint16 res = GetIndustryCallback(CBID_INDUSTRY_OUTPUT_CARGO_TYPES, j, 0, i, type, INVALID_TILE);
  1483 			uint16 res = GetIndustryCallback(CBID_INDUSTRY_OUTPUT_CARGO_TYPES, j, 0, i, type, INVALID_TILE);
  1484 			if (res == CALLBACK_FAILED || GB(res, 0, 8) == CT_INVALID) break;
  1484 			if (res == CALLBACK_FAILED || GB(res, 0, 8) == CT_INVALID) break;
  1485 			i->produced_cargo[j] = GetCargoTranslation(GB(res, 0, 8), indspec->grf_prop.grffile);
  1485 			i->produced_cargo[j] = GetCargoTranslation(GB(res, 0, 8), indspec->grf_prop.grffile);
  1511 			if (size > i->height)i->height = size;
  1511 			if (size > i->height)i->height = size;
  1512 
  1512 
  1513 			DoCommand(cur_tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
  1513 			DoCommand(cur_tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
  1514 
  1514 
  1515 			MakeIndustry(cur_tile, i->index, it->gfx);
  1515 			MakeIndustry(cur_tile, i->index, it->gfx);
       
  1516 
  1516 			if (_generating_world) {
  1517 			if (_generating_world) {
  1517 				SetIndustryConstructionCounter(cur_tile, 3);
  1518 				SetIndustryConstructionCounter(cur_tile, 3);
  1518 				SetIndustryConstructionStage(cur_tile, 2);
  1519 				SetIndustryConstructionStage(cur_tile, 2);
       
  1520 			}
       
  1521 			if (it->gfx >= NEW_INDUSTRYTILEOFFSET) {
       
  1522 				/* New industry */
       
  1523 				const IndustryTileSpec *its = GetIndustryTileSpec(it->gfx);
       
  1524 				if (its->animation_info != 0xFFFF) AddAnimatedTile(cur_tile);
  1519 			}
  1525 			}
  1520 		}
  1526 		}
  1521 	} while ((++it)->ti.x != -0x80);
  1527 	} while ((++it)->ti.x != -0x80);
  1522 
  1528 
  1523 	i->width++;
  1529 	i->width++;
  1543 	const IndustryTileTable *it = indspec->table[itspec_index];
  1549 	const IndustryTileTable *it = indspec->table[itspec_index];
  1544 	bool custom_shape_check = false;
  1550 	bool custom_shape_check = false;
  1545 
  1551 
  1546 	if (!CheckIfIndustryTilesAreFree(tile, it, itspec_index, type, &custom_shape_check)) return NULL;
  1552 	if (!CheckIfIndustryTilesAreFree(tile, it, itspec_index, type, &custom_shape_check)) return NULL;
  1547 
  1553 
  1548 	if (HASBIT(GetIndustrySpec(type)->callback_flags, CBM_IND_LOCATION)) {
  1554 	if (HasBit(GetIndustrySpec(type)->callback_flags, CBM_IND_LOCATION)) {
  1549 		if (!CheckIfCallBackAllowsCreation(tile, type, itspec_index)) return NULL;
  1555 		if (!CheckIfCallBackAllowsCreation(tile, type, itspec_index)) return NULL;
  1550 	} else {
  1556 	} else {
  1551 		if (!_check_new_industry_procs[indspec->check_proc](tile)) return NULL;
  1557 		if (!_check_new_industry_procs[indspec->check_proc](tile)) return NULL;
  1552 	}
  1558 	}
  1553 
  1559 
  1575 
  1581 
  1576 /** Build/Fund an industry
  1582 /** Build/Fund an industry
  1577  * @param tile tile where industry is built
  1583  * @param tile tile where industry is built
  1578  * @param flags of operations to conduct
  1584  * @param flags of operations to conduct
  1579  * @param p1 industry type see build_industry.h and see industry.h
  1585  * @param p1 industry type see build_industry.h and see industry.h
  1580  * @param p2 unused
  1586  * @param p2 first layout to try
  1581  * @return index of the newly create industry, or CMD_ERROR if it failed
  1587  * @return index of the newly create industry, or CMD_ERROR if it failed
  1582  */
  1588  */
  1583 CommandCost CmdBuildIndustry(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1589 CommandCost CmdBuildIndustry(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1584 {
  1590 {
  1585 	const IndustrySpec *indspec;
  1591 	const IndustrySpec *indspec;
  1623 			}
  1629 			}
  1624 		}
  1630 		}
  1625 	} else {
  1631 	} else {
  1626 		int count = indspec->num_table;
  1632 		int count = indspec->num_table;
  1627 		const IndustryTileTable * const *itt = indspec->table;
  1633 		const IndustryTileTable * const *itt = indspec->table;
  1628 		int num = RandomRange(count);
  1634 		int num = Clamp(p2, 0, count - 1);
  1629 
  1635 
  1630 		_error_message = STR_0239_SITE_UNSUITABLE;
  1636 		_error_message = STR_0239_SITE_UNSUITABLE;
  1631 		do {
  1637 		do {
  1632 			if (--count < 0) return CMD_ERROR;
  1638 			if (--count < 0) return CMD_ERROR;
  1633 			if (--num < 0) num = indspec->num_table - 1;
  1639 			if (--num < 0) num = indspec->num_table - 1;
  1789 	ProbabilityHelper cumulative_probs[NUM_INDUSTRYTYPES]; // probability collector
  1795 	ProbabilityHelper cumulative_probs[NUM_INDUSTRYTYPES]; // probability collector
  1790 	uint16 probability_max = 0;
  1796 	uint16 probability_max = 0;
  1791 
  1797 
  1792 	/* Generate a list of all possible industries that can be built. */
  1798 	/* Generate a list of all possible industries that can be built. */
  1793 	for (j = 0; j < NUM_INDUSTRYTYPES; j++) {
  1799 	for (j = 0; j < NUM_INDUSTRYTYPES; j++) {
  1794 		byte chance = GetIndustrySpec(j)->appear_ingame[_opt.landscape];
  1800 		ind_spc = GetIndustrySpec(j);
       
  1801 		byte chance = ind_spc->appear_ingame[_opt.landscape];
       
  1802 
       
  1803 		if (!ind_spc->enabled || chance == 0) continue;
  1795 
  1804 
  1796 		/* If there is no Callback CBID_INDUSTRY_AVAILABLE or if this one did anot failed,
  1805 		/* If there is no Callback CBID_INDUSTRY_AVAILABLE or if this one did anot failed,
  1797 		 * and if appearing chance for this landscape is above 0, this industry can be chosen */
  1806 		 * and if appearing chance for this landscape is above 0, this industry can be chosen */
  1798 		if (CheckIfCallBackAllowsAvailability(j, IACT_RANDOMCREATION) && chance != 0) {
  1807 		if (CheckIfCallBackAllowsAvailability(j, IACT_RANDOMCREATION)) {
  1799 			probability_max += chance;
  1808 			probability_max += chance;
  1800 			/* adds the result for this industry */
  1809 			/* adds the result for this industry */
  1801 			cumulative_probs[num].ind = j;
  1810 			cumulative_probs[num].ind = j;
  1802 			cumulative_probs[num++].prob = probability_max;
  1811 			cumulative_probs[num++].prob = probability_max;
  1803 		}
  1812 		}
  1846 {
  1855 {
  1847 	const IndustrySpec *indspec = GetIndustrySpec(type);
  1856 	const IndustrySpec *indspec = GetIndustrySpec(type);
  1848 
  1857 
  1849 	/* oil wells (or the industries with that flag set) are always allowed to closedown */
  1858 	/* oil wells (or the industries with that flag set) are always allowed to closedown */
  1850 	if (indspec->behaviour & INDUSTRYBEH_DONT_INCR_PROD && _opt.landscape == LT_TEMPERATE) return false;
  1859 	if (indspec->behaviour & INDUSTRYBEH_DONT_INCR_PROD && _opt.landscape == LT_TEMPERATE) return false;
  1851 	return (indspec->behaviour & INDUSTRYBEH_CANCLOSE_LASTINSTANCE && GetIndustryTypeCount(type) <= 1);
  1860 	return (indspec->behaviour & INDUSTRYBEH_CANCLOSE_LASTINSTANCE) == 0 && GetIndustryTypeCount(type) <= 1;
  1852 }
  1861 }
       
  1862 
       
  1863 /**
       
  1864 * Can given cargo type be accepted or produced by the industry?
       
  1865 * @param cargo: Cargo type
       
  1866 * @param ind: Industry
       
  1867 * @param *c_accepts: Pointer to boolean for acceptance of cargo
       
  1868 * @param *c_produces: Pointer to boolean for production of cargo
       
  1869 * @return: \c *c_accepts is set when industry accepts the cargo type,
       
  1870 *          \c *c_produces is set when the industry produces the cargo type
       
  1871 */
       
  1872 static void CanCargoServiceIndustry(CargoID cargo, Industry *ind, bool *c_accepts, bool *c_produces)
       
  1873 {
       
  1874 	const IndustrySpec *indspec = GetIndustrySpec(ind->type);
       
  1875 
       
  1876 	/* Check for acceptance of cargo */
       
  1877 	for (uint j = 0; j < lengthof(ind->accepts_cargo) && ind->accepts_cargo[j] != CT_INVALID; j++) {
       
  1878 		if (cargo == ind->accepts_cargo[j]) {
       
  1879 			if (HasBit(indspec->callback_flags, CBM_IND_REFUSE_CARGO)) {
       
  1880 				uint16 res = GetIndustryCallback(CBID_INDUSTRY_REFUSE_CARGO,
       
  1881 						0, GetReverseCargoTranslation(cargo, indspec->grf_prop.grffile),
       
  1882 						ind, ind->type, ind->xy);
       
  1883 				if (res == 0) continue;
       
  1884 			}
       
  1885 			*c_accepts = true;
       
  1886 			break;
       
  1887 		}
       
  1888 	}
       
  1889 
       
  1890 	/* Check for produced cargo */
       
  1891 	for (uint j = 0; j < lengthof(ind->produced_cargo) && ind->produced_cargo[j] != CT_INVALID; j++) {
       
  1892 		if (cargo == ind->produced_cargo[j]) {
       
  1893 			*c_produces = true;
       
  1894 			break;
       
  1895 		}
       
  1896 	}
       
  1897 }
       
  1898 
       
  1899 /**
       
  1900 * Compute who can service the industry.
       
  1901 *
       
  1902 * Here, 'can service' means that he/she has trains and stations close enough
       
  1903 * to the industry with the right cargo type and the right orders (ie has the
       
  1904 * technical means).
       
  1905 *
       
  1906 * @param ind: Industry being investigated.
       
  1907 *
       
  1908 * @return: 0 if nobody can service the industry, 2 if the local player can
       
  1909 * service the industry, and 1 otherwise (only competitors can service the
       
  1910 * industry)
       
  1911 */
       
  1912 int WhoCanServiceIndustry(Industry* ind)
       
  1913 {
       
  1914 	/* Find all stations within reach of the industry */
       
  1915 	StationSet stations = FindStationsAroundIndustryTile(ind->xy, ind->width, ind->height);
       
  1916 
       
  1917 	if (stations.size() == 0) return 0; // No stations found at all => nobody services
       
  1918 
       
  1919 	const Vehicle *v;
       
  1920 	int result = 0;
       
  1921 	FOR_ALL_VEHICLES(v) {
       
  1922 		/* Is it worthwhile to try this vehicle? */
       
  1923 		if (v->owner != _local_player && result != 0) continue;
       
  1924 
       
  1925 		/* Check whether it accepts the right kind of cargo */
       
  1926 		bool c_accepts = false;
       
  1927 		bool c_produces = false;
       
  1928 		if (v->type == VEH_TRAIN && IsFrontEngine(v)) {
       
  1929 			const Vehicle *u = v;
       
  1930 			BEGIN_ENUM_WAGONS(u)
       
  1931 				CanCargoServiceIndustry(u->cargo_type, ind, &c_accepts, &c_produces);
       
  1932 			END_ENUM_WAGONS(u)
       
  1933 		} else if (v->type == VEH_ROAD || v->type == VEH_SHIP || v->type == VEH_AIRCRAFT) {
       
  1934 			CanCargoServiceIndustry(v->cargo_type, ind, &c_accepts, &c_produces);
       
  1935 		} else {
       
  1936 			continue;
       
  1937 		}
       
  1938 		if (!c_accepts && !c_produces) continue; // Wrong cargo
       
  1939 
       
  1940 		/* Check orders of the vehicle.
       
  1941 		 * We cannot check the first of shared orders only, since the first vehicle in such a chain
       
  1942 		 * may have a different cargo type.
       
  1943 		 */
       
  1944 		const Order *o;
       
  1945 		FOR_VEHICLE_ORDERS(v, o) {
       
  1946 			if (o->type == OT_GOTO_STATION && !HasBit(o->flags, OFB_TRANSFER)) {
       
  1947 				/* Vehicle visits a station to load or unload */
       
  1948 				Station *st = GetStation(o->dest);
       
  1949 				if (!st->IsValid()) continue;
       
  1950 
       
  1951 				/* Same cargo produced by industry is dropped here => not serviced by vehicle v */
       
  1952 				if (HasBit(o->flags, OFB_UNLOAD) && !c_accepts) break;
       
  1953 
       
  1954 				if (stations.find(st) != stations.end()) {
       
  1955 					if (v->owner == _local_player) return 2; // Player services industry
       
  1956 					result = 1; // Competitor services industry
       
  1957 				}
       
  1958 			}
       
  1959 		}
       
  1960 	}
       
  1961 	return result;
       
  1962 }
       
  1963 
       
  1964 /**
       
  1965 * Report news that industry production has changed significantly
       
  1966 *
       
  1967 * @param ind: Industry with changed production
       
  1968 * @param type: Cargo type that has changed
       
  1969 * @param percent: Percentage of change (>0 means increase, <0 means decrease)
       
  1970 */
       
  1971 static void ReportNewsProductionChangeIndustry(Industry *ind, CargoID type, int percent)
       
  1972 {
       
  1973 	NewsType nt;
       
  1974 
       
  1975 	switch (WhoCanServiceIndustry(ind)) {
       
  1976 		case 0: nt = NT_INDUSTRY_NOBODY; break;
       
  1977 		case 1: nt = NT_INDUSTRY_OTHER;  break;
       
  1978 		case 2: nt = NT_INDUSTRY_PLAYER; break;
       
  1979 		default: NOT_REACHED(); break;
       
  1980 	}
       
  1981 	SetDParam(2, abs(percent));
       
  1982 	SetDParam(0, GetCargo(type)->name);
       
  1983 	SetDParam(1, ind->index);
       
  1984 	AddNewsItem(
       
  1985 		percent >= 0 ? STR_INDUSTRY_PROD_GOUP : STR_INDUSTRY_PROD_GODOWN,
       
  1986 		NEWS_FLAGS(NM_THIN, NF_VIEWPORT | NF_TILE, nt, 0),
       
  1987 		ind->xy + TileDiffXY(1, 1), 0
       
  1988 	);
       
  1989 }
       
  1990 
       
  1991 enum {
       
  1992 	PERCENT_TRANSPORTED_60 = 153,
       
  1993 };
  1853 
  1994 
  1854 /** Change industry production or do closure
  1995 /** Change industry production or do closure
  1855  * @param i Industry for which changes are performed
  1996  * @param i Industry for which changes are performed
  1856  * @param monthly true if it's the monthly call, false if it's the random call
  1997  * @param monthly true if it's the monthly call, false if it's the random call
  1857  */
  1998  */
  1861 	StringID str = STR_NULL;
  2002 	StringID str = STR_NULL;
  1862 	bool closeit = false;
  2003 	bool closeit = false;
  1863 	const IndustrySpec *indspec = GetIndustrySpec(i->type);
  2004 	const IndustrySpec *indspec = GetIndustrySpec(i->type);
  1864 	bool standard = true;
  2005 	bool standard = true;
  1865 	bool suppress_message = false;
  2006 	bool suppress_message = false;
  1866 	/* don't use smooth economy for industries using production callbacks */
  2007 	/* don't use smooth economy for industries using production related callbacks */
  1867 	bool smooth_economy = _patches.smooth_economy && !(HASBIT(indspec->callback_flags, CBM_IND_PRODUCTION_256_TICKS) || HASBIT(indspec->callback_flags, CBM_IND_PRODUCTION_CARGO_ARRIVAL));
  2008 	bool smooth_economy = _patches.smooth_economy &&
       
  2009 	                      !(HasBit(indspec->callback_flags, CBM_IND_PRODUCTION_256_TICKS) || HasBit(indspec->callback_flags, CBM_IND_PRODUCTION_CARGO_ARRIVAL)) && // production callbacks
       
  2010 	                      !(HasBit(indspec->callback_flags, CBM_IND_MONTHLYPROD_CHANGE) || HasBit(indspec->callback_flags, CBM_IND_PRODUCTION_CHANGE));            // production change callbacks
  1868 	byte div = 0;
  2011 	byte div = 0;
  1869 	byte mul = 0;
  2012 	byte mul = 0;
  1870 
  2013 
  1871 	if (HASBIT(indspec->callback_flags, monthly ? CBM_IND_MONTHLYPROD_CHANGE : CBM_IND_PRODUCTION_CHANGE)) {
  2014 	if (HasBit(indspec->callback_flags, monthly ? CBM_IND_MONTHLYPROD_CHANGE : CBM_IND_PRODUCTION_CHANGE)) {
  1872 		uint16 res = GetIndustryCallback(monthly ? CBID_INDUSTRY_MONTHLYPROD_CHANGE : CBID_INDUSTRY_PRODUCTION_CHANGE, 0, Random(), i, i->type, i->xy);
  2015 		uint16 res = GetIndustryCallback(monthly ? CBID_INDUSTRY_MONTHLYPROD_CHANGE : CBID_INDUSTRY_PRODUCTION_CHANGE, 0, Random(), i, i->type, i->xy);
       
  2016 		standard = false;
       
  2017 		monthly = false; // smooth economy is disabled so we need to fake random industry production change to allow 'use standard' result
  1873 		if (res != CALLBACK_FAILED) {
  2018 		if (res != CALLBACK_FAILED) {
  1874 			standard = false;
  2019 			suppress_message = HasBit(res, 7);
  1875 			suppress_message = HASBIT(res, 7);
       
  1876 			/* Get the custom message if any */
  2020 			/* Get the custom message if any */
  1877 			if (HASBIT(res, 8)) str = MapGRFStringID(indspec->grf_prop.grffile->grfid, GB(GetRegister(0x100), 0, 16));
  2021 			if (HasBit(res, 8)) str = MapGRFStringID(indspec->grf_prop.grffile->grfid, GB(GetRegister(0x100), 0, 16));
  1878 			res = GB(res, 0, 4);
  2022 			res = GB(res, 0, 4);
  1879 			switch(res) {
  2023 			switch(res) {
  1880 				default: NOT_REACHED();
  2024 				default: NOT_REACHED();
  1881 				case 0x0: break;                  // Do nothing, but show the custom message if any
  2025 				case 0x0: break;                  // Do nothing, but show the custom message if any
  1882 				case 0x1: div = 1; break;         // Halve industry production. If production reaches the quarter of the default, the industry is closed instead.
  2026 				case 0x1: div = 1; break;         // Halve industry production. If production reaches the quarter of the default, the industry is closed instead.
  1883 				case 0x2: mul = 1; break;         // Double industry production if it hasn't reached eight times of the original yet.
  2027 				case 0x2: mul = 1; break;         // Double industry production if it hasn't reached eight times of the original yet.
  1884 				case 0x3: closeit = true; break;  // The industry announces imminent closure, and is physically removed from the map next month.
  2028 				case 0x3: closeit = true; break;  // The industry announces imminent closure, and is physically removed from the map next month.
  1885 				case 0x4: standard = true; break; // Do the standard random production change as if this industry was a primary one.
  2029 				case 0x4: standard = true; break; // Do the standard random production change as if this industry was a primary one.
  1886 				case 0x5: case 0x6: case 0x7:     // Divide production by 4, 8, 16
  2030 				case 0x5: case 0x6: case 0x7:     // Divide production by 4, 8, 16
  1887 				case 0x8: div = res - 0x5; break; // Divide production by 32
  2031 				case 0x8: div = res - 0x3; break; // Divide production by 32
  1888 				case 0x9: case 0xA: case 0xB:     // Multiply production by 4, 8, 16
  2032 				case 0x9: case 0xA: case 0xB:     // Multiply production by 4, 8, 16
  1889 				case 0xC: mul = res - 0x9; break; // Multiply production by 32
  2033 				case 0xC: mul = res - 0x7; break; // Multiply production by 32
  1890 			}
  2034 			}
  1891 		}
  2035 		}
  1892 	}
  2036 	}
  1893 
  2037 
  1894 	if (standard && monthly != smooth_economy) return;
  2038 	if (standard && monthly != smooth_economy) return;
  1900 		bool only_decrease = (indspec->behaviour & INDUSTRYBEH_DONT_INCR_PROD) && _opt.landscape == LT_TEMPERATE;
  2044 		bool only_decrease = (indspec->behaviour & INDUSTRYBEH_DONT_INCR_PROD) && _opt.landscape == LT_TEMPERATE;
  1901 
  2045 
  1902 		if (smooth_economy) {
  2046 		if (smooth_economy) {
  1903 			closeit = true;
  2047 			closeit = true;
  1904 			for (byte j = 0; j < 2 && i->produced_cargo[j] != CT_INVALID; j++){
  2048 			for (byte j = 0; j < 2 && i->produced_cargo[j] != CT_INVALID; j++){
  1905 				uint32 r = Random();
       
  1906 				int old_prod, new_prod, percent;
  2049 				int old_prod, new_prod, percent;
  1907 				int mag;
  2050 				int mult = (i->last_month_pct_transported[j] > PERCENT_TRANSPORTED_60) ? 1 : -1;
  1908 
  2051 
  1909 				new_prod = old_prod = i->production_rate[j];
  2052 				new_prod = old_prod = i->production_rate[j];
  1910 
  2053 
  1911 				if (CHANCE16I(20, 1024, r)) new_prod -= max(((RandomRange(50) + 10) * old_prod) >> 8, 1U);
  2054 				if (only_decrease || CHANCE16(1, 3)) mult *= -1;
  1912 				/* Chance of increasing becomes better when more is transported */
  2055 
  1913 				if (CHANCE16I(20 + (i->last_month_pct_transported[j] * 20 >> 8), 1024, r >> 16) && !only_decrease) {
  2056 				if (CHANCE16(1, 22)) {
  1914 					new_prod += max(((RandomRange(50) + 10) * old_prod) >> 8, 1U);
  2057 					new_prod += mult * (max(((RandomRange(50) + 10) * old_prod) >> 8, 1U));
  1915 				}
  2058 				}
  1916 
  2059 
  1917 				new_prod = clamp(new_prod, 1, 255);
  2060 				/* Prevent production to overflow or Oil Rig passengers to be over-"produced" */
       
  2061 				new_prod = Clamp(new_prod, 1, 255);
       
  2062 
       
  2063 				if (((indspec->behaviour & INDUSTRYBEH_BUILT_ONWATER) != 0) && j == 1)
       
  2064 					new_prod = Clamp(new_prod, 0, 16);
       
  2065 
  1918 				/* Do not stop closing the industry when it has the lowest possible production rate */
  2066 				/* Do not stop closing the industry when it has the lowest possible production rate */
  1919 				if (new_prod == old_prod && old_prod > 1) {
  2067 				if (new_prod == old_prod && old_prod > 1) {
  1920 					closeit = false;
  2068 					closeit = false;
  1921 					continue;
  2069 					continue;
  1922 				}
  2070 				}
  1925 				i->production_rate[j] = new_prod;
  2073 				i->production_rate[j] = new_prod;
  1926 
  2074 
  1927 				/* Close the industry when it has the lowest possible production rate */
  2075 				/* Close the industry when it has the lowest possible production rate */
  1928 				if (new_prod > 1) closeit = false;
  2076 				if (new_prod > 1) closeit = false;
  1929 
  2077 
  1930 				mag = abs(percent);
  2078 				if (abs(percent) >= 10) {
  1931 				if (mag >= 10) {
  2079 					ReportNewsProductionChangeIndustry(i, i->produced_cargo[j], percent);
  1932 					SetDParam(2, mag);
       
  1933 					SetDParam(0, GetCargo(i->produced_cargo[j])->name);
       
  1934 					SetDParam(1, i->index);
       
  1935 					AddNewsItem(
       
  1936 						percent >= 0 ? STR_INDUSTRY_PROD_GOUP : STR_INDUSTRY_PROD_GODOWN,
       
  1937 						NEWS_FLAGS(NM_THIN, NF_VIEWPORT | NF_TILE, NT_ECONOMY, 0),
       
  1938 						i->xy + TileDiffXY(1, 1), 0
       
  1939 					);
       
  1940 				}
  2080 				}
  1941 			}
  2081 			}
  1942 		} else {
  2082 		} else {
  1943 			if (only_decrease || CHANCE16(1, 3)) {
  2083 			if (only_decrease || CHANCE16(1, 3)) {
  1944 				/* If you transport > 60%, 66% chance we increase, else 33% chance we increase */
  2084 				/* If you transport > 60%, 66% chance we increase, else 33% chance we increase */
  1945 				if (!only_decrease && (i->last_month_pct_transported[0] > 153) != CHANCE16(1, 3)) {
  2085 				if (!only_decrease && (i->last_month_pct_transported[0] > PERCENT_TRANSPORTED_60) != CHANCE16(1, 3)) {
  1946 					mul = 1; // Increase production
  2086 					mul = 1; // Increase production
  1947 				} else {
  2087 				} else {
  1948 					div = 1; // Decrease production
  2088 					div = 1; // Decrease production
  1949 				}
  2089 				}
  1950 			}
  2090 			}
  1982 		i->prod_level = 0;
  2122 		i->prod_level = 0;
  1983 		str = indspec->closure_text;
  2123 		str = indspec->closure_text;
  1984 	}
  2124 	}
  1985 
  2125 
  1986 	if (!suppress_message && str != STR_NULL) {
  2126 	if (!suppress_message && str != STR_NULL) {
       
  2127 		NewsType nt;
       
  2128 		/* Compute news category */
       
  2129 		if (closeit) {
       
  2130 			nt = NT_OPENCLOSE;
       
  2131 		} else {
       
  2132 			switch (WhoCanServiceIndustry(i)) {
       
  2133 				case 0: nt = NT_INDUSTRY_NOBODY; break;
       
  2134 				case 1: nt = NT_INDUSTRY_OTHER;  break;
       
  2135 				case 2: nt = NT_INDUSTRY_PLAYER; break;
       
  2136 				default: NOT_REACHED(); break;
       
  2137 			}
       
  2138 		}
       
  2139 		/* Set parameters of news string */
  1987 		if (str > STR_LAST_STRINGID) {
  2140 		if (str > STR_LAST_STRINGID) {
  1988 			SetDParam(0, STR_TOWN);
  2141 			SetDParam(0, STR_TOWN);
  1989 			SetDParam(1, i->town->index);
  2142 			SetDParam(1, i->town->index);
  1990 			SetDParam(2, indspec->name);
  2143 			SetDParam(2, indspec->name);
       
  2144 		} else if (closeit) {
       
  2145 			SetDParam(0, STR_INDUSTRY_FORMAT);
       
  2146 			SetDParam(1, i->town->index);
       
  2147 			SetDParam(2, indspec->name);
  1991 		} else {
  2148 		} else {
  1992 			SetDParam(0, i->index);
  2149 			SetDParam(0, i->index);
  1993 		}
  2150 		}
       
  2151 		/* and report the news to the user */
  1994 		AddNewsItem(str,
  2152 		AddNewsItem(str,
  1995 			NEWS_FLAGS(NM_THIN, NF_VIEWPORT | NF_TILE, closeit ? NT_OPENCLOSE : NT_ECONOMY, 0),
  2153 			NEWS_FLAGS(NM_THIN, NF_VIEWPORT | NF_TILE, nt, 0),
  1996 			i->xy + TileDiffXY(1, 1), 0);
  2154 			i->xy + TileDiffXY(1, 1), 0);
  1997 	}
  2155 	}
  1998 }
  2156 }
  1999 
  2157 
  2000 void IndustryMonthlyLoop()
  2158 void IndustryMonthlyLoop()
  2068 		if (!IsSteepSlope(tileh_old) && !IsSteepSlope(tileh_new) && (GetTileMaxZ(tile) == z_new + GetSlopeMaxZ(tileh_new))) {
  2226 		if (!IsSteepSlope(tileh_old) && !IsSteepSlope(tileh_new) && (GetTileMaxZ(tile) == z_new + GetSlopeMaxZ(tileh_new))) {
  2069 			const IndustryGfx gfx = GetIndustryGfx(tile);
  2227 			const IndustryGfx gfx = GetIndustryGfx(tile);
  2070 			const IndustryTileSpec *itspec = GetIndustryTileSpec(gfx);
  2228 			const IndustryTileSpec *itspec = GetIndustryTileSpec(gfx);
  2071 
  2229 
  2072 			/* Call callback 3C 'disable autosloping for industry tiles'. */
  2230 			/* Call callback 3C 'disable autosloping for industry tiles'. */
  2073 			if (HASBIT(itspec->callback_flags, CBM_INDT_AUTOSLOPE)) {
  2231 			if (HasBit(itspec->callback_flags, CBM_INDT_AUTOSLOPE)) {
  2074 				/* If the callback fails, allow autoslope. */
  2232 				/* If the callback fails, allow autoslope. */
  2075 				uint16 res = GetIndustryTileCallback(CBID_INDUSTRY_AUTOSLOPE, 0, 0, gfx, GetIndustryByTile(tile), tile);
  2233 				uint16 res = GetIndustryTileCallback(CBID_INDUSTRY_AUTOSLOPE, 0, 0, gfx, GetIndustryByTile(tile), tile);
  2076 				if ((res == 0) || (res == CALLBACK_FAILED)) return _price.terraform;
  2234 				if ((res == 0) || (res == CALLBACK_FAILED)) return _price.terraform;
  2077 			} else {
  2235 			} else {
  2078 				// allow autoslope
  2236 				/* allow autoslope */
  2079 				return _price.terraform;
  2237 				return _price.terraform;
  2080 			}
  2238 			}
  2081 		}
  2239 		}
  2082 	}
  2240 	}
  2083 	return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
  2241 	return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
  2135 	SLE_CONDVAR(Industry, last_cargo_accepted_at,     SLE_INT32,                 70, SL_MAX_VERSION),
  2293 	SLE_CONDVAR(Industry, last_cargo_accepted_at,     SLE_INT32,                 70, SL_MAX_VERSION),
  2136 	SLE_CONDVAR(Industry, selected_layout,            SLE_UINT8,                 73, SL_MAX_VERSION),
  2294 	SLE_CONDVAR(Industry, selected_layout,            SLE_UINT8,                 73, SL_MAX_VERSION),
  2137 
  2295 
  2138 	SLE_CONDARRX(cpp_offsetof(Industry, psa) + cpp_offsetof(Industry::PersistentStorage, storage), SLE_UINT32, 16, 76, SL_MAX_VERSION),
  2296 	SLE_CONDARRX(cpp_offsetof(Industry, psa) + cpp_offsetof(Industry::PersistentStorage, storage), SLE_UINT32, 16, 76, SL_MAX_VERSION),
  2139 
  2297 
       
  2298 	SLE_CONDVAR(Industry, random_triggers,            SLE_UINT8,                 82, SL_MAX_VERSION),
       
  2299 	SLE_CONDVAR(Industry, random,                     SLE_UINT16,                82, SL_MAX_VERSION),
       
  2300 
  2140 	/* reserve extra space in savegame here. (currently 32 bytes) */
  2301 	/* reserve extra space in savegame here. (currently 32 bytes) */
  2141 	SLE_CONDNULL(32, 2, SL_MAX_VERSION),
  2302 	SLE_CONDNULL(32, 2, SL_MAX_VERSION),
  2142 
  2303 
  2143 	SLE_END()
  2304 	SLE_END()
  2144 };
  2305 };