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 } |