(svn r26582) -Feature-ish: quickly decay cargo after about 21 months of not having picked any of the cargo, and prevent houses and industries providing more cargo

This commit is contained in:
rubidium 2014-05-11 18:35:34 +00:00
parent b590a64718
commit 0ceb05ee9f
2 changed files with 34 additions and 15 deletions

View File

@ -169,11 +169,12 @@ struct GoodsEntry {
GES_ACCEPTANCE,
/**
* Set when the cargo was ever waiting at the station.
* This indicates whether a cargo has a rating at the station.
* Set when cargo was ever waiting at the station.
* It is set when cargo supplied by surrounding tiles is moved to the station, or when
* arriving vehicles unload/transfer cargo without it being a final delivery.
* This also indicates, whether a cargo has a rating at the station.
* This flag is never cleared.
*
* This flag is cleared after 255 * STATION_RATING_TICKS of not having seen a pickup.
*/
GES_RATING,

View File

@ -3240,6 +3240,28 @@ static inline void byte_inc_sat(byte *p)
if (b != 0) *p = b;
}
/**
* Truncate the cargo by a specific amount.
* @param cs The type of cargo to perform the truncation for.
* @param ge The goods entry, of the station, to truncate.
* @param amount The amount to truncate the cargo by.
*/
static void TruncateCargo(const CargoSpec *cs, GoodsEntry *ge, uint amount = UINT_MAX)
{
/* If truncating also punish the source stations' ratings to
* decrease the flow of incoming cargo. */
StationCargoAmountMap waiting_per_source;
ge->cargo.Truncate(amount, &waiting_per_source);
for (StationCargoAmountMap::iterator i(waiting_per_source.begin()); i != waiting_per_source.end(); ++i) {
Station *source_station = Station::GetIfValid(i->first);
if (source_station == NULL) continue;
GoodsEntry &source_ge = source_station->goods[cs->Index()];
source_ge.max_waiting_cargo = max(source_ge.max_waiting_cargo, i->second);
}
}
static void UpdateStationRating(Station *st)
{
bool waiting_changed = false;
@ -3260,6 +3282,13 @@ static void UpdateStationRating(Station *st)
/* Only change the rating if we are moving this cargo */
if (ge->HasRating()) {
byte_inc_sat(&ge->time_since_pickup);
if (ge->time_since_pickup == 255 && _settings_game.order.selectgoods) {
ClrBit(ge->status, GoodsEntry::GES_RATING);
ge->last_speed = 0;
TruncateCargo(cs, ge);
waiting_changed = true;
continue;
}
bool skip = false;
int rating = 0;
@ -3373,18 +3402,7 @@ static void UpdateStationRating(Station *st)
* next rating calculation. */
ge->max_waiting_cargo = 0;
/* If truncating also punish the source stations' ratings to
* decrease the flow of incoming cargo. */
StationCargoAmountMap waiting_per_source;
ge->cargo.Truncate(ge->cargo.AvailableCount() - waiting, &waiting_per_source);
for (StationCargoAmountMap::iterator i(waiting_per_source.begin()); i != waiting_per_source.end(); ++i) {
Station *source_station = Station::GetIfValid(i->first);
if (source_station == NULL) continue;
GoodsEntry &source_ge = source_station->goods[cs->Index()];
source_ge.max_waiting_cargo = max(source_ge.max_waiting_cargo, i->second);
}
TruncateCargo(cs, ge, ge->cargo.AvailableCount() - waiting);
} else {
/* If the average number per next hop is low, be more forgiving. */
ge->max_waiting_cargo = waiting_avg;