Mark dirty the catchment of a station on change as necessary for zoning.
If the zoning mode is station catchment, or unserved industry/building, mark dirty the station catchment rectangle before removing, or after adding, (a) station tile(s). In the case of unserved industry mode, increase the refreshed catchment radius by 10 tiles, to wholly include industries partially inside the catchment area.
This commit is contained in:
@@ -291,13 +291,11 @@ uint Station::GetCatchmentRadius() const
|
|||||||
* Determines catchment rectangle of this station
|
* Determines catchment rectangle of this station
|
||||||
* @return clamped catchment rectangle
|
* @return clamped catchment rectangle
|
||||||
*/
|
*/
|
||||||
Rect Station::GetCatchmentRect() const
|
Rect Station::GetCatchmentRectUsingRadius(uint catchment_radius) const
|
||||||
{
|
{
|
||||||
assert(!this->rect.IsEmpty());
|
assert(!this->rect.IsEmpty());
|
||||||
|
|
||||||
/* Compute acceptance rectangle */
|
/* Compute acceptance rectangle */
|
||||||
int catchment_radius = this->GetCatchmentRadius();
|
|
||||||
|
|
||||||
Rect ret = {
|
Rect ret = {
|
||||||
max<int>(this->rect.left - catchment_radius, 0),
|
max<int>(this->rect.left - catchment_radius, 0),
|
||||||
max<int>(this->rect.top - catchment_radius, 0),
|
max<int>(this->rect.top - catchment_radius, 0),
|
||||||
|
@@ -489,7 +489,11 @@ public:
|
|||||||
static void RecomputeIndustriesNearForAll();
|
static void RecomputeIndustriesNearForAll();
|
||||||
|
|
||||||
uint GetCatchmentRadius() const;
|
uint GetCatchmentRadius() const;
|
||||||
Rect GetCatchmentRect() const;
|
Rect GetCatchmentRectUsingRadius(uint radius) const;
|
||||||
|
inline Rect GetCatchmentRect() const
|
||||||
|
{
|
||||||
|
return GetCatchmentRectUsingRadius(this->GetCatchmentRadius());
|
||||||
|
}
|
||||||
|
|
||||||
/* virtual */ inline bool TileBelongsToRailStation(TileIndex tile) const
|
/* virtual */ inline bool TileBelongsToRailStation(TileIndex tile) const
|
||||||
{
|
{
|
||||||
|
@@ -53,6 +53,7 @@
|
|||||||
#include "linkgraph/linkgraph_base.h"
|
#include "linkgraph/linkgraph_base.h"
|
||||||
#include "linkgraph/refresh.h"
|
#include "linkgraph/refresh.h"
|
||||||
#include "widgets/station_widget.h"
|
#include "widgets/station_widget.h"
|
||||||
|
#include "zoning.h"
|
||||||
|
|
||||||
#include "table/strings.h"
|
#include "table/strings.h"
|
||||||
|
|
||||||
@@ -1383,6 +1384,7 @@ CommandCost CmdBuildRailStation(TileIndex tile_org, DoCommandFlag flags, uint32
|
|||||||
st->UpdateVirtCoord();
|
st->UpdateVirtCoord();
|
||||||
UpdateStationAcceptance(st, false);
|
UpdateStationAcceptance(st, false);
|
||||||
st->RecomputeIndustriesNear();
|
st->RecomputeIndustriesNear();
|
||||||
|
ZoningMarkDirtyStationCoverageArea(st);
|
||||||
InvalidateWindowData(WC_SELECT_STATION, 0, 0);
|
InvalidateWindowData(WC_SELECT_STATION, 0, 0);
|
||||||
InvalidateWindowData(WC_STATION_LIST, st->owner, 0);
|
InvalidateWindowData(WC_STATION_LIST, st->owner, 0);
|
||||||
SetWindowWidgetDirty(WC_STATION_VIEW, st->index, WID_SV_TRAINS);
|
SetWindowWidgetDirty(WC_STATION_VIEW, st->index, WID_SV_TRAINS);
|
||||||
@@ -1495,6 +1497,9 @@ CommandCost RemoveFromRailBaseStation(TileArea ta, SmallVector<T *, 4> &affected
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (flags & DC_EXEC) {
|
if (flags & DC_EXEC) {
|
||||||
|
bool already_affected = affected_stations.Include(st);
|
||||||
|
if (!already_affected) ZoningMarkDirtyStationCoverageArea(st);
|
||||||
|
|
||||||
/* read variables before the station tile is removed */
|
/* read variables before the station tile is removed */
|
||||||
uint specindex = GetCustomStationSpecIndex(tile);
|
uint specindex = GetCustomStationSpecIndex(tile);
|
||||||
Track track = GetRailStationTrack(tile);
|
Track track = GetRailStationTrack(tile);
|
||||||
@@ -1529,8 +1534,6 @@ CommandCost RemoveFromRailBaseStation(TileArea ta, SmallVector<T *, 4> &affected
|
|||||||
|
|
||||||
DeallocateSpecFromStation(st, specindex);
|
DeallocateSpecFromStation(st, specindex);
|
||||||
|
|
||||||
affected_stations.Include(st);
|
|
||||||
|
|
||||||
if (v != NULL) {
|
if (v != NULL) {
|
||||||
/* Restore station reservation. */
|
/* Restore station reservation. */
|
||||||
if (IsRailStationTile(v->tile)) SetRailStationPlatformReservation(v->tile, TrackdirToExitdir(v->GetVehicleTrackdir()), true);
|
if (IsRailStationTile(v->tile)) SetRailStationPlatformReservation(v->tile, TrackdirToExitdir(v->GetVehicleTrackdir()), true);
|
||||||
@@ -1674,6 +1677,9 @@ static CommandCost RemoveRailStation(TileIndex tile, DoCommandFlag flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Station *st = Station::GetByTile(tile);
|
Station *st = Station::GetByTile(tile);
|
||||||
|
|
||||||
|
if (flags & DC_EXEC) ZoningMarkDirtyStationCoverageArea(st);
|
||||||
|
|
||||||
CommandCost cost = RemoveRailStation(st, flags, _price[PR_CLEAR_STATION_RAIL]);
|
CommandCost cost = RemoveRailStation(st, flags, _price[PR_CLEAR_STATION_RAIL]);
|
||||||
|
|
||||||
if (flags & DC_EXEC) st->RecomputeIndustriesNear();
|
if (flags & DC_EXEC) st->RecomputeIndustriesNear();
|
||||||
@@ -1863,6 +1869,7 @@ CommandCost CmdBuildRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
|
|||||||
|
|
||||||
MarkTileDirtyByTile(cur_tile);
|
MarkTileDirtyByTile(cur_tile);
|
||||||
}
|
}
|
||||||
|
ZoningMarkDirtyStationCoverageArea(st);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (st != NULL) {
|
if (st != NULL) {
|
||||||
@@ -1933,6 +1940,7 @@ static CommandCost RemoveRoadStop(TileIndex tile, DoCommandFlag flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (flags & DC_EXEC) {
|
if (flags & DC_EXEC) {
|
||||||
|
ZoningMarkDirtyStationCoverageArea(st);
|
||||||
if (*primary_stop == cur_stop) {
|
if (*primary_stop == cur_stop) {
|
||||||
/* removed the first stop in the list */
|
/* removed the first stop in the list */
|
||||||
*primary_stop = cur_stop->next;
|
*primary_stop = cur_stop->next;
|
||||||
@@ -2299,6 +2307,7 @@ CommandCost CmdBuildAirport(TileIndex tile, DoCommandFlag flags, uint32 p1, uint
|
|||||||
st->UpdateVirtCoord();
|
st->UpdateVirtCoord();
|
||||||
UpdateStationAcceptance(st, false);
|
UpdateStationAcceptance(st, false);
|
||||||
st->RecomputeIndustriesNear();
|
st->RecomputeIndustriesNear();
|
||||||
|
ZoningMarkDirtyStationCoverageArea(st);
|
||||||
InvalidateWindowData(WC_SELECT_STATION, 0, 0);
|
InvalidateWindowData(WC_SELECT_STATION, 0, 0);
|
||||||
InvalidateWindowData(WC_STATION_LIST, st->owner, 0);
|
InvalidateWindowData(WC_STATION_LIST, st->owner, 0);
|
||||||
InvalidateWindowData(WC_STATION_VIEW, st->index, -1);
|
InvalidateWindowData(WC_STATION_VIEW, st->index, -1);
|
||||||
@@ -2337,6 +2346,7 @@ static CommandCost RemoveAirport(TileIndex tile, DoCommandFlag flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (flags & DC_EXEC) {
|
if (flags & DC_EXEC) {
|
||||||
|
ZoningMarkDirtyStationCoverageArea(st);
|
||||||
const AirportSpec *as = st->airport.GetSpec();
|
const AirportSpec *as = st->airport.GetSpec();
|
||||||
/* The noise level is the noise from the airport and reduce it to account for the distance to the town center.
|
/* The noise level is the noise from the airport and reduce it to account for the distance to the town center.
|
||||||
* And as for construction, always remove it, even if the setting is not set, in order to avoid the
|
* And as for construction, always remove it, even if the setting is not set, in order to avoid the
|
||||||
@@ -2539,6 +2549,7 @@ CommandCost CmdBuildDock(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
|
|||||||
st->UpdateVirtCoord();
|
st->UpdateVirtCoord();
|
||||||
UpdateStationAcceptance(st, false);
|
UpdateStationAcceptance(st, false);
|
||||||
st->RecomputeIndustriesNear();
|
st->RecomputeIndustriesNear();
|
||||||
|
ZoningMarkDirtyStationCoverageArea(st);
|
||||||
InvalidateWindowData(WC_SELECT_STATION, 0, 0);
|
InvalidateWindowData(WC_SELECT_STATION, 0, 0);
|
||||||
InvalidateWindowData(WC_STATION_LIST, st->owner, 0);
|
InvalidateWindowData(WC_STATION_LIST, st->owner, 0);
|
||||||
SetWindowWidgetDirty(WC_STATION_VIEW, st->index, WID_SV_SHIPS);
|
SetWindowWidgetDirty(WC_STATION_VIEW, st->index, WID_SV_SHIPS);
|
||||||
@@ -2569,6 +2580,7 @@ static CommandCost RemoveDock(TileIndex tile, DoCommandFlag flags)
|
|||||||
if (ret.Failed()) return ret;
|
if (ret.Failed()) return ret;
|
||||||
|
|
||||||
if (flags & DC_EXEC) {
|
if (flags & DC_EXEC) {
|
||||||
|
ZoningMarkDirtyStationCoverageArea(st);
|
||||||
DoClearSquare(tile1);
|
DoClearSquare(tile1);
|
||||||
MarkTileDirtyByTile(tile1);
|
MarkTileDirtyByTile(tile1);
|
||||||
MakeWaterKeepingClass(tile2, st->owner);
|
MakeWaterKeepingClass(tile2, st->owner);
|
||||||
@@ -3903,11 +3915,13 @@ void BuildOilRig(TileIndex tile)
|
|||||||
st->UpdateVirtCoord();
|
st->UpdateVirtCoord();
|
||||||
UpdateStationAcceptance(st, false);
|
UpdateStationAcceptance(st, false);
|
||||||
st->RecomputeIndustriesNear();
|
st->RecomputeIndustriesNear();
|
||||||
|
ZoningMarkDirtyStationCoverageArea(st);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeleteOilRig(TileIndex tile)
|
void DeleteOilRig(TileIndex tile)
|
||||||
{
|
{
|
||||||
Station *st = Station::GetByTile(tile);
|
Station *st = Station::GetByTile(tile);
|
||||||
|
ZoningMarkDirtyStationCoverageArea(st);
|
||||||
|
|
||||||
MakeWaterKeepingClass(tile, OWNER_NONE);
|
MakeWaterKeepingClass(tile, OWNER_NONE);
|
||||||
|
|
||||||
|
@@ -45,4 +45,7 @@ void DrawTileZoning(const TileInfo *ti);
|
|||||||
|
|
||||||
void ShowZoningToolbar();
|
void ShowZoningToolbar();
|
||||||
|
|
||||||
|
void ZoningMarkDirtyStationCoverageArea(const Station *st);
|
||||||
|
inline void ZoningMarkDirtyStationCoverageArea(const Waypoint *st) { } // no-op
|
||||||
|
|
||||||
#endif /* ZONING_H */
|
#endif /* ZONING_H */
|
||||||
|
@@ -330,3 +330,35 @@ void DrawTileZoning(const TileInfo *ti)
|
|||||||
DrawZoningSprites(SPR_ZONING_INNER_HIGHLIGHT_BASE, TileZoningSpriteEvaluation(ti->tile, _local_company, _zoning.inner), ti);
|
DrawZoningSprites(SPR_ZONING_INNER_HIGHLIGHT_BASE, TileZoningSpriteEvaluation(ti->tile, _local_company, _zoning.inner), ti);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint GetZoningModeDependantStationCoverageRadius(const Station *st, ZoningEvaluationMode ev_mode)
|
||||||
|
{
|
||||||
|
switch (ev_mode) {
|
||||||
|
case ZEM_STA_CATCH: return st->GetCatchmentRadius();
|
||||||
|
case ZEM_BUL_UNSER: return st->GetCatchmentRadius();
|
||||||
|
case ZEM_IND_UNSER: return st->GetCatchmentRadius() + 10; // this is to wholly update industries partially within the region
|
||||||
|
default: return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark dirty the coverage area around a station if the current zoning mode depends on station coverage
|
||||||
|
*
|
||||||
|
* @param const Station *st
|
||||||
|
* The station to use
|
||||||
|
*/
|
||||||
|
void ZoningMarkDirtyStationCoverageArea(const Station *st)
|
||||||
|
{
|
||||||
|
if (st->rect.IsEmpty()) return;
|
||||||
|
|
||||||
|
uint radius = max<uint>(GetZoningModeDependantStationCoverageRadius(st, _zoning.outer), GetZoningModeDependantStationCoverageRadius(st, _zoning.inner));
|
||||||
|
|
||||||
|
if (radius > 0) {
|
||||||
|
Rect rect = st->GetCatchmentRectUsingRadius(radius);
|
||||||
|
for (int x = rect.left; x <= rect.right; x++) {
|
||||||
|
for (int y = rect.top; y <= rect.bottom; y++) {
|
||||||
|
MarkTileDirtyByTile(TileXY(x, y));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user