Changeset - r23429:dad55774ae34
[Not reviewed]
master
0 6 0
peter1138 - 5 years ago 2019-02-24 19:16:24
peter1138@openttd.org
Codechange: Convert IndustryVector to a std::set.
6 files changed with 30 insertions and 19 deletions:
0 comments (0 inline, 0 general)
src/cargomonitor.cpp
Show inline comments
 
@@ -142,20 +142,20 @@ void AddCargoDelivery(CargoID cargo_type
 
		}
 
	}
 

	
 
	/* Handle delivery.
 
	 * Note that delivery in the right area is sufficient to prevent trouble with neighbouring industries or houses. */
 

	
 
	/* Town delivery. */
 
	CargoMonitorID num = EncodeCargoTownMonitor(company, cargo_type, st->town->index);
 
	CargoMonitorMap::iterator iter = _cargo_deliveries.find(num);
 
	if (iter != _cargo_deliveries.end()) iter->second += amount;
 

	
 
	/* Industry delivery. */
 
	for (const Industry * const *ip = st->industries_near.Begin(); ip != st->industries_near.End(); ip++) {
 
		if ((*ip)->index != dest) continue;
 
		CargoMonitorID num = EncodeCargoIndustryMonitor(company, cargo_type, (*ip)->index);
 
	for (Industry *ind : st->industries_near) {
 
		if (ind->index != dest) continue;
 
		CargoMonitorID num = EncodeCargoIndustryMonitor(company, cargo_type, ind->index);
 
		CargoMonitorMap::iterator iter = _cargo_deliveries.find(num);
 
		if (iter != _cargo_deliveries.end()) iter->second += amount;
 
	}
 
}
 

	
src/economy.cpp
Show inline comments
 
@@ -1035,26 +1035,27 @@ static SmallIndustryList _cargo_delivery
 
 */
 
static uint DeliverGoodsToIndustry(const Station *st, CargoID cargo_type, uint num_pieces, IndustryID source, CompanyID company)
 
{
 
	/* Find the nearest industrytile to the station sign inside the catchment area, whose industry accepts the cargo.
 
	 * This fails in three cases:
 
	 *  1) The station accepts the cargo because there are enough houses around it accepting the cargo.
 
	 *  2) The industries in the catchment area temporarily reject the cargo, and the daily station loop has not yet updated station acceptance.
 
	 *  3) The results of callbacks CBID_INDUSTRY_REFUSE_CARGO and CBID_INDTILE_CARGO_ACCEPTANCE are inconsistent. (documented behaviour)
 
	 */
 

	
 
	uint accepted = 0;
 

	
 
	for (uint i = 0; i < st->industries_near.Length() && num_pieces != 0; i++) {
 
		Industry *ind = st->industries_near[i];
 
	for (Industry *ind : st->industries_near) {
 
		if (num_pieces == 0) break;
 

	
 
		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;
 
		}
 
		/* Check if matching cargo has been found */
src/industry_cmd.cpp
Show inline comments
 
@@ -512,38 +512,38 @@ static CommandCost ClearTile_Industry(Ti
 
 */
 
static bool TransportIndustryGoods(TileIndex tile)
 
{
 
	Industry *i = Industry::GetByTile(tile);
 
	const IndustrySpec *indspec = GetIndustrySpec(i->type);
 
	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;
 
		neutral.insert(i->neutral_station);
 
	}
 

	
 
	for (uint j = 0; j < lengthof(i->produced_cargo_waiting); j++) {
 
		uint cw = min(i->produced_cargo_waiting[j], 255);
 
		if (cw > indspec->minimal_cargo && i->produced_cargo[j] != CT_INVALID) {
 
			i->produced_cargo_waiting[j] -= cw;
 

	
 
			/* fluctuating economy? */
 
			if (EconomyIsInRecession()) cw = (cw + 1) / 2;
 

	
 
			i->this_month_production[j] += cw;
 

	
 
			uint am = MoveGoodsToStation(i->produced_cargo[j], cw, ST_INDUSTRY, i->index, neutral.Length() != 0 ? &neutral : stations.GetStations());
 
			uint am = MoveGoodsToStation(i->produced_cargo[j], cw, ST_INDUSTRY, i->index, neutral.size() != 0 ? &neutral : stations.GetStations());
 
			i->this_month_transported[j] += am;
 

	
 
			moved_cargo |= (am != 0);
 
		}
 
	}
 

	
 
	return moved_cargo;
 
}
 

	
 

	
 
static void AnimateTile_Industry(TileIndex tile)
 
{
 
@@ -2898,12 +2898,17 @@ extern const TileTypeProcs _tile_type_in
 
	AddAcceptedCargo_Industry,   // add_accepted_cargo_proc
 
	GetTileDesc_Industry,        // get_tile_desc_proc
 
	GetTileTrackStatus_Industry, // get_tile_track_status_proc
 
	ClickTile_Industry,          // click_tile_proc
 
	AnimateTile_Industry,        // animate_tile_proc
 
	TileLoop_Industry,           // tile_loop_proc
 
	ChangeTileOwner_Industry,    // change_tile_owner_proc
 
	NULL,                        // add_produced_cargo_proc
 
	NULL,                        // vehicle_enter_tile_proc
 
	GetFoundation_Industry,      // get_foundation_proc
 
	TerraformTile_Industry,      // terraform_tile_proc
 
};
 

	
 
bool IndustryCompare::operator() (const Industry *lhs, const Industry *rhs) const
 
{
 
	return lhs->index < rhs->index;
 
}
src/station.cpp
Show inline comments
 
@@ -298,76 +298,76 @@ Rect Station::GetCatchmentRect() const
 
	Rect ret = {
 
		max<int>(this->rect.left   - catchment_radius, 0),
 
		max<int>(this->rect.top    - catchment_radius, 0),
 
		min<int>(this->rect.right  + catchment_radius, MapMaxX()),
 
		min<int>(this->rect.bottom + catchment_radius, MapMaxY())
 
	};
 

	
 
	return ret;
 
}
 

	
 
/** Rect and pointer to IndustryVector */
 
struct RectAndIndustryVector {
 
	Rect rect;                       ///< The rectangle to search the industries in.
 
	IndustryVector *industries_near; ///< The nearby industries.
 
	Rect rect;                     ///< The rectangle to search the industries in.
 
	IndustryList *industries_near; ///< The nearby industries.
 
};
 

	
 
/**
 
 * Callback function for Station::RecomputeIndustriesNear()
 
 * Tests whether tile is an industry and possibly adds
 
 * the industry to station's industries_near list.
 
 * @param ind_tile tile to check
 
 * @param user_data pointer to RectAndIndustryVector
 
 * @return always false, we want to search all tiles
 
 */
 
static bool FindIndustryToDeliver(TileIndex ind_tile, void *user_data)
 
{
 
	/* Only process industry tiles */
 
	if (!IsTileType(ind_tile, MP_INDUSTRY)) return false;
 

	
 
	RectAndIndustryVector *riv = (RectAndIndustryVector *)user_data;
 
	Industry *ind = Industry::GetByTile(ind_tile);
 

	
 
	/* Don't check further if this industry is already in the list */
 
	if (riv->industries_near->Contains(ind)) return false;
 
	if (riv->industries_near->find(ind) != riv->industries_near->end()) return false;
 

	
 
	/* Only process tiles in the station acceptance rectangle */
 
	int x = TileX(ind_tile);
 
	int y = TileY(ind_tile);
 
	if (x < riv->rect.left || x > riv->rect.right || y < riv->rect.top || y > riv->rect.bottom) return false;
 

	
 
	/* Include only industries that can accept cargo */
 
	uint cargo_index;
 
	for (cargo_index = 0; cargo_index < lengthof(ind->accepts_cargo); cargo_index++) {
 
		if (ind->accepts_cargo[cargo_index] != CT_INVALID) break;
 
	}
 
	if (cargo_index >= lengthof(ind->accepts_cargo)) return false;
 

	
 
	*riv->industries_near->Append() = ind;
 
	riv->industries_near->insert(ind);
 

	
 
	return false;
 
}
 

	
 
/**
 
 * Recomputes Station::industries_near, list of industries possibly
 
 * accepting cargo in station's catchment radius
 
 */
 
void Station::RecomputeIndustriesNear()
 
{
 
	this->industries_near.Clear();
 
	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;
 
		this->industries_near.insert(this->industry);
 
		return;
 
	}
 

	
 
	RectAndIndustryVector riv = {
 
		this->GetCatchmentRect(),
 
		&this->industries_near
 
	};
 

	
 
	/* Compute maximum extent of acceptance rectangle wrt. station sign */
 
	TileIndex start_tile = this->xy;
 
	uint max_radius = max(
 
		max(DistanceManhattan(start_tile, TileXY(riv.rect.left,  riv.rect.top)), DistanceManhattan(start_tile, TileXY(riv.rect.left,  riv.rect.bottom))),
src/station_base.h
Show inline comments
 
@@ -11,24 +11,25 @@
 

	
 
#ifndef STATION_BASE_H
 
#define STATION_BASE_H
 

	
 
#include "core/random_func.hpp"
 
#include "base_station_base.h"
 
#include "newgrf_airport.h"
 
#include "cargopacket.h"
 
#include "industry_type.h"
 
#include "linkgraph/linkgraph_type.h"
 
#include "newgrf_storage.h"
 
#include <map>
 
#include <set>
 

	
 
typedef Pool<BaseStation, StationID, 32, 64000> StationPool;
 
extern StationPool _station_pool;
 

	
 
static const byte INITIAL_STATION_RATING = 175;
 

	
 
/**
 
 * Flow statistics telling how much flow should be sent along a link. This is
 
 * done by creating "flow shares" and using std::map's upper_bound() method to
 
 * look them up with a random number. A flow share is the difference between a
 
 * key in a map and the previous key. So one key in the map doesn't actually
 
 * mean anything by itself.
 
@@ -431,25 +432,29 @@ private:
 
	inline const HangarTileTable *GetHangarDataByTile(TileIndex tile) const
 
	{
 
		const AirportSpec *as = this->GetSpec();
 
		for (uint i = 0; i < as->nof_depots; i++) {
 
			if (this->GetRotatedTileFromOffset(as->depot_table[i].ti) == tile) {
 
				return as->depot_table + i;
 
			}
 
		}
 
		NOT_REACHED();
 
	}
 
};
 

	
 
typedef SmallVector<Industry *, 2> IndustryVector;
 
struct IndustryCompare {
 
	bool operator() (const Industry *lhs, const Industry *rhs) const;
 
};
 

	
 
typedef std::set<Industry *, IndustryCompare> IndustryList;
 

	
 
/** Station data structure */
 
struct Station FINAL : SpecializedStation<Station, false> {
 
public:
 
	RoadStop *GetPrimaryRoadStop(RoadStopType type) const
 
	{
 
		return type == ROADSTOP_BUS ? bus_stops : truck_stops;
 
	}
 

	
 
	RoadStop *GetPrimaryRoadStop(const struct RoadVehicle *v) const;
 

	
 
	RoadStop *bus_stops;    ///< All the road stops
 
@@ -463,26 +468,26 @@ public:
 
	IndustryType indtype;   ///< Industry type to get the name from
 

	
 
	StationHadVehicleOfTypeByte had_vehicle_of_type;
 

	
 
	byte time_since_load;
 
	byte time_since_unload;
 

	
 
	byte last_vehicle_type;
 
	std::list<Vehicle *> loading_vehicles;
 
	GoodsEntry goods[NUM_CARGO];  ///< Goods at this station
 
	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)
 
	IndustryList 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();
 

	
 
	void AddFacility(StationFacility new_facility_bit, TileIndex facil_xy);
 

	
 
	void MarkTilesDirty(bool cargo_change) const;
 

	
 
	void UpdateVirtCoord();
 

	
 
	void AfterStationTileSetChange(bool adding, StationType type);
 

	
src/subsidy.cpp
Show inline comments
 
@@ -587,27 +587,27 @@ bool CheckSubsidised(CargoID cargo_type,
 
		}
 
	}
 

	
 
	bool subsidised = false;
 

	
 
	/* Check if there's a (new) subsidy that applies. There can be more subsidies triggered by this delivery!
 
	 * Think about the case that subsidies are A->B and A->C and station has both B and C in its catchment area */
 
	Subsidy *s;
 
	FOR_ALL_SUBSIDIES(s) {
 
		if (s->cargo_type == cargo_type && s->src_type == src_type && s->src == src && (!s->IsAwarded() || s->awarded == company)) {
 
			switch (s->dst_type) {
 
				case ST_INDUSTRY:
 
					for (const Industry * const *ip = st->industries_near.Begin(); ip != st->industries_near.End(); ip++) {
 
						if (s->dst == (*ip)->index) {
 
							assert((*ip)->part_of_subsidy & POS_DST);
 
					for (Industry *ind : st->industries_near) {
 
						if (s->dst == ind->index) {
 
							assert(ind->part_of_subsidy & POS_DST);
 
							subsidised = true;
 
							if (!s->IsAwarded()) s->AwardTo(company);
 
						}
 
					}
 
					break;
 
				case ST_TOWN:
 
					for (const Town * const *tp = towns_near.Begin(); tp != towns_near.End(); tp++) {
 
						if (s->dst == (*tp)->index) {
 
							assert((*tp)->cache.part_of_subsidy & POS_DST);
 
							subsidised = true;
 
							if (!s->IsAwarded()) s->AwardTo(company);
 
						}
0 comments (0 inline, 0 general)