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 "industry_map.h" |
8 #include "industry_map.h" |
9 #include "station_map.h" |
9 #include "station_map.h" |
10 #include "table/strings.h" |
|
11 #include "table/sprites.h" |
|
12 #include "train.h" |
10 #include "train.h" |
13 #include "landscape.h" |
11 #include "landscape.h" |
14 #include "viewport_func.h" |
12 #include "viewport_func.h" |
15 #include "command_func.h" |
13 #include "command_func.h" |
16 #include "industry.h" |
14 #include "industry.h" |
17 #include "town.h" |
15 #include "town.h" |
18 #include "news.h" |
16 #include "news.h" |
19 #include "saveload.h" |
17 #include "saveload.h" |
20 #include "variables.h" |
18 #include "variables.h" |
21 #include "table/industry_land.h" |
|
22 #include "table/build_industry.h" |
|
23 #include "genworld.h" |
19 #include "genworld.h" |
24 #include "water_map.h" |
20 #include "water_map.h" |
25 #include "tree_map.h" |
21 #include "tree_map.h" |
26 #include "cargotype.h" |
22 #include "cargotype.h" |
27 #include "newgrf.h" |
23 #include "newgrf.h" |
38 #include "functions.h" |
34 #include "functions.h" |
39 #include "window_func.h" |
35 #include "window_func.h" |
40 #include "date_func.h" |
36 #include "date_func.h" |
41 #include "vehicle_func.h" |
37 #include "vehicle_func.h" |
42 #include "sound_func.h" |
38 #include "sound_func.h" |
|
39 |
|
40 #include "table/strings.h" |
|
41 #include "table/sprites.h" |
|
42 #include "table/industry_land.h" |
|
43 #include "table/build_industry.h" |
43 |
44 |
44 void ShowIndustryViewWindow(int industry); |
45 void ShowIndustryViewWindow(int industry); |
45 void BuildOilRig(TileIndex tile); |
46 void BuildOilRig(TileIndex tile); |
46 |
47 |
47 static byte _industry_sound_ctr; |
48 static byte _industry_sound_ctr; |
838 |
839 |
839 static bool IsBadFarmFieldTile(TileIndex tile) |
840 static bool IsBadFarmFieldTile(TileIndex tile) |
840 { |
841 { |
841 switch (GetTileType(tile)) { |
842 switch (GetTileType(tile)) { |
842 case MP_CLEAR: return IsClearGround(tile, CLEAR_FIELDS) || IsClearGround(tile, CLEAR_SNOW) || IsClearGround(tile, CLEAR_DESERT); |
843 case MP_CLEAR: return IsClearGround(tile, CLEAR_FIELDS) || IsClearGround(tile, CLEAR_SNOW) || IsClearGround(tile, CLEAR_DESERT); |
843 case MP_TREES: return false; |
844 case MP_TREES: return (GetTreeGround(tile) == TREE_GROUND_SHORE); |
844 default: return true; |
845 default: return true; |
845 } |
846 } |
846 } |
847 } |
847 |
848 |
848 static bool IsBadFarmFieldTile2(TileIndex tile) |
849 static bool IsBadFarmFieldTile2(TileIndex tile) |
849 { |
850 { |
850 switch (GetTileType(tile)) { |
851 switch (GetTileType(tile)) { |
851 case MP_CLEAR: return IsClearGround(tile, CLEAR_SNOW) || IsClearGround(tile, CLEAR_DESERT); |
852 case MP_CLEAR: return IsClearGround(tile, CLEAR_SNOW) || IsClearGround(tile, CLEAR_DESERT); |
852 case MP_TREES: return false; |
853 case MP_TREES: return (GetTreeGround(tile) == TREE_GROUND_SHORE); |
853 default: return true; |
854 default: return true; |
854 } |
855 } |
855 } |
856 } |
856 |
857 |
857 static void SetupFarmFieldFence(TileIndex tile, int size, byte type, Axis direction) |
858 static void SetupFarmFieldFence(TileIndex tile, int size, byte type, Axis direction) |
1375 _current_player = old_player; |
1376 _current_player = old_player; |
1376 return true; |
1377 return true; |
1377 } |
1378 } |
1378 |
1379 |
1379 |
1380 |
1380 static bool CheckIfTooCloseToIndustry(TileIndex tile, int type) |
1381 static bool CheckIfFarEnoughFromIndustry(TileIndex tile, int type) |
1381 { |
1382 { |
1382 const IndustrySpec *indspec = GetIndustrySpec(type); |
1383 const IndustrySpec *indspec = GetIndustrySpec(type); |
1383 const Industry *i; |
1384 const Industry *i; |
1384 |
1385 |
1385 /* accepting industries won't be close, not even with patch */ |
|
1386 if (_patches.same_industry_close && indspec->accepts_cargo[0] == CT_INVALID) |
1386 if (_patches.same_industry_close && indspec->accepts_cargo[0] == CT_INVALID) |
|
1387 /* Allow primary industries to be placed close to any other industry */ |
1387 return true; |
1388 return true; |
1388 |
1389 |
1389 FOR_ALL_INDUSTRIES(i) { |
1390 FOR_ALL_INDUSTRIES(i) { |
|
1391 /* Within 14 tiles from another industry is considered close */ |
|
1392 bool in_low_distance = DistanceMax(tile, i->xy) <= 14; |
|
1393 |
1390 /* check if an industry that accepts the same goods is nearby */ |
1394 /* check if an industry that accepts the same goods is nearby */ |
1391 if (DistanceMax(tile, i->xy) <= 14 && |
1395 if (in_low_distance && |
1392 indspec->accepts_cargo[0] != CT_INVALID && |
1396 indspec->accepts_cargo[0] != CT_INVALID && // not a primary industry? |
1393 indspec->accepts_cargo[0] == i->accepts_cargo[0] && ( |
1397 indspec->accepts_cargo[0] == i->accepts_cargo[0] && ( |
1394 _game_mode != GM_EDITOR || |
1398 /* at least one of those options must be true */ |
1395 !_patches.same_industry_close || |
1399 _game_mode != GM_EDITOR || // editor must not be stopped |
1396 !_patches.multiple_industry_per_town |
1400 !_patches.same_industry_close || |
1397 )) { |
1401 !_patches.multiple_industry_per_town)) { |
1398 _error_message = STR_INDUSTRY_TOO_CLOSE; |
1402 _error_message = STR_INDUSTRY_TOO_CLOSE; |
1399 return false; |
1403 return false; |
1400 } |
1404 } |
1401 |
1405 |
1402 /* check "not close to" field. */ |
1406 /* check if there are any conflicting industry types around */ |
1403 if ((i->type == indspec->conflicting[0] || i->type == indspec->conflicting[1] || i->type == indspec->conflicting[2]) && |
1407 if ((i->type == indspec->conflicting[0] || |
1404 DistanceMax(tile, i->xy) <= 14) { |
1408 i->type == indspec->conflicting[1] || |
|
1409 i->type == indspec->conflicting[2]) && |
|
1410 in_low_distance) { |
1405 _error_message = STR_INDUSTRY_TOO_CLOSE; |
1411 _error_message = STR_INDUSTRY_TOO_CLOSE; |
1406 return false; |
1412 return false; |
1407 } |
1413 } |
1408 } |
1414 } |
1409 return true; |
1415 return true; |
1540 * @param tile tile where industry is built |
1546 * @param tile tile where industry is built |
1541 * @param type of industry to build |
1547 * @param type of industry to build |
1542 * @param flags of operations to conduct |
1548 * @param flags of operations to conduct |
1543 * @param indspec pointer to industry specifications |
1549 * @param indspec pointer to industry specifications |
1544 * @param itspec_index the index of the itsepc to build/fund |
1550 * @param itspec_index the index of the itsepc to build/fund |
|
1551 * @param seed random seed (possibly) used by industries |
1545 * @return the pointer of the newly created industry, or NULL if it failed |
1552 * @return the pointer of the newly created industry, or NULL if it failed |
1546 */ |
1553 */ |
1547 static Industry *CreateNewIndustryHelper(TileIndex tile, IndustryType type, uint32 flags, const IndustrySpec *indspec, uint itspec_index) |
1554 static Industry *CreateNewIndustryHelper(TileIndex tile, IndustryType type, uint32 flags, const IndustrySpec *indspec, uint itspec_index, uint32 seed) |
1548 { |
1555 { |
1549 const IndustryTileTable *it = indspec->table[itspec_index]; |
1556 const IndustryTileTable *it = indspec->table[itspec_index]; |
1550 bool custom_shape_check = false; |
1557 bool custom_shape_check = false; |
1551 |
1558 |
1552 if (!CheckIfIndustryTilesAreFree(tile, it, itspec_index, type, &custom_shape_check)) return NULL; |
1559 if (!CheckIfIndustryTilesAreFree(tile, it, itspec_index, type, &custom_shape_check)) return NULL; |
1553 |
1560 |
1554 if (HasBit(GetIndustrySpec(type)->callback_flags, CBM_IND_LOCATION)) { |
1561 if (HasBit(GetIndustrySpec(type)->callback_flags, CBM_IND_LOCATION)) { |
1555 if (!CheckIfCallBackAllowsCreation(tile, type, itspec_index)) return NULL; |
1562 if (!CheckIfCallBackAllowsCreation(tile, type, itspec_index, seed)) return NULL; |
1556 } else { |
1563 } else { |
1557 if (!_check_new_industry_procs[indspec->check_proc](tile)) return NULL; |
1564 if (!_check_new_industry_procs[indspec->check_proc](tile)) return NULL; |
1558 } |
1565 } |
1559 |
1566 |
1560 if (!custom_shape_check && _patches.land_generator == LG_TERRAGENESIS && _generating_world && !_ignore_restrictions && !CheckIfCanLevelIndustryPlatform(tile, 0, it, type)) return NULL; |
1567 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; |
1568 if (!CheckIfFarEnoughFromIndustry(tile, type)) return NULL; |
1562 |
1569 |
1563 const Town *t = CheckMultipleIndustryInTown(tile, type); |
1570 const Town *t = CheckMultipleIndustryInTown(tile, type); |
1564 if (t == NULL) return NULL; |
1571 if (t == NULL) return NULL; |
1565 |
1572 |
1566 if (!CheckIfIndustryIsAllowed(tile, type, t)) return NULL; |
1573 if (!CheckIfIndustryIsAllowed(tile, type, t)) return NULL; |
1580 } |
1587 } |
1581 |
1588 |
1582 /** Build/Fund an industry |
1589 /** Build/Fund an industry |
1583 * @param tile tile where industry is built |
1590 * @param tile tile where industry is built |
1584 * @param flags of operations to conduct |
1591 * @param flags of operations to conduct |
1585 * @param p1 industry type see build_industry.h and see industry.h |
1592 * @param p1 various bitstuffed elements |
1586 * @param p2 first layout to try |
1593 * - p1 = (bit 0 - 15) - industry type see build_industry.h and see industry.h |
|
1594 * - p1 = (bit 16 - 31) - first layout to try |
|
1595 * @param p2 seed to use for variable 8F |
1587 * @return index of the newly create industry, or CMD_ERROR if it failed |
1596 * @return index of the newly create industry, or CMD_ERROR if it failed |
1588 */ |
1597 */ |
1589 CommandCost CmdBuildIndustry(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
1598 CommandCost CmdBuildIndustry(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
1590 { |
1599 { |
1591 const IndustrySpec *indspec; |
1600 const IndustrySpec *indspec = GetIndustrySpec(GB(p1, 0, 16)); |
1592 |
|
1593 indspec = GetIndustrySpec(p1); |
|
1594 |
1601 |
1595 /* Check if the to-be built/founded industry is available for this climate. */ |
1602 /* Check if the to-be built/founded industry is available for this climate. */ |
1596 if (!indspec->enabled) { |
1603 if (!indspec->enabled) { |
1597 return CMD_ERROR; |
1604 return CMD_ERROR; |
1598 } |
1605 } |
1612 for (int i = 0; i < 5000; i++) { |
1619 for (int i = 0; i < 5000; i++) { |
1613 /* We should not have more than one Random() in a function call |
1620 /* We should not have more than one Random() in a function call |
1614 * because parameter evaluation order is not guaranteed in the c++ standard |
1621 * because parameter evaluation order is not guaranteed in the c++ standard |
1615 */ |
1622 */ |
1616 tile = RandomTile(); |
1623 tile = RandomTile(); |
1617 const Industry *ind = CreateNewIndustryHelper(tile, p1, flags, indspec, RandomRange(indspec->num_table)); |
1624 const Industry *ind = CreateNewIndustryHelper(tile, p1, flags, indspec, RandomRange(indspec->num_table), p2); |
1618 if (ind != NULL) { |
1625 if (ind != NULL) { |
1619 SetDParam(0, indspec->name); |
1626 SetDParam(0, indspec->name); |
1620 if (indspec->new_industry_text > STR_LAST_STRINGID) { |
1627 if (indspec->new_industry_text > STR_LAST_STRINGID) { |
1621 SetDParam(1, STR_TOWN); |
1628 SetDParam(1, STR_TOWN); |
1622 SetDParam(2, ind->town->index); |
1629 SetDParam(2, ind->town->index); |
1631 } |
1638 } |
1632 } |
1639 } |
1633 } else { |
1640 } else { |
1634 int count = indspec->num_table; |
1641 int count = indspec->num_table; |
1635 const IndustryTileTable * const *itt = indspec->table; |
1642 const IndustryTileTable * const *itt = indspec->table; |
1636 int num = Clamp(p2, 0, count - 1); |
1643 int num = Clamp(GB(p1, 16, 16), 0, count - 1); |
1637 |
1644 |
1638 _error_message = STR_0239_SITE_UNSUITABLE; |
1645 _error_message = STR_0239_SITE_UNSUITABLE; |
1639 do { |
1646 do { |
1640 if (--count < 0) return CMD_ERROR; |
1647 if (--count < 0) return CMD_ERROR; |
1641 if (--num < 0) num = indspec->num_table - 1; |
1648 if (--num < 0) num = indspec->num_table - 1; |
1642 } while (!CheckIfIndustryTilesAreFree(tile, itt[num], num, p1)); |
1649 } while (!CheckIfIndustryTilesAreFree(tile, itt[num], num, p1)); |
1643 |
1650 |
1644 if (CreateNewIndustryHelper(tile, p1, flags, indspec, num) == NULL) return CMD_ERROR; |
1651 if (CreateNewIndustryHelper(tile, p1, flags, indspec, num, p2) == NULL) return CMD_ERROR; |
1645 } |
1652 } |
1646 |
1653 |
1647 return CommandCost(EXPENSES_OTHER, indspec->GetConstructionCost()); |
1654 return CommandCost(EXPENSES_OTHER, indspec->GetConstructionCost()); |
1648 } |
1655 } |
1649 |
1656 |
1650 |
1657 |
1651 Industry *CreateNewIndustry(TileIndex tile, IndustryType type) |
1658 Industry *CreateNewIndustry(TileIndex tile, IndustryType type) |
1652 { |
1659 { |
1653 const IndustrySpec *indspec = GetIndustrySpec(type); |
1660 const IndustrySpec *indspec = GetIndustrySpec(type); |
1654 |
1661 |
1655 return CreateNewIndustryHelper(tile, type, DC_EXEC, indspec, RandomRange(indspec->num_table)); |
1662 uint32 seed = Random(); |
|
1663 return CreateNewIndustryHelper(tile, type, DC_EXEC, indspec, RandomRange(indspec->num_table), seed); |
1656 } |
1664 } |
1657 |
1665 |
1658 enum { |
1666 enum { |
1659 NB_NUMOFINDUSTRY = 11, |
1667 NB_NUMOFINDUSTRY = 11, |
1660 NB_DIFFICULTY_LEVEL = 5, |
1668 NB_DIFFICULTY_LEVEL = 5, |
1943 * We cannot check the first of shared orders only, since the first vehicle in such a chain |
1951 * We cannot check the first of shared orders only, since the first vehicle in such a chain |
1944 * may have a different cargo type. |
1952 * may have a different cargo type. |
1945 */ |
1953 */ |
1946 const Order *o; |
1954 const Order *o; |
1947 FOR_VEHICLE_ORDERS(v, o) { |
1955 FOR_VEHICLE_ORDERS(v, o) { |
1948 if (o->type == OT_GOTO_STATION && !HasBit(o->flags, OFB_TRANSFER)) { |
1956 if (o->type == OT_GOTO_STATION && !HasBit(o->flags, OF_TRANSFER)) { |
1949 /* Vehicle visits a station to load or unload */ |
1957 /* Vehicle visits a station to load or unload */ |
1950 Station *st = GetStation(o->dest); |
1958 Station *st = GetStation(o->dest); |
1951 if (!st->IsValid()) continue; |
1959 if (!st->IsValid()) continue; |
1952 |
1960 |
1953 /* Same cargo produced by industry is dropped here => not serviced by vehicle v */ |
1961 /* Same cargo produced by industry is dropped here => not serviced by vehicle v */ |
1954 if (HasBit(o->flags, OFB_UNLOAD) && !c_accepts) break; |
1962 if (HasBit(o->flags, OF_UNLOAD) && !c_accepts) break; |
1955 |
1963 |
1956 if (stations.find(st) != stations.end()) { |
1964 if (stations.find(st) != stations.end()) { |
1957 if (v->owner == _local_player) return 2; // Player services industry |
1965 if (v->owner == _local_player) return 2; // Player services industry |
1958 result = 1; // Competitor services industry |
1966 result = 1; // Competitor services industry |
1959 } |
1967 } |
2292 SLE_CONDVAR(Industry, xy, SLE_FILE_U16 | SLE_VAR_U32, 0, 5), |
2304 SLE_CONDVAR(Industry, xy, SLE_FILE_U16 | SLE_VAR_U32, 0, 5), |
2293 SLE_CONDVAR(Industry, xy, SLE_UINT32, 6, SL_MAX_VERSION), |
2305 SLE_CONDVAR(Industry, xy, SLE_UINT32, 6, SL_MAX_VERSION), |
2294 SLE_VAR(Industry, width, SLE_UINT8), |
2306 SLE_VAR(Industry, width, SLE_UINT8), |
2295 SLE_VAR(Industry, height, SLE_UINT8), |
2307 SLE_VAR(Industry, height, SLE_UINT8), |
2296 SLE_REF(Industry, town, REF_TOWN), |
2308 SLE_REF(Industry, town, REF_TOWN), |
2297 SLE_CONDNULL( 2, 2, 60), ///< used to be industry's produced_cargo |
2309 SLE_CONDNULL( 2, 0, 60), ///< used to be industry's produced_cargo |
2298 SLE_CONDARR(Industry, produced_cargo, SLE_UINT8, 2, 78, SL_MAX_VERSION), |
2310 SLE_CONDARR(Industry, produced_cargo, SLE_UINT8, 2, 78, SL_MAX_VERSION), |
2299 SLE_CONDARR(Industry, incoming_cargo_waiting, SLE_UINT16, 3, 70, SL_MAX_VERSION), |
2311 SLE_CONDARR(Industry, incoming_cargo_waiting, SLE_UINT16, 3, 70, SL_MAX_VERSION), |
2300 SLE_ARR(Industry, produced_cargo_waiting, SLE_UINT16, 2), |
2312 SLE_ARR(Industry, produced_cargo_waiting, SLE_UINT16, 2), |
2301 SLE_ARR(Industry, production_rate, SLE_UINT8, 2), |
2313 SLE_ARR(Industry, production_rate, SLE_UINT8, 2), |
2302 SLE_CONDNULL( 3, 2, 60), ///< used to be industry's accepts_cargo |
2314 SLE_CONDNULL( 3, 0, 60), ///< used to be industry's accepts_cargo |
2303 SLE_CONDARR(Industry, accepts_cargo, SLE_UINT8, 3, 78, SL_MAX_VERSION), |
2315 SLE_CONDARR(Industry, accepts_cargo, SLE_UINT8, 3, 78, SL_MAX_VERSION), |
2304 SLE_VAR(Industry, prod_level, SLE_UINT8), |
2316 SLE_VAR(Industry, prod_level, SLE_UINT8), |
2305 SLE_ARR(Industry, this_month_production, SLE_UINT16, 2), |
2317 SLE_ARR(Industry, this_month_production, SLE_UINT16, 2), |
2306 SLE_ARR(Industry, this_month_transported, SLE_UINT16, 2), |
2318 SLE_ARR(Industry, this_month_transported, SLE_UINT16, 2), |
2307 SLE_ARR(Industry, last_month_pct_transported, SLE_UINT8, 2), |
2319 SLE_ARR(Industry, last_month_pct_transported, SLE_UINT8, 2), |