|
@@ -34,12 +34,13 @@
|
|
|
#include "date_func.h"
|
|
|
#include "vehicle_func.h"
|
|
|
#include "string_func.h"
|
|
|
#include "animated_tile_func.h"
|
|
|
#include "elrail_func.h"
|
|
|
#include "station_base.h"
|
|
|
#include "station_kdtree.h"
|
|
|
#include "roadstop_base.h"
|
|
|
#include "newgrf_railtype.h"
|
|
|
#include "waypoint_base.h"
|
|
|
#include "waypoint_func.h"
|
|
|
#include "pbs.h"
|
|
|
#include "debug.h"
|
|
@@ -356,25 +357,27 @@ static StringID GenerateStationName(Stat
|
|
|
* @param tile the tile to search from.
|
|
|
* @return the closest station or NULL if too far.
|
|
|
*/
|
|
|
static Station *GetClosestDeletedStation(TileIndex tile)
|
|
|
{
|
|
|
uint threshold = 8;
|
|
|
|
|
|
Station *best_station = NULL;
|
|
|
Station *st;
|
|
|
|
|
|
FOR_ALL_STATIONS(st) {
|
|
|
ForAllStationsRadius(tile, threshold, [&](Station *st) {
|
|
|
if (!st->IsInUse() && st->owner == _current_company) {
|
|
|
uint cur_dist = DistanceManhattan(tile, st->xy);
|
|
|
|
|
|
if (cur_dist < threshold) {
|
|
|
threshold = cur_dist;
|
|
|
best_station = st;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
} else if (cur_dist == threshold && best_station != NULL) {
|
|
|
/* In case of a tie, lowest station ID wins */
|
|
|
if (st->index < best_station->index) best_station = st;
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
|
|
|
return best_station;
|
|
|
}
|
|
|
|
|
|
|
|
|
void Station::GetTileArea(TileArea *ta, StationType type) const
|
|
@@ -664,14 +667,19 @@ static void UpdateStationSignCoord(BaseS
|
|
|
{
|
|
|
const StationRect *r = &st->rect;
|
|
|
|
|
|
if (r->IsEmpty()) return; // no tiles belong to this station
|
|
|
|
|
|
/* clamp sign coord to be inside the station rect */
|
|
|
st->xy = TileXY(ClampU(TileX(st->xy), r->left, r->right), ClampU(TileY(st->xy), r->top, r->bottom));
|
|
|
TileIndex new_xy = TileXY(ClampU(TileX(st->xy), r->left, r->right), ClampU(TileY(st->xy), r->top, r->bottom));
|
|
|
if (new_xy != st->xy) {
|
|
|
_station_kdtree.Remove(st->index);
|
|
|
st->xy = new_xy;
|
|
|
_station_kdtree.Insert(st->index);
|
|
|
st->UpdateVirtCoord();
|
|
|
}
|
|
|
|
|
|
if (!Station::IsExpected(st)) return;
|
|
|
Station *full_station = Station::From(st);
|
|
|
for (CargoID c = 0; c < NUM_CARGO; ++c) {
|
|
|
LinkGraphID lg = full_station->goods[c].link_graph;
|
|
|
if (!LinkGraph::IsValidID(lg)) continue;
|
|
@@ -703,12 +711,13 @@ static CommandCost BuildStationPart(Stat
|
|
|
} else {
|
|
|
/* allocate and initialize new station */
|
|
|
if (!Station::CanAllocateItem()) return_cmd_error(STR_ERROR_TOO_MANY_STATIONS_LOADING);
|
|
|
|
|
|
if (flags & DC_EXEC) {
|
|
|
*st = new Station(area.tile);
|
|
|
_station_kdtree.Insert((*st)->index);
|
|
|
|
|
|
(*st)->town = ClosestTownFromTile(area.tile, UINT_MAX);
|
|
|
(*st)->string_id = GenerateStationName(*st, area.tile, name_class);
|
|
|
|
|
|
if (Company::IsValidID(_current_company)) {
|
|
|
SetBit((*st)->town->have_ratings, _current_company);
|
|
@@ -3691,26 +3700,23 @@ void StationMonthlyLoop()
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
void ModifyStationRatingAround(TileIndex tile, Owner owner, int amount, uint radius)
|
|
|
{
|
|
|
Station *st;
|
|
|
|
|
|
FOR_ALL_STATIONS(st) {
|
|
|
if (st->owner == owner &&
|
|
|
DistanceManhattan(tile, st->xy) <= radius) {
|
|
|
ForAllStationsRadius(tile, radius, [&](Station *st) {
|
|
|
if (st->owner == owner) {
|
|
|
for (CargoID i = 0; i < NUM_CARGO; i++) {
|
|
|
GoodsEntry *ge = &st->goods[i];
|
|
|
|
|
|
if (ge->status != 0) {
|
|
|
ge->rating = Clamp(ge->rating + amount, 0, 255);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
|
|
|
static uint UpdateStationWaiting(Station *st, CargoID type, uint amount, SourceType source_type, SourceID source_id)
|
|
|
{
|
|
|
/* We can't allocate a CargoPacket? Then don't do anything
|
|
|
* at all; i.e. just discard the incoming cargo. */
|
|
@@ -3944,12 +3950,13 @@ void BuildOilRig(TileIndex tile)
|
|
|
if (!Station::CanAllocateItem()) {
|
|
|
DEBUG(misc, 0, "Can't allocate station for oilrig at 0x%X, reverting to oilrig only", tile);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
Station *st = new Station(tile);
|
|
|
_station_kdtree.Insert(st->index);
|
|
|
st->town = ClosestTownFromTile(tile, UINT_MAX);
|
|
|
|
|
|
st->string_id = GenerateStationName(st, tile, STATIONNAMING_OILRIG);
|
|
|
|
|
|
assert(IsTileType(tile, MP_INDUSTRY));
|
|
|
/* Mark industry as associated both ways */
|