Changeset - r23420:9c4e5ff5cf11
[Not reviewed]
master
0 14 0
PeterN - 5 years ago 2019-03-08 18:30:44
peter@fuzzle.org
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.
14 files changed with 81 insertions and 4 deletions:
0 comments (0 inline, 0 general)
src/economy.cpp
Show inline comments
 
@@ -1048,6 +1048,11 @@ static uint DeliverGoodsToIndustry(const
 
		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;
src/industry.h
Show inline comments
 
@@ -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
src/industry_cmd.cpp
Show inline comments
 
@@ -517,6 +517,12 @@ static bool TransportIndustryGoods(TileI
 
	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(TileI
 

	
 
			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);
src/lang/english.txt
Show inline comments
 
@@ -1184,6 +1184,8 @@ STR_CONFIG_SETTING_AUTOSLOPE            
 
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}
src/saveload/afterload.cpp
Show inline comments
 
@@ -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;
src/saveload/industry_sl.cpp
Show inline comments
 
@@ -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),
src/saveload/saveload.h
Show inline comments
 
@@ -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
 
};
 

	
src/settings_gui.cpp
Show inline comments
 
@@ -1743,6 +1743,7 @@ static SettingsContainer &GetSettingsTre
 
				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));
src/settings_type.h
Show inline comments
 
@@ -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
src/station.cpp
Show inline comments
 
@@ -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
src/station_base.h
Show inline comments
 
@@ -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();
src/station_cmd.cpp
Show inline comments
 
@@ -506,6 +506,8 @@ CargoArray GetProductionAroundTiles(Tile
 
	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(Tile
 
 * @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(Tile
 
	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
 
			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 TileA
 
	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 TileA
 
			/* 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));
 

	
src/station_func.h
Show inline comments
 
@@ -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 sta
 
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);
 

	
src/table/settings.ini
Show inline comments
 
@@ -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
0 comments (0 inline, 0 general)