File diff r12233:9d0861714103 → r12234:fd1a494e7620
src/station_cmd.cpp
Show inline comments
 
@@ -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
 
};