summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPeterN <peter@fuzzle.org>2019-03-08 18:30:44 +0000
committerGitHub <noreply@github.com>2019-03-08 18:30:44 +0000
commitdd20ccee88a55ed08abb2a47b88cafc7c92a5e81 (patch)
tree98b6230bacf879cab4abd26d4049e4abc237a310 /src
parent41563a871b175f3469254d57dc019fda5210f8a9 (diff)
downloadopenttd-dd20ccee88a55ed08abb2a47b88cafc7c92a5e81.tar.xz
Feature: Industries with neutral stations (e.g. Oil Rig) only supply/accept cargo to/from their neutral station. (#7234)
This change is a controlled by a game setting, located under Environment -> Industries which allows toggling the behaviour. It defaults to enabled. "Company stations can serve industries with attached neutral stations" When enabled, industries with attached neutral station (such as Oil Rigs) may also be served by company-owned stations built nearby. This is the traditional behaviour. When disabled, these industries may only be served by their neutral station. Any nearby company-owned stations won't be able to serve them, nor will the neutral station serve anything else other than the industry.
Diffstat (limited to 'src')
-rw-r--r--src/economy.cpp5
-rw-r--r--src/industry.h2
-rw-r--r--src/industry_cmd.cpp8
-rw-r--r--src/lang/english.txt2
-rw-r--r--src/saveload/afterload.cpp19
-rw-r--r--src/saveload/industry_sl.cpp1
-rw-r--r--src/saveload/saveload.h2
-rw-r--r--src/settings_gui.cpp1
-rw-r--r--src/settings_type.h1
-rw-r--r--src/station.cpp6
-rw-r--r--src/station_base.h1
-rw-r--r--src/station_cmd.cpp25
-rw-r--r--src/station_func.h3
-rw-r--r--src/table/settings.ini9
14 files changed, 81 insertions, 4 deletions
diff --git a/src/economy.cpp b/src/economy.cpp
index 898bc5447..205064096 100644
--- a/src/economy.cpp
+++ b/src/economy.cpp
@@ -1048,6 +1048,11 @@ static uint DeliverGoodsToIndustry(const Station *st, CargoID cargo_type, uint n
Industry *ind = st->industries_near[i];
if (ind->index == source) continue;
+ if (!_settings_game.station.serve_neutral_industries) {
+ /* If this industry is only served by its neutral station, check it's us. */
+ if (ind->neutral_station != NULL && ind->neutral_station != st) continue;
+ }
+
uint cargo_index;
for (cargo_index = 0; cargo_index < lengthof(ind->accepts_cargo); cargo_index++) {
if (cargo_type == ind->accepts_cargo[cargo_index]) break;
diff --git a/src/industry.h b/src/industry.h
index af0208b3c..b7a954d40 100644
--- a/src/industry.h
+++ b/src/industry.h
@@ -18,6 +18,7 @@
#include "industry_map.h"
#include "industrytype.h"
#include "tilearea_type.h"
+#include "station_base.h"
typedef Pool<Industry, IndustryID, 64, 64000> IndustryPool;
@@ -41,6 +42,7 @@ enum ProductionLevels {
struct Industry : IndustryPool::PoolItem<&_industry_pool> {
TileArea location; ///< Location of the industry
Town *town; ///< Nearest town
+ Station *neutral_station; ///< Associated neutral station
CargoID produced_cargo[INDUSTRY_NUM_OUTPUTS]; ///< 16 production cargo slots
uint16 produced_cargo_waiting[INDUSTRY_NUM_OUTPUTS]; ///< amount of cargo produced per cargo
uint16 incoming_cargo_waiting[INDUSTRY_NUM_INPUTS]; ///< incoming cargo waiting to be processed
diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp
index d918ef16b..ad12e5450 100644
--- a/src/industry_cmd.cpp
+++ b/src/industry_cmd.cpp
@@ -517,6 +517,12 @@ static bool TransportIndustryGoods(TileIndex tile)
bool moved_cargo = false;
StationFinder stations(i->location);
+ StationList neutral;
+
+ if (i->neutral_station != NULL && !_settings_game.station.serve_neutral_industries) {
+ /* Industry has a neutral station. Use it and ignore any other nearby stations. */
+ *neutral.Append() = i->neutral_station;
+ }
for (uint j = 0; j < lengthof(i->produced_cargo_waiting); j++) {
uint cw = min(i->produced_cargo_waiting[j], 255);
@@ -528,7 +534,7 @@ static bool TransportIndustryGoods(TileIndex tile)
i->this_month_production[j] += cw;
- uint am = MoveGoodsToStation(i->produced_cargo[j], cw, ST_INDUSTRY, i->index, stations.GetStations());
+ uint am = MoveGoodsToStation(i->produced_cargo[j], cw, ST_INDUSTRY, i->index, neutral.Length() != 0 ? &neutral : stations.GetStations());
i->this_month_transported[j] += am;
moved_cargo |= (am != 0);
diff --git a/src/lang/english.txt b/src/lang/english.txt
index c19275c64..8bcfd9588 100644
--- a/src/lang/english.txt
+++ b/src/lang/english.txt
@@ -1184,6 +1184,8 @@ STR_CONFIG_SETTING_AUTOSLOPE :Allow landscapi
STR_CONFIG_SETTING_AUTOSLOPE_HELPTEXT :Allow landscaping under buildings and tracks without removing them
STR_CONFIG_SETTING_CATCHMENT :Allow more realistically sized catchment areas: {STRING2}
STR_CONFIG_SETTING_CATCHMENT_HELPTEXT :Have differently sized catchment areas for different types of stations and airports
+STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES :Company stations can serve industries with attached neutral stations: {STRING2}
+STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES_HELPTEXT :When enabled, industries with attached stations (such as Oil Rigs) may also be served by company owned stations built nearby. When disabled, these industries may only be served by their attached stations. Any nearby company stations won't be able to serve them, nor will the attached station serve anything else other than the industry
STR_CONFIG_SETTING_EXTRADYNAMITE :Allow removal of more town-owned roads, bridges and tunnels: {STRING2}
STR_CONFIG_SETTING_EXTRADYNAMITE_HELPTEXT :Make it easier to remove town-owned infrastructure and buildings
STR_CONFIG_SETTING_TRAIN_LENGTH :Maximum length of trains: {STRING2}
diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp
index 55552413a..a29635eab 100644
--- a/src/saveload/afterload.cpp
+++ b/src/saveload/afterload.cpp
@@ -3085,6 +3085,25 @@ bool AfterLoadGame()
_settings_game.economy.town_cargogen_mode = TCGM_ORIGINAL;
}
+ if (IsSavegameVersionBefore(SLV_SERVE_NEUTRAL_INDUSTRIES)) {
+ /* Ensure the original neutral industry/station behaviour is used */
+ _settings_game.station.serve_neutral_industries = true;
+
+ /* Link oil rigs to their industry and back. */
+ Station *st;
+ FOR_ALL_STATIONS(st) {
+ if (IsTileType(st->xy, MP_STATION) && IsOilRig(st->xy)) {
+ /* Industry tile is always adjacent during construction by TileDiffXY(0, 1) */
+ st->industry = Industry::GetByTile(st->xy + TileDiffXY(0, 1));
+ st->industry->neutral_station = st;
+ }
+ }
+ } else {
+ /* Link neutral station back to industry, as this is not saved. */
+ Industry *ind;
+ FOR_ALL_INDUSTRIES(ind) if (ind->neutral_station != NULL) ind->neutral_station->industry = ind;
+ }
+
/* Station acceptance is some kind of cache */
if (IsSavegameVersionBefore(SLV_127)) {
Station *st;
diff --git a/src/saveload/industry_sl.cpp b/src/saveload/industry_sl.cpp
index 9e81861c4..e5a0b74a3 100644
--- a/src/saveload/industry_sl.cpp
+++ b/src/saveload/industry_sl.cpp
@@ -25,6 +25,7 @@ static const SaveLoad _industry_desc[] = {
SLE_VAR(Industry, location.w, SLE_FILE_U8 | SLE_VAR_U16),
SLE_VAR(Industry, location.h, SLE_FILE_U8 | SLE_VAR_U16),
SLE_REF(Industry, town, REF_TOWN),
+ SLE_CONDREF(Industry, neutral_station, REF_STATION, SLV_SERVE_NEUTRAL_INDUSTRIES, SL_MAX_VERSION),
SLE_CONDNULL( 2, SL_MIN_VERSION, SLV_61), ///< used to be industry's produced_cargo
SLE_CONDARR(Industry, produced_cargo, SLE_UINT8, 2, SLV_78, SLV_EXTEND_INDUSTRY_CARGO_SLOTS),
SLE_CONDARR(Industry, produced_cargo, SLE_UINT8, 16, SLV_EXTEND_INDUSTRY_CARGO_SLOTS, SL_MAX_VERSION),
diff --git a/src/saveload/saveload.h b/src/saveload/saveload.h
index d881a76c2..331d62d7f 100644
--- a/src/saveload/saveload.h
+++ b/src/saveload/saveload.h
@@ -294,6 +294,8 @@ enum SaveLoadVersion : uint16 {
SLV_TOWN_CARGOGEN, ///< 208 PR#6965 New algorithms for town building cargo generation.
SLV_SHIP_CURVE_PENALTY, ///< 209 PR#7289 Configurable ship curve penalties.
+ SLV_SERVE_NEUTRAL_INDUSTRIES, ///< 210 PR#7234 Company stations can serve industries with attached neutral stations.
+
SL_MAX_VERSION, ///< Highest possible saveload version
};
diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp
index 4d851333c..60430b490 100644
--- a/src/settings_gui.cpp
+++ b/src/settings_gui.cpp
@@ -1743,6 +1743,7 @@ static SettingsContainer &GetSettingsTree()
industries->Add(new SettingEntry("economy.multiple_industry_per_town"));
industries->Add(new SettingEntry("game_creation.oil_refinery_limit"));
industries->Add(new SettingEntry("economy.smooth_economy"));
+ industries->Add(new SettingEntry("station.serve_neutral_industries"));
}
SettingsPage *cdist = environment->Add(new SettingsPage(STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST));
diff --git a/src/settings_type.h b/src/settings_type.h
index 46df6c8ec..503342545 100644
--- a/src/settings_type.h
+++ b/src/settings_type.h
@@ -527,6 +527,7 @@ struct LinkGraphSettings {
/** Settings related to stations. */
struct StationSettings {
bool modified_catchment; ///< different-size catchment areas
+ bool serve_neutral_industries; ///< company stations can serve industries with attached neutral stations
bool adjacent_stations; ///< allow stations to be built directly adjacent to other stations
bool distant_join_stations; ///< allow to join non-adjacent stations
bool never_expire_airports; ///< never expire airports
diff --git a/src/station.cpp b/src/station.cpp
index f86286f3d..dc50b4f10 100644
--- a/src/station.cpp
+++ b/src/station.cpp
@@ -356,6 +356,12 @@ void Station::RecomputeIndustriesNear()
this->industries_near.Clear();
if (this->rect.IsEmpty()) return;
+ if (!_settings_game.station.serve_neutral_industries && this->industry != NULL) {
+ /* Station is associated with an industry, so we only need to deliver to that industry. */
+ *this->industries_near.Append() = this->industry;
+ return;
+ }
+
RectAndIndustryVector riv = {
this->GetCatchmentRect(),
&this->industries_near
diff --git a/src/station_base.h b/src/station_base.h
index bf860538d..0ea960bb1 100644
--- a/src/station_base.h
+++ b/src/station_base.h
@@ -473,6 +473,7 @@ public:
CargoTypes always_accepted; ///< Bitmask of always accepted cargo types (by houses, HQs, industry tiles when industry doesn't accept cargo)
IndustryVector industries_near; ///< Cached list of industries near the station that can accept cargo, @see DeliverGoodsToIndustry()
+ Industry *industry; ///< NOSAVE: Associated industry for neutral stations. (Rebuilt on load from Industry->st)
Station(TileIndex tile = INVALID_TILE);
~Station();
diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp
index e6864d70d..a9460e562 100644
--- a/src/station_cmd.cpp
+++ b/src/station_cmd.cpp
@@ -506,6 +506,8 @@ CargoArray GetProductionAroundTiles(TileIndex tile, int w, int h, int rad)
const Industry *i;
FOR_ALL_INDUSTRIES(i) {
if (!ta.Intersects(i->location)) continue;
+ /* Skip industry with neutral station */
+ if (i->neutral_station != NULL && !_settings_game.station.serve_neutral_industries) continue;
for (uint j = 0; j < lengthof(i->produced_cargo); j++) {
CargoID cargo = i->produced_cargo[j];
@@ -523,8 +525,9 @@ CargoArray GetProductionAroundTiles(TileIndex tile, int w, int h, int rad)
* @param h Y extent of area
* @param rad Search radius in addition to given area
* @param always_accepted bitmask of cargo accepted by houses and headquarters; can be NULL
+ * @param ind Industry associated with neutral station (e.g. oil rig) or NULL
*/
-CargoArray GetAcceptanceAroundTiles(TileIndex tile, int w, int h, int rad, CargoTypes *always_accepted)
+CargoArray GetAcceptanceAroundTiles(TileIndex tile, int w, int h, int rad, CargoTypes *always_accepted, const Industry *ind)
{
CargoArray acceptance;
if (always_accepted != NULL) *always_accepted = 0;
@@ -547,6 +550,15 @@ CargoArray GetAcceptanceAroundTiles(TileIndex tile, int w, int h, int rad, Cargo
for (int yc = y1; yc != y2; yc++) {
for (int xc = x1; xc != x2; xc++) {
TileIndex tile = TileXY(xc, yc);
+
+ if (!_settings_game.station.serve_neutral_industries) {
+ if (ind != NULL) {
+ if (!IsTileType(tile, MP_INDUSTRY)) continue;
+ if (Industry::GetByTile(tile) != ind) continue;
+ } else {
+ if (IsTileType(tile, MP_INDUSTRY) && Industry::GetByTile(tile)->neutral_station != NULL) continue;
+ }
+ }
AddAcceptedCargo(tile, acceptance, always_accepted);
}
}
@@ -572,7 +584,8 @@ void UpdateStationAcceptance(Station *st, bool show_msg)
st->rect.right - st->rect.left + 1,
st->rect.bottom - st->rect.top + 1,
st->GetCatchmentRadius(),
- &st->always_accepted
+ &st->always_accepted,
+ _settings_game.station.serve_neutral_industries ? NULL : st->industry
);
}
@@ -3795,6 +3808,8 @@ void FindStationsAroundTiles(const TileArea &location, StationList *stations)
uint min_y = (y > max_rad) ? y - max_rad : 0;
uint max_y = y + location.h + max_rad;
+ IndustryID ind = IsTileType(location.tile, MP_INDUSTRY) ? GetIndustryIndex(location.tile) : INVALID_INDUSTRY;
+
if (min_x == 0 && _settings_game.construction.freeform_edges) min_x = 1;
if (min_y == 0 && _settings_game.construction.freeform_edges) min_y = 1;
if (max_x >= MapSizeX()) max_x = MapSizeX() - 1;
@@ -3809,6 +3824,9 @@ void FindStationsAroundTiles(const TileArea &location, StationList *stations)
/* st can be NULL in case of waypoints */
if (st == NULL) continue;
+ /* Check if neutral station is attached to us */
+ if (!_settings_game.station.serve_neutral_industries && st->industry != NULL && st->industry->index != ind) continue;
+
if (_settings_game.station.modified_catchment) {
int rad = st->GetCatchmentRadius();
int rad_x = cx - x;
@@ -3918,6 +3936,9 @@ void BuildOilRig(TileIndex tile)
st->string_id = GenerateStationName(st, tile, STATIONNAMING_OILRIG);
assert(IsTileType(tile, MP_INDUSTRY));
+ /* Mark industry as associated both ways */
+ st->industry = Industry::GetByTile(tile);
+ st->industry->neutral_station = st;
DeleteAnimatedTile(tile);
MakeOilrig(tile, st->index, GetWaterClass(tile));
diff --git a/src/station_func.h b/src/station_func.h
index 9748297f2..ca3885e8b 100644
--- a/src/station_func.h
+++ b/src/station_func.h
@@ -19,6 +19,7 @@
#include "economy_func.h"
#include "rail.h"
#include "linkgraph/linkgraph_type.h"
+#include "industry_type.h"
void ModifyStationRatingAround(TileIndex tile, Owner owner, int amount, uint radius);
@@ -28,7 +29,7 @@ void ShowStationViewWindow(StationID station);
void UpdateAllStationVirtCoords();
CargoArray GetProductionAroundTiles(TileIndex tile, int w, int h, int rad);
-CargoArray GetAcceptanceAroundTiles(TileIndex tile, int w, int h, int rad, CargoTypes *always_accepted = NULL);
+CargoArray GetAcceptanceAroundTiles(TileIndex tile, int w, int h, int rad, CargoTypes *always_accepted = NULL, const Industry *ind = NULL);
void UpdateStationAcceptance(Station *st, bool show_msg);
diff --git a/src/table/settings.ini b/src/table/settings.ini
index bb8769c4c..13d848362 100644
--- a/src/table/settings.ini
+++ b/src/table/settings.ini
@@ -1221,6 +1221,15 @@ cat = SC_EXPERT
[SDT_BOOL]
base = GameSettings
+var = station.serve_neutral_industries
+def = true
+from = SLV_SERVE_NEUTRAL_INDUSTRIES
+str = STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES
+strhelp = STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES_HELPTEXT
+proc = StationCatchmentChanged
+
+[SDT_BOOL]
+base = GameSettings
var = order.gradual_loading
from = SLV_40
guiflags = SGF_NO_NETWORK