mirror of https://github.com/OpenTTD/OpenTTD.git
(svn r18110) -Codechange [FS#3316]: search for stations nearby only once per producer (instead of once pre produced cargo type) (fonsinchen)
This commit is contained in:
parent
e41c2e128b
commit
47660b984b
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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? */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue