src/industry_cmd.cpp
branchNewGRF_ports
changeset 6871 5a9dc001e1ad
parent 6870 ca3fd1fbe311
child 6872 1c4a4a609f85
equal deleted inserted replaced
6870:ca3fd1fbe311 6871:5a9dc001e1ad
    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"
       
    43 #include "water.h"
    41 
    44 
    42 void ShowIndustryViewWindow(int industry);
    45 void ShowIndustryViewWindow(int industry);
    43 void BuildOilRig(TileIndex tile);
    46 void BuildOilRig(TileIndex tile);
    44 
    47 
    45 static byte _industry_sound_ctr;
    48 static byte _industry_sound_ctr;
    64 	memcpy(&_industry_specs, &_origin_industry_specs, sizeof(_origin_industry_specs));
    67 	memcpy(&_industry_specs, &_origin_industry_specs, sizeof(_origin_industry_specs));
    65 
    68 
    66 	/* once performed, enable only the current climate industries */
    69 	/* once performed, enable only the current climate industries */
    67 	for (IndustryType i = 0; i < NUM_INDUSTRYTYPES; i++) {
    70 	for (IndustryType i = 0; i < NUM_INDUSTRYTYPES; i++) {
    68 		_industry_specs[i].enabled = i < NEW_INDUSTRYOFFSET &&
    71 		_industry_specs[i].enabled = i < NEW_INDUSTRYOFFSET &&
    69 				HASBIT(_origin_industry_specs[i].climate_availability, _opt.landscape);
    72 				HasBit(_origin_industry_specs[i].climate_availability, _opt.landscape);
    70 	}
    73 	}
    71 
    74 
    72 	memset(&_industry_tile_specs, 0, sizeof(_industry_tile_specs));
    75 	memset(&_industry_tile_specs, 0, sizeof(_industry_tile_specs));
    73 	memcpy(&_industry_tile_specs, &_origin_industry_tile_specs, sizeof(_origin_industry_tile_specs));
    76 	memcpy(&_industry_tile_specs, &_origin_industry_tile_specs, sizeof(_origin_industry_tile_specs));
    74 
    77 
   286 	dits = &_industry_draw_tile_data[gfx << 2 | (indts->anim_state ?
   289 	dits = &_industry_draw_tile_data[gfx << 2 | (indts->anim_state ?
   287 			GetIndustryAnimationState(ti->tile) & INDUSTRY_COMPLETED :
   290 			GetIndustryAnimationState(ti->tile) & INDUSTRY_COMPLETED :
   288 			GetIndustryConstructionStage(ti->tile))];
   291 			GetIndustryConstructionStage(ti->tile))];
   289 
   292 
   290 	image = dits->ground.sprite;
   293 	image = dits->ground.sprite;
   291 	if (HASBIT(image, PALETTE_MODIFIER_COLOR) && dits->ground.pal == PAL_NONE) {
   294 	if (HasBit(image, PALETTE_MODIFIER_COLOR) && dits->ground.pal == PAL_NONE) {
   292 		pal = GENERAL_SPRITE_COLOR(ind->random_color);
   295 		pal = GENERAL_SPRITE_COLOR(ind->random_color);
   293 	} else {
   296 	} else {
   294 		pal = dits->ground.pal;
   297 		pal = dits->ground.pal;
   295 	}
   298 	}
   296 
   299 
   301 
   304 
   302 	/* Add industry on top of the ground? */
   305 	/* Add industry on top of the ground? */
   303 	image = dits->building.sprite;
   306 	image = dits->building.sprite;
   304 	if (image != 0) {
   307 	if (image != 0) {
   305 		AddSortableSpriteToDraw(image,
   308 		AddSortableSpriteToDraw(image,
   306 			(HASBIT(image, PALETTE_MODIFIER_COLOR) && dits->building.pal == PAL_NONE) ? GENERAL_SPRITE_COLOR(ind->random_color) : dits->building.pal,
   309 			(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,
   310 			ti->x + dits->subtile_x,
   308 			ti->y + dits->subtile_y,
   311 			ti->y + dits->subtile_y,
   309 			dits->width,
   312 			dits->width,
   310 			dits->height,
   313 			dits->height,
   311 			dits->dz,
   314 			dits->dz,
   312 			ti->z,
   315 			ti->z,
   313 			HASBIT(_transparent_opt, TO_INDUSTRIES));
   316 			IsTransparencySet(TO_INDUSTRIES));
   314 
   317 
   315 		if (HASBIT(_transparent_opt, TO_INDUSTRIES)) return;
   318 		if (IsTransparencySet(TO_INDUSTRIES)) return;
   316 	}
   319 	}
   317 
   320 
   318 	{
   321 	{
   319 		int proc = dits->draw_proc - 1;
   322 		int proc = dits->draw_proc - 1;
   320 		if (proc >= 0) _industry_draw_tile_procs[proc](ti);
   323 		if (proc >= 0) _industry_draw_tile_procs[proc](ti);
   342 
   345 
   343 	/* And then these will always point to a same sized array with the required data */
   346 	/* And then these will always point to a same sized array with the required data */
   344 	const CargoID *accepts_cargo = itspec->accepts_cargo;
   347 	const CargoID *accepts_cargo = itspec->accepts_cargo;
   345 	const uint8 *acceptance = itspec->acceptance;
   348 	const uint8 *acceptance = itspec->acceptance;
   346 
   349 
   347 	if (HASBIT(itspec->callback_flags, CBM_INDT_ACCEPT_CARGO)) {
   350 	if (HasBit(itspec->callback_flags, CBM_INDT_ACCEPT_CARGO)) {
   348 		uint16 res = GetIndustryTileCallback(CBID_INDTILE_ACCEPT_CARGO, 0, 0, gfx, GetIndustryByTile(tile), tile);
   351 		uint16 res = GetIndustryTileCallback(CBID_INDTILE_ACCEPT_CARGO, 0, 0, gfx, GetIndustryByTile(tile), tile);
   349 		if (res != CALLBACK_FAILED) {
   352 		if (res != CALLBACK_FAILED) {
   350 			accepts_cargo = raw_accepts_cargo;
   353 			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);
   354 			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 		}
   355 		}
   353 	}
   356 	}
   354 
   357 
   355 	if (HASBIT(itspec->callback_flags, CBM_INDT_CARGO_ACCEPTANCE)) {
   358 	if (HasBit(itspec->callback_flags, CBM_INDT_CARGO_ACCEPTANCE)) {
   356 		uint16 res = GetIndustryTileCallback(CBID_INDTILE_CARGO_ACCEPTANCE, 0, 0, gfx, GetIndustryByTile(tile), tile);
   359 		uint16 res = GetIndustryTileCallback(CBID_INDTILE_CARGO_ACCEPTANCE, 0, 0, gfx, GetIndustryByTile(tile), tile);
   357 		if (res != CALLBACK_FAILED) {
   360 		if (res != CALLBACK_FAILED) {
   358 			acceptance = raw_acceptance;
   361 			acceptance = raw_acceptance;
   359 			for (uint i = 0; i < lengthof(itspec->accepts_cargo); i++) raw_acceptance[i] = GB(res, i * 4, 4);
   362 			for (uint i = 0; i < lengthof(itspec->accepts_cargo); i++) raw_acceptance[i] = GB(res, i * 4, 4);
   360 		}
   363 		}
   396 		SetDParam(0, indspec->name);
   399 		SetDParam(0, indspec->name);
   397 		return_cmd_error(STR_4800_IN_THE_WAY);
   400 		return_cmd_error(STR_4800_IN_THE_WAY);
   398 	}
   401 	}
   399 
   402 
   400 	if (flags & DC_EXEC) delete i;
   403 	if (flags & DC_EXEC) delete i;
   401 	return CommandCost();
   404 	return CommandCost(indspec->GetRemovalCost());
   402 }
   405 }
   403 
   406 
   404 static void TransportIndustryGoods(TileIndex tile)
   407 static void TransportIndustryGoods(TileIndex tile)
   405 {
   408 {
   406 	Industry *i = GetIndustryByTile(tile);
   409 	Industry *i = GetIndustryByTile(tile);
   407 	const IndustrySpec *indspec = GetIndustrySpec(i->type);
   410 	const IndustrySpec *indspec = GetIndustrySpec(i->type);
   408 	uint cw, am;
   411 	bool moved_cargo = false;
   409 
   412 
   410 	cw = min(i->produced_cargo_waiting[0], 255);
   413 	for (uint j = 0; j < lengthof(i->produced_cargo_waiting); j++) {
   411 	if (cw > indspec->minimal_cargo/* && i->produced_cargo[0] != 0xFF*/) {
   414 		uint cw = min(i->produced_cargo_waiting[j], 255);
   412 		i->produced_cargo_waiting[0] -= cw;
   415 		if (cw > indspec->minimal_cargo && i->produced_cargo[j] != CT_INVALID) {
   413 
   416 			i->produced_cargo_waiting[j] -= cw;
   414 		/* fluctuating economy? */
   417 
   415 		if (_economy.fluct <= 0) cw = (cw + 1) / 2;
   418 			/* fluctuating economy? */
   416 
   419 			if (_economy.fluct <= 0) cw = (cw + 1) / 2;
   417 		i->this_month_production[0] += cw;
   420 
   418 
   421 			i->this_month_production[j] += cw;
   419 		am = MoveGoodsToStation(i->xy, i->width, i->height, i->produced_cargo[0], cw);
   422 
   420 		i->this_month_transported[0] += am;
   423 			uint am = MoveGoodsToStation(i->xy, i->width, i->height, i->produced_cargo[j], cw);
   421 		if (am != 0 && !StartStopIndustryTileAnimation(i, IAT_INDUSTRY_DISTRIBUTES_CARGO)) {
   424 			i->this_month_transported[j] += am;
   422 			uint newgfx = GetIndustryTileSpec(GetIndustryGfx(tile))->anim_production;
   425 
   423 
   426 			moved_cargo |= (am != 0);
   424 			if (newgfx != INDUSTRYTILE_NOANIM) {
   427 		}
   425 				ResetIndustryConstructionStage(tile);
   428 	}
   426 				SetIndustryCompleted(tile, true);
   429 
   427 				SetIndustryGfx(tile, newgfx);
   430 	if (moved_cargo && !StartStopIndustryTileAnimation(i, IAT_INDUSTRY_DISTRIBUTES_CARGO)) {
   428 				MarkTileDirtyByTile(tile);
   431 		uint newgfx = GetIndustryTileSpec(GetIndustryGfx(tile))->anim_production;
   429 			}
   432 
   430 		}
   433 		if (newgfx != INDUSTRYTILE_NOANIM) {
   431 	}
   434 			ResetIndustryConstructionStage(tile);
   432 
   435 			SetIndustryCompleted(tile, true);
   433 	cw = min(i->produced_cargo_waiting[1], 255);
   436 			SetIndustryGfx(tile, newgfx);
   434 	if (cw > indspec->minimal_cargo) {
   437 			MarkTileDirtyByTile(tile);
   435 		i->produced_cargo_waiting[1] -= cw;
   438 		}
   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 	}
   439 	}
   444 }
   440 }
   445 
   441 
   446 
   442 
   447 static void AnimateTile_Industry(TileIndex tile)
   443 static void AnimateTile_Industry(TileIndex tile)
   560 
   556 
   561 	case GFX_OILWELL_ANIMATED_1:
   557 	case GFX_OILWELL_ANIMATED_1:
   562 	case GFX_OILWELL_ANIMATED_2:
   558 	case GFX_OILWELL_ANIMATED_2:
   563 	case GFX_OILWELL_ANIMATED_3:
   559 	case GFX_OILWELL_ANIMATED_3:
   564 		if ((_tick_counter & 7) == 0) {
   560 		if ((_tick_counter & 7) == 0) {
   565 			bool b = CHANCE16(1, 7);
   561 			bool b = Chance16(1, 7);
   566 			IndustryGfx gfx = GetIndustryGfx(tile);
   562 			IndustryGfx gfx = GetIndustryGfx(tile);
   567 
   563 
   568 			m = GetIndustryAnimationState(tile) + 1;
   564 			m = GetIndustryAnimationState(tile) + 1;
   569 			if (m == 4 && (m = 0, ++gfx) == GFX_OILWELL_ANIMATED_3 + 1 && (gfx = GFX_OILWELL_ANIMATED_1, b)) {
   565 			if (m == 4 && (m = 0, ++gfx) == GFX_OILWELL_ANIMATED_3 + 1 && (gfx = GFX_OILWELL_ANIMATED_1, b)) {
   570 				SetIndustryGfx(tile, GFX_OILWELL_NOT_ANIMATED);
   566 				SetIndustryGfx(tile, GFX_OILWELL_NOT_ANIMATED);
   647 
   643 
   648 	if (!IsIndustryCompleted(tile)) return;
   644 	if (!IsIndustryCompleted(tile)) return;
   649 
   645 
   650 	IndustryGfx gfx = GetIndustryGfx(tile);
   646 	IndustryGfx gfx = GetIndustryGfx(tile);
   651 	if (gfx >= NEW_INDUSTRYTILEOFFSET) {
   647 	if (gfx >= NEW_INDUSTRYTILEOFFSET) {
   652 		/* New industry */
   648 		/* New industries are already animated on construction. */
   653 		const IndustryTileSpec *its = GetIndustryTileSpec(gfx);
       
   654 		if (its->animation_info != 0xFFFF) AddAnimatedTile(tile);
       
   655 		return;
   649 		return;
   656 	}
   650 	}
   657 
   651 
   658 	switch (gfx) {
   652 	switch (gfx) {
   659 	case GFX_POWERPLANT_CHIMNEY:
   653 	case GFX_POWERPLANT_CHIMNEY:
   706 
   700 
   707 static void TileLoop_Industry(TileIndex tile)
   701 static void TileLoop_Industry(TileIndex tile)
   708 {
   702 {
   709 	IndustryGfx newgfx;
   703 	IndustryGfx newgfx;
   710 	IndustryGfx gfx;
   704 	IndustryGfx gfx;
       
   705 
       
   706 	TriggerIndustryTile(tile, INDTILE_TRIGGER_TILE_LOOP);
   711 
   707 
   712 	if (!IsIndustryCompleted(tile)) {
   708 	if (!IsIndustryCompleted(tile)) {
   713 		MakeIndustryTileBigger(tile);
   709 		MakeIndustryTileBigger(tile);
   714 		return;
   710 		return;
   715 	}
   711 	}
   740 		break;
   736 		break;
   741 
   737 
   742 	case GFX_COAL_MINE_TOWER_NOT_ANIMATED:
   738 	case GFX_COAL_MINE_TOWER_NOT_ANIMATED:
   743 	case GFX_COPPER_MINE_TOWER_NOT_ANIMATED:
   739 	case GFX_COPPER_MINE_TOWER_NOT_ANIMATED:
   744 	case GFX_GOLD_MINE_TOWER_NOT_ANIMATED:
   740 	case GFX_GOLD_MINE_TOWER_NOT_ANIMATED:
   745 		if (!(_tick_counter & 0x400) && CHANCE16(1, 2)) {
   741 		if (!(_tick_counter & 0x400) && Chance16(1, 2)) {
   746 			switch (gfx) {
   742 			switch (gfx) {
   747 				case GFX_COAL_MINE_TOWER_NOT_ANIMATED:   gfx = GFX_COAL_MINE_TOWER_ANIMATED;   break;
   743 				case GFX_COAL_MINE_TOWER_NOT_ANIMATED:   gfx = GFX_COAL_MINE_TOWER_ANIMATED;   break;
   748 				case GFX_COPPER_MINE_TOWER_NOT_ANIMATED: gfx = GFX_COPPER_MINE_TOWER_ANIMATED; break;
   744 				case GFX_COPPER_MINE_TOWER_NOT_ANIMATED: gfx = GFX_COPPER_MINE_TOWER_ANIMATED; break;
   749 				case GFX_GOLD_MINE_TOWER_NOT_ANIMATED:   gfx = GFX_GOLD_MINE_TOWER_ANIMATED;   break;
   745 				case GFX_GOLD_MINE_TOWER_NOT_ANIMATED:   gfx = GFX_GOLD_MINE_TOWER_ANIMATED;   break;
   750 			}
   746 			}
   753 			AddAnimatedTile(tile);
   749 			AddAnimatedTile(tile);
   754 		}
   750 		}
   755 		break;
   751 		break;
   756 
   752 
   757 	case GFX_OILWELL_NOT_ANIMATED:
   753 	case GFX_OILWELL_NOT_ANIMATED:
   758 		if (CHANCE16(1, 6)) {
   754 		if (Chance16(1, 6)) {
   759 			SetIndustryGfx(tile, GFX_OILWELL_ANIMATED_1);
   755 			SetIndustryGfx(tile, GFX_OILWELL_ANIMATED_1);
   760 			SetIndustryAnimationState(tile, 0);
   756 			SetIndustryAnimationState(tile, 0);
   761 			AddAnimatedTile(tile);
   757 			AddAnimatedTile(tile);
   762 		}
   758 		}
   763 		break;
   759 		break;
   777 			DeleteAnimatedTile(tile);
   773 			DeleteAnimatedTile(tile);
   778 		}
   774 		}
   779 		break;
   775 		break;
   780 
   776 
   781 	case GFX_POWERPLANT_SPARKS:
   777 	case GFX_POWERPLANT_SPARKS:
   782 		if (CHANCE16(1, 3)) {
   778 		if (Chance16(1, 3)) {
   783 			SndPlayTileFx(SND_0C_ELECTRIC_SPARK, tile);
   779 			SndPlayTileFx(SND_0C_ELECTRIC_SPARK, tile);
   784 			AddAnimatedTile(tile);
   780 			AddAnimatedTile(tile);
   785 		}
   781 		}
   786 		break;
   782 		break;
   787 
   783 
   807 	case GFX_TOFFEE_QUARY:
   803 	case GFX_TOFFEE_QUARY:
   808 		AddAnimatedTile(tile);
   804 		AddAnimatedTile(tile);
   809 		break;
   805 		break;
   810 
   806 
   811 	case GFX_SUGAR_MINE_SIEVE:
   807 	case GFX_SUGAR_MINE_SIEVE:
   812 		if (CHANCE16(1, 3)) AddAnimatedTile(tile);
   808 		if (Chance16(1, 3)) AddAnimatedTile(tile);
   813 		break;
   809 		break;
   814 	}
   810 	}
   815 }
   811 }
   816 
   812 
   817 static void ClickTile_Industry(TileIndex tile)
   813 static void ClickTile_Industry(TileIndex tile)
   865 		tile = TILE_MASK(tile);
   861 		tile = TILE_MASK(tile);
   866 
   862 
   867 		if (IsTileType(tile, MP_CLEAR) || IsTileType(tile, MP_TREES)) {
   863 		if (IsTileType(tile, MP_CLEAR) || IsTileType(tile, MP_TREES)) {
   868 			byte or_ = type;
   864 			byte or_ = type;
   869 
   865 
   870 			if (or_ == 1 && CHANCE16(1, 7)) or_ = 2;
   866 			if (or_ == 1 && Chance16(1, 7)) or_ = 2;
   871 
   867 
   872 			if (direction == AXIS_X) {
   868 			if (direction == AXIS_X) {
   873 				SetFenceSE(tile, or_);
   869 				SetFenceSE(tile, or_);
   874 			} else {
   870 			} else {
   875 				SetFenceSW(tile, or_);
   871 				SetFenceSW(tile, or_);
   992 	uint num;
   988 	uint num;
   993 	const IndustrySpec *indsp = GetIndustrySpec(i->type);
   989 	const IndustrySpec *indsp = GetIndustrySpec(i->type);
   994 
   990 
   995 	/* play a sound? */
   991 	/* play a sound? */
   996 	if ((i->counter & 0x3F) == 0) {
   992 	if ((i->counter & 0x3F) == 0) {
   997 		if (CHANCE16R(1, 14, r) && (num = indsp->number_of_sounds) != 0) {
   993 		if (Chance16R(1, 14, r) && (num = indsp->number_of_sounds) != 0) {
   998 			SndPlayTileFx(
   994 			SndPlayTileFx(
   999 				(SoundFx)(indsp->random_sounds[((r >> 16) * num) >> 16]),
   995 				(SoundFx)(indsp->random_sounds[((r >> 16) * num) >> 16]),
  1000 				i->xy);
   996 				i->xy);
  1001 		}
   997 		}
  1002 	}
   998 	}
  1003 
   999 
  1004 	i->counter--;
  1000 	i->counter--;
  1005 
  1001 
  1006 	/* produce some cargo */
  1002 	/* produce some cargo */
  1007 	if ((i->counter & 0xFF) == 0) {
  1003 	if ((i->counter & 0xFF) == 0) {
  1008 		if (HASBIT(indsp->callback_flags, CBM_IND_PRODUCTION_256_TICKS)) IndustryProductionCallback(i, 1);
  1004 		if (HasBit(indsp->callback_flags, CBM_IND_PRODUCTION_256_TICKS)) IndustryProductionCallback(i, 1);
  1009 
  1005 
  1010 		IndustyBehaviour indbehav = indsp->behaviour;
  1006 		IndustryBehaviour indbehav = indsp->behaviour;
  1011 		i->produced_cargo_waiting[0] = min(0xffff, i->produced_cargo_waiting[0] + i->production_rate[0]);
  1007 		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]);
  1008 		i->produced_cargo_waiting[1] = min(0xffff, i->produced_cargo_waiting[1] + i->production_rate[1]);
  1013 
  1009 
  1014 		if ((indbehav & INDUSTRYBEH_PLANT_FIELDS) != 0) {
  1010 		if ((indbehav & INDUSTRYBEH_PLANT_FIELDS) != 0) {
  1015 			bool plant;
  1011 			bool plant;
  1016 			if (HASBIT(indsp->callback_flags, CBM_IND_SPECIAL_EFFECT)) {
  1012 			if (HasBit(indsp->callback_flags, CBM_IND_SPECIAL_EFFECT)) {
  1017 				plant = (GetIndustryCallback(CBID_INDUSTRY_SPECIAL_EFFECT, Random(), 0, i, i->type, i->xy) != 0);
  1013 				plant = (GetIndustryCallback(CBID_INDUSTRY_SPECIAL_EFFECT, Random(), 0, i, i->type, i->xy) != 0);
  1018 			} else {
  1014 			} else {
  1019 				plant = CHANCE16(1, 8);
  1015 				plant = Chance16(1, 8);
  1020 			}
  1016 			}
  1021 
  1017 
  1022 			if (plant) PlantRandomFarmField(i);
  1018 			if (plant) PlantRandomFarmField(i);
  1023 		}
  1019 		}
  1024 		if ((indbehav & INDUSTRYBEH_CUT_TREES) != 0) {
  1020 		if ((indbehav & INDUSTRYBEH_CUT_TREES) != 0) {
  1025 			bool cut = ((i->counter & 0x1FF) == 0);
  1021 			bool cut = ((i->counter & 0x1FF) == 0);
  1026 			if (HASBIT(indsp->callback_flags, CBM_IND_SPECIAL_EFFECT)) {
  1022 			if (HasBit(indsp->callback_flags, CBM_IND_SPECIAL_EFFECT)) {
  1027 				cut = (GetIndustryCallback(CBID_INDUSTRY_SPECIAL_EFFECT, 0, 1, i, i->type, i->xy) != 0);
  1023 				cut = (GetIndustryCallback(CBID_INDUSTRY_SPECIAL_EFFECT, 0, 1, i, i->type, i->xy) != 0);
  1028 			}
  1024 			}
  1029 
  1025 
  1030 			if (cut) ChopLumberMillTrees(i);
  1026 			if (cut) ChopLumberMillTrees(i);
  1031 		}
  1027 		}
  1048 	}
  1044 	}
  1049 
  1045 
  1050 	if (_game_mode == GM_EDITOR) return;
  1046 	if (_game_mode == GM_EDITOR) return;
  1051 
  1047 
  1052 	FOR_ALL_INDUSTRIES(i) {
  1048 	FOR_ALL_INDUSTRIES(i) {
       
  1049 		TriggerIndustry(i, INDUSTRY_TRIGGER_INDUSTRY_TICK);
  1053 		StartStopIndustryTileAnimation(i, IAT_INDUSTRY_TICK);
  1050 		StartStopIndustryTileAnimation(i, IAT_INDUSTRY_TICK);
  1054 		ProduceIndustryGoods(i);
  1051 		ProduceIndustryGoods(i);
  1055 	}
  1052 	}
  1056 }
  1053 }
  1057 
  1054 
  1183 	return t;
  1180 	return t;
  1184 }
  1181 }
  1185 
  1182 
  1186 bool IsSlopeRefused(Slope current, Slope refused)
  1183 bool IsSlopeRefused(Slope current, Slope refused)
  1187 {
  1184 {
       
  1185 	if (IsSteepSlope(current)) return true;
  1188 	if (current != SLOPE_FLAT) {
  1186 	if (current != SLOPE_FLAT) {
  1189 		if (refused & SLOPE_STEEP) return true;
  1187 		if (refused & SLOPE_STEEP) return true;
  1190 
  1188 
  1191 		Slope t = ComplementSlope(current);
  1189 		Slope t = ComplementSlope(current);
  1192 
  1190 
  1218 			if (!IsTileType(cur_tile, MP_WATER) ||
  1216 			if (!IsTileType(cur_tile, MP_WATER) ||
  1219 					GetTileSlope(cur_tile, NULL) != SLOPE_FLAT) {
  1217 					GetTileSlope(cur_tile, NULL) != SLOPE_FLAT) {
  1220 				return false;
  1218 				return false;
  1221 			}
  1219 			}
  1222 		} else {
  1220 		} else {
  1223 			if (!EnsureNoVehicle(cur_tile)) return false;
  1221 			if (!EnsureNoVehicleOnGround(cur_tile)) return false;
  1224 			if (MayHaveBridgeAbove(cur_tile) && IsBridgeAbove(cur_tile)) return false;
  1222 			if (MayHaveBridgeAbove(cur_tile) && IsBridgeAbove(cur_tile)) return false;
  1225 
  1223 
  1226 			const IndustryTileSpec *its = GetIndustryTileSpec(gfx);
  1224 			const IndustryTileSpec *its = GetIndustryTileSpec(gfx);
  1227 
  1225 
  1228 			IndustyBehaviour ind_behav = GetIndustrySpec(type)->behaviour;
  1226 			IndustryBehaviour ind_behav = GetIndustrySpec(type)->behaviour;
  1229 
  1227 
  1230 			if (HASBIT(its->callback_flags, CBM_INDT_SHAPE_CHECK)) {
  1228 			/* Perform land/water check if not disabled */
       
  1229 			if (!HasBit(its->slopes_refused, 5) && (IsWaterTile(cur_tile) == !(ind_behav & INDUSTRYBEH_BUILT_ONWATER))) return false;
       
  1230 
       
  1231 			if (HasBit(its->callback_flags, CBM_INDT_SHAPE_CHECK)) {
  1231 				custom_shape = true;
  1232 				custom_shape = true;
  1232 				if (!PerformIndustryTileSlopeCheck(tile, cur_tile, its, type, gfx, itspec_index)) return false;
  1233 				if (!PerformIndustryTileSlopeCheck(tile, cur_tile, its, type, gfx, itspec_index)) return false;
  1233 			} else {
  1234 			} else {
  1234 				if (ind_behav & INDUSTRYBEH_BUILT_ONWATER) {
  1235 				Slope tileh = GetTileSlope(cur_tile, NULL);
  1235 					/* As soon as the tile is not water, bail out.
  1236 				refused_slope |= IsSlopeRefused(tileh, its->slopes_refused);
  1236 					* But that does not mean the search is over.  You have
  1237 			}
  1237 					* to make sure every tile of the industry will be only water*/
  1238 
  1238 					if (!IsClearWaterTile(cur_tile)) return false;
  1239 			if (ind_behav & (INDUSTRYBEH_ONLY_INTOWN | INDUSTRYBEH_TOWN1200_MORE)) {
  1239 				} else {
       
  1240 					Slope tileh;
       
  1241 
       
  1242 					if (IsClearWaterTile(cur_tile)) return false;
       
  1243 
       
  1244 					tileh = GetTileSlope(cur_tile, NULL);
       
  1245 					if (IsSteepSlope(tileh)) return false;
       
  1246 
       
  1247 					refused_slope |= IsSlopeRefused(tileh, its->slopes_refused);
       
  1248 				}
       
  1249 			}
       
  1250 
       
  1251 			if (ind_behav & INDUSTRYBEH_ONLY_INTOWN) {
       
  1252 				if (!IsTileType(cur_tile, MP_HOUSE)) {
  1240 				if (!IsTileType(cur_tile, MP_HOUSE)) {
  1253 					_error_message = STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS;
  1241 					_error_message = STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS;
  1254 					return false;
  1242 					return false;
  1255 				}
  1243 				}
  1256 				if (CmdFailed(DoCommand(cur_tile, 0, 0, 0, CMD_LANDSCAPE_CLEAR))) return false;
  1244 				if (CmdFailed(DoCommand(cur_tile, 0, 0, 0, CMD_LANDSCAPE_CLEAR))) return false;
  1300 		/* Is the tile clear? */
  1288 		/* Is the tile clear? */
  1301 		if ((GetTileType(tile_walk) != MP_CLEAR) && (GetTileType(tile_walk) != MP_TREES))
  1289 		if ((GetTileType(tile_walk) != MP_CLEAR) && (GetTileType(tile_walk) != MP_TREES))
  1302 			return false;
  1290 			return false;
  1303 
  1291 
  1304 		/* Don't allow too big of a change if this is the sub-tile check */
  1292 		/* Don't allow too big of a change if this is the sub-tile check */
  1305 		if (internal != 0 && delta(curh, height) > 1) return false;
  1293 		if (internal != 0 && Delta(curh, height) > 1) return false;
  1306 
  1294 
  1307 		/* Different height, so the surrounding tiles of this tile
  1295 		/* Different height, so the surrounding tiles of this tile
  1308 		 *  has to be correct too (in level, or almost in level)
  1296 		 *  has to be correct too (in level, or almost in level)
  1309 		 *  else you get a chain-reaction of terraforming. */
  1297 		 *  else you get a chain-reaction of terraforming. */
  1310 		if (internal == 0 && curh != height) {
  1298 		if (internal == 0 && curh != height) {
  1439 	i->accepts_cargo[1] = indspec->accepts_cargo[1];
  1427 	i->accepts_cargo[1] = indspec->accepts_cargo[1];
  1440 	i->accepts_cargo[2] = indspec->accepts_cargo[2];
  1428 	i->accepts_cargo[2] = indspec->accepts_cargo[2];
  1441 	i->production_rate[0] = indspec->production_rate[0];
  1429 	i->production_rate[0] = indspec->production_rate[0];
  1442 	i->production_rate[1] = indspec->production_rate[1];
  1430 	i->production_rate[1] = indspec->production_rate[1];
  1443 
  1431 
  1444 	/* don't use smooth economy for industries using production callbacks */
  1432 	/* don't use smooth economy for industries using production related callbacks */
  1445 	if (_patches.smooth_economy  && !(HASBIT(indspec->callback_flags, CBM_IND_PRODUCTION_256_TICKS) || HASBIT(indspec->callback_flags, CBM_IND_PRODUCTION_CARGO_ARRIVAL))) {
  1433 	if (_patches.smooth_economy &&
       
  1434 	    !(HasBit(indspec->callback_flags, CBM_IND_PRODUCTION_256_TICKS) || HasBit(indspec->callback_flags, CBM_IND_PRODUCTION_CARGO_ARRIVAL)) && // production callbacks
       
  1435 	    !(HasBit(indspec->callback_flags, CBM_IND_MONTHLYPROD_CHANGE) || HasBit(indspec->callback_flags, CBM_IND_PRODUCTION_CHANGE))             // production change callbacks
       
  1436 	) {
  1446 		i->production_rate[0] = min((RandomRange(256) + 128) * i->production_rate[0] >> 8 , 255);
  1437 		i->production_rate[0] = min((RandomRange(256) + 128) * i->production_rate[0] >> 8 , 255);
  1447 		i->production_rate[1] = min((RandomRange(256) + 128) * i->production_rate[1] >> 8 , 255);
  1438 		i->production_rate[1] = min((RandomRange(256) + 128) * i->production_rate[1] >> 8 , 255);
  1448 	}
  1439 	}
  1449 
  1440 
  1450 	i->town = t;
  1441 	i->town = t;
  1451 	i->owner = owner;
  1442 	i->owner = owner;
  1452 
  1443 
  1453 	r = Random();
  1444 	r = Random();
  1454 	i->random_color = GB(r, 8, 4);
  1445 	i->random_color = GB(r, 0, 4);
  1455 	i->counter = GB(r, 0, 12);
  1446 	i->counter = GB(r, 4, 12);
       
  1447 	i->random = GB(r, 16, 16);
  1456 	i->produced_cargo_waiting[0] = 0;
  1448 	i->produced_cargo_waiting[0] = 0;
  1457 	i->produced_cargo_waiting[1] = 0;
  1449 	i->produced_cargo_waiting[1] = 0;
  1458 	i->incoming_cargo_waiting[0] = 0;
  1450 	i->incoming_cargo_waiting[0] = 0;
  1459 	i->incoming_cargo_waiting[1] = 0;
  1451 	i->incoming_cargo_waiting[1] = 0;
  1460 	i->incoming_cargo_waiting[2] = 0;
  1452 	i->incoming_cargo_waiting[2] = 0;
  1470 	i->last_prod_year = _cur_year;
  1462 	i->last_prod_year = _cur_year;
  1471 	i->last_month_production[0] = i->production_rate[0] * 8;
  1463 	i->last_month_production[0] = i->production_rate[0] * 8;
  1472 	i->last_month_production[1] = i->production_rate[1] * 8;
  1464 	i->last_month_production[1] = i->production_rate[1] * 8;
  1473 	i->founder = _current_player;
  1465 	i->founder = _current_player;
  1474 
  1466 
  1475 	if (HASBIT(indspec->callback_flags, CBM_IND_DECIDE_COLOUR)) {
  1467 	if (HasBit(indspec->callback_flags, CBM_IND_DECIDE_COLOUR)) {
  1476 		uint16 res = GetIndustryCallback(CBID_INDUSTRY_DECIDE_COLOUR, 0, 0, i, type, INVALID_TILE);
  1468 		uint16 res = GetIndustryCallback(CBID_INDUSTRY_DECIDE_COLOUR, 0, 0, i, type, INVALID_TILE);
  1477 		if (res != CALLBACK_FAILED) i->random_color = GB(res, 0, 4);
  1469 		if (res != CALLBACK_FAILED) i->random_color = GB(res, 0, 4);
  1478 	}
  1470 	}
  1479 
  1471 
  1480 	if (HASBIT(indspec->callback_flags, CBM_IND_INPUT_CARGO_TYPES)) {
  1472 	if (HasBit(indspec->callback_flags, CBM_IND_INPUT_CARGO_TYPES)) {
  1481 		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++) i->accepts_cargo[j] = CT_INVALID;
  1482 		for (j = 0; j < lengthof(i->accepts_cargo); j++) {
  1474 		for (j = 0; j < lengthof(i->accepts_cargo); j++) {
  1483 			uint16 res = GetIndustryCallback(CBID_INDUSTRY_INPUT_CARGO_TYPES, j, 0, i, type, INVALID_TILE);
  1475 			uint16 res = GetIndustryCallback(CBID_INDUSTRY_INPUT_CARGO_TYPES, j, 0, i, type, INVALID_TILE);
  1484 			if (res == CALLBACK_FAILED || GB(res, 0, 8) == CT_INVALID) break;
  1476 			if (res == CALLBACK_FAILED || GB(res, 0, 8) == CT_INVALID) break;
  1485 			i->accepts_cargo[j] = GetCargoTranslation(GB(res, 0, 8), indspec->grf_prop.grffile);
  1477 			i->accepts_cargo[j] = GetCargoTranslation(GB(res, 0, 8), indspec->grf_prop.grffile);
  1486 		}
  1478 		}
  1487 	}
  1479 	}
  1488 
  1480 
  1489 	if (HASBIT(indspec->callback_flags, CBM_IND_OUTPUT_CARGO_TYPES)) {
  1481 	if (HasBit(indspec->callback_flags, CBM_IND_OUTPUT_CARGO_TYPES)) {
  1490 		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++) i->produced_cargo[j] = CT_INVALID;
  1491 		for (j = 0; j < lengthof(i->produced_cargo); j++) {
  1483 		for (j = 0; j < lengthof(i->produced_cargo); j++) {
  1492 			uint16 res = GetIndustryCallback(CBID_INDUSTRY_OUTPUT_CARGO_TYPES, j, 0, i, type, INVALID_TILE);
  1484 			uint16 res = GetIndustryCallback(CBID_INDUSTRY_OUTPUT_CARGO_TYPES, j, 0, i, type, INVALID_TILE);
  1493 			if (res == CALLBACK_FAILED || GB(res, 0, 8) == CT_INVALID) break;
  1485 			if (res == CALLBACK_FAILED || GB(res, 0, 8) == CT_INVALID) break;
  1494 			i->produced_cargo[j] = GetCargoTranslation(GB(res, 0, 8), indspec->grf_prop.grffile);
  1486 			i->produced_cargo[j] = GetCargoTranslation(GB(res, 0, 8), indspec->grf_prop.grffile);
  1520 			if (size > i->height)i->height = size;
  1512 			if (size > i->height)i->height = size;
  1521 
  1513 
  1522 			DoCommand(cur_tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
  1514 			DoCommand(cur_tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
  1523 
  1515 
  1524 			MakeIndustry(cur_tile, i->index, it->gfx);
  1516 			MakeIndustry(cur_tile, i->index, it->gfx);
       
  1517 
  1525 			if (_generating_world) {
  1518 			if (_generating_world) {
  1526 				SetIndustryConstructionCounter(cur_tile, 3);
  1519 				SetIndustryConstructionCounter(cur_tile, 3);
  1527 				SetIndustryConstructionStage(cur_tile, 2);
  1520 				SetIndustryConstructionStage(cur_tile, 2);
       
  1521 			}
       
  1522 			if (it->gfx >= NEW_INDUSTRYTILEOFFSET) {
       
  1523 				/* New industry */
       
  1524 				const IndustryTileSpec *its = GetIndustryTileSpec(it->gfx);
       
  1525 				if (its->animation_info != 0xFFFF) AddAnimatedTile(cur_tile);
  1528 			}
  1526 			}
  1529 		}
  1527 		}
  1530 	} while ((++it)->ti.x != -0x80);
  1528 	} while ((++it)->ti.x != -0x80);
  1531 
  1529 
  1532 	i->width++;
  1530 	i->width++;
  1552 	const IndustryTileTable *it = indspec->table[itspec_index];
  1550 	const IndustryTileTable *it = indspec->table[itspec_index];
  1553 	bool custom_shape_check = false;
  1551 	bool custom_shape_check = false;
  1554 
  1552 
  1555 	if (!CheckIfIndustryTilesAreFree(tile, it, itspec_index, type, &custom_shape_check)) return NULL;
  1553 	if (!CheckIfIndustryTilesAreFree(tile, it, itspec_index, type, &custom_shape_check)) return NULL;
  1556 
  1554 
  1557 	if (HASBIT(GetIndustrySpec(type)->callback_flags, CBM_IND_LOCATION)) {
  1555 	if (HasBit(GetIndustrySpec(type)->callback_flags, CBM_IND_LOCATION)) {
  1558 		if (!CheckIfCallBackAllowsCreation(tile, type, itspec_index)) return NULL;
  1556 		if (!CheckIfCallBackAllowsCreation(tile, type, itspec_index)) return NULL;
  1559 	} else {
  1557 	} else {
  1560 		if (!_check_new_industry_procs[indspec->check_proc](tile)) return NULL;
  1558 		if (!_check_new_industry_procs[indspec->check_proc](tile)) return NULL;
  1561 	}
  1559 	}
  1562 
  1560 
  1584 
  1582 
  1585 /** Build/Fund an industry
  1583 /** Build/Fund an industry
  1586  * @param tile tile where industry is built
  1584  * @param tile tile where industry is built
  1587  * @param flags of operations to conduct
  1585  * @param flags of operations to conduct
  1588  * @param p1 industry type see build_industry.h and see industry.h
  1586  * @param p1 industry type see build_industry.h and see industry.h
  1589  * @param p2 unused
  1587  * @param p2 first layout to try
  1590  * @return index of the newly create industry, or CMD_ERROR if it failed
  1588  * @return index of the newly create industry, or CMD_ERROR if it failed
  1591  */
  1589  */
  1592 CommandCost CmdBuildIndustry(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1590 CommandCost CmdBuildIndustry(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1593 {
  1591 {
  1594 	int num;
       
  1595 	const IndustryTileTable * const *itt;
       
  1596 	const IndustrySpec *indspec;
  1592 	const IndustrySpec *indspec;
  1597 
  1593 
  1598 	SET_EXPENSES_TYPE(EXPENSES_OTHER);
  1594 	SET_EXPENSES_TYPE(EXPENSES_OTHER);
  1599 
  1595 
  1600 	indspec = GetIndustrySpec(p1);
  1596 	indspec = GetIndustrySpec(p1);
  1615 			/* Prospecting has a chance to fail, however we cannot guarantee that something can
  1611 			/* Prospecting has a chance to fail, however we cannot guarantee that something can
  1616 			 * be built on the map, so the chance gets lower when the map is fuller, but there
  1612 			 * be built on the map, so the chance gets lower when the map is fuller, but there
  1617 			 * is nothing we can really do about that. */
  1613 			 * is nothing we can really do about that. */
  1618 			if (Random() <= indspec->prospecting_chance) {
  1614 			if (Random() <= indspec->prospecting_chance) {
  1619 				for (int i = 0; i < 5000; i++) {
  1615 				for (int i = 0; i < 5000; i++) {
  1620 					uint tilespec_index = RandomRange(indspec->num_table);
  1616 					const Industry *ind = CreateNewIndustryHelper(RandomTile(), p1, flags, indspec, RandomRange(indspec->num_table));
  1621 					const Industry *ind = CreateNewIndustryHelper(RandomTile(), p1, flags, indspec, tilespec_index);
       
  1622 					if (ind != NULL) {
  1617 					if (ind != NULL) {
  1623 						SetDParam(0, indspec->name);
  1618 						SetDParam(0, indspec->name);
  1624 						SetDParam(1, ind->town->index);
  1619 						if (indspec->new_industry_text > STR_LAST_STRINGID) {
       
  1620 							SetDParam(1, STR_TOWN);
       
  1621 							SetDParam(2, ind->town->index);
       
  1622 						} else {
       
  1623 							SetDParam(1, ind->town->index);
       
  1624 						}
  1625 						AddNewsItem(indspec->new_industry_text,
  1625 						AddNewsItem(indspec->new_industry_text,
  1626 								NEWS_FLAGS(NM_THIN, NF_VIEWPORT | NF_TILE, NT_OPENCLOSE, 0), ind->xy, 0);
  1626 								NEWS_FLAGS(NM_THIN, NF_VIEWPORT | NF_TILE, NT_OPENCLOSE, 0), ind->xy, 0);
  1627 						break;
  1627 						break;
  1628 					}
  1628 					}
  1629 				}
  1629 				}
  1630 			}
  1630 			}
  1631 		}
  1631 		}
  1632 	} else {
  1632 	} else {
  1633 		num = indspec->num_table;
  1633 		int count = indspec->num_table;
  1634 		itt = indspec->table;
  1634 		const IndustryTileTable * const *itt = indspec->table;
  1635 
  1635 		int num = Clamp(p2, 0, count - 1);
  1636 
  1636 
       
  1637 		_error_message = STR_0239_SITE_UNSUITABLE;
  1637 		do {
  1638 		do {
  1638 			if (--num < 0) return_cmd_error(STR_0239_SITE_UNSUITABLE);
  1639 			if (--count < 0) return CMD_ERROR;
       
  1640 			if (--num < 0) num = indspec->num_table - 1;
  1639 		} while (!CheckIfIndustryTilesAreFree(tile, itt[num], num, p1));
  1641 		} while (!CheckIfIndustryTilesAreFree(tile, itt[num], num, p1));
  1640 
  1642 
  1641 		if (CreateNewIndustryHelper(tile, p1, flags, indspec, num) == NULL) return CMD_ERROR;
  1643 		if (CreateNewIndustryHelper(tile, p1, flags, indspec, num) == NULL) return CMD_ERROR;
  1642 	}
  1644 	}
  1643 
  1645 
  1794 	ProbabilityHelper cumulative_probs[NUM_INDUSTRYTYPES]; // probability collector
  1796 	ProbabilityHelper cumulative_probs[NUM_INDUSTRYTYPES]; // probability collector
  1795 	uint16 probability_max = 0;
  1797 	uint16 probability_max = 0;
  1796 
  1798 
  1797 	/* Generate a list of all possible industries that can be built. */
  1799 	/* Generate a list of all possible industries that can be built. */
  1798 	for (j = 0; j < NUM_INDUSTRYTYPES; j++) {
  1800 	for (j = 0; j < NUM_INDUSTRYTYPES; j++) {
  1799 		byte chance = GetIndustrySpec(j)->appear_ingame[_opt.landscape];
  1801 		ind_spc = GetIndustrySpec(j);
       
  1802 		byte chance = ind_spc->appear_ingame[_opt.landscape];
       
  1803 
       
  1804 		if (!ind_spc->enabled || chance == 0) continue;
  1800 
  1805 
  1801 		/* If there is no Callback CBID_INDUSTRY_AVAILABLE or if this one did anot failed,
  1806 		/* If there is no Callback CBID_INDUSTRY_AVAILABLE or if this one did anot failed,
  1802 		 * and if appearing chance for this landscape is above 0, this industry can be chosen */
  1807 		 * and if appearing chance for this landscape is above 0, this industry can be chosen */
  1803 		if (CheckIfCallBackAllowsAvailability(j, IACT_RANDOMCREATION) && chance != 0) {
  1808 		if (CheckIfCallBackAllowsAvailability(j, IACT_RANDOMCREATION)) {
  1804 			probability_max += chance;
  1809 			probability_max += chance;
  1805 			/* adds the result for this industry */
  1810 			/* adds the result for this industry */
  1806 			cumulative_probs[num].ind = j;
  1811 			cumulative_probs[num].ind = j;
  1807 			cumulative_probs[num++].prob = probability_max;
  1812 			cumulative_probs[num++].prob = probability_max;
  1808 		}
  1813 		}
  1827 		if (ind != NULL) break;
  1832 		if (ind != NULL) break;
  1828 		if (--num == 0) return;
  1833 		if (--num == 0) return;
  1829 	}
  1834 	}
  1830 
  1835 
  1831 	SetDParam(0, ind_spc->name);
  1836 	SetDParam(0, ind_spc->name);
  1832 	SetDParam(1, ind->town->index);
  1837 	if (ind_spc->new_industry_text > STR_LAST_STRINGID) {
       
  1838 		SetDParam(1, STR_TOWN);
       
  1839 		SetDParam(2, ind->town->index);
       
  1840 	} else {
       
  1841 		SetDParam(1, ind->town->index);
       
  1842 	}
  1833 	AddNewsItem(ind_spc->new_industry_text,
  1843 	AddNewsItem(ind_spc->new_industry_text,
  1834 		NEWS_FLAGS(NM_THIN, NF_VIEWPORT | NF_TILE, NT_OPENCLOSE, 0), ind->xy, 0);
  1844 		NEWS_FLAGS(NM_THIN, NF_VIEWPORT | NF_TILE, NT_OPENCLOSE, 0), ind->xy, 0);
  1835 }
  1845 }
  1836 
  1846 
  1837 /**
  1847 /**
  1846 {
  1856 {
  1847 	const IndustrySpec *indspec = GetIndustrySpec(type);
  1857 	const IndustrySpec *indspec = GetIndustrySpec(type);
  1848 
  1858 
  1849 	/* oil wells (or the industries with that flag set) are always allowed to closedown */
  1859 	/* 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;
  1860 	if (indspec->behaviour & INDUSTRYBEH_DONT_INCR_PROD && _opt.landscape == LT_TEMPERATE) return false;
  1851 	return (indspec->behaviour & INDUSTRYBEH_CANCLOSE_LASTINSTANCE && GetIndustryTypeCount(type) <= 1);
  1861 	return (indspec->behaviour & INDUSTRYBEH_CANCLOSE_LASTINSTANCE) == 0 && GetIndustryTypeCount(type) <= 1;
  1852 }
  1862 }
       
  1863 
       
  1864 /**
       
  1865 * Can given cargo type be accepted or produced by the industry?
       
  1866 * @param cargo: Cargo type
       
  1867 * @param ind: Industry
       
  1868 * @param *c_accepts: Pointer to boolean for acceptance of cargo
       
  1869 * @param *c_produces: Pointer to boolean for production of cargo
       
  1870 * @return: \c *c_accepts is set when industry accepts the cargo type,
       
  1871 *          \c *c_produces is set when the industry produces the cargo type
       
  1872 */
       
  1873 static void CanCargoServiceIndustry(CargoID cargo, Industry *ind, bool *c_accepts, bool *c_produces)
       
  1874 {
       
  1875 	const IndustrySpec *indspec = GetIndustrySpec(ind->type);
       
  1876 
       
  1877 	/* Check for acceptance of cargo */
       
  1878 	for (uint j = 0; j < lengthof(ind->accepts_cargo) && ind->accepts_cargo[j] != CT_INVALID; j++) {
       
  1879 		if (cargo == ind->accepts_cargo[j]) {
       
  1880 			if (HasBit(indspec->callback_flags, CBM_IND_REFUSE_CARGO)) {
       
  1881 				uint16 res = GetIndustryCallback(CBID_INDUSTRY_REFUSE_CARGO,
       
  1882 						0, GetReverseCargoTranslation(cargo, indspec->grf_prop.grffile),
       
  1883 						ind, ind->type, ind->xy);
       
  1884 				if (res == 0) continue;
       
  1885 			}
       
  1886 			*c_accepts = true;
       
  1887 			break;
       
  1888 		}
       
  1889 	}
       
  1890 
       
  1891 	/* Check for produced cargo */
       
  1892 	for (uint j = 0; j < lengthof(ind->produced_cargo) && ind->produced_cargo[j] != CT_INVALID; j++) {
       
  1893 		if (cargo == ind->produced_cargo[j]) {
       
  1894 			*c_produces = true;
       
  1895 			break;
       
  1896 		}
       
  1897 	}
       
  1898 }
       
  1899 
       
  1900 /**
       
  1901 * Compute who can service the industry.
       
  1902 *
       
  1903 * Here, 'can service' means that he/she has trains and stations close enough
       
  1904 * to the industry with the right cargo type and the right orders (ie has the
       
  1905 * technical means).
       
  1906 *
       
  1907 * @param ind: Industry being investigated.
       
  1908 *
       
  1909 * @return: 0 if nobody can service the industry, 2 if the local player can
       
  1910 * service the industry, and 1 otherwise (only competitors can service the
       
  1911 * industry)
       
  1912 */
       
  1913 int WhoCanServiceIndustry(Industry* ind)
       
  1914 {
       
  1915 	/* Find all stations within reach of the industry */
       
  1916 	StationSet stations = FindStationsAroundIndustryTile(ind->xy, ind->width, ind->height);
       
  1917 
       
  1918 	if (stations.size() == 0) return 0; // No stations found at all => nobody services
       
  1919 
       
  1920 	const Vehicle *v;
       
  1921 	int result = 0;
       
  1922 	FOR_ALL_VEHICLES(v) {
       
  1923 		/* Is it worthwhile to try this vehicle? */
       
  1924 		if (v->owner != _local_player && result != 0) continue;
       
  1925 
       
  1926 		/* Check whether it accepts the right kind of cargo */
       
  1927 		bool c_accepts = false;
       
  1928 		bool c_produces = false;
       
  1929 		if (v->type == VEH_TRAIN && IsFrontEngine(v)) {
       
  1930 			const Vehicle *u = v;
       
  1931 			BEGIN_ENUM_WAGONS(u)
       
  1932 				CanCargoServiceIndustry(u->cargo_type, ind, &c_accepts, &c_produces);
       
  1933 			END_ENUM_WAGONS(u)
       
  1934 		} else if (v->type == VEH_ROAD || v->type == VEH_SHIP || v->type == VEH_AIRCRAFT) {
       
  1935 			CanCargoServiceIndustry(v->cargo_type, ind, &c_accepts, &c_produces);
       
  1936 		} else {
       
  1937 			continue;
       
  1938 		}
       
  1939 		if (!c_accepts && !c_produces) continue; // Wrong cargo
       
  1940 
       
  1941 		/* Check orders of the vehicle.
       
  1942 		 * We cannot check the first of shared orders only, since the first vehicle in such a chain
       
  1943 		 * may have a different cargo type.
       
  1944 		 */
       
  1945 		const Order *o;
       
  1946 		FOR_VEHICLE_ORDERS(v, o) {
       
  1947 			if (o->type == OT_GOTO_STATION && !HasBit(o->flags, OFB_TRANSFER)) {
       
  1948 				/* Vehicle visits a station to load or unload */
       
  1949 				Station *st = GetStation(o->dest);
       
  1950 				if (!st->IsValid()) continue;
       
  1951 
       
  1952 				/* Same cargo produced by industry is dropped here => not serviced by vehicle v */
       
  1953 				if (HasBit(o->flags, OFB_UNLOAD) && !c_accepts) break;
       
  1954 
       
  1955 				if (stations.find(st) != stations.end()) {
       
  1956 					if (v->owner == _local_player) return 2; // Player services industry
       
  1957 					result = 1; // Competitor services industry
       
  1958 				}
       
  1959 			}
       
  1960 		}
       
  1961 	}
       
  1962 	return result;
       
  1963 }
       
  1964 
       
  1965 /**
       
  1966 * Report news that industry production has changed significantly
       
  1967 *
       
  1968 * @param ind: Industry with changed production
       
  1969 * @param type: Cargo type that has changed
       
  1970 * @param percent: Percentage of change (>0 means increase, <0 means decrease)
       
  1971 */
       
  1972 static void ReportNewsProductionChangeIndustry(Industry *ind, CargoID type, int percent)
       
  1973 {
       
  1974 	NewsType nt;
       
  1975 
       
  1976 	switch (WhoCanServiceIndustry(ind)) {
       
  1977 		case 0: nt = NT_INDUSTRY_NOBODY; break;
       
  1978 		case 1: nt = NT_INDUSTRY_OTHER;  break;
       
  1979 		case 2: nt = NT_INDUSTRY_PLAYER; break;
       
  1980 		default: NOT_REACHED(); break;
       
  1981 	}
       
  1982 	SetDParam(2, abs(percent));
       
  1983 	SetDParam(0, GetCargo(type)->name);
       
  1984 	SetDParam(1, ind->index);
       
  1985 	AddNewsItem(
       
  1986 		percent >= 0 ? STR_INDUSTRY_PROD_GOUP : STR_INDUSTRY_PROD_GODOWN,
       
  1987 		NEWS_FLAGS(NM_THIN, NF_VIEWPORT | NF_TILE, nt, 0),
       
  1988 		ind->xy + TileDiffXY(1, 1), 0
       
  1989 	);
       
  1990 }
       
  1991 
       
  1992 enum {
       
  1993 	PERCENT_TRANSPORTED_60 = 153,
       
  1994 };
  1853 
  1995 
  1854 /** Change industry production or do closure
  1996 /** Change industry production or do closure
  1855  * @param i Industry for which changes are performed
  1997  * @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
  1998  * @param monthly true if it's the monthly call, false if it's the random call
  1857  */
  1999  */
  1861 	StringID str = STR_NULL;
  2003 	StringID str = STR_NULL;
  1862 	bool closeit = false;
  2004 	bool closeit = false;
  1863 	const IndustrySpec *indspec = GetIndustrySpec(i->type);
  2005 	const IndustrySpec *indspec = GetIndustrySpec(i->type);
  1864 	bool standard = true;
  2006 	bool standard = true;
  1865 	bool suppress_message = false;
  2007 	bool suppress_message = false;
  1866 	/* don't use smooth economy for industries using production callbacks */
  2008 	/* 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));
  2009 	bool smooth_economy = _patches.smooth_economy &&
       
  2010 	                      !(HasBit(indspec->callback_flags, CBM_IND_PRODUCTION_256_TICKS) || HasBit(indspec->callback_flags, CBM_IND_PRODUCTION_CARGO_ARRIVAL)) && // production callbacks
       
  2011 	                      !(HasBit(indspec->callback_flags, CBM_IND_MONTHLYPROD_CHANGE) || HasBit(indspec->callback_flags, CBM_IND_PRODUCTION_CHANGE));            // production change callbacks
  1868 	byte div = 0;
  2012 	byte div = 0;
  1869 	byte mul = 0;
  2013 	byte mul = 0;
  1870 
  2014 	int8 increment = 0;
  1871 	if (HASBIT(indspec->callback_flags, monthly ? CBM_IND_MONTHLYPROD_CHANGE : CBM_IND_PRODUCTION_CHANGE)) {
  2015 
       
  2016 	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);
  2017 		uint16 res = GetIndustryCallback(monthly ? CBID_INDUSTRY_MONTHLYPROD_CHANGE : CBID_INDUSTRY_PRODUCTION_CHANGE, 0, Random(), i, i->type, i->xy);
       
  2018 		standard = false;
       
  2019 		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) {
  2020 		if (res != CALLBACK_FAILED) {
  1874 			standard = false;
  2021 			suppress_message = HasBit(res, 7);
  1875 			suppress_message = HASBIT(res, 7);
       
  1876 			/* Get the custom message if any */
  2022 			/* Get the custom message if any */
  1877 			if (HASBIT(res, 8)) str = MapGRFStringID(indspec->grf_prop.grffile->grfid, GB(GetRegister(0x100), 0, 16));
  2023 			if (HasBit(res, 8)) str = MapGRFStringID(indspec->grf_prop.grffile->grfid, GB(GetRegister(0x100), 0, 16));
  1878 			res = GB(res, 0, 4);
  2024 			res = GB(res, 0, 4);
  1879 			switch(res) {
  2025 			switch(res) {
  1880 				default: NOT_REACHED();
  2026 				default: NOT_REACHED();
  1881 				case 0x0: break;                  // Do nothing, but show the custom message if any
  2027 				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.
  2028 				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.
  2029 				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.
  2030 				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.
  2031 				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
  2032 				case 0x5: case 0x6: case 0x7:     // Divide production by 4, 8, 16
  1887 				case 0x8: div = res - 0x5; break; // Divide production by 32
  2033 				case 0x8: div = res - 0x3; break; // Divide production by 32
  1888 				case 0x9: case 0xA: case 0xB:     // Multiply production by 4, 8, 16
  2034 				case 0x9: case 0xA: case 0xB:     // Multiply production by 4, 8, 16
  1889 				case 0xC: mul = res - 0x9; break; // Multiply production by 32
  2035 				case 0xC: mul = res - 0x7; break; // Multiply production by 32
       
  2036 				case 0xD:                         // decrement production
       
  2037 				case 0xE:                         // increment production
       
  2038 					increment = res == 0x0D ? -1 : 1;
       
  2039 					break;
  1890 			}
  2040 			}
  1891 		}
  2041 		}
  1892 	}
  2042 	}
  1893 
  2043 
  1894 	if (standard && monthly != smooth_economy) return;
  2044 	if (standard && monthly != smooth_economy) return;
  1900 		bool only_decrease = (indspec->behaviour & INDUSTRYBEH_DONT_INCR_PROD) && _opt.landscape == LT_TEMPERATE;
  2050 		bool only_decrease = (indspec->behaviour & INDUSTRYBEH_DONT_INCR_PROD) && _opt.landscape == LT_TEMPERATE;
  1901 
  2051 
  1902 		if (smooth_economy) {
  2052 		if (smooth_economy) {
  1903 			closeit = true;
  2053 			closeit = true;
  1904 			for (byte j = 0; j < 2 && i->produced_cargo[j] != CT_INVALID; j++){
  2054 			for (byte j = 0; j < 2 && i->produced_cargo[j] != CT_INVALID; j++){
  1905 				uint32 r = Random();
       
  1906 				int old_prod, new_prod, percent;
  2055 				int old_prod, new_prod, percent;
  1907 				int mag;
  2056 				int mult = (i->last_month_pct_transported[j] > PERCENT_TRANSPORTED_60) ? 1 : -1;
  1908 
  2057 
  1909 				new_prod = old_prod = i->production_rate[j];
  2058 				new_prod = old_prod = i->production_rate[j];
  1910 
  2059 
  1911 				if (CHANCE16I(20, 1024, r)) new_prod -= max(((RandomRange(50) + 10) * old_prod) >> 8, 1U);
  2060 				if (only_decrease) {
  1912 				/* Chance of increasing becomes better when more is transported */
  2061 					mult = -1;
  1913 				if (CHANCE16I(20 + (i->last_month_pct_transported[j] * 20 >> 8), 1024, r >> 16) && !only_decrease) {
  2062 				} else if (Chance16(1, 3)) {
  1914 					new_prod += max(((RandomRange(50) + 10) * old_prod) >> 8, 1U);
  2063 					mult *= -1;
  1915 				}
  2064 				}
  1916 
  2065 
  1917 				new_prod = clamp(new_prod, 1, 255);
  2066 				if (Chance16(1, 22)) {
       
  2067 					new_prod += mult * (max(((RandomRange(50) + 10) * old_prod) >> 8, 1U));
       
  2068 				}
       
  2069 
       
  2070 				/* Prevent production to overflow or Oil Rig passengers to be over-"produced" */
       
  2071 				new_prod = Clamp(new_prod, 1, 255);
       
  2072 
       
  2073 				if (((indspec->behaviour & INDUSTRYBEH_BUILT_ONWATER) != 0) && j == 1)
       
  2074 					new_prod = Clamp(new_prod, 0, 16);
       
  2075 
  1918 				/* Do not stop closing the industry when it has the lowest possible production rate */
  2076 				/* Do not stop closing the industry when it has the lowest possible production rate */
  1919 				if (new_prod == old_prod && old_prod > 1) {
  2077 				if (new_prod == old_prod && old_prod > 1) {
  1920 					closeit = false;
  2078 					closeit = false;
  1921 					continue;
  2079 					continue;
  1922 				}
  2080 				}
  1925 				i->production_rate[j] = new_prod;
  2083 				i->production_rate[j] = new_prod;
  1926 
  2084 
  1927 				/* Close the industry when it has the lowest possible production rate */
  2085 				/* Close the industry when it has the lowest possible production rate */
  1928 				if (new_prod > 1) closeit = false;
  2086 				if (new_prod > 1) closeit = false;
  1929 
  2087 
  1930 				mag = abs(percent);
  2088 				if (abs(percent) >= 10) {
  1931 				if (mag >= 10) {
  2089 					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 				}
  2090 				}
  1941 			}
  2091 			}
  1942 		} else {
  2092 		} else {
  1943 			if (only_decrease || CHANCE16(1, 3)) {
  2093 			if (only_decrease || Chance16(1, 3)) {
  1944 				/* If you transport > 60%, 66% chance we increase, else 33% chance we increase */
  2094 				/* 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)) {
  2095 				if (!only_decrease && (i->last_month_pct_transported[0] > PERCENT_TRANSPORTED_60) != Chance16(1, 3)) {
  1946 					mul = 1; // Increase production
  2096 					mul = 1; // Increase production
  1947 				} else {
  2097 				} else {
  1948 					div = 1; // Decrease production
  2098 					div = 1; // Decrease production
  1949 				}
  2099 				}
  1950 			}
  2100 			}
  1951 		}
  2101 		}
  1952 	}
  2102 	}
  1953 
  2103 
  1954 	if (standard && indspec->life_type & INDUSTRYLIFE_PROCESSING) {
  2104 	if (standard && indspec->life_type & INDUSTRYLIFE_PROCESSING) {
  1955 		if ( (byte)(_cur_year - i->last_prod_year) >= 5 && CHANCE16(1, smooth_economy ? 180 : 2)) {
  2105 		if ( (byte)(_cur_year - i->last_prod_year) >= 5 && Chance16(1, smooth_economy ? 180 : 2)) {
  1956 			closeit = true;
  2106 			closeit = true;
  1957 		}
  2107 		}
  1958 	}
  2108 	}
  1959 
  2109 
  1960 	/* Increase if needed */
  2110 	/* Increase if needed */
  1975 			i->production_rate[1] = (i->production_rate[1] + 1) >> 1;
  2125 			i->production_rate[1] = (i->production_rate[1] + 1) >> 1;
  1976 			if (str == STR_NULL) str = indspec->production_down_text;
  2126 			if (str == STR_NULL) str = indspec->production_down_text;
  1977 		}
  2127 		}
  1978 	}
  2128 	}
  1979 
  2129 
       
  2130 	if (increment != 0) {
       
  2131 		i->prod_level = ClampU(i->prod_level + increment, 4, 0x80);
       
  2132 		if (i->prod_level == 4) closeit = true;
       
  2133 	}
       
  2134 
  1980 	/* Close if needed and allowed */
  2135 	/* Close if needed and allowed */
  1981 	if (closeit && !CheckIndustryCloseDownProtection(i->type)) {
  2136 	if (closeit && !CheckIndustryCloseDownProtection(i->type)) {
  1982 		i->prod_level = 0;
  2137 		i->prod_level = 0;
  1983 		str = indspec->closure_text;
  2138 		str = indspec->closure_text;
  1984 	}
  2139 	}
  1985 
  2140 
  1986 	if (!suppress_message && str != STR_NULL) {
  2141 	if (!suppress_message && str != STR_NULL) {
  1987 		SetDParam(0, i->index);
  2142 		NewsType nt;
       
  2143 		/* Compute news category */
       
  2144 		if (closeit) {
       
  2145 			nt = NT_OPENCLOSE;
       
  2146 		} else {
       
  2147 			switch (WhoCanServiceIndustry(i)) {
       
  2148 				case 0: nt = NT_INDUSTRY_NOBODY; break;
       
  2149 				case 1: nt = NT_INDUSTRY_OTHER;  break;
       
  2150 				case 2: nt = NT_INDUSTRY_PLAYER; break;
       
  2151 				default: NOT_REACHED(); break;
       
  2152 			}
       
  2153 		}
       
  2154 		/* Set parameters of news string */
       
  2155 		if (str > STR_LAST_STRINGID) {
       
  2156 			SetDParam(0, STR_TOWN);
       
  2157 			SetDParam(1, i->town->index);
       
  2158 			SetDParam(2, indspec->name);
       
  2159 		} else if (closeit) {
       
  2160 			SetDParam(0, STR_INDUSTRY_FORMAT);
       
  2161 			SetDParam(1, i->town->index);
       
  2162 			SetDParam(2, indspec->name);
       
  2163 		} else {
       
  2164 			SetDParam(0, i->index);
       
  2165 		}
       
  2166 		/* and report the news to the user */
  1988 		AddNewsItem(str,
  2167 		AddNewsItem(str,
  1989 			NEWS_FLAGS(NM_THIN, NF_VIEWPORT | NF_TILE, closeit ? NT_OPENCLOSE : NT_ECONOMY, 0),
  2168 			NEWS_FLAGS(NM_THIN, NF_VIEWPORT | NF_TILE, nt, 0),
  1990 			i->xy + TileDiffXY(1, 1), 0);
  2169 			i->xy + TileDiffXY(1, 1), 0);
  1991 	}
  2170 	}
  1992 }
  2171 }
  1993 
  2172 
  1994 void IndustryMonthlyLoop()
  2173 void IndustryMonthlyLoop()
  2005 			ChangeIndustryProduction(i, true);
  2184 			ChangeIndustryProduction(i, true);
  2006 		}
  2185 		}
  2007 	}
  2186 	}
  2008 
  2187 
  2009 	/* 3% chance that we start a new industry */
  2188 	/* 3% chance that we start a new industry */
  2010 	if (CHANCE16(3, 100)) {
  2189 	if (Chance16(3, 100)) {
  2011 		MaybeNewIndustry();
  2190 		MaybeNewIndustry();
  2012 	} else {
  2191 	} else {
  2013 		i = GetRandomIndustry();
  2192 		i = GetRandomIndustry();
  2014 		if (i != NULL) ChangeIndustryProduction(i, false);
  2193 		if (i != NULL) ChangeIndustryProduction(i, false);
  2015 	}
  2194 	}
  2044 	return (_price.build_industry *
  2223 	return (_price.build_industry *
  2045 			(_patches.raw_industry_construction == 1 && this->IsRawIndustry() ?
  2224 			(_patches.raw_industry_construction == 1 && this->IsRawIndustry() ?
  2046 					this->raw_industry_cost_multiplier :
  2225 					this->raw_industry_cost_multiplier :
  2047 					this->cost_multiplier
  2226 					this->cost_multiplier
  2048 			)) >> 8;
  2227 			)) >> 8;
       
  2228 }
       
  2229 
       
  2230 Money IndustrySpec::GetRemovalCost() const
       
  2231 {
       
  2232 	return (_price.remove_house * this->removal_cost_multiplier) >> 8;
  2049 }
  2233 }
  2050 
  2234 
  2051 static CommandCost TerraformTile_Industry(TileIndex tile, uint32 flags, uint z_new, Slope tileh_new)
  2235 static CommandCost TerraformTile_Industry(TileIndex tile, uint32 flags, uint z_new, Slope tileh_new)
  2052 {
  2236 {
  2053 	if (AutoslopeEnabled()) {
  2237 	if (AutoslopeEnabled()) {
  2062 		if (!IsSteepSlope(tileh_old) && !IsSteepSlope(tileh_new) && (GetTileMaxZ(tile) == z_new + GetSlopeMaxZ(tileh_new))) {
  2246 		if (!IsSteepSlope(tileh_old) && !IsSteepSlope(tileh_new) && (GetTileMaxZ(tile) == z_new + GetSlopeMaxZ(tileh_new))) {
  2063 			const IndustryGfx gfx = GetIndustryGfx(tile);
  2247 			const IndustryGfx gfx = GetIndustryGfx(tile);
  2064 			const IndustryTileSpec *itspec = GetIndustryTileSpec(gfx);
  2248 			const IndustryTileSpec *itspec = GetIndustryTileSpec(gfx);
  2065 
  2249 
  2066 			/* Call callback 3C 'disable autosloping for industry tiles'. */
  2250 			/* Call callback 3C 'disable autosloping for industry tiles'. */
  2067 			if (HASBIT(itspec->callback_flags, CBM_INDT_AUTOSLOPE)) {
  2251 			if (HasBit(itspec->callback_flags, CBM_INDT_AUTOSLOPE)) {
  2068 				/* If the callback fails, allow autoslope. */
  2252 				/* If the callback fails, allow autoslope. */
  2069 				uint16 res = GetIndustryTileCallback(CBID_INDUSTRY_AUTOSLOPE, 0, 0, gfx, GetIndustryByTile(tile), tile);
  2253 				uint16 res = GetIndustryTileCallback(CBID_INDUSTRY_AUTOSLOPE, 0, 0, gfx, GetIndustryByTile(tile), tile);
  2070 				if ((res == 0) || (res == CALLBACK_FAILED)) return _price.terraform;
  2254 				if ((res == 0) || (res == CALLBACK_FAILED)) return _price.terraform;
  2071 			} else {
  2255 			} else {
  2072 				// allow autoslope
  2256 				/* allow autoslope */
  2073 				return _price.terraform;
  2257 				return _price.terraform;
  2074 			}
  2258 			}
  2075 		}
  2259 		}
  2076 	}
  2260 	}
  2077 	return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
  2261 	return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
  2129 	SLE_CONDVAR(Industry, last_cargo_accepted_at,     SLE_INT32,                 70, SL_MAX_VERSION),
  2313 	SLE_CONDVAR(Industry, last_cargo_accepted_at,     SLE_INT32,                 70, SL_MAX_VERSION),
  2130 	SLE_CONDVAR(Industry, selected_layout,            SLE_UINT8,                 73, SL_MAX_VERSION),
  2314 	SLE_CONDVAR(Industry, selected_layout,            SLE_UINT8,                 73, SL_MAX_VERSION),
  2131 
  2315 
  2132 	SLE_CONDARRX(cpp_offsetof(Industry, psa) + cpp_offsetof(Industry::PersistentStorage, storage), SLE_UINT32, 16, 76, SL_MAX_VERSION),
  2316 	SLE_CONDARRX(cpp_offsetof(Industry, psa) + cpp_offsetof(Industry::PersistentStorage, storage), SLE_UINT32, 16, 76, SL_MAX_VERSION),
  2133 
  2317 
       
  2318 	SLE_CONDVAR(Industry, random_triggers,            SLE_UINT8,                 82, SL_MAX_VERSION),
       
  2319 	SLE_CONDVAR(Industry, random,                     SLE_UINT16,                82, SL_MAX_VERSION),
       
  2320 
  2134 	/* reserve extra space in savegame here. (currently 32 bytes) */
  2321 	/* reserve extra space in savegame here. (currently 32 bytes) */
  2135 	SLE_CONDNULL(32, 2, SL_MAX_VERSION),
  2322 	SLE_CONDNULL(32, 2, SL_MAX_VERSION),
  2136 
  2323 
  2137 	SLE_END()
  2324 	SLE_END()
  2138 };
  2325 };