summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/economy_func.h3
-rw-r--r--src/industry_cmd.cpp4
-rw-r--r--src/station_cmd.cpp19
-rw-r--r--src/station_func.h2
-rw-r--r--src/station_type.h24
-rw-r--r--src/town_cmd.cpp8
-rw-r--r--src/unmovable_cmd.cpp6
7 files changed, 53 insertions, 13 deletions
diff --git a/src/economy_func.h b/src/economy_func.h
index 38505d450..e4a77fb6a 100644
--- a/src/economy_func.h
+++ b/src/economy_func.h
@@ -21,6 +21,7 @@
#include "industry_type.h"
#include "company_type.h"
#include "station_type.h"
+#include "station_func.h"
void ResetPriceBaseMultipliers();
void SetPriceBaseMultiplier(Price price, int factor);
@@ -35,7 +36,7 @@ int UpdateCompanyRatingAndValue(Company *c, bool update);
void StartupIndustryDailyChanges(bool init_counter);
Money GetTransportedGoodsIncome(uint num_pieces, uint dist, byte transit_days, CargoID cargo_type);
-uint MoveGoodsToStation(TileIndex tile, int w, int h, CargoID type, uint amount, SourceType source_type, SourceID source_id);
+uint MoveGoodsToStation(CargoID type, uint amount, SourceType source_type, SourceID source_id, const StationList *all_stations);
void PrepareUnload(Vehicle *front_v);
void LoadUnloadStation(Station *st);
diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp
index 7080ac4a8..5e0ad84db 100644
--- a/src/industry_cmd.cpp
+++ b/src/industry_cmd.cpp
@@ -507,6 +507,8 @@ static void TransportIndustryGoods(TileIndex tile)
const IndustrySpec *indspec = GetIndustrySpec(i->type);
bool moved_cargo = false;
+ StationFinder stations(i->xy, i->width, i->height);
+
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) {
@@ -517,7 +519,7 @@ static void TransportIndustryGoods(TileIndex tile)
i->this_month_production[j] += cw;
- uint am = MoveGoodsToStation(i->xy, i->width, i->height, i->produced_cargo[j], cw, ST_INDUSTRY, i->index);
+ uint am = MoveGoodsToStation(i->produced_cargo[j], cw, ST_INDUSTRY, i->index, stations.GetStations());
i->this_month_transported[j] += am;
moved_cargo |= (am != 0);
diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp
index 601322cf5..d17d0dc49 100644
--- a/src/station_cmd.cpp
+++ b/src/station_cmd.cpp
@@ -3009,7 +3009,20 @@ void FindStationsAroundTiles(TileIndex tile, int w_prod, int h_prod, StationList
}
}
-uint MoveGoodsToStation(TileIndex tile, int w, int h, CargoID type, uint amount, SourceType source_type, SourceID source_id)
+/**
+ * Run a tile loop to find stations around a tile, on demand. Cache the result for further requests
+ * @return pointer to a StationList containing all stations found
+ */
+const StationList *StationFinder::GetStations()
+{
+ if (this->tile != INVALID_TILE) {
+ FindStationsAroundTiles(this->tile, this->x_extent, this->y_extent, &this->stations);
+ this->tile = INVALID_TILE;
+ }
+ return &this->stations;
+}
+
+uint MoveGoodsToStation(CargoID type, uint amount, SourceType source_type, SourceID source_id, const StationList *all_stations)
{
/* Return if nothing to do. Also the rounding below fails for 0. */
if (amount == 0) return 0;
@@ -3019,9 +3032,7 @@ uint MoveGoodsToStation(TileIndex tile, int w, int h, CargoID type, uint amount,
uint best_rating1 = 0; // rating of st1
uint best_rating2 = 0; // rating of st2
- StationList all_stations;
- FindStationsAroundTiles(tile, w, h, &all_stations);
- for (Station **st_iter = all_stations.Begin(); st_iter != all_stations.End(); ++st_iter) {
+ for (Station * const *st_iter = all_stations->Begin(); st_iter != all_stations->End(); ++st_iter) {
Station *st = *st_iter;
/* Is the station reserved exclusively for somebody else? */
diff --git a/src/station_func.h b/src/station_func.h
index 0f87d1938..22a7cf79a 100644
--- a/src/station_func.h
+++ b/src/station_func.h
@@ -19,11 +19,9 @@
#include "tile_type.h"
#include "cargo_type.h"
#include "vehicle_type.h"
-#include "core/smallvec_type.hpp"
void ModifyStationRatingAround(TileIndex tile, Owner owner, int amount, uint radius);
-typedef SmallVector<Station*, 1> StationList;
void FindStationsAroundTiles(TileIndex tile, int w_prod, int h_prod, StationList *stations);
void ShowStationViewWindow(StationID station);
diff --git a/src/station_type.h b/src/station_type.h
index 5f827fffc..2784f123b 100644
--- a/src/station_type.h
+++ b/src/station_type.h
@@ -13,6 +13,7 @@
#define STATION_TYPE_H
#include "core/enum_type.hpp"
+#include "core/smallvec_type.hpp"
#include "tile_type.h"
typedef uint16 StationID;
@@ -115,4 +116,27 @@ struct TileArea {
uint8 h; ///< The height of the area
};
+/** List of stations */
+typedef SmallVector<Station *, 2> StationList;
+
+/**
+ * Structure contains cached list of stations nearby. The list
+ * is created upon first call to GetStations()
+ */
+class StationFinder {
+ StationList stations; ///< List of stations nearby
+ TileIndex tile; ///< Northern tile of producer, INVALID_TILE when # stations is valid
+ int x_extent; ///< Width of producer
+ int y_extent; ///< Height of producer
+public:
+ /**
+ * Constructs StationFinder
+ * @param t northern tile
+ * @param dx width of producer
+ * @param dy height of producer
+ */
+ StationFinder(TileIndex t, int dx, int dy) : tile(t), x_extent(dx), y_extent(dy) {}
+ const StationList *GetStations();
+};
+
#endif /* STATION_TYPE_H */
diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp
index 0d2b45b71..30c4806b1 100644
--- a/src/town_cmd.cpp
+++ b/src/town_cmd.cpp
@@ -465,6 +465,8 @@ static void TileLoop_Town(TileIndex tile)
Town *t = Town::GetByTile(tile);
uint32 r = Random();
+ StationFinder stations(tile, 1, 1);
+
if (HasBit(hs->callback_mask, CBM_HOUSE_PRODUCE_CARGO)) {
for (uint i = 0; i < 256; i++) {
uint16 callback = GetHouseCallback(CBID_HOUSE_PRODUCE_CARGO, i, r, house_id, t, tile);
@@ -477,7 +479,7 @@ static void TileLoop_Town(TileIndex tile)
uint amt = GB(callback, 0, 8);
if (amt == 0) continue;
- uint moved = MoveGoodsToStation(tile, 1, 1, cargo, amt, ST_TOWN, t->index);
+ uint moved = MoveGoodsToStation(cargo, amt, ST_TOWN, t->index, stations.GetStations());
const CargoSpec *cs = CargoSpec::Get(cargo);
switch (cs->town_effect) {
@@ -501,7 +503,7 @@ static void TileLoop_Town(TileIndex tile)
if (_economy.fluct <= 0) amt = (amt + 1) >> 1;
t->new_max_pass += amt;
- t->new_act_pass += MoveGoodsToStation(tile, 1, 1, CT_PASSENGERS, amt, ST_TOWN, t->index);
+ t->new_act_pass += MoveGoodsToStation(CT_PASSENGERS, amt, ST_TOWN, t->index, stations.GetStations());
}
if (GB(r, 8, 8) < hs->mail_generation) {
@@ -509,7 +511,7 @@ static void TileLoop_Town(TileIndex tile)
if (_economy.fluct <= 0) amt = (amt + 1) >> 1;
t->new_max_mail += amt;
- t->new_act_mail += MoveGoodsToStation(tile, 1, 1, CT_MAIL, amt, ST_TOWN, t->index);
+ t->new_act_mail += MoveGoodsToStation(CT_MAIL, amt, ST_TOWN, t->index, stations.GetStations());
}
}
diff --git a/src/unmovable_cmd.cpp b/src/unmovable_cmd.cpp
index 93ac08998..931d2d7c9 100644
--- a/src/unmovable_cmd.cpp
+++ b/src/unmovable_cmd.cpp
@@ -344,12 +344,14 @@ static void TileLoop_Unmovable(TileIndex tile)
uint level = GetCompanyHQSize(tile) + 1;
assert(level < 6);
+ StationFinder stations(tile, 2, 2);
+
uint r = Random();
/* Top town buildings generate 250, so the top HQ type makes 256. */
if (GB(r, 0, 8) < (256 / 4 / (6 - level))) {
uint amt = GB(r, 0, 8) / 8 / 4 + 1;
if (_economy.fluct <= 0) amt = (amt + 1) >> 1;
- MoveGoodsToStation(tile, 2, 2, CT_PASSENGERS, amt, ST_HEADQUARTERS, GetTileOwner(tile));
+ MoveGoodsToStation(CT_PASSENGERS, amt, ST_HEADQUARTERS, GetTileOwner(tile), stations.GetStations());
}
/* Top town building generates 90, HQ can make up to 196. The
@@ -358,7 +360,7 @@ static void TileLoop_Unmovable(TileIndex tile)
if (GB(r, 8, 8) < (196 / 4 / (6 - level))) {
uint amt = GB(r, 8, 8) / 8 / 4 + 1;
if (_economy.fluct <= 0) amt = (amt + 1) >> 1;
- MoveGoodsToStation(tile, 2, 2, CT_MAIL, amt, ST_HEADQUARTERS, GetTileOwner(tile));
+ MoveGoodsToStation(CT_MAIL, amt, ST_HEADQUARTERS, GetTileOwner(tile), stations.GetStations());
}
}