|
@@ -479,103 +479,97 @@ void GetProductionAroundTiles(AcceptedCa
|
|
|
|
|
|
if (!IsTileType(tile, MP_STATION)) {
|
|
|
GetProducedCargoProc *gpc = _tile_type_procs[GetTileType(tile)]->get_produced_cargo_proc;
|
|
|
if (gpc != NULL) {
|
|
|
CargoID cargos[256]; // Required for CBID_HOUSE_PRODUCE_CARGO.
|
|
|
memset(cargos, CT_INVALID, sizeof(cargos));
|
|
|
|
|
|
gpc(tile, cargos);
|
|
|
for (uint i = 0; i < lengthof(cargos); ++i) {
|
|
|
if (cargos[i] != CT_INVALID) produced[cargos[i]]++;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Get a list of the cargo types that are accepted around the tile.
|
|
|
* @param accepts Destination array of accepted cargo
|
|
|
* @param tile Center of the search area
|
|
|
* @param w X extent of area
|
|
|
* @param h Y extent of area
|
|
|
* @param rad Search radius in addition to given area
|
|
|
*/
|
|
|
void GetAcceptanceAroundTiles(AcceptedCargo accepts, TileIndex tile,
|
|
|
int w, int h, int rad)
|
|
|
{
|
|
|
memset(accepts, 0, sizeof(AcceptedCargo)); // sizeof(AcceptedCargo) != sizeof(accepts) (== sizeof(uint *))
|
|
|
|
|
|
int x = TileX(tile);
|
|
|
int y = TileY(tile);
|
|
|
|
|
|
/* expand the region by rad tiles on each side
|
|
|
* while making sure that we remain inside the board. */
|
|
|
int x2 = min(x + w + rad, MapSizeX());
|
|
|
int y2 = min(y + h + rad, MapSizeY());
|
|
|
int x1 = max(x - rad, 0);
|
|
|
int y1 = max(y - rad, 0);
|
|
|
|
|
|
assert(x1 < x2);
|
|
|
assert(y1 < y2);
|
|
|
assert(w > 0);
|
|
|
assert(h > 0);
|
|
|
|
|
|
for (int yc = y1; yc != y2; yc++) {
|
|
|
for (int xc = x1; xc != x2; xc++) {
|
|
|
TileIndex tile = TileXY(xc, yc);
|
|
|
|
|
|
if (!IsTileType(tile, MP_STATION)) {
|
|
|
AcceptedCargo ac;
|
|
|
|
|
|
GetAcceptedCargo(tile, ac);
|
|
|
for (uint i = 0; i < lengthof(ac); ++i) accepts[i] += ac[i];
|
|
|
}
|
|
|
AddAcceptedCargo(tile, accepts);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/** Update the acceptance for a station.
|
|
|
* @param st Station to update
|
|
|
* @param show_msg controls whether to display a message that acceptance was changed.
|
|
|
*/
|
|
|
static void UpdateStationAcceptance(Station *st, bool show_msg)
|
|
|
{
|
|
|
/* Don't update acceptance for a buoy */
|
|
|
if (st->IsBuoy()) return;
|
|
|
|
|
|
/* old accepted goods types */
|
|
|
uint old_acc = GetAcceptanceMask(st);
|
|
|
|
|
|
/* And retrieve the acceptance. */
|
|
|
AcceptedCargo accepts;
|
|
|
if (!st->rect.IsEmpty()) {
|
|
|
GetAcceptanceAroundTiles(
|
|
|
accepts,
|
|
|
TileXY(st->rect.left, st->rect.top),
|
|
|
st->rect.right - st->rect.left + 1,
|
|
|
st->rect.bottom - st->rect.top + 1,
|
|
|
st->GetCatchmentRadius()
|
|
|
);
|
|
|
} else {
|
|
|
memset(accepts, 0, sizeof(accepts));
|
|
|
}
|
|
|
|
|
|
/* Adjust in case our station only accepts fewer kinds of goods */
|
|
|
for (CargoID i = 0; i < NUM_CARGO; i++) {
|
|
|
uint amt = min(accepts[i], 15);
|
|
|
|
|
|
/* Make sure the station can accept the goods type. */
|
|
|
bool is_passengers = IsCargoInClass(i, CC_PASSENGERS);
|
|
|
if ((!is_passengers && !(st->facilities & (byte)~FACIL_BUS_STOP)) ||
|
|
|
(is_passengers && !(st->facilities & (byte)~FACIL_TRUCK_STOP))) {
|
|
|
amt = 0;
|
|
|
}
|
|
|
|
|
|
SB(st->goods[i].acceptance_pickup, GoodsEntry::ACCEPTANCE, 1, amt >= 8);
|
|
|
}
|
|
|
|
|
|
/* Only show a message in case the acceptance was actually changed. */
|
|
|
uint new_acc = GetAcceptanceMask(st);
|
|
|
if (old_acc == new_acc) return;
|
|
|
|
|
@@ -2303,101 +2297,96 @@ static void DrawTile_Station(TileInfo *t
|
|
|
image, pal,
|
|
|
ti->x + dtss->delta_x, ti->y + dtss->delta_y,
|
|
|
dtss->size_x, dtss->size_y,
|
|
|
dtss->size_z, ti->z + dtss->delta_z,
|
|
|
!HasBit(image, SPRITE_MODIFIER_OPAQUE) && IsTransparencySet(TO_BUILDINGS)
|
|
|
);
|
|
|
} else {
|
|
|
/* For stations and original spritelayouts delta_x and delta_y are signed */
|
|
|
AddChildSpriteScreen(image, pal, dtss->delta_x, dtss->delta_y, !HasBit(image, SPRITE_MODIFIER_OPAQUE) && IsTransparencySet(TO_BUILDINGS));
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void StationPickerDrawSprite(int x, int y, StationType st, RailType railtype, RoadType roadtype, int image)
|
|
|
{
|
|
|
int32 total_offset = 0;
|
|
|
SpriteID pal = COMPANY_SPRITE_COLOUR(_local_company);
|
|
|
const DrawTileSprites *t = &_station_display_datas[st][image];
|
|
|
|
|
|
if (railtype != INVALID_RAILTYPE) {
|
|
|
const RailtypeInfo *rti = GetRailTypeInfo(railtype);
|
|
|
total_offset = rti->total_offset;
|
|
|
}
|
|
|
|
|
|
SpriteID img = t->ground.sprite;
|
|
|
DrawSprite(img + total_offset, HasBit(img, PALETTE_MODIFIER_COLOUR) ? pal : PAL_NONE, x, y);
|
|
|
|
|
|
if (roadtype == ROADTYPE_TRAM) {
|
|
|
DrawSprite(SPR_TRAMWAY_TRAM + (t->ground.sprite == SPR_ROAD_PAVED_STRAIGHT_X ? 1 : 0), PAL_NONE, x, y);
|
|
|
}
|
|
|
|
|
|
const DrawTileSeqStruct *dtss;
|
|
|
foreach_draw_tile_seq(dtss, t->seq) {
|
|
|
Point pt = RemapCoords(dtss->delta_x, dtss->delta_y, dtss->delta_z);
|
|
|
DrawSprite(dtss->image.sprite + total_offset, pal, x + pt.x, y + pt.y);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static uint GetSlopeZ_Station(TileIndex tile, uint x, uint y)
|
|
|
{
|
|
|
return GetTileMaxZ(tile);
|
|
|
}
|
|
|
|
|
|
static Foundation GetFoundation_Station(TileIndex tile, Slope tileh)
|
|
|
{
|
|
|
return FlatteningFoundation(tileh);
|
|
|
}
|
|
|
|
|
|
static void GetAcceptedCargo_Station(TileIndex tile, AcceptedCargo ac)
|
|
|
{
|
|
|
/* not used */
|
|
|
}
|
|
|
|
|
|
static void GetTileDesc_Station(TileIndex tile, TileDesc *td)
|
|
|
{
|
|
|
td->owner[0] = GetTileOwner(tile);
|
|
|
if (IsDriveThroughStopTile(tile)) {
|
|
|
Owner road_owner = INVALID_OWNER;
|
|
|
Owner tram_owner = INVALID_OWNER;
|
|
|
RoadTypes rts = GetRoadTypes(tile);
|
|
|
if (HasBit(rts, ROADTYPE_ROAD)) road_owner = GetRoadOwner(tile, ROADTYPE_ROAD);
|
|
|
if (HasBit(rts, ROADTYPE_TRAM)) tram_owner = GetRoadOwner(tile, ROADTYPE_TRAM);
|
|
|
|
|
|
/* Is there a mix of owners? */
|
|
|
if ((tram_owner != INVALID_OWNER && tram_owner != td->owner[0]) ||
|
|
|
(road_owner != INVALID_OWNER && road_owner != td->owner[0])) {
|
|
|
uint i = 1;
|
|
|
if (road_owner != INVALID_OWNER) {
|
|
|
td->owner_type[i] = STR_LAND_AREA_INFORMATION_ROAD_OWNER;
|
|
|
td->owner[i] = road_owner;
|
|
|
i++;
|
|
|
}
|
|
|
if (tram_owner != INVALID_OWNER) {
|
|
|
td->owner_type[i] = STR_LAND_AREA_INFORMATION_TRAM_OWNER;
|
|
|
td->owner[i] = tram_owner;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
td->build_date = Station::GetByTile(tile)->build_date;
|
|
|
|
|
|
const StationSpec *spec = GetStationSpec(tile);
|
|
|
|
|
|
if (spec != NULL) {
|
|
|
td->station_class = GetStationClassName(spec->sclass);
|
|
|
td->station_name = spec->name;
|
|
|
|
|
|
if (spec->grffile != NULL) {
|
|
|
const GRFConfig *gc = GetGRFConfig(spec->grffile->grfid);
|
|
|
td->grf = gc->name;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
StringID str;
|
|
|
switch (GetStationType(tile)) {
|
|
|
default: NOT_REACHED();
|
|
|
case STATION_RAIL: str = STR_STATION_DESCRIPTION_RAILROAD_STATION; break;
|
|
|
case STATION_AIRPORT:
|
|
|
str = (IsHangar(tile) ? STR_STATION_DESCRIPTION_AIRCRAFT_HANGAR : STR_STATION_DESCRIPTION_AIRPORT);
|
|
|
break;
|
|
|
case STATION_TRUCK: str = STR_STATION_DESCRIPTION_TRUCK_LOADING_AREA; break;
|
|
|
case STATION_BUS: str = STR_STATION_DESCRIPTION_BUS_STATION; break;
|
|
@@ -3118,60 +3107,60 @@ static CommandCost ClearTile_Station(Til
|
|
|
case STATION_BUOY: return RemoveBuoy(st, flags);
|
|
|
case STATION_DOCK: return RemoveDock(st, flags);
|
|
|
default: break;
|
|
|
}
|
|
|
|
|
|
return CMD_ERROR;
|
|
|
}
|
|
|
|
|
|
static CommandCost TerraformTile_Station(TileIndex tile, DoCommandFlag flags, uint z_new, Slope tileh_new)
|
|
|
{
|
|
|
if (_settings_game.construction.build_on_slopes && AutoslopeEnabled()) {
|
|
|
/* TODO: If you implement newgrf callback 149 'land slope check', you have to decide what to do with it here.
|
|
|
* TTDP does not call it.
|
|
|
*/
|
|
|
if (!IsSteepSlope(tileh_new) && (GetTileMaxZ(tile) == z_new + GetSlopeMaxZ(tileh_new))) {
|
|
|
switch (GetStationType(tile)) {
|
|
|
case STATION_RAIL: {
|
|
|
DiagDirection direction = AxisToDiagDir(GetRailStationAxis(tile));
|
|
|
if (!AutoslopeCheckForEntranceEdge(tile, z_new, tileh_new, direction)) break;
|
|
|
if (!AutoslopeCheckForEntranceEdge(tile, z_new, tileh_new, ReverseDiagDir(direction))) break;
|
|
|
return CommandCost(EXPENSES_CONSTRUCTION, _price.terraform);
|
|
|
}
|
|
|
|
|
|
case STATION_AIRPORT:
|
|
|
return CommandCost(EXPENSES_CONSTRUCTION, _price.terraform);
|
|
|
|
|
|
case STATION_TRUCK:
|
|
|
case STATION_BUS: {
|
|
|
DiagDirection direction = GetRoadStopDir(tile);
|
|
|
if (!AutoslopeCheckForEntranceEdge(tile, z_new, tileh_new, direction)) break;
|
|
|
if (IsDriveThroughStopTile(tile)) {
|
|
|
if (!AutoslopeCheckForEntranceEdge(tile, z_new, tileh_new, ReverseDiagDir(direction))) break;
|
|
|
}
|
|
|
return CommandCost(EXPENSES_CONSTRUCTION, _price.terraform);
|
|
|
}
|
|
|
|
|
|
default: break;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
|
|
|
}
|
|
|
|
|
|
|
|
|
extern const TileTypeProcs _tile_type_station_procs = {
|
|
|
DrawTile_Station, // draw_tile_proc
|
|
|
GetSlopeZ_Station, // get_slope_z_proc
|
|
|
ClearTile_Station, // clear_tile_proc
|
|
|
GetAcceptedCargo_Station, // get_accepted_cargo_proc
|
|
|
NULL, // get_accepted_cargo_proc
|
|
|
GetTileDesc_Station, // get_tile_desc_proc
|
|
|
GetTileTrackStatus_Station, // get_tile_track_status_proc
|
|
|
ClickTile_Station, // click_tile_proc
|
|
|
AnimateTile_Station, // animate_tile_proc
|
|
|
TileLoop_Station, // tile_loop_clear
|
|
|
ChangeTileOwner_Station, // change_tile_owner_clear
|
|
|
NULL, // get_produced_cargo_proc
|
|
|
VehicleEnter_Station, // vehicle_enter_tile_proc
|
|
|
GetFoundation_Station, // get_foundation_proc
|
|
|
TerraformTile_Station, // terraform_tile_proc
|
|
|
};
|