src/industry_cmd.cpp
branchnoai
changeset 9723 eee46cb39750
parent 9722 ebf0ece7d8f6
child 9724 b39bc69bb2f2
equal deleted inserted replaced
9722:ebf0ece7d8f6 9723:eee46cb39750
     3 /** @file industry_cmd.cpp */
     3 /** @file industry_cmd.cpp */
     4 
     4 
     5 #include "stdafx.h"
     5 #include "stdafx.h"
     6 #include "openttd.h"
     6 #include "openttd.h"
     7 #include "clear_map.h"
     7 #include "clear_map.h"
     8 #include "functions.h"
       
     9 #include "industry_map.h"
     8 #include "industry_map.h"
    10 #include "station_map.h"
     9 #include "station_map.h"
    11 #include "table/strings.h"
    10 #include "table/strings.h"
    12 #include "strings.h"
       
    13 #include "table/sprites.h"
    11 #include "table/sprites.h"
    14 #include "map.h"
       
    15 #include "tile.h"
       
    16 #include "train.h"
    12 #include "train.h"
    17 #include "landscape.h"
    13 #include "landscape.h"
    18 #include "viewport.h"
    14 #include "viewport_func.h"
    19 #include "command.h"
    15 #include "command_func.h"
    20 #include "industry.h"
    16 #include "industry.h"
    21 #include "town.h"
    17 #include "town.h"
    22 #include "vehicle.h"
       
    23 #include "news.h"
    18 #include "news.h"
    24 #include "saveload.h"
    19 #include "saveload.h"
    25 #include "economy.h"
       
    26 #include "sound.h"
       
    27 #include "variables.h"
    20 #include "variables.h"
    28 #include "table/industry_land.h"
    21 #include "table/industry_land.h"
    29 #include "table/build_industry.h"
    22 #include "table/build_industry.h"
    30 #include "genworld.h"
    23 #include "genworld.h"
    31 #include "date.h"
       
    32 #include "water_map.h"
    24 #include "water_map.h"
    33 #include "tree_map.h"
    25 #include "tree_map.h"
    34 #include "cargotype.h"
    26 #include "cargotype.h"
    35 #include "newgrf.h"
    27 #include "newgrf.h"
    36 #include "newgrf_commons.h"
    28 #include "newgrf_commons.h"
    38 #include "newgrf_industrytiles.h"
    30 #include "newgrf_industrytiles.h"
    39 #include "newgrf_callbacks.h"
    31 #include "newgrf_callbacks.h"
    40 #include "misc/autoptr.hpp"
    32 #include "misc/autoptr.hpp"
    41 #include "autoslope.h"
    33 #include "autoslope.h"
    42 #include "transparency.h"
    34 #include "transparency.h"
       
    35 #include "water.h"
       
    36 #include "strings_func.h"
       
    37 #include "tile_cmd.h"
       
    38 #include "functions.h"
       
    39 #include "window_func.h"
       
    40 #include "date_func.h"
       
    41 #include "vehicle_func.h"
       
    42 #include "sound_func.h"
    43 
    43 
    44 void ShowIndustryViewWindow(int industry);
    44 void ShowIndustryViewWindow(int industry);
    45 void BuildOilRig(TileIndex tile);
    45 void BuildOilRig(TileIndex tile);
    46 
    46 
    47 static byte _industry_sound_ctr;
    47 static byte _industry_sound_ctr;
   398 		SetDParam(0, indspec->name);
   398 		SetDParam(0, indspec->name);
   399 		return_cmd_error(STR_4800_IN_THE_WAY);
   399 		return_cmd_error(STR_4800_IN_THE_WAY);
   400 	}
   400 	}
   401 
   401 
   402 	if (flags & DC_EXEC) delete i;
   402 	if (flags & DC_EXEC) delete i;
   403 	return CommandCost();
   403 	return CommandCost(EXPENSES_CONSTRUCTION, indspec->GetRemovalCost());
   404 }
   404 }
   405 
   405 
   406 static void TransportIndustryGoods(TileIndex tile)
   406 static void TransportIndustryGoods(TileIndex tile)
   407 {
   407 {
   408 	Industry *i = GetIndustryByTile(tile);
   408 	Industry *i = GetIndustryByTile(tile);
   555 
   555 
   556 	case GFX_OILWELL_ANIMATED_1:
   556 	case GFX_OILWELL_ANIMATED_1:
   557 	case GFX_OILWELL_ANIMATED_2:
   557 	case GFX_OILWELL_ANIMATED_2:
   558 	case GFX_OILWELL_ANIMATED_3:
   558 	case GFX_OILWELL_ANIMATED_3:
   559 		if ((_tick_counter & 7) == 0) {
   559 		if ((_tick_counter & 7) == 0) {
   560 			bool b = CHANCE16(1, 7);
   560 			bool b = Chance16(1, 7);
   561 			IndustryGfx gfx = GetIndustryGfx(tile);
   561 			IndustryGfx gfx = GetIndustryGfx(tile);
   562 
   562 
   563 			m = GetIndustryAnimationState(tile) + 1;
   563 			m = GetIndustryAnimationState(tile) + 1;
   564 			if (m == 4 && (m = 0, ++gfx) == GFX_OILWELL_ANIMATED_3 + 1 && (gfx = GFX_OILWELL_ANIMATED_1, b)) {
   564 			if (m == 4 && (m = 0, ++gfx) == GFX_OILWELL_ANIMATED_3 + 1 && (gfx = GFX_OILWELL_ANIMATED_1, b)) {
   565 				SetIndustryGfx(tile, GFX_OILWELL_NOT_ANIMATED);
   565 				SetIndustryGfx(tile, GFX_OILWELL_NOT_ANIMATED);
   735 		break;
   735 		break;
   736 
   736 
   737 	case GFX_COAL_MINE_TOWER_NOT_ANIMATED:
   737 	case GFX_COAL_MINE_TOWER_NOT_ANIMATED:
   738 	case GFX_COPPER_MINE_TOWER_NOT_ANIMATED:
   738 	case GFX_COPPER_MINE_TOWER_NOT_ANIMATED:
   739 	case GFX_GOLD_MINE_TOWER_NOT_ANIMATED:
   739 	case GFX_GOLD_MINE_TOWER_NOT_ANIMATED:
   740 		if (!(_tick_counter & 0x400) && CHANCE16(1, 2)) {
   740 		if (!(_tick_counter & 0x400) && Chance16(1, 2)) {
   741 			switch (gfx) {
   741 			switch (gfx) {
   742 				case GFX_COAL_MINE_TOWER_NOT_ANIMATED:   gfx = GFX_COAL_MINE_TOWER_ANIMATED;   break;
   742 				case GFX_COAL_MINE_TOWER_NOT_ANIMATED:   gfx = GFX_COAL_MINE_TOWER_ANIMATED;   break;
   743 				case GFX_COPPER_MINE_TOWER_NOT_ANIMATED: gfx = GFX_COPPER_MINE_TOWER_ANIMATED; break;
   743 				case GFX_COPPER_MINE_TOWER_NOT_ANIMATED: gfx = GFX_COPPER_MINE_TOWER_ANIMATED; break;
   744 				case GFX_GOLD_MINE_TOWER_NOT_ANIMATED:   gfx = GFX_GOLD_MINE_TOWER_ANIMATED;   break;
   744 				case GFX_GOLD_MINE_TOWER_NOT_ANIMATED:   gfx = GFX_GOLD_MINE_TOWER_ANIMATED;   break;
   745 			}
   745 			}
   748 			AddAnimatedTile(tile);
   748 			AddAnimatedTile(tile);
   749 		}
   749 		}
   750 		break;
   750 		break;
   751 
   751 
   752 	case GFX_OILWELL_NOT_ANIMATED:
   752 	case GFX_OILWELL_NOT_ANIMATED:
   753 		if (CHANCE16(1, 6)) {
   753 		if (Chance16(1, 6)) {
   754 			SetIndustryGfx(tile, GFX_OILWELL_ANIMATED_1);
   754 			SetIndustryGfx(tile, GFX_OILWELL_ANIMATED_1);
   755 			SetIndustryAnimationState(tile, 0);
   755 			SetIndustryAnimationState(tile, 0);
   756 			AddAnimatedTile(tile);
   756 			AddAnimatedTile(tile);
   757 		}
   757 		}
   758 		break;
   758 		break;
   772 			DeleteAnimatedTile(tile);
   772 			DeleteAnimatedTile(tile);
   773 		}
   773 		}
   774 		break;
   774 		break;
   775 
   775 
   776 	case GFX_POWERPLANT_SPARKS:
   776 	case GFX_POWERPLANT_SPARKS:
   777 		if (CHANCE16(1, 3)) {
   777 		if (Chance16(1, 3)) {
   778 			SndPlayTileFx(SND_0C_ELECTRIC_SPARK, tile);
   778 			SndPlayTileFx(SND_0C_ELECTRIC_SPARK, tile);
   779 			AddAnimatedTile(tile);
   779 			AddAnimatedTile(tile);
   780 		}
   780 		}
   781 		break;
   781 		break;
   782 
   782 
   802 	case GFX_TOFFEE_QUARY:
   802 	case GFX_TOFFEE_QUARY:
   803 		AddAnimatedTile(tile);
   803 		AddAnimatedTile(tile);
   804 		break;
   804 		break;
   805 
   805 
   806 	case GFX_SUGAR_MINE_SIEVE:
   806 	case GFX_SUGAR_MINE_SIEVE:
   807 		if (CHANCE16(1, 3)) AddAnimatedTile(tile);
   807 		if (Chance16(1, 3)) AddAnimatedTile(tile);
   808 		break;
   808 		break;
   809 	}
   809 	}
   810 }
   810 }
   811 
   811 
   812 static void ClickTile_Industry(TileIndex tile)
   812 static void ClickTile_Industry(TileIndex tile)
   860 		tile = TILE_MASK(tile);
   860 		tile = TILE_MASK(tile);
   861 
   861 
   862 		if (IsTileType(tile, MP_CLEAR) || IsTileType(tile, MP_TREES)) {
   862 		if (IsTileType(tile, MP_CLEAR) || IsTileType(tile, MP_TREES)) {
   863 			byte or_ = type;
   863 			byte or_ = type;
   864 
   864 
   865 			if (or_ == 1 && CHANCE16(1, 7)) or_ = 2;
   865 			if (or_ == 1 && Chance16(1, 7)) or_ = 2;
   866 
   866 
   867 			if (direction == AXIS_X) {
   867 			if (direction == AXIS_X) {
   868 				SetFenceSE(tile, or_);
   868 				SetFenceSE(tile, or_);
   869 			} else {
   869 			} else {
   870 				SetFenceSW(tile, or_);
   870 				SetFenceSW(tile, or_);
   987 	uint num;
   987 	uint num;
   988 	const IndustrySpec *indsp = GetIndustrySpec(i->type);
   988 	const IndustrySpec *indsp = GetIndustrySpec(i->type);
   989 
   989 
   990 	/* play a sound? */
   990 	/* play a sound? */
   991 	if ((i->counter & 0x3F) == 0) {
   991 	if ((i->counter & 0x3F) == 0) {
   992 		if (CHANCE16R(1, 14, r) && (num = indsp->number_of_sounds) != 0) {
   992 		if (Chance16R(1, 14, r) && (num = indsp->number_of_sounds) != 0) {
   993 			SndPlayTileFx(
   993 			SndPlayTileFx(
   994 				(SoundFx)(indsp->random_sounds[((r >> 16) * num) >> 16]),
   994 				(SoundFx)(indsp->random_sounds[((r >> 16) * num) >> 16]),
   995 				i->xy);
   995 				i->xy);
   996 		}
   996 		}
   997 	}
   997 	}
  1009 		if ((indbehav & INDUSTRYBEH_PLANT_FIELDS) != 0) {
  1009 		if ((indbehav & INDUSTRYBEH_PLANT_FIELDS) != 0) {
  1010 			bool plant;
  1010 			bool plant;
  1011 			if (HasBit(indsp->callback_flags, CBM_IND_SPECIAL_EFFECT)) {
  1011 			if (HasBit(indsp->callback_flags, CBM_IND_SPECIAL_EFFECT)) {
  1012 				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);
  1013 			} else {
  1013 			} else {
  1014 				plant = CHANCE16(1, 8);
  1014 				plant = Chance16(1, 8);
  1015 			}
  1015 			}
  1016 
  1016 
  1017 			if (plant) PlantRandomFarmField(i);
  1017 			if (plant) PlantRandomFarmField(i);
  1018 		}
  1018 		}
  1019 		if ((indbehav & INDUSTRYBEH_CUT_TREES) != 0) {
  1019 		if ((indbehav & INDUSTRYBEH_CUT_TREES) != 0) {
  1181 
  1181 
  1182 bool IsSlopeRefused(Slope current, Slope refused)
  1182 bool IsSlopeRefused(Slope current, Slope refused)
  1183 {
  1183 {
  1184 	if (IsSteepSlope(current)) return true;
  1184 	if (IsSteepSlope(current)) return true;
  1185 	if (current != SLOPE_FLAT) {
  1185 	if (current != SLOPE_FLAT) {
  1186 		if (refused & SLOPE_STEEP) return true;
  1186 		if (IsSteepSlope(refused)) return true;
  1187 
  1187 
  1188 		Slope t = ComplementSlope(current);
  1188 		Slope t = ComplementSlope(current);
  1189 
  1189 
  1190 		if (refused & 1 && (t & SLOPE_NW)) return false;
  1190 		if (refused & SLOPE_W && (t & SLOPE_NW)) return true;
  1191 		if (refused & 2 && (t & SLOPE_NE)) return false;
  1191 		if (refused & SLOPE_S && (t & SLOPE_NE)) return true;
  1192 		if (refused & 4 && (t & SLOPE_SW)) return false;
  1192 		if (refused & SLOPE_E && (t & SLOPE_SW)) return true;
  1193 		if (refused & 8 && (t & SLOPE_SE)) return false;
  1193 		if (refused & SLOPE_N && (t & SLOPE_SE)) return true;
  1194 	}
  1194 	}
  1195 
  1195 
  1196 	return false;
  1196 	return false;
  1197 }
  1197 }
  1198 
  1198 
  1235 				refused_slope |= IsSlopeRefused(tileh, its->slopes_refused);
  1235 				refused_slope |= IsSlopeRefused(tileh, its->slopes_refused);
  1236 			}
  1236 			}
  1237 
  1237 
  1238 			if (ind_behav & (INDUSTRYBEH_ONLY_INTOWN | INDUSTRYBEH_TOWN1200_MORE)) {
  1238 			if (ind_behav & (INDUSTRYBEH_ONLY_INTOWN | INDUSTRYBEH_TOWN1200_MORE)) {
  1239 				if (!IsTileType(cur_tile, MP_HOUSE)) {
  1239 				if (!IsTileType(cur_tile, MP_HOUSE)) {
  1240 					_error_message = STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS;
  1240 					_error_message = STR_030D_CAN_ONLY_BE_BUILT_IN_TOWNS;
  1241 					return false;
  1241 					return false;
  1242 				}
  1242 				}
  1243 				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;
  1244 			} else if ((ind_behav & INDUSTRYBEH_ONLY_NEARTOWN) == 0 || !IsTileType(cur_tile, MP_HOUSE)) {
  1244 			} else if ((ind_behav & INDUSTRYBEH_ONLY_NEARTOWN) == 0 || !IsTileType(cur_tile, MP_HOUSE)) {
  1245 				if (CmdFailed(DoCommand(cur_tile, 0, 0, DC_AUTO, CMD_LANDSCAPE_CLEAR))) return false;
  1245 				if (CmdFailed(DoCommand(cur_tile, 0, 0, DC_AUTO, CMD_LANDSCAPE_CLEAR))) return false;
  1250 	if (custom_shape_check != NULL) *custom_shape_check = custom_shape;
  1250 	if (custom_shape_check != NULL) *custom_shape_check = custom_shape;
  1251 
  1251 
  1252 	/* It is almost impossible to have a fully flat land in TG, so what we
  1252 	/* It is almost impossible to have a fully flat land in TG, so what we
  1253 	 *  do is that we check if we can make the land flat later on. See
  1253 	 *  do is that we check if we can make the land flat later on. See
  1254 	 *  CheckIfCanLevelIndustryPlatform(). */
  1254 	 *  CheckIfCanLevelIndustryPlatform(). */
  1255 	return !refused_slope || (_patches.land_generator == LG_TERRAGENESIS && _generating_world && !custom_shape);
  1255 	return !refused_slope || (_patches.land_generator == LG_TERRAGENESIS && _generating_world && !custom_shape && !_ignore_restrictions);
  1256 }
  1256 }
  1257 
  1257 
  1258 static bool CheckIfIndustryIsAllowed(TileIndex tile, int type, const Town *t)
  1258 static bool CheckIfIndustryIsAllowed(TileIndex tile, int type, const Town *t)
  1259 {
  1259 {
  1260 	if ((GetIndustrySpec(type)->behaviour & INDUSTRYBEH_TOWN1200_MORE) && t->population < 1200) {
  1260 	if ((GetIndustrySpec(type)->behaviour & INDUSTRYBEH_TOWN1200_MORE) && t->population < 1200) {
  1287 		/* Is the tile clear? */
  1287 		/* Is the tile clear? */
  1288 		if ((GetTileType(tile_walk) != MP_CLEAR) && (GetTileType(tile_walk) != MP_TREES))
  1288 		if ((GetTileType(tile_walk) != MP_CLEAR) && (GetTileType(tile_walk) != MP_TREES))
  1289 			return false;
  1289 			return false;
  1290 
  1290 
  1291 		/* Don't allow too big of a change if this is the sub-tile check */
  1291 		/* Don't allow too big of a change if this is the sub-tile check */
  1292 		if (internal != 0 && delta(curh, height) > 1) return false;
  1292 		if (internal != 0 && Delta(curh, height) > 1) return false;
  1293 
  1293 
  1294 		/* Different height, so the surrounding tiles of this tile
  1294 		/* Different height, so the surrounding tiles of this tile
  1295 		 *  has to be correct too (in level, or almost in level)
  1295 		 *  has to be correct too (in level, or almost in level)
  1296 		 *  else you get a chain-reaction of terraforming. */
  1296 		 *  else you get a chain-reaction of terraforming. */
  1297 		if (internal == 0 && curh != height) {
  1297 		if (internal == 0 && curh != height) {
  1510 			size = it->ti.y;
  1510 			size = it->ti.y;
  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, Random());
  1516 
  1516 
  1517 			if (_generating_world) {
  1517 			if (_generating_world) {
  1518 				SetIndustryConstructionCounter(cur_tile, 3);
  1518 				SetIndustryConstructionCounter(cur_tile, 3);
  1519 				SetIndustryConstructionStage(cur_tile, 2);
  1519 				SetIndustryConstructionStage(cur_tile, 2);
  1520 			}
  1520 			}
  1555 		if (!CheckIfCallBackAllowsCreation(tile, type, itspec_index)) return NULL;
  1555 		if (!CheckIfCallBackAllowsCreation(tile, type, itspec_index)) return NULL;
  1556 	} else {
  1556 	} else {
  1557 		if (!_check_new_industry_procs[indspec->check_proc](tile)) return NULL;
  1557 		if (!_check_new_industry_procs[indspec->check_proc](tile)) return NULL;
  1558 	}
  1558 	}
  1559 
  1559 
  1560 	if (!custom_shape_check && _patches.land_generator == LG_TERRAGENESIS && _generating_world && !CheckIfCanLevelIndustryPlatform(tile, 0, it, type)) return NULL;
  1560 	if (!custom_shape_check && _patches.land_generator == LG_TERRAGENESIS && _generating_world && !_ignore_restrictions && !CheckIfCanLevelIndustryPlatform(tile, 0, it, type)) return NULL;
  1561 	if (!CheckIfTooCloseToIndustry(tile, type)) return NULL;
  1561 	if (!CheckIfTooCloseToIndustry(tile, type)) return NULL;
  1562 
  1562 
  1563 	const Town *t = CheckMultipleIndustryInTown(tile, type);
  1563 	const Town *t = CheckMultipleIndustryInTown(tile, type);
  1564 	if (t == NULL) return NULL;
  1564 	if (t == NULL) return NULL;
  1565 
  1565 
  1588  */
  1588  */
  1589 CommandCost CmdBuildIndustry(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1589 CommandCost CmdBuildIndustry(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1590 {
  1590 {
  1591 	const IndustrySpec *indspec;
  1591 	const IndustrySpec *indspec;
  1592 
  1592 
  1593 	SET_EXPENSES_TYPE(EXPENSES_OTHER);
       
  1594 
       
  1595 	indspec = GetIndustrySpec(p1);
  1593 	indspec = GetIndustrySpec(p1);
  1596 
  1594 
  1597 	/* Check if the to-be built/founded industry is available for this climate. */
  1595 	/* Check if the to-be built/founded industry is available for this climate. */
  1598 	if (!indspec->enabled) {
  1596 	if (!indspec->enabled) {
  1599 		return CMD_ERROR;
  1597 		return CMD_ERROR;
  1610 			/* Prospecting has a chance to fail, however we cannot guarantee that something can
  1608 			/* Prospecting has a chance to fail, however we cannot guarantee that something can
  1611 			 * be built on the map, so the chance gets lower when the map is fuller, but there
  1609 			 * be built on the map, so the chance gets lower when the map is fuller, but there
  1612 			 * is nothing we can really do about that. */
  1610 			 * is nothing we can really do about that. */
  1613 			if (Random() <= indspec->prospecting_chance) {
  1611 			if (Random() <= indspec->prospecting_chance) {
  1614 				for (int i = 0; i < 5000; i++) {
  1612 				for (int i = 0; i < 5000; i++) {
  1615 					const Industry *ind = CreateNewIndustryHelper(RandomTile(), p1, flags, indspec, RandomRange(indspec->num_table));
  1613 					/* We should not have more than one Random() in a function call
       
  1614 					 * because parameter evaluation order is not guaranteed in the c++ standard
       
  1615 					 */
       
  1616 					tile = RandomTile();
       
  1617 					const Industry *ind = CreateNewIndustryHelper(tile, p1, flags, indspec, RandomRange(indspec->num_table));
  1616 					if (ind != NULL) {
  1618 					if (ind != NULL) {
  1617 						SetDParam(0, indspec->name);
  1619 						SetDParam(0, indspec->name);
  1618 						if (indspec->new_industry_text > STR_LAST_STRINGID) {
  1620 						if (indspec->new_industry_text > STR_LAST_STRINGID) {
  1619 							SetDParam(1, STR_TOWN);
  1621 							SetDParam(1, STR_TOWN);
  1620 							SetDParam(2, ind->town->index);
  1622 							SetDParam(2, ind->town->index);
  1640 		} while (!CheckIfIndustryTilesAreFree(tile, itt[num], num, p1));
  1642 		} while (!CheckIfIndustryTilesAreFree(tile, itt[num], num, p1));
  1641 
  1643 
  1642 		if (CreateNewIndustryHelper(tile, p1, flags, indspec, num) == NULL) return CMD_ERROR;
  1644 		if (CreateNewIndustryHelper(tile, p1, flags, indspec, num) == NULL) return CMD_ERROR;
  1643 	}
  1645 	}
  1644 
  1646 
  1645 	return CommandCost(indspec->GetConstructionCost());
  1647 	return CommandCost(EXPENSES_OTHER, indspec->GetConstructionCost());
  1646 }
  1648 }
  1647 
  1649 
  1648 
  1650 
  1649 Industry *CreateNewIndustry(TileIndex tile, IndustryType type)
  1651 Industry *CreateNewIndustry(TileIndex tile, IndustryType type)
  1650 {
  1652 {
  1988 	);
  1990 	);
  1989 }
  1991 }
  1990 
  1992 
  1991 enum {
  1993 enum {
  1992 	PERCENT_TRANSPORTED_60 = 153,
  1994 	PERCENT_TRANSPORTED_60 = 153,
       
  1995 	PERCENT_TRANSPORTED_80 = 204,
  1993 };
  1996 };
  1994 
  1997 
  1995 /** Change industry production or do closure
  1998 /** Change industry production or do closure
  1996  * @param i Industry for which changes are performed
  1999  * @param i Industry for which changes are performed
  1997  * @param monthly true if it's the monthly call, false if it's the random call
  2000  * @param monthly true if it's the monthly call, false if it's the random call
  2008 	bool smooth_economy = _patches.smooth_economy &&
  2011 	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
  2012 	                      !(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
  2013 	                      !(HasBit(indspec->callback_flags, CBM_IND_MONTHLYPROD_CHANGE) || HasBit(indspec->callback_flags, CBM_IND_PRODUCTION_CHANGE));            // production change callbacks
  2011 	byte div = 0;
  2014 	byte div = 0;
  2012 	byte mul = 0;
  2015 	byte mul = 0;
       
  2016 	int8 increment = 0;
  2013 
  2017 
  2014 	if (HasBit(indspec->callback_flags, monthly ? CBM_IND_MONTHLYPROD_CHANGE : CBM_IND_PRODUCTION_CHANGE)) {
  2018 	if (HasBit(indspec->callback_flags, monthly ? CBM_IND_MONTHLYPROD_CHANGE : CBM_IND_PRODUCTION_CHANGE)) {
  2015 		uint16 res = GetIndustryCallback(monthly ? CBID_INDUSTRY_MONTHLYPROD_CHANGE : CBID_INDUSTRY_PRODUCTION_CHANGE, 0, Random(), i, i->type, i->xy);
  2019 		uint16 res = GetIndustryCallback(monthly ? CBID_INDUSTRY_MONTHLYPROD_CHANGE : CBID_INDUSTRY_PRODUCTION_CHANGE, 0, Random(), i, i->type, i->xy);
  2016 		standard = false;
  2020 		standard = false;
  2017 		monthly = false; // smooth economy is disabled so we need to fake random industry production change to allow 'use standard' result
  2021 		monthly = false; // smooth economy is disabled so we need to fake random industry production change to allow 'use standard' result
  2029 				case 0x4: standard = true; break; // Do the standard random production change as if this industry was a primary one.
  2033 				case 0x4: standard = true; break; // Do the standard random production change as if this industry was a primary one.
  2030 				case 0x5: case 0x6: case 0x7:     // Divide production by 4, 8, 16
  2034 				case 0x5: case 0x6: case 0x7:     // Divide production by 4, 8, 16
  2031 				case 0x8: div = res - 0x3; break; // Divide production by 32
  2035 				case 0x8: div = res - 0x3; break; // Divide production by 32
  2032 				case 0x9: case 0xA: case 0xB:     // Multiply production by 4, 8, 16
  2036 				case 0x9: case 0xA: case 0xB:     // Multiply production by 4, 8, 16
  2033 				case 0xC: mul = res - 0x7; break; // Multiply production by 32
  2037 				case 0xC: mul = res - 0x7; break; // Multiply production by 32
       
  2038 				case 0xD:                         // decrement production
       
  2039 				case 0xE:                         // increment production
       
  2040 					increment = res == 0x0D ? -1 : 1;
       
  2041 					break;
  2034 			}
  2042 			}
  2035 		}
  2043 		}
  2036 	}
  2044 	}
  2037 
  2045 
  2038 	if (standard && monthly != smooth_economy) return;
  2046 	if (standard && monthly != smooth_economy) return;
  2044 		bool only_decrease = (indspec->behaviour & INDUSTRYBEH_DONT_INCR_PROD) && _opt.landscape == LT_TEMPERATE;
  2052 		bool only_decrease = (indspec->behaviour & INDUSTRYBEH_DONT_INCR_PROD) && _opt.landscape == LT_TEMPERATE;
  2045 
  2053 
  2046 		if (smooth_economy) {
  2054 		if (smooth_economy) {
  2047 			closeit = true;
  2055 			closeit = true;
  2048 			for (byte j = 0; j < 2 && i->produced_cargo[j] != CT_INVALID; j++){
  2056 			for (byte j = 0; j < 2 && i->produced_cargo[j] != CT_INVALID; j++){
       
  2057 				uint32 r = Random();
  2049 				int old_prod, new_prod, percent;
  2058 				int old_prod, new_prod, percent;
       
  2059 				/* If over 60% is transported, mult is 1, else mult is -1. */
  2050 				int mult = (i->last_month_pct_transported[j] > PERCENT_TRANSPORTED_60) ? 1 : -1;
  2060 				int mult = (i->last_month_pct_transported[j] > PERCENT_TRANSPORTED_60) ? 1 : -1;
  2051 
  2061 
  2052 				new_prod = old_prod = i->production_rate[j];
  2062 				new_prod = old_prod = i->production_rate[j];
  2053 
  2063 
  2054 				if (only_decrease || CHANCE16(1, 3)) mult *= -1;
  2064 				/* For industries with only_decrease flags (temperate terrain Oil Wells),
  2055 
  2065 				 * the multiplier will always be -1 so they will only decrease. */
  2056 				if (CHANCE16(1, 22)) {
  2066 				if (only_decrease) {
       
  2067 					mult = -1;
       
  2068 				/* For normal industries, if over 60% is transported, 33% chance for decrease.
       
  2069 				 * Bonus for very high station ratings (over 80%): 16% chance for decrease. */
       
  2070 				} else if (Chance16I(1, ((i->last_month_pct_transported[j] > PERCENT_TRANSPORTED_80) ? 6 : 3), r)) {
       
  2071 					mult *= -1;
       
  2072 				}
       
  2073 
       
  2074 				/* 4.5% chance for 3-23% (or 1 unit for very low productions) production change,
       
  2075 				 * determined by mult value. If mult = 1 prod. increases, else (-1) it decreases. */
       
  2076 				if (Chance16I(1, 22, r >> 16)) {
  2057 					new_prod += mult * (max(((RandomRange(50) + 10) * old_prod) >> 8, 1U));
  2077 					new_prod += mult * (max(((RandomRange(50) + 10) * old_prod) >> 8, 1U));
  2058 				}
  2078 				}
  2059 
  2079 
  2060 				/* Prevent production to overflow or Oil Rig passengers to be over-"produced" */
  2080 				/* Prevent production to overflow or Oil Rig passengers to be over-"produced" */
  2061 				new_prod = Clamp(new_prod, 1, 255);
  2081 				new_prod = Clamp(new_prod, 1, 255);
  2078 				if (abs(percent) >= 10) {
  2098 				if (abs(percent) >= 10) {
  2079 					ReportNewsProductionChangeIndustry(i, i->produced_cargo[j], percent);
  2099 					ReportNewsProductionChangeIndustry(i, i->produced_cargo[j], percent);
  2080 				}
  2100 				}
  2081 			}
  2101 			}
  2082 		} else {
  2102 		} else {
  2083 			if (only_decrease || CHANCE16(1, 3)) {
  2103 			if (only_decrease || Chance16(1, 3)) {
  2084 				/* If you transport > 60%, 66% chance we increase, else 33% chance we increase */
  2104 				/* If more than 60% transported, 66% chance of increase, else 33% chance of increase */
  2085 				if (!only_decrease && (i->last_month_pct_transported[0] > PERCENT_TRANSPORTED_60) != CHANCE16(1, 3)) {
  2105 				if (!only_decrease && (i->last_month_pct_transported[0] > PERCENT_TRANSPORTED_60) != Chance16(1, 3)) {
  2086 					mul = 1; // Increase production
  2106 					mul = 1; // Increase production
  2087 				} else {
  2107 				} else {
  2088 					div = 1; // Decrease production
  2108 					div = 1; // Decrease production
  2089 				}
  2109 				}
  2090 			}
  2110 			}
  2091 		}
  2111 		}
  2092 	}
  2112 	}
  2093 
  2113 
  2094 	if (standard && indspec->life_type & INDUSTRYLIFE_PROCESSING) {
  2114 	if (standard && indspec->life_type & INDUSTRYLIFE_PROCESSING) {
  2095 		if ( (byte)(_cur_year - i->last_prod_year) >= 5 && CHANCE16(1, smooth_economy ? 180 : 2)) {
  2115 		if ( (byte)(_cur_year - i->last_prod_year) >= 5 && Chance16(1, smooth_economy ? 180 : 2)) {
  2096 			closeit = true;
  2116 			closeit = true;
  2097 		}
  2117 		}
  2098 	}
  2118 	}
  2099 
  2119 
  2100 	/* Increase if needed */
  2120 	/* Increase if needed */
  2113 			i->prod_level >>= 1;
  2133 			i->prod_level >>= 1;
  2114 			i->production_rate[0] = (i->production_rate[0] + 1) >> 1;
  2134 			i->production_rate[0] = (i->production_rate[0] + 1) >> 1;
  2115 			i->production_rate[1] = (i->production_rate[1] + 1) >> 1;
  2135 			i->production_rate[1] = (i->production_rate[1] + 1) >> 1;
  2116 			if (str == STR_NULL) str = indspec->production_down_text;
  2136 			if (str == STR_NULL) str = indspec->production_down_text;
  2117 		}
  2137 		}
       
  2138 	}
       
  2139 
       
  2140 	if (increment != 0) {
       
  2141 		i->prod_level = ClampU(i->prod_level + increment, 4, 0x80);
       
  2142 		if (i->prod_level == 4) closeit = true;
  2118 	}
  2143 	}
  2119 
  2144 
  2120 	/* Close if needed and allowed */
  2145 	/* Close if needed and allowed */
  2121 	if (closeit && !CheckIndustryCloseDownProtection(i->type)) {
  2146 	if (closeit && !CheckIndustryCloseDownProtection(i->type)) {
  2122 		i->prod_level = 0;
  2147 		i->prod_level = 0;
  2169 			ChangeIndustryProduction(i, true);
  2194 			ChangeIndustryProduction(i, true);
  2170 		}
  2195 		}
  2171 	}
  2196 	}
  2172 
  2197 
  2173 	/* 3% chance that we start a new industry */
  2198 	/* 3% chance that we start a new industry */
  2174 	if (CHANCE16(3, 100)) {
  2199 	if (Chance16(3, 100)) {
  2175 		MaybeNewIndustry();
  2200 		MaybeNewIndustry();
  2176 	} else {
  2201 	} else {
  2177 		i = GetRandomIndustry();
  2202 		i = GetRandomIndustry();
  2178 		if (i != NULL) ChangeIndustryProduction(i, false);
  2203 		if (i != NULL) ChangeIndustryProduction(i, false);
  2179 	}
  2204 	}
  2208 	return (_price.build_industry *
  2233 	return (_price.build_industry *
  2209 			(_patches.raw_industry_construction == 1 && this->IsRawIndustry() ?
  2234 			(_patches.raw_industry_construction == 1 && this->IsRawIndustry() ?
  2210 					this->raw_industry_cost_multiplier :
  2235 					this->raw_industry_cost_multiplier :
  2211 					this->cost_multiplier
  2236 					this->cost_multiplier
  2212 			)) >> 8;
  2237 			)) >> 8;
       
  2238 }
       
  2239 
       
  2240 Money IndustrySpec::GetRemovalCost() const
       
  2241 {
       
  2242 	return (_price.remove_house * this->removal_cost_multiplier) >> 8;
  2213 }
  2243 }
  2214 
  2244 
  2215 static CommandCost TerraformTile_Industry(TileIndex tile, uint32 flags, uint z_new, Slope tileh_new)
  2245 static CommandCost TerraformTile_Industry(TileIndex tile, uint32 flags, uint z_new, Slope tileh_new)
  2216 {
  2246 {
  2217 	if (AutoslopeEnabled()) {
  2247 	if (AutoslopeEnabled()) {
  2229 
  2259 
  2230 			/* Call callback 3C 'disable autosloping for industry tiles'. */
  2260 			/* Call callback 3C 'disable autosloping for industry tiles'. */
  2231 			if (HasBit(itspec->callback_flags, CBM_INDT_AUTOSLOPE)) {
  2261 			if (HasBit(itspec->callback_flags, CBM_INDT_AUTOSLOPE)) {
  2232 				/* If the callback fails, allow autoslope. */
  2262 				/* If the callback fails, allow autoslope. */
  2233 				uint16 res = GetIndustryTileCallback(CBID_INDUSTRY_AUTOSLOPE, 0, 0, gfx, GetIndustryByTile(tile), tile);
  2263 				uint16 res = GetIndustryTileCallback(CBID_INDUSTRY_AUTOSLOPE, 0, 0, gfx, GetIndustryByTile(tile), tile);
  2234 				if ((res == 0) || (res == CALLBACK_FAILED)) return _price.terraform;
  2264 				if ((res == 0) || (res == CALLBACK_FAILED)) return CommandCost(EXPENSES_CONSTRUCTION, _price.terraform);
  2235 			} else {
  2265 			} else {
  2236 				/* allow autoslope */
  2266 				/* allow autoslope */
  2237 				return _price.terraform;
  2267 				return CommandCost(EXPENSES_CONSTRUCTION, _price.terraform);
  2238 			}
  2268 			}
  2239 		}
  2269 		}
  2240 	}
  2270 	}
  2241 	return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
  2271 	return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
  2242 }
  2272 }