File diff r12929:f1f4ae7c2a92 → r12930:ae0ddab1903d
src/saveload/afterload.cpp
Show inline comments
 
@@ -189,96 +189,98 @@ static void UpdateCurrencies()
 
/* Up to revision 1413 the invisible tiles at the southern border have not been
 
 * MP_VOID, even though they should have. This is fixed by this function
 
 */
 
static void UpdateVoidTiles()
 
{
 
	uint i;
 

	
 
	for (i = 0; i < MapMaxY(); ++i) MakeVoid(i * MapSizeX() + MapMaxX());
 
	for (i = 0; i < MapSizeX(); ++i) MakeVoid(MapSizeX() * MapMaxY() + i);
 
}
 

	
 
static inline RailType UpdateRailType(RailType rt, RailType min)
 
{
 
	return rt >= min ? (RailType)(rt + 1): rt;
 
}
 

	
 
/**
 
 * Initialization of the windows and several kinds of caches.
 
 * This is not done directly in AfterLoadGame because these
 
 * functions require that all saveload conversions have been
 
 * done. As people tend to add savegame conversion stuff after
 
 * the intialization of the windows and caches quite some bugs
 
 * had been made.
 
 * Moving this out of there is both cleaner and less bug-prone.
 
 */
 
static void InitializeWindowsAndCaches()
 
{
 
	/* Initialize windows */
 
	ResetWindowSystem();
 
	SetupColoursAndInitialWindow();
 

	
 
	ResetViewportAfterLoadGame();
 

	
 
	/* Update coordinates of the signs. */
 
	UpdateAllStationVirtCoords();
 
	UpdateAllSignVirtCoords();
 
	UpdateAllTownVirtCoords();
 

	
 
	Company *c;
 
	FOR_ALL_COMPANIES(c) {
 
		/* For each company, verify (while loading a scenario) that the inauguration date is the current year and set it
 
		 * accordingly if it is not the case.  No need to set it on companies that are not been used already,
 
		 * thus the MIN_YEAR (which is really nothing more than Zero, initialized value) test */
 
		if (_file_to_saveload.filetype == FT_SCENARIO && c->inaugurated_year != MIN_YEAR) {
 
			c->inaugurated_year = _cur_year;
 
		}
 
	}
 

	
 
	RecomputePrices();
 

	
 
	SetCachedEngineCounts();
 

	
 
	Station::RecomputeIndustriesNearForAll();
 
	RebuildSubsidisedSourceAndDestinationCache();
 

	
 
	/* Towns have a noise controlled number of airports system
 
	 * So each airport's noise value must be added to the town->noise_reached value
 
	 * Reset each town's noise_reached value to '0' before. */
 
	UpdateAirportsNoise();
 

	
 
	CheckTrainsLengths();
 
}
 

	
 
typedef void (CDECL *SignalHandlerPointer)(int);
 
static SignalHandlerPointer _prev_segfault = NULL;
 
static SignalHandlerPointer _prev_abort    = NULL;
 
static SignalHandlerPointer _prev_fpe      = NULL;
 

	
 
static void CDECL HandleSavegameLoadCrash(int signum);
 

	
 
/**
 
 * Replaces signal handlers of SIGSEGV and SIGABRT
 
 * and stores pointers to original handlers in memory.
 
 */
 
static void SetSignalHandlers()
 
{
 
	_prev_segfault = signal(SIGSEGV, HandleSavegameLoadCrash);
 
	_prev_abort    = signal(SIGABRT, HandleSavegameLoadCrash);
 
	_prev_fpe      = signal(SIGFPE,  HandleSavegameLoadCrash);
 
}
 

	
 
/**
 
 * Resets signal handlers back to original handlers.
 
 */
 
static void ResetSignalHandlers()
 
{
 
	signal(SIGSEGV, _prev_segfault);
 
	signal(SIGABRT, _prev_abort);
 
	signal(SIGFPE,  _prev_fpe);
 
}
 

	
 
/**
 
 * Try to find the overridden GRF identifier of the given GRF.
 
 * @param c the GRF to get the 'previous' version of.
 
 * @return the GRF identifier or \a c if none could be found.
 
 */
 
static const GRFIdentifier *GetOverriddenIdentifier(const GRFConfig *c)
 
{
 
@@ -485,99 +487,96 @@ bool AfterLoadGame()
 
		/* the same applies to Company::location_of_HQ */
 
		Company *c;
 
		FOR_ALL_COMPANIES(c) {
 
			if (c->location_of_HQ == 0 || (CheckSavegameVersion(4) && c->location_of_HQ == 0xFFFF)) {
 
				c->location_of_HQ = INVALID_TILE;
 
			}
 
		}
 
	}
 

	
 
	/* convert road side to my format. */
 
	if (_settings_game.vehicle.road_side) _settings_game.vehicle.road_side = 1;
 

	
 
	/* Check if all NewGRFs are present, we are very strict in MP mode */
 
	GRFListCompatibility gcf_res = IsGoodGRFConfigList();
 
	if (_networking && gcf_res != GLC_ALL_GOOD) {
 
		SetSaveLoadError(STR_NETWORK_ERROR_CLIENT_NEWGRF_MISMATCH);
 
		/* Restore the signals */
 
		ResetSignalHandlers();
 
		return false;
 
	}
 

	
 
	switch (gcf_res) {
 
		case GLC_COMPATIBLE: _switch_mode_errorstr = STR_NEWGRF_COMPATIBLE_LOAD_WARNING; break;
 
		case GLC_NOT_FOUND:  _switch_mode_errorstr = STR_NEWGRF_DISABLED_WARNING; _pause_mode = PM_PAUSED_ERROR; break;
 
		default: break;
 
	}
 

	
 
	/* Update current year
 
	 * must be done before loading sprites as some newgrfs check it */
 
	SetDate(_date);
 

	
 
	/* Force dynamic engines off when loading older savegames */
 
	if (CheckSavegameVersion(95)) _settings_game.vehicle.dynamic_engines = 0;
 

	
 
	/* Load the sprites */
 
	GfxLoadSprites();
 
	LoadStringWidthTable();
 

	
 
	/* Copy temporary data to Engine pool */
 
	CopyTempEngineData();
 

	
 
	/* Connect front and rear engines of multiheaded trains and converts
 
	 * subtype to the new format */
 
	if (CheckSavegameVersionOldStyle(17, 1)) ConvertOldMultiheadToNew();
 

	
 
	/* Connect front and rear engines of multiheaded trains */
 
	ConnectMultiheadedTrains();
 

	
 
	/* reinit the landscape variables (landscape might have changed) */
 
	InitializeLandscapeVariables(true);
 

	
 
	/* Update all vehicles */
 
	AfterLoadVehicles(true);
 

	
 
	/* Make sure there is an AI attached to an AI company */
 
	{
 
		Company *c;
 
		FOR_ALL_COMPANIES(c) {
 
			if (c->is_ai && c->ai_instance == NULL) AI::StartNew(c->index);
 
		}
 
	}
 

	
 
	/* make sure there is a town in the game */
 
	if (_game_mode == GM_NORMAL && !ClosestTownFromTile(0, UINT_MAX)) {
 
		SetSaveLoadError(STR_ERROR_NO_TOWN_IN_SCENARIO);
 
		/* Restore the signals */
 
		ResetSignalHandlers();
 
		return false;
 
	}
 

	
 
	/* The void tiles on the southern border used to belong to a wrong class (pre 4.3).
 
	 * This problem appears in savegame version 21 too, see r3455. But after loading the
 
	 * savegame and saving again, the buggy map array could be converted to new savegame
 
	 * version. It didn't show up before r12070. */
 
	if (CheckSavegameVersion(87)) UpdateVoidTiles();
 

	
 
	/* If Load Scenario / New (Scenario) Game is used,
 
	 *  a company does not exist yet. So create one here.
 
	 * 1 exeption: network-games. Those can have 0 companies
 
	 *   But this exeption is not true for non dedicated network_servers! */
 
	if (!Company::IsValidID(COMPANY_FIRST) && (!_networking || (_networking && _network_server && !_network_dedicated)))
 
		DoStartupNewCompany(false);
 

	
 
	/* Fix the cache for cargo payments. */
 
	CargoPayment *cp;
 
	FOR_ALL_CARGO_PAYMENTS(cp) {
 
		cp->front->cargo_payment = cp;
 
		cp->current_station = cp->front->last_station_visited;
 
	}
 

	
 
	if (CheckSavegameVersion(72)) {
 
		/* Locks/shiplifts in very old savegames had OWNER_WATER as owner */
 
		for (TileIndex t = 0; t < MapSize(); t++) {
 
			switch (GetTileType(t)) {
 
				default: break;
 

	
 
				case MP_WATER:
 
					if (GetWaterTileType(t) == WATER_TILE_LOCK && GetTileOwner(t) == OWNER_WATER) SetTileOwner(t, OWNER_NONE);
 
					break;
 
@@ -1884,85 +1883,103 @@ bool AfterLoadGame()
 
			if (wp->facilities & FACIL_TRAIN) {
 
				wp->train_station.tile = wp->xy;
 
				wp->train_station.w = 1;
 
				wp->train_station.h = 1;
 
			} else {;
 
				wp->train_station.tile = INVALID_TILE;
 
				wp->train_station.w = 0;
 
				wp->train_station.h = 0;
 
			}
 
		}
 
	}
 

	
 
	if (CheckSavegameVersion(125)) {
 
		/* Convert old subsidies */
 
		Subsidy *s;
 
		FOR_ALL_SUBSIDIES(s) {
 
			/* Convert only nonawarded subsidies. The original source and destination town/industry
 
			 * can't be determined anymore for awarded subsidies, so invalidate them. */
 
			if (s->remaining < 12) {
 
				s->remaining = 12 - s->remaining; // convert "age" to "remaining"
 
				s->awarded = INVALID_COMPANY; // not awarded to anyone
 
				const CargoSpec *cs = CargoSpec::Get(s->cargo_type);
 
				switch (cs->town_effect) {
 
					case TE_PASSENGERS:
 
					case TE_MAIL:
 
						/* Town -> Town */
 
						s->src_type = s->dst_type = ST_TOWN;
 
						if (Town::IsValidID(s->src) && Town::IsValidID(s->dst)) continue;
 
						break;
 
					case TE_GOODS:
 
					case TE_FOOD:
 
						/* Industry -> Town */
 
						s->src_type = ST_INDUSTRY;
 
						s->dst_type = ST_TOWN;
 
						if (Industry::IsValidID(s->src) && Town::IsValidID(s->dst)) continue;
 
						break;
 
					default:
 
						/* Industry -> Industry */
 
						s->src_type = s->dst_type = ST_INDUSTRY;
 
						if (Industry::IsValidID(s->src) && Industry::IsValidID(s->dst)) continue;
 
						break;
 
				}
 
			}
 
			/* Awarded subsidy or invalid source/destination, invalidate */
 
			delete s;
 
		}
 
	}
 

	
 
	if (CheckSavegameVersion(126)) {
 
		/* Recompute inflation based on old unround loan limit
 
		 * Note: Max loan is 500000. With an inflation of 4% across 170 years
 
		 *       that results in a max loan of about 0.7 * 2^31.
 
		 *       So taking the 16 bit fractional part into account there are plenty of bits left
 
		 *       for unmodified savegames ...
 
		 */
 
		uint64 aimed_inflation = (_economy.old_max_loan_unround << 16 | _economy.old_max_loan_unround_fract) / _settings_game.difficulty.max_loan;
 

	
 
		/* ... well, just clamp it then. */
 
		if (aimed_inflation > MAX_INFLATION) aimed_inflation = MAX_INFLATION;
 

	
 
		/* Simulate the inflation, so we also get the payment inflation */
 
		while (_economy.inflation_prices < aimed_inflation) {
 
			AddInflation(false);
 
		}
 
	}
 

	
 
	AfterLoadLabelMaps();
 

	
 
	GamelogPrintDebug(1);
 

	
 
	InitializeWindowsAndCaches();
 
	/* Restore the signals */
 
	ResetSignalHandlers();
 
	return true;
 
}
 

	
 
/** Reload all NewGRF files during a running game. This is a cut-down
 
 * version of AfterLoadGame().
 
 * XXX - We need to reset the vehicle position hash because with a non-empty
 
 * hash AfterLoadVehicles() will loop infinitely. We need AfterLoadVehicles()
 
 * to recalculate vehicle data as some NewGRF vehicle sets could have been
 
 * removed or added and changed statistics */
 
void ReloadNewGRFData()
 
{
 
	/* reload grf data */
 
	GfxLoadSprites();
 
	LoadStringWidthTable();
 
	ResetEconomy();
 
	RecomputePrices();
 
	/* reload vehicles */
 
	ResetVehiclePosHash();
 
	AfterLoadVehicles(false);
 
	StartupEngines();
 
	SetCachedEngineCounts();
 
	/* update station graphics */
 
	AfterLoadStations();
 
	/* Check and update house and town values */
 
	UpdateHousesAndTowns();
 
	/* Update livery selection windows */
 
	for (CompanyID i = COMPANY_FIRST; i < MAX_COMPANIES; i++) InvalidateWindowData(WC_COMPANY_COLOUR, i);
 
	/* redraw the whole screen */
 
	MarkWholeScreenDirty();
 
	CheckTrainsLengths();
 
}