File diff r20004:ac98050bc27f → r20005:47118c6806f3
src/station_cmd.cpp
Show inline comments
 
@@ -1215,50 +1215,51 @@ CommandCost CmdBuildRailStation(TileInde
 
		byte *layout_ptr;
 
		byte numtracks_orig;
 
		Track track;
 

	
 
		st->train_station = new_location;
 
		st->AddFacility(FACIL_TRAIN, new_location.tile);
 

	
 
		st->rect.BeforeAddRect(tile_org, w_org, h_org, StationRect::ADD_TRY);
 

	
 
		if (statspec != NULL) {
 
			/* Include this station spec's animation trigger bitmask
 
			 * in the station's cached copy. */
 
			st->cached_anim_triggers |= statspec->animation.triggers;
 
		}
 

	
 
		tile_delta = (axis == AXIS_X ? TileDiffXY(1, 0) : TileDiffXY(0, 1));
 
		track = AxisToTrack(axis);
 

	
 
		layout_ptr = AllocaM(byte, numtracks * plat_len);
 
		GetStationLayout(layout_ptr, numtracks, plat_len, statspec);
 

	
 
		numtracks_orig = numtracks;
 

	
 
		Company *c = Company::Get(st->owner);
 
		TileIndex tile_track = tile_org;
 
		do {
 
			TileIndex tile = tile_org;
 
			TileIndex tile = tile_track;
 
			int w = plat_len;
 
			do {
 
				byte layout = *layout_ptr++;
 
				if (IsRailStationTile(tile) && HasStationReservation(tile)) {
 
					/* Check for trains having a reservation for this tile. */
 
					Train *v = GetTrainForReservation(tile, AxisToTrack(GetRailStationAxis(tile)));
 
					if (v != NULL) {
 
						FreeTrainTrackReservation(v);
 
						*affected_vehicles.Append() = v;
 
						if (IsRailStationTile(v->tile)) SetRailStationPlatformReservation(v->tile, TrackdirToExitdir(v->GetVehicleTrackdir()), false);
 
						for (; v->Next() != NULL; v = v->Next()) { }
 
						if (IsRailStationTile(v->tile)) SetRailStationPlatformReservation(v->tile, TrackdirToExitdir(ReverseTrackdir(v->GetVehicleTrackdir())), false);
 
					}
 
				}
 

	
 
				/* Railtype can change when overbuilding. */
 
				if (IsRailStationTile(tile)) {
 
					if (!IsStationTileBlocked(tile)) c->infrastructure.rail[GetRailType(tile)]--;
 
					c->infrastructure.station--;
 
				}
 

	
 
				/* Remove animation if overbuilding */
 
				DeleteAnimatedTile(tile);
 
				byte old_specindex = HasStationTileRail(tile) ? GetCustomStationSpecIndex(tile) : 0;
 
@@ -1272,62 +1273,87 @@ CommandCost CmdBuildRailStation(TileInde
 

	
 
				if (!IsStationTileBlocked(tile)) c->infrastructure.rail[rt]++;
 
				c->infrastructure.station++;
 

	
 
				if (statspec != NULL) {
 
					/* Use a fixed axis for GetPlatformInfo as our platforms / numtracks are always the right way around */
 
					uint32 platinfo = GetPlatformInfo(AXIS_X, GetStationGfx(tile), plat_len, numtracks_orig, plat_len - w, numtracks_orig - numtracks, false);
 

	
 
					/* As the station is not yet completely finished, the station does not yet exist. */
 
					uint16 callback = GetStationCallback(CBID_STATION_TILE_LAYOUT, platinfo, 0, statspec, NULL, tile);
 
					if (callback != CALLBACK_FAILED) {
 
						if (callback < 8) {
 
							SetStationGfx(tile, (callback & ~1) + axis);
 
						} else {
 
							ErrorUnknownCallbackResult(statspec->grf_prop.grffile->grfid, CBID_STATION_TILE_LAYOUT, callback);
 
						}
 
					}
 

	
 
					/* Trigger station animation -- after building? */
 
					TriggerStationAnimation(st, tile, SAT_BUILT);
 
				}
 

	
 
				tile += tile_delta;
 
			} while (--w);
 
			AddTrackToSignalBuffer(tile_org, track, _current_company);
 
			YapfNotifyTrackLayoutChange(tile_org, track);
 
			tile_org += tile_delta ^ TileDiffXY(1, 1); // perpendicular to tile_delta
 
			AddTrackToSignalBuffer(tile_track, track, _current_company);
 
			YapfNotifyTrackLayoutChange(tile_track, track);
 
			tile_track += tile_delta ^ TileDiffXY(1, 1); // perpendicular to tile_delta
 
		} while (--numtracks);
 

	
 
		for (uint i = 0; i < affected_vehicles.Length(); ++i) {
 
			/* Restore reservations of trains. */
 
			Train *v = affected_vehicles[i];
 
			if (IsRailStationTile(v->tile)) SetRailStationPlatformReservation(v->tile, TrackdirToExitdir(v->GetVehicleTrackdir()), true);
 
			TryPathReserve(v, true, true);
 
			for (; v->Next() != NULL; v = v->Next()) { }
 
			if (IsRailStationTile(v->tile)) SetRailStationPlatformReservation(v->tile, TrackdirToExitdir(ReverseTrackdir(v->GetVehicleTrackdir())), true);
 
		}
 

	
 
		/* Check whether we need to expand the reservation of trains already on the station. */
 
		TileArea update_reservation_area;
 
		if (axis == AXIS_X) {
 
			update_reservation_area = TileArea(tile_org, 1, numtracks_orig);
 
		} else {
 
			update_reservation_area = TileArea(tile_org, numtracks_orig, 1);
 
		}
 

	
 
		TILE_AREA_LOOP(tile, update_reservation_area) {
 
			DiagDirection dir = AxisToDiagDir(axis);
 
			TileIndexDiff tile_offset = TileOffsByDiagDir(dir);
 
			TileIndex platform_begin = tile - tile_offset * (st->GetPlatformLength(tile, ReverseDiagDir(dir)) - 1);
 
			TileIndex platform_end   = tile + tile_offset * (st->GetPlatformLength(tile, dir) - 1);
 

	
 
			/* If there is at least on reservation on the platform, we reserve the whole platform. */
 
			bool reservation = false;
 
			for (TileIndex t = platform_begin; !reservation && t <= platform_end; t += tile_offset) {
 
				reservation = HasStationReservation(t);
 
			}
 

	
 
			if (reservation) {
 
				SetRailStationPlatformReservation(platform_begin, dir, true);
 
			}
 
		}
 

	
 
		st->MarkTilesDirty(false);
 
		st->UpdateVirtCoord();
 
		UpdateStationAcceptance(st, false);
 
		st->RecomputeIndustriesNear();
 
		InvalidateWindowData(WC_SELECT_STATION, 0, 0);
 
		InvalidateWindowData(WC_STATION_LIST, st->owner, 0);
 
		SetWindowWidgetDirty(WC_STATION_VIEW, st->index, WID_SV_TRAINS);
 
		DirtyCompanyInfrastructureWindows(st->owner);
 
	}
 

	
 
	return cost;
 
}
 

	
 
static void MakeRailStationAreaSmaller(BaseStation *st)
 
{
 
	TileArea ta = st->train_station;
 

	
 
restart:
 

	
 
	/* too small? */
 
	if (ta.w != 0 && ta.h != 0) {
 
		/* check the left side, x = constant, y changes */
 
		for (uint i = 0; !st->TileBelongsToRailStation(ta.tile + TileDiffXY(0, i));) {
 
			/* the left side is unused? */