Changeset - r17772:ce3cc7016cdc
[Not reviewed]
projects/openttd_vs100.vcxproj
Show inline comments
 
@@ -719,48 +719,49 @@
 
    <ClCompile Include="..\src\saveload\cheat_sl.cpp" />
 
    <ClCompile Include="..\src\saveload\company_sl.cpp" />
 
    <ClCompile Include="..\src\saveload\depot_sl.cpp" />
 
    <ClCompile Include="..\src\saveload\economy_sl.cpp" />
 
    <ClCompile Include="..\src\saveload\engine_sl.cpp" />
 
    <ClCompile Include="..\src\saveload\gamelog_sl.cpp" />
 
    <ClCompile Include="..\src\saveload\group_sl.cpp" />
 
    <ClCompile Include="..\src\saveload\industry_sl.cpp" />
 
    <ClCompile Include="..\src\saveload\labelmaps_sl.cpp" />
 
    <ClCompile Include="..\src\saveload\map_sl.cpp" />
 
    <ClCompile Include="..\src\saveload\misc_sl.cpp" />
 
    <ClCompile Include="..\src\saveload\newgrf_sl.cpp" />
 
    <ClInclude Include="..\src\saveload\newgrf_sl.h" />
 
    <ClCompile Include="..\src\saveload\object_sl.cpp" />
 
    <ClCompile Include="..\src\saveload\oldloader.cpp" />
 
    <ClInclude Include="..\src\saveload\oldloader.h" />
 
    <ClCompile Include="..\src\saveload\oldloader_sl.cpp" />
 
    <ClCompile Include="..\src\saveload\order_sl.cpp" />
 
    <ClCompile Include="..\src\saveload\saveload.cpp" />
 
    <ClInclude Include="..\src\saveload\saveload.h" />
 
    <ClInclude Include="..\src\saveload\saveload_filter.h" />
 
    <ClInclude Include="..\src\saveload\saveload_internal.h" />
 
    <ClCompile Include="..\src\saveload\signs_sl.cpp" />
 
    <ClCompile Include="..\src\saveload\station_sl.cpp" />
 
    <ClCompile Include="..\src\saveload\storage_sl.cpp" />
 
    <ClCompile Include="..\src\saveload\strings_sl.cpp" />
 
    <ClCompile Include="..\src\saveload\subsidy_sl.cpp" />
 
    <ClCompile Include="..\src\saveload\town_sl.cpp" />
 
    <ClCompile Include="..\src\saveload\vehicle_sl.cpp" />
 
    <ClCompile Include="..\src\saveload\waypoint_sl.cpp" />
 
    <ClInclude Include="..\src\table\airport_defaults.h" />
 
    <ClInclude Include="..\src\table\airport_movement.h" />
 
    <ClInclude Include="..\src\table\airporttile_ids.h" />
 
    <ClInclude Include="..\src\table\airporttiles.h" />
 
    <ClInclude Include="..\src\table\animcursors.h" />
 
    <ClInclude Include="..\src\table\autorail.h" />
 
    <ClInclude Include="..\src\table\bridge_land.h" />
 
    <ClInclude Include="..\src\table\build_industry.h" />
 
    <ClInclude Include="..\src\table\cargo_const.h" />
 
    <ClInclude Include="..\src\table\clear_land.h" />
 
    <ClInclude Include="..\src\table\control_codes.h" />
 
    <ClInclude Include="..\src\table\elrail_data.h" />
 
    <ClInclude Include="..\src\table\engines.h" />
 
    <ClInclude Include="..\src\table\genland.h" />
 
    <ClInclude Include="..\src\table\industry_land.h" />
 
    <ClInclude Include="..\src\table\landscape_sprite.h" />
 
    <ClInclude Include="..\src\table\newgrf_debug_data.h" />
 
    <ClInclude Include="..\src\table\object_land.h" />
 
    <ClInclude Include="..\src\table\palette_convert.h" />
projects/openttd_vs100.vcxproj.filters
Show inline comments
 
@@ -1419,48 +1419,51 @@
 
    <ClCompile Include="..\src\saveload\oldloader_sl.cpp">
 
      <Filter>Save/Load handlers</Filter>
 
    </ClCompile>
 
    <ClCompile Include="..\src\saveload\order_sl.cpp">
 
      <Filter>Save/Load handlers</Filter>
 
    </ClCompile>
 
    <ClCompile Include="..\src\saveload\saveload.cpp">
 
      <Filter>Save/Load handlers</Filter>
 
    </ClCompile>
 
    <ClInclude Include="..\src\saveload\saveload.h">
 
      <Filter>Save/Load handlers</Filter>
 
    </ClInclude>
 
    <ClInclude Include="..\src\saveload\saveload_filter.h">
 
      <Filter>Save/Load handlers</Filter>
 
    </ClInclude>
 
    <ClInclude Include="..\src\saveload\saveload_internal.h">
 
      <Filter>Save/Load handlers</Filter>
 
    </ClInclude>
 
    <ClCompile Include="..\src\saveload\signs_sl.cpp">
 
      <Filter>Save/Load handlers</Filter>
 
    </ClCompile>
 
    <ClCompile Include="..\src\saveload\station_sl.cpp">
 
      <Filter>Save/Load handlers</Filter>
 
    </ClCompile>
 
    <ClCompile Include="..\src\saveload\storage_sl.cpp">
 
      <Filter>Save/Load handlers</Filter>
 
    </ClCompile>
 
    <ClCompile Include="..\src\saveload\strings_sl.cpp">
 
      <Filter>Save/Load handlers</Filter>
 
    </ClCompile>
 
    <ClCompile Include="..\src\saveload\subsidy_sl.cpp">
 
      <Filter>Save/Load handlers</Filter>
 
    </ClCompile>
 
    <ClCompile Include="..\src\saveload\town_sl.cpp">
 
      <Filter>Save/Load handlers</Filter>
 
    </ClCompile>
 
    <ClCompile Include="..\src\saveload\vehicle_sl.cpp">
 
      <Filter>Save/Load handlers</Filter>
 
    </ClCompile>
 
    <ClCompile Include="..\src\saveload\waypoint_sl.cpp">
 
      <Filter>Save/Load handlers</Filter>
 
    </ClCompile>
 
    <ClInclude Include="..\src\table\airport_defaults.h">
 
      <Filter>Tables</Filter>
 
    </ClInclude>
 
    <ClInclude Include="..\src\table\airport_movement.h">
 
      <Filter>Tables</Filter>
 
    </ClInclude>
 
    <ClInclude Include="..\src\table\airporttile_ids.h">
 
      <Filter>Tables</Filter>
 
    </ClInclude>
projects/openttd_vs80.vcproj
Show inline comments
 
@@ -2234,48 +2234,52 @@
 
				RelativePath=".\..\src\saveload\saveload.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\saveload\saveload.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\saveload\saveload_filter.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\saveload\saveload_internal.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\saveload\signs_sl.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\saveload\station_sl.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\saveload\storage_sl.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\saveload\strings_sl.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\saveload\subsidy_sl.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\saveload\town_sl.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\saveload\vehicle_sl.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\saveload\waypoint_sl.cpp"
 
				>
 
			</File>
 
		</Filter>
 
		<Filter
 
			Name="Tables"
 
			>
 
			<File
projects/openttd_vs90.vcproj
Show inline comments
 
@@ -2231,48 +2231,52 @@
 
				RelativePath=".\..\src\saveload\saveload.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\saveload\saveload.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\saveload\saveload_filter.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\saveload\saveload_internal.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\saveload\signs_sl.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\saveload\station_sl.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\saveload\storage_sl.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\saveload\strings_sl.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\saveload\subsidy_sl.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\saveload\town_sl.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\saveload\vehicle_sl.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\saveload\waypoint_sl.cpp"
 
				>
 
			</File>
 
		</Filter>
 
		<Filter
 
			Name="Tables"
 
			>
 
			<File
source.list
Show inline comments
 
@@ -477,48 +477,49 @@ saveload/cargopacket_sl.cpp
 
saveload/cheat_sl.cpp
 
saveload/company_sl.cpp
 
saveload/depot_sl.cpp
 
saveload/economy_sl.cpp
 
saveload/engine_sl.cpp
 
saveload/gamelog_sl.cpp
 
saveload/group_sl.cpp
 
saveload/industry_sl.cpp
 
saveload/labelmaps_sl.cpp
 
saveload/map_sl.cpp
 
saveload/misc_sl.cpp
 
saveload/newgrf_sl.cpp
 
saveload/newgrf_sl.h
 
saveload/object_sl.cpp
 
saveload/oldloader.cpp
 
saveload/oldloader.h
 
saveload/oldloader_sl.cpp
 
saveload/order_sl.cpp
 
saveload/saveload.cpp
 
saveload/saveload.h
 
saveload/saveload_filter.h
 
saveload/saveload_internal.h
 
saveload/signs_sl.cpp
 
saveload/station_sl.cpp
 
saveload/storage_sl.cpp
 
saveload/strings_sl.cpp
 
saveload/subsidy_sl.cpp
 
saveload/town_sl.cpp
 
saveload/vehicle_sl.cpp
 
saveload/waypoint_sl.cpp
 

	
 
# Tables
 
table/airport_defaults.h
 
table/airport_movement.h
 
table/airporttile_ids.h
 
table/airporttiles.h
 
table/animcursors.h
 
table/autorail.h
 
table/bridge_land.h
 
table/build_industry.h
 
table/cargo_const.h
 
table/clear_land.h
 
table/control_codes.h
 
table/elrail_data.h
 
table/engines.h
 
table/genland.h
 
table/industry_land.h
 
table/landscape_sprite.h
 
table/newgrf_debug_data.h
src/industry.h
Show inline comments
 
@@ -17,83 +17,81 @@
 
#include "subsidy_type.h"
 
#include "industry_map.h"
 
#include "tilearea_type.h"
 

	
 

	
 
typedef Pool<Industry, IndustryID, 64, 64000> IndustryPool;
 
extern IndustryPool _industry_pool;
 

	
 
/**
 
 * Production level maximum, minimum and default values.
 
 * It is not a value been really used in order to change, but rather an indicator
 
 * of how the industry is behaving.
 
 */
 
enum ProductionLevels {
 
	PRODLEVEL_CLOSURE = 0x00,  ///< signal set to actually close the industry
 
	PRODLEVEL_MINIMUM = 0x04,  ///< below this level, the industry is set to be closing
 
	PRODLEVEL_DEFAULT = 0x10,  ///< default level set when the industry is created
 
	PRODLEVEL_MAXIMUM = 0x80,  ///< the industry is running at full speed
 
};
 

	
 
/**
 
 * Defines the internal data of a functional industry.
 
 */
 
struct Industry : IndustryPool::PoolItem<&_industry_pool> {
 
	typedef PersistentStorageArray<int32, 16> PersistentStorage;
 

	
 
	TileArea location;                  ///< Location of the industry
 
	Town *town;                         ///< Nearest town
 
	CargoID produced_cargo[2];          ///< 2 production cargo slots
 
	uint16 produced_cargo_waiting[2];   ///< amount of cargo produced per cargo
 
	uint16 incoming_cargo_waiting[3];   ///< incoming cargo waiting to be processed
 
	byte production_rate[2];            ///< production rate for each cargo
 
	byte prod_level;                    ///< general production level
 
	CargoID accepts_cargo[3];           ///< 3 input cargo slots
 
	uint16 this_month_production[2];    ///< stats of this month's production per cargo
 
	uint16 this_month_transported[2];   ///< stats of this month's transport per cargo
 
	byte last_month_pct_transported[2]; ///< percentage transported per cargo in the last full month
 
	uint16 last_month_production[2];    ///< total units produced per cargo in the last full month
 
	uint16 last_month_transported[2];   ///< total units transported per cargo in the last full month
 
	uint16 counter;                     ///< used for animation and/or production (if available cargo)
 

	
 
	IndustryType type;                  ///< type of industry.
 
	OwnerByte owner;                    ///< owner of the industry.  Which SHOULD always be (imho) OWNER_NONE
 
	byte random_colour;                 ///< randomized colour of the industry, for display purpose
 
	Year last_prod_year;                ///< last year of production
 
	byte was_cargo_delivered;           ///< flag that indicate this has been the closest industry chosen for cargo delivery by a station. see DeliverGoodsToIndustry
 

	
 
	PartOfSubsidyByte part_of_subsidy;  ///< NOSAVE: is this industry a source/destination of a subsidy?
 

	
 
	OwnerByte founder;                  ///< Founder of the industry
 
	Date construction_date;             ///< Date of the construction of the industry
 
	uint8 construction_type;            ///< Way the industry was constructed (@see IndustryConstructionType)
 
	Date last_cargo_accepted_at;        ///< Last day cargo was accepted by this industry
 
	byte selected_layout;               ///< Which tile layout was used when creating the industry
 

	
 
	byte random_triggers;               ///< Triggers for the random
 
	uint16 random;                      ///< Random value used for randomisation of all kinds of things
 

	
 
	PersistentStorage psa;              ///< Persistent storage for NewGRF industries.
 
	PersistentStorage *psa;             ///< Persistent storage for NewGRF industries.
 

	
 
	Industry(TileIndex tile = INVALID_TILE) : location(tile, 0, 0) {}
 
	~Industry();
 

	
 
	void RecomputeProductionMultipliers();
 

	
 
	/**
 
	 * Get the industry of the given tile
 
	 * @param tile the tile to get the industry from
 
	 * @pre IsTileType(t, MP_INDUSTRY)
 
	 * @return the industry
 
	 */
 
	static FORCEINLINE Industry *GetByTile(TileIndex tile)
 
	{
 
		return Industry::Get(GetIndustryIndex(tile));
 
	}
 

	
 
	static Industry *GetRandom();
 
	static void PostDestructor(size_t index);
 

	
 
	/**
 
	 * Increment the count of industries for this type.
 
	 * @param type IndustryType to increment
 
	 * @pre type < NUM_INDUSTRYTYPES
src/industry_cmd.cpp
Show inline comments
 
@@ -146,48 +146,51 @@ Industry::~Industry()
 
				/* MakeWaterKeepingClass() can also handle 'land' */
 
				MakeWaterKeepingClass(tile_cur, OWNER_NONE);
 
			}
 
		} else if (IsTileType(tile_cur, MP_STATION) && IsOilRig(tile_cur)) {
 
			DeleteOilRig(tile_cur);
 
		}
 
	}
 

	
 
	if (GetIndustrySpec(this->type)->behaviour & INDUSTRYBEH_PLANT_FIELDS) {
 
		TileArea ta(this->location.tile - TileDiffXY(min(TileX(this->location.tile), 21), min(TileY(this->location.tile), 21)), 42, 42);
 
		ta.ClampToMap();
 

	
 
		/* Remove the farmland and convert it to regular tiles over time. */
 
		TILE_AREA_LOOP(tile_cur, ta) {
 
			if (IsTileType(tile_cur, MP_CLEAR) && IsClearGround(tile_cur, CLEAR_FIELDS) &&
 
					GetIndustryIndexOfField(tile_cur) == this->index) {
 
				SetIndustryIndexOfField(tile_cur, INVALID_INDUSTRY);
 
			}
 
		}
 
	}
 

	
 
	/* don't let any disaster vehicle target invalid industry */
 
	ReleaseDisastersTargetingIndustry(this->index);
 

	
 
	/* Clear the persistent storage. */
 
	delete this->psa;
 

	
 
	DecIndustryTypeCount(this->type);
 

	
 
	DeleteIndustryNews(this->index);
 
	DeleteWindowById(WC_INDUSTRY_VIEW, this->index);
 
	DeleteNewGRFInspectWindow(GSF_INDUSTRIES, this->index);
 

	
 
	DeleteSubsidyWith(ST_INDUSTRY, this->index);
 
	CargoPacket::InvalidateAllFrom(ST_INDUSTRY, this->index);
 
}
 

	
 
/**
 
 * Invalidating some stuff after removing item from the pool.
 
 * @param index index of deleted item
 
 */
 
void Industry::PostDestructor(size_t index)
 
{
 
	InvalidateWindowData(WC_INDUSTRY_DIRECTORY, 0, 0);
 
	Station::RecomputeIndustriesNearForAll();
 
}
 

	
 

	
 
/**
 
 * Return a random valid industry.
 
 * @return random industry, NULL if there are no industries
src/newgrf_airport.cpp
Show inline comments
 
@@ -128,94 +128,104 @@ void AirportOverrideManager::SetEntitySp
 
}
 

	
 
uint32 AirportGetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available)
 
{
 
	const Station *st = object->u.airport.st;
 
	byte layout       = object->u.airport.layout;
 

	
 
	if (object->scope == VSG_SCOPE_PARENT) {
 
		DEBUG(grf, 1, "Parent scope for airports unavailable");
 
		*available = false;
 
		return UINT_MAX;
 
	}
 

	
 
	switch (variable) {
 
		case 0x40: return layout;
 
	}
 

	
 
	if (st == NULL) {
 
		*available = false;
 
		return UINT_MAX;
 
	}
 

	
 
	switch (variable) {
 
		/* Get a variable from the persistent storage */
 
		case 0x7C: return st->airport.psa.GetValue(parameter);
 
		case 0x7C: return (st->airport.psa != NULL) ? st->airport.psa->GetValue(parameter) : 0;
 

	
 
		case 0xF0: return st->facilities;
 
		case 0xFA: return Clamp(st->build_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0, 65535);
 
	}
 

	
 
	return st->GetNewGRFVariable(object, variable, parameter, available);
 
}
 

	
 
static const SpriteGroup *AirportResolveReal(const ResolverObject *object, const RealSpriteGroup *group)
 
{
 
	/* Airport action 2s should always have only 1 "loaded" state, but some
 
	 * times things don't follow the spec... */
 
	if (group->num_loaded > 0) return group->loaded[0];
 
	if (group->num_loading > 0) return group->loading[0];
 

	
 
	return NULL;
 
}
 

	
 
static uint32 AirportGetRandomBits(const ResolverObject *object)
 
{
 
	const Station *st = object->u.airport.st;
 
	const TileIndex tile = object->u.airport.tile;
 
	return (st == NULL ? 0 : st->random_bits) | (tile == INVALID_TILE ? 0 : GetStationTileRandomBits(tile) << 16);
 
}
 

	
 
static uint32 AirportGetTriggers(const ResolverObject *object)
 
{
 
	return 0;
 
}
 

	
 
static void AirportSetTriggers(const ResolverObject *object, int triggers)
 
{
 
}
 

	
 
/**
 
 * Store a value into the object's persistent storage.
 
 * @param object Object that we want to query.
 
 * @param pos Position in the persistent storage to use.
 
 * @param value Value to store.
 
 */
 
void AirportStorePSA(ResolverObject *object, uint pos, int32 value)
 
{
 
	Station *st = object->u.airport.st;
 
	if (object->scope != VSG_SCOPE_SELF || st == NULL) return;
 
	st->airport.psa.StoreValue(pos, value);
 

	
 
	if (st->airport.psa == NULL) {
 
		/* There is no need to create a storage if the value is zero. */
 
		if (value == 0) return;
 

	
 
		/* Create storage on first modification. */
 
		uint32 grfid = (object->grffile != NULL) ? object->grffile->grfid : 0;
 
		assert(PersistentStorage::CanAllocateItem());
 
		st->airport.psa = new PersistentStorage(grfid);
 
	}
 
	st->airport.psa->StoreValue(pos, value);
 
}
 

	
 
static void NewAirportResolver(ResolverObject *res, TileIndex tile, Station *st, byte airport_id, byte layout)
 
{
 
	res->GetRandomBits = AirportGetRandomBits;
 
	res->GetTriggers   = AirportGetTriggers;
 
	res->SetTriggers   = AirportSetTriggers;
 
	res->GetVariable   = AirportGetVariable;
 
	res->ResolveReal   = AirportResolveReal;
 
	res->StorePSA      = AirportStorePSA;
 

	
 
	res->u.airport.st         = st;
 
	res->u.airport.airport_id = airport_id;
 
	res->u.airport.layout     = layout;
 
	res->u.airport.tile       = tile;
 

	
 
	res->callback        = CBID_NO_CALLBACK;
 
	res->callback_param1 = 0;
 
	res->callback_param2 = 0;
 
	res->last_value      = 0;
 
	res->trigger         = 0;
 
	res->reseed          = 0;
 
	res->count           = 0;
 

	
src/newgrf_debug_gui.cpp
Show inline comments
 
@@ -137,60 +137,60 @@ public:
 
	/**
 
	 * Set the string parameters to write the right data for a STRINGn.
 
	 * @param index the index to get the string parameters for.
 
	 */
 
	virtual void SetStringParameters(uint index) const = 0;
 

	
 
	/**
 
	 * Resolve (action2) variable for a given index.
 
	 * @param index The (instance) index to resolve the variable for.
 
	 * @param var   The variable to actually resolve.
 
	 * @param param The varaction2 0x60+x parameter to pass.
 
	 * @param avail Return whether the variable is available.
 
	 * @return The resolved variable's value.
 
	 */
 
	virtual uint Resolve(uint index, uint var, uint param, bool *avail) const
 
	{
 
		ResolverObject ro;
 
		memset(&ro, 0, sizeof(ro));
 
		this->Resolve(&ro, index);
 
		return ro.GetVariable(&ro, var, param, avail);
 
	}
 

	
 
	/**
 
	 * Allows to know the size of the persistent storage.
 
	 * @param index Unused.
 
	 * @param index Index of the item.
 
	 * @param grfid Unused.
 
	 * @return Size of the persistent storage in indices.
 
	 */
 
	virtual uint GetPSASize(uint index, uint32 grfid) const
 
	{
 
		return 0;
 
	}
 

	
 
	/**
 
	 * Gets the first position of the array containing the persistent storage.
 
	 * @param index Unused.
 
	 * @param index Index of the item.
 
	 * @param grfid Unused.
 
	 * @return Pointer to the first position of the storage array or NULL if not present.
 
	 */
 
	virtual int32 *GetPSAFirstPosition(uint index, uint32 grfid) const
 
	{
 
		return NULL;
 
	}
 

	
 
protected:
 
	/**
 
	 * Actually execute the real resolving for a given (instance) index.
 
	 * @param ro    The resolver object to fill with everything
 
	 *              needed to be able to resolve a variable.
 
	 * @param index The (instance) index of the to-be-resolved variable.
 
	 */
 
	virtual void Resolve(ResolverObject *ro, uint index) const {}
 

	
 
	/**
 
	 * Helper to make setting the strings easier.
 
	 * @param string the string to actually draw.
 
	 * @param index  the (instance) index for the string.
 
	 */
 
	void SetSimpleStringParameters(StringID string, uint32 index) const
 
	{
 
@@ -347,53 +347,53 @@ struct NewGRFInspectWindow : Window {
 
		uint index = GetFeatureIndex(this->window_number);
 
		const NIFeature *nif  = GetFeature(this->window_number);
 
		const NIHelper *nih   = nif->helper;
 
		const void *base      = nih->GetInstance(index);
 
		const void *base_spec = nih->GetSpec(index);
 

	
 
		uint i = 0;
 
		if (nif->variables != NULL) {
 
			this->DrawString(r, i++, "Variables:");
 
			for (const NIVariable *niv = nif->variables; niv->name != NULL; niv++) {
 
				bool avail = true;
 
				uint param = HasVariableParameter(niv->var) ? NewGRFInspectWindow::var60params[GetFeatureNum(this->window_number)][niv->var - 0x60] : 0;
 
				uint value = nih->Resolve(index, niv->var, param, &avail);
 

	
 
				if (!avail) continue;
 

	
 
				if (HasVariableParameter(niv->var)) {
 
					this->DrawString(r, i++, "  %02x[%02x]: %08x (%s)", niv->var, param, value, niv->name);
 
				} else {
 
					this->DrawString(r, i++, "  %02x: %08x (%s)", niv->var, value, niv->name);
 
				}
 
			}
 
		}
 

	
 
		uint psa_size = nih->GetPSASize(0, 0);
 
		if (psa_size != 0) {
 
		uint psa_size = nih->GetPSASize(index, 0);
 
		int32 *psa = nih->GetPSAFirstPosition(index, 0);
 
		if (psa_size != 0 && psa != NULL) {
 
			this->DrawString(r, i++, "Persistent storage:");
 
			assert(psa_size % 4 == 0);
 
			int32 *psa = nih->GetPSAFirstPosition(0, 0);
 
			for (uint j = 0; j < psa_size; j += 4, psa += 4) {
 
				this->DrawString(r, i++, "  %i: %i %i %i %i", j, psa[0], psa[1], psa[2], psa[3]);
 
			}
 
		}
 

	
 
		if (nif->properties != NULL) {
 
			this->DrawString(r, i++, "Properties:");
 
			for (const NIProperty *nip = nif->properties; nip->name != NULL; nip++) {
 
				void *ptr = (byte*)base + nip->offset;
 
				uint value;
 
				switch (nip->read_size) {
 
					case 1: value = *(uint8  *)ptr; break;
 
					case 2: value = *(uint16 *)ptr; break;
 
					case 4: value = *(uint32 *)ptr; break;
 
					default: NOT_REACHED();
 
				}
 

	
 
				StringID string;
 
				SetDParam(0, value);
 
				switch (nip->type) {
 
					case NIT_INT:
 
						string = STR_JUST_INT;
 
						break;
 

	
src/newgrf_industries.cpp
Show inline comments
 
@@ -262,49 +262,49 @@ uint32 IndustryGetVariable(const Resolve
 
			return 0xFFFFFFFF;
 

	
 
		/* Distance of nearest industry of given type */
 
		case 0x64: return GetClosestIndustry(tile, MapNewGRFIndustryType(parameter, indspec->grf_prop.grffile->grfid), industry);
 
		/* Get town zone and Manhattan distance of closest town */
 
		case 0x65: return GetTownRadiusGroup(industry->town, tile) << 16 | min(DistanceManhattan(tile, industry->town->xy), 0xFFFF);
 
		/* Get square of Euclidian distance of closes town */
 
		case 0x66: return GetTownRadiusGroup(industry->town, tile) << 16 | min(DistanceSquare(tile, industry->town->xy), 0xFFFF);
 

	
 
		/* Count of industry, distance of closest instance
 
		 * 68 is the same as 67, but with a filtering on selected layout */
 
		case 0x67:
 
		case 0x68: {
 
			byte layout_filter = 0;
 
			bool town_filter = false;
 
			if (variable == 0x68) {
 
				uint32 reg = GetRegister(0x101);
 
				layout_filter = GB(reg, 0, 8);
 
				town_filter = HasBit(reg, 8);
 
			}
 
			return GetCountAndDistanceOfClosestInstance(parameter, layout_filter, town_filter, industry);
 
		}
 

	
 
		/* Get a variable from the persistent storage */
 
		case 0x7C: return industry->psa.GetValue(parameter);
 
		case 0x7C: return (industry->psa != NULL) ? industry->psa->GetValue(parameter) : 0;
 

	
 
		/* Industry structure access*/
 
		case 0x80: return industry->location.tile;
 
		case 0x81: return GB(industry->location.tile, 8, 8);
 
		/* Pointer to the town the industry is associated with */
 
		case 0x82: return industry->town->index;
 
		case 0x83:
 
		case 0x84:
 
		case 0x85: DEBUG(grf, 0, "NewGRFs shouldn't be doing pointer magic"); break; // not supported
 
		case 0x86: return industry->location.w;
 
		case 0x87: return industry->location.h;// xy dimensions
 

	
 
		case 0x88:
 
		case 0x89: return industry->produced_cargo[variable - 0x88];
 
		case 0x8A: return industry->produced_cargo_waiting[0];
 
		case 0x8B: return GB(industry->produced_cargo_waiting[0], 8, 8);
 
		case 0x8C: return industry->produced_cargo_waiting[1];
 
		case 0x8D: return GB(industry->produced_cargo_waiting[1], 8, 8);
 
		case 0x8E:
 
		case 0x8F: return industry->production_rate[variable - 0x8E];
 
		case 0x90:
 
		case 0x91:
 
		case 0x92: return industry->accepts_cargo[variable - 0x90];
 
		case 0x93: return industry->prod_level;
 
@@ -365,49 +365,61 @@ static uint32 IndustryGetRandomBits(cons
 

	
 
static uint32 IndustryGetTriggers(const ResolverObject *object)
 
{
 
	const Industry *ind = object->u.industry.ind;
 
	return ind != NULL ? ind->random_triggers : 0;
 
}
 

	
 
static void IndustrySetTriggers(const ResolverObject *object, int triggers)
 
{
 
	Industry *ind = object->u.industry.ind;
 
	assert(ind != NULL && ind->index != INVALID_INDUSTRY);
 
	ind->random_triggers = triggers;
 
}
 

	
 
/**
 
 * Store a value into the object's persistent storage.
 
 * @param object Object that we want to query.
 
 * @param pos Position in the persistent storage to use.
 
 * @param value Value to store.
 
 */
 
void IndustryStorePSA(ResolverObject *object, uint pos, int32 value)
 
{
 
	Industry *ind = object->u.industry.ind;
 
	if (object->scope != VSG_SCOPE_SELF || ind->index == INVALID_INDUSTRY) return;
 
	ind->psa.StoreValue(pos, value);
 

	
 
	if (ind->psa == NULL) {
 
		/* There is no need to create a storage if the value is zero. */
 
		if (value == 0) return;
 

	
 
		/* Create storage on first modification. */
 
		const IndustrySpec *indsp = GetIndustrySpec(ind->type);
 
		uint32 grfid = (indsp->grf_prop.grffile != NULL) ? indsp->grf_prop.grffile->grfid : 0;
 
		assert(PersistentStorage::CanAllocateItem());
 
		ind->psa = new PersistentStorage(grfid);
 
	}
 

	
 
	ind->psa->StoreValue(pos, value);
 
}
 

	
 
static void NewIndustryResolver(ResolverObject *res, TileIndex tile, Industry *indus, IndustryType type)
 
{
 
	res->GetRandomBits = IndustryGetRandomBits;
 
	res->GetTriggers   = IndustryGetTriggers;
 
	res->SetTriggers   = IndustrySetTriggers;
 
	res->GetVariable   = IndustryGetVariable;
 
	res->ResolveReal   = IndustryResolveReal;
 
	res->StorePSA      = IndustryStorePSA;
 

	
 
	res->u.industry.tile = tile;
 
	res->u.industry.ind  = indus;
 
	res->u.industry.gfx  = INVALID_INDUSTRYTILE;
 
	res->u.industry.type = type;
 

	
 
	res->callback        = CBID_NO_CALLBACK;
 
	res->callback_param1 = 0;
 
	res->callback_param2 = 0;
 
	res->last_value      = 0;
 
	res->trigger         = 0;
 
	res->reseed          = 0;
 
	res->count           = 0;
 

	
src/newgrf_industrytiles.cpp
Show inline comments
 
@@ -137,49 +137,61 @@ static uint32 IndustryTileGetTriggers(co
 

	
 
static void IndustryTileSetTriggers(const ResolverObject *object, int triggers)
 
{
 
	const TileIndex tile = object->u.industry.tile;
 
	Industry *ind = object->u.industry.ind;
 
	assert(ind != NULL && ind->index != INVALID_INDUSTRY && IsValidTile(tile) && IsTileType(tile, MP_INDUSTRY));
 

	
 
	if (object->scope == VSG_SCOPE_SELF) {
 
		SetIndustryTriggers(tile, triggers);
 
	} else {
 
		ind->random_triggers = triggers;
 
	}
 
}
 

	
 
/**
 
 * Store a value into the persistent storage of the object's parent.
 
 * @param object Object that we want to query.
 
 * @param pos Position in the persistent storage to use.
 
 * @param value Value to store.
 
 */
 
void IndustryTileStorePSA(ResolverObject *object, uint pos, int32 value)
 
{
 
	Industry *ind = object->u.industry.ind;
 
	if (object->scope != VSG_SCOPE_PARENT || ind->index == INVALID_INDUSTRY) return;
 
	ind->psa.StoreValue(pos, value);
 

	
 
	if (ind->psa == NULL) {
 
		/* There is no need to create a storage if the value is zero. */
 
		if (value == 0) return;
 

	
 
		/* Create storage on first modification. */
 
		const IndustrySpec *indsp = GetIndustrySpec(ind->type);
 
		uint32 grfid = (indsp->grf_prop.grffile != NULL) ? indsp->grf_prop.grffile->grfid : 0;
 
		assert(PersistentStorage::CanAllocateItem());
 
		ind->psa = new PersistentStorage(grfid);
 
	}
 

	
 
	ind->psa->StoreValue(pos, value);
 
}
 

	
 
static void NewIndustryTileResolver(ResolverObject *res, IndustryGfx gfx, TileIndex tile, Industry *indus)
 
{
 
	res->GetRandomBits = IndustryTileGetRandomBits;
 
	res->GetTriggers   = IndustryTileGetTriggers;
 
	res->SetTriggers   = IndustryTileSetTriggers;
 
	res->GetVariable   = IndustryTileGetVariable;
 
	res->ResolveReal   = IndustryTileResolveReal;
 
	res->StorePSA      = IndustryTileStorePSA;
 

	
 
	res->u.industry.tile = tile;
 
	res->u.industry.ind  = indus;
 
	res->u.industry.gfx  = gfx;
 
	res->u.industry.type = indus->type;
 

	
 
	res->callback        = CBID_NO_CALLBACK;
 
	res->callback_param1 = 0;
 
	res->callback_param2 = 0;
 
	res->last_value      = 0;
 
	res->trigger         = 0;
 
	res->reseed          = 0;
 
	res->count           = 0;
 

	
src/newgrf_storage.cpp
Show inline comments
 
/* $Id$ */
 

	
 
/*
 
 * This file is part of OpenTTD.
 
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/** @file newgrf_storage.cpp Functionality related to the temporary and persistent storage arrays for NewGRFs. */
 

	
 
#include "stdafx.h"
 
#include "newgrf_storage.h"
 
#include "core/pool_func.hpp"
 
#include <set>
 

	
 
PersistentStoragePool _persistent_storage_pool("PersistentStorage");
 
INSTANTIATE_POOL_METHODS(PersistentStorage)
 

	
 
/** The changed storage arrays */
 
static std::set<BaseStorageArray*> _changed_storage_arrays;
 

	
 
/**
 
 * Remove references to use.
 
 */
 
BaseStorageArray::~BaseStorageArray()
 
{
 
	_changed_storage_arrays.erase(this);
 
}
 

	
 
/**
 
 * Add the changed storage array to the list of changed arrays.
 
 * This is done so we only have to revert/save the changed
 
 * arrays, which saves quite a few clears, etc. after callbacks.
 
 * @param storage the array that has changed
 
 */
 
void AddChangedStorage(BaseStorageArray *storage)
 
{
 
	_changed_storage_arrays.insert(storage);
 
}
 

	
 
/**
 
 * Clear the changes made since the last ClearStorageChanges.
src/newgrf_storage.h
Show inline comments
 
/* $Id$ */
 

	
 
/*
 
 * This file is part of OpenTTD.
 
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/** @file newgrf_storage.h Functionality related to the temporary and persistent storage arrays for NewGRFs. */
 

	
 
#ifndef NEWGRF_STORAGE_H
 
#define NEWGRF_STORAGE_H
 

	
 
#include "core/alloc_func.hpp"
 
#include "core/pool_type.hpp"
 

	
 
/**
 
 * Base class for all NewGRF storage arrays. Nothing fancy, only here
 
 * so we have a generalised class to use.
 
 */
 
struct BaseStorageArray
 
{
 
	virtual ~BaseStorageArray();
 

	
 
	/**
 
	 * Clear the changes made since the last ClearChanges.
 
	 * This can be done in two ways:
 
	 *  - saving the changes permanently
 
	 *  - reverting to the previous version
 
	 * @param keep_changes do we save or revert the changes since the last ClearChanges?
 
	 */
 
	virtual void ClearChanges(bool keep_changes) = 0;
 

	
 
	/**
 
	 * Stores some value at a given position.
 
	 * @param pos   the position to write at
 
	 * @param value the value to write
 
	 */
 
	virtual void StoreValue(uint pos, int32 value) = 0;
 
@@ -157,25 +158,61 @@ struct TemporaryStorageArray : BaseStora
 
	}
 

	
 
	/**
 
	 * Gets the value from a given position.
 
	 * @param pos the position to get the data from
 
	 * @return the data from that position
 
	 */
 
	TYPE GetValue(uint pos) const
 
	{
 
		/* Out of the scope of the array */
 
		if (pos >= SIZE) return 0;
 

	
 
		return this->storage[pos];
 
	}
 

	
 
	void ClearChanges(bool keep_changes)
 
	{
 
		memset(this->storage, 0, sizeof(this->storage));
 
	}
 
};
 

	
 
void AddChangedStorage(BaseStorageArray *storage);
 
void ClearStorageChanges(bool keep_changes);
 

	
 

	
 
typedef PersistentStorageArray<int32, 16> OldPersistentStorage;
 

	
 
typedef uint32 PersistentStorageID;
 

	
 
struct PersistentStorage;
 
typedef Pool<PersistentStorage, PersistentStorageID, 1, 0xFF000> PersistentStoragePool;
 

	
 
extern PersistentStoragePool _persistent_storage_pool;
 

	
 
/**
 
 * Class for pooled persistent storage of data.
 
 * On ClearChanges that data is always zero-ed.
 
 */
 
struct PersistentStorage : PersistentStorageArray<int32, 16>, PersistentStoragePool::PoolItem<&_persistent_storage_pool> {
 
	uint32 grfid; ///< GRFID associated to this persistent storage. A value of zero means "default".
 

	
 
	/** We don't want GCC to zero our struct! It already is zeroed and has an index! */
 
	PersistentStorage(const uint32 new_grfid) : grfid(new_grfid)
 
	{
 
		this->prev_storage = NULL;
 
		memset(this->storage, 0, sizeof(this->storage));
 
	}
 

	
 
	/** Free the memory used by the persistent storage. */
 
	~PersistentStorage()
 
	{
 
		free(this->prev_storage);
 
	}
 
};
 

	
 
assert_compile(cpp_lengthof(OldPersistentStorage, storage) == cpp_lengthof(PersistentStorage, storage));
 

	
 
#define FOR_ALL_STORAGES_FROM(var, start) FOR_ALL_ITEMS_FROM(PersistentStorage, storage_index, var, start)
 
#define FOR_ALL_STORAGES(var) FOR_ALL_STORAGES_FROM(var, 0)
 

	
 
#endif /* NEWGRF_STORAGE_H */
src/saveload/afterload.cpp
Show inline comments
 
@@ -2574,48 +2574,100 @@ bool AfterLoadGame()
 

	
 
	if (IsSavegameVersionBefore(159)) {
 
		/* If the savegame is old (before version 100), then the value of 255
 
		 * for these settings did not mean "disabled". As such everything
 
		 * before then did reverse.
 
		 * To simplify stuff we disable all turning around or we do not
 
		 * disable anything at all. So, if some reversing was disabled we
 
		 * will keep reversing disabled, otherwise it'll be turned on. */
 
		_settings_game.pf.reverse_at_signals = IsSavegameVersionBefore(100) || (_settings_game.pf.wait_oneway_signal != 255 && _settings_game.pf.wait_twoway_signal != 255 && _settings_game.pf.wait_for_pbs_path != 255);
 

	
 
		Train *t;
 
		FOR_ALL_TRAINS(t) {
 
			_settings_game.vehicle.max_train_length = max<uint8>(_settings_game.vehicle.max_train_length, CeilDiv(t->gcache.cached_total_length, TILE_SIZE));
 
		}
 
	}
 

	
 
	if (IsSavegameVersionBefore(160)) {
 
		/* Setting difficulty industry_density other than zero get bumped to +1
 
		 * since a new option (minimal at position 1) has been added */
 
		if (_settings_game.difficulty.industry_density > 0) {
 
			_settings_game.difficulty.industry_density++;
 
		}
 
	}
 

	
 
	if (IsSavegameVersionBefore(161)) {
 
		/* Before savegame version 161, persistent storages were not stored in a pool. */
 

	
 
		if (!IsSavegameVersionBefore(76)) {
 
			Industry *ind;
 
			FOR_ALL_INDUSTRIES(ind) {
 
				assert(ind->psa != NULL);
 

	
 
				/* Check if the old storage was empty. */
 
				bool is_empty = true;
 
				for (uint i = 0; i < sizeof(ind->psa->storage); i++) {
 
					if (ind->psa->GetValue(i) != 0) {
 
						is_empty = false;
 
						break;
 
					}
 
				}
 

	
 
				if (!is_empty) {
 
					ind->psa->grfid = _industry_mngr.GetGRFID(ind->type);
 
				} else {
 
					delete ind->psa;
 
					ind->psa = NULL;
 
				}
 
			}
 
		}
 

	
 
		if (!IsSavegameVersionBefore(145)) {
 
			Station *st;
 
			FOR_ALL_STATIONS(st) {
 
				if (!st->facilities & FACIL_AIRPORT) continue;
 
				assert(st->airport.psa != NULL);
 

	
 
				/* Check if the old storage was empty. */
 
				bool is_empty = true;
 
				for (uint i = 0; i < sizeof(st->airport.psa->storage); i++) {
 
					if (st->airport.psa->GetValue(i) != 0) {
 
						is_empty = false;
 
						break;
 
					}
 
				}
 

	
 
				if (!is_empty) {
 
					st->airport.psa->grfid = _airport_mngr.GetGRFID(st->airport.type);
 
				} else {
 
					delete st->airport.psa;
 
					st->airport.psa = NULL;
 

	
 
				}
 
			}
 
		}
 
	}
 

	
 
	/* Road stops is 'only' updating some caches */
 
	AfterLoadRoadStops();
 
	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();
src/saveload/industry_sl.cpp
Show inline comments
 
/* $Id$ */
 

	
 
/*
 
 * This file is part of OpenTTD.
 
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/** @file industry_sl.cpp Code handling saving and loading of industries */
 

	
 
#include "../stdafx.h"
 
#include "../industry.h"
 
#include "../newgrf.h"
 

	
 
#include "saveload.h"
 
#include "newgrf_sl.h"
 

	
 
static OldPersistentStorage _old_ind_persistent_storage;
 

	
 
static const SaveLoad _industry_desc[] = {
 
	SLE_CONDVAR(Industry, location.tile,              SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
 
	SLE_CONDVAR(Industry, location.tile,              SLE_UINT32,                  6, SL_MAX_VERSION),
 
	    SLE_VAR(Industry, location.w,                 SLE_FILE_U8 | SLE_VAR_U16),
 
	    SLE_VAR(Industry, location.h,                 SLE_FILE_U8 | SLE_VAR_U16),
 
	    SLE_REF(Industry, town,                       REF_TOWN),
 
	SLE_CONDNULL( 2, 0, 60),       ///< used to be industry's produced_cargo
 
	SLE_CONDARR(Industry, produced_cargo,             SLE_UINT8,  2,              78, SL_MAX_VERSION),
 
	SLE_CONDARR(Industry, incoming_cargo_waiting,     SLE_UINT16, 3,              70, SL_MAX_VERSION),
 
	    SLE_ARR(Industry, produced_cargo_waiting,     SLE_UINT16, 2),
 
	    SLE_ARR(Industry, production_rate,            SLE_UINT8,  2),
 
	SLE_CONDNULL( 3, 0, 60),       ///< used to be industry's accepts_cargo
 
	SLE_CONDARR(Industry, accepts_cargo,              SLE_UINT8,  3,              78, SL_MAX_VERSION),
 
	    SLE_VAR(Industry, prod_level,                 SLE_UINT8),
 
	    SLE_ARR(Industry, this_month_production,      SLE_UINT16, 2),
 
	    SLE_ARR(Industry, this_month_transported,     SLE_UINT16, 2),
 
	    SLE_ARR(Industry, last_month_pct_transported, SLE_UINT8,  2),
 
	    SLE_ARR(Industry, last_month_production,      SLE_UINT16, 2),
 
	    SLE_ARR(Industry, last_month_transported,     SLE_UINT16, 2),
 

	
 
	    SLE_VAR(Industry, counter,                    SLE_UINT16),
 

	
 
	    SLE_VAR(Industry, type,                       SLE_UINT8),
 
	    SLE_VAR(Industry, owner,                      SLE_UINT8),
 
	    SLE_VAR(Industry, random_colour,              SLE_UINT8),
 
	SLE_CONDVAR(Industry, last_prod_year,             SLE_FILE_U8 | SLE_VAR_I32,  0, 30),
 
	SLE_CONDVAR(Industry, last_prod_year,             SLE_INT32,                 31, SL_MAX_VERSION),
 
	    SLE_VAR(Industry, was_cargo_delivered,        SLE_UINT8),
 

	
 
	SLE_CONDVAR(Industry, founder,                    SLE_UINT8,                 70, SL_MAX_VERSION),
 
	SLE_CONDVAR(Industry, construction_date,          SLE_INT32,                 70, SL_MAX_VERSION),
 
	SLE_CONDVAR(Industry, construction_type,          SLE_UINT8,                 70, SL_MAX_VERSION),
 
	SLE_CONDVAR(Industry, last_cargo_accepted_at,     SLE_INT32,                 70, SL_MAX_VERSION),
 
	SLE_CONDVAR(Industry, selected_layout,            SLE_UINT8,                 73, SL_MAX_VERSION),
 

	
 
	SLE_CONDARR(Industry, psa.storage,                SLE_UINT32, 16,            76, SL_MAX_VERSION),
 
	SLEG_CONDARR(_old_ind_persistent_storage.storage, SLE_UINT32, 16,            76, 160),
 
	SLE_CONDREF(Industry, psa,                        REF_STORAGE,              161, SL_MAX_VERSION),
 

	
 
	SLE_CONDVAR(Industry, random_triggers,            SLE_UINT8,                 82, SL_MAX_VERSION),
 
	SLE_CONDVAR(Industry, random,                     SLE_UINT16,                82, SL_MAX_VERSION),
 

	
 
	SLE_CONDNULL(32, 2, 143), // old reserved space
 

	
 
	SLE_END()
 
};
 

	
 
static void Save_INDY()
 
{
 
	Industry *ind;
 

	
 
	/* Write the industries */
 
	FOR_ALL_INDUSTRIES(ind) {
 
		SlSetArrayIndex(ind->index);
 
		SlObject(ind, _industry_desc);
 
	}
 
}
 

	
 
static void Save_IIDS()
 
{
 
	Save_NewGRFMapping(_industry_mngr);
 
}
 

	
 
static void Save_TIDS()
 
{
 
	Save_NewGRFMapping(_industile_mngr);
 
}
 

	
 
static void Load_INDY()
 
{
 
	int index;
 

	
 
	Industry::ResetIndustryCounts();
 

	
 
	while ((index = SlIterateArray()) != -1) {
 
		Industry *i = new (index) Industry();
 
		SlObject(i, _industry_desc);
 

	
 
		/* Before savegame version 161, persistent storages were not stored in a pool. */
 
		if (IsSavegameVersionBefore(161) && !IsSavegameVersionBefore(76)) {
 
			/* Store the old persistent storage. The GRFID will be added later. */
 
			assert(PersistentStorage::CanAllocateItem());
 
			i->psa = new PersistentStorage(0);
 
			memcpy(i->psa->storage, _old_ind_persistent_storage.storage, sizeof(i->psa->storage));
 
		}
 
		Industry::IncIndustryTypeCount(i->type);
 
	}
 
}
 

	
 
static void Load_IIDS()
 
{
 
	Load_NewGRFMapping(_industry_mngr);
 
}
 

	
 
static void Load_TIDS()
 
{
 
	Load_NewGRFMapping(_industile_mngr);
 
}
 

	
 
static void Ptrs_INDY()
 
{
 
	Industry *i;
 

	
 
	FOR_ALL_INDUSTRIES(i) {
 
		SlObject(i, _industry_desc);
 
	}
 
}
 

	
 
/** Description of the data to save and load in #IndustryBuildData. */
src/saveload/saveload.cpp
Show inline comments
 
@@ -204,50 +204,51 @@
 
 *  137   18912
 
 *  138   18942   1.0.x
 
 *  139   19346
 
 *  140   19382
 
 *  141   19799
 
 *  142   20003
 
 *  143   20048
 
 *  144   20334
 
 *  145   20376
 
 *  146   20446
 
 *  147   20621
 
 *  148   20659
 
 *  149   20832
 
 *  150   20857
 
 *  151   20918
 
 *  152   21171
 
 *  153   21263
 
 *  154   21426
 
 *  155   21453
 
 *  156   21728
 
 *  157   21862
 
 *  158   21933
 
 *  159   21962
 
 *  160   21974
 
 *  161   22567
 
 */
 
extern const uint16 SAVEGAME_VERSION = 160; ///< Current savegame version of OpenTTD.
 
extern const uint16 SAVEGAME_VERSION = 161; ///< Current savegame version of OpenTTD.
 

	
 
SavegameType _savegame_type; ///< type of savegame we are loading
 

	
 
uint32 _ttdp_version;     ///< version of TTDP savegame (if applicable)
 
uint16 _sl_version;       ///< the major savegame version identifier
 
byte   _sl_minor_version; ///< the minor savegame version, DO NOT USE!
 
char _savegame_format[8]; ///< how to compress savegames
 
bool _do_autosave;        ///< are we doing an autosave at the moment?
 

	
 
/** What are we currently doing? */
 
enum SaveLoadAction {
 
	SLA_LOAD,        ///< loading
 
	SLA_SAVE,        ///< saving
 
	SLA_PTRS,        ///< fixing pointers
 
	SLA_NULL,        ///< null all pointers (on loading error)
 
	SLA_LOAD_CHECK,  ///< partial loading into #_load_check_data
 
};
 

	
 
enum NeedLength {
 
	NL_NONE = 0,       ///< not working in NeedLength mode
 
	NL_WANTLENGTH = 1, ///< writing length and data
 
	NL_CALCLENGTH = 2, ///< need to calculate the length
 
};
 

	
 
@@ -383,78 +384,80 @@ extern const ChunkHandler _misc_chunk_ha
 
extern const ChunkHandler _name_chunk_handlers[];
 
extern const ChunkHandler _cheat_chunk_handlers[] ;
 
extern const ChunkHandler _setting_chunk_handlers[];
 
extern const ChunkHandler _company_chunk_handlers[];
 
extern const ChunkHandler _engine_chunk_handlers[];
 
extern const ChunkHandler _veh_chunk_handlers[];
 
extern const ChunkHandler _waypoint_chunk_handlers[];
 
extern const ChunkHandler _depot_chunk_handlers[];
 
extern const ChunkHandler _order_chunk_handlers[];
 
extern const ChunkHandler _town_chunk_handlers[];
 
extern const ChunkHandler _sign_chunk_handlers[];
 
extern const ChunkHandler _station_chunk_handlers[];
 
extern const ChunkHandler _industry_chunk_handlers[];
 
extern const ChunkHandler _economy_chunk_handlers[];
 
extern const ChunkHandler _subsidy_chunk_handlers[];
 
extern const ChunkHandler _ai_chunk_handlers[];
 
extern const ChunkHandler _animated_tile_chunk_handlers[];
 
extern const ChunkHandler _newgrf_chunk_handlers[];
 
extern const ChunkHandler _group_chunk_handlers[];
 
extern const ChunkHandler _cargopacket_chunk_handlers[];
 
extern const ChunkHandler _autoreplace_chunk_handlers[];
 
extern const ChunkHandler _labelmaps_chunk_handlers[];
 
extern const ChunkHandler _airport_chunk_handlers[];
 
extern const ChunkHandler _object_chunk_handlers[];
 
extern const ChunkHandler _persistent_storage_chunk_handlers[];
 

	
 
/** Array of all chunks in a savegame, \c NULL terminated. */
 
static const ChunkHandler * const _chunk_handlers[] = {
 
	_gamelog_chunk_handlers,
 
	_map_chunk_handlers,
 
	_misc_chunk_handlers,
 
	_name_chunk_handlers,
 
	_cheat_chunk_handlers,
 
	_setting_chunk_handlers,
 
	_veh_chunk_handlers,
 
	_waypoint_chunk_handlers,
 
	_depot_chunk_handlers,
 
	_order_chunk_handlers,
 
	_industry_chunk_handlers,
 
	_economy_chunk_handlers,
 
	_subsidy_chunk_handlers,
 
	_engine_chunk_handlers,
 
	_town_chunk_handlers,
 
	_sign_chunk_handlers,
 
	_station_chunk_handlers,
 
	_company_chunk_handlers,
 
	_ai_chunk_handlers,
 
	_animated_tile_chunk_handlers,
 
	_newgrf_chunk_handlers,
 
	_group_chunk_handlers,
 
	_cargopacket_chunk_handlers,
 
	_autoreplace_chunk_handlers,
 
	_labelmaps_chunk_handlers,
 
	_airport_chunk_handlers,
 
	_object_chunk_handlers,
 
	_persistent_storage_chunk_handlers,
 
	NULL,
 
};
 

	
 
/**
 
 * Iterate over all chunk handlers.
 
 * @param ch the chunk handler iterator
 
 */
 
#define FOR_ALL_CHUNK_HANDLERS(ch) \
 
	for (const ChunkHandler * const *chsc = _chunk_handlers; *chsc != NULL; chsc++) \
 
		for (const ChunkHandler *ch = *chsc; ch != NULL; ch = (ch->flags & CH_LAST) ? NULL : ch + 1)
 

	
 
/** Null all pointers (convert index -> NULL) */
 
static void SlNullPointers()
 
{
 
	_sl.action = SLA_NULL;
 

	
 
	/* We don't want any savegame conversion code to run
 
	 * during NULLing; especially those that try to get
 
	 * pointers from other pools. */
 
	_sl_version = SAVEGAME_VERSION;
 

	
 
	DEBUG(sl, 1, "Nulling pointers");
 

	
 
	FOR_ALL_CHUNK_HANDLERS(ch) {
 
@@ -1152,51 +1155,52 @@ void SlArray(void *array, size_t length,
 

	
 
/**
 
 * Pointers cannot be saved to a savegame, so this functions gets
 
 * the index of the item, and if not available, it hussles with
 
 * pointers (looks really bad :()
 
 * Remember that a NULL item has value 0, and all
 
 * indices have +1, so vehicle 0 is saved as index 1.
 
 * @param obj The object that we want to get the index of
 
 * @param rt SLRefType type of the object the index is being sought of
 
 * @return Return the pointer converted to an index of the type pointed to
 
 */
 
static size_t ReferenceToInt(const void *obj, SLRefType rt)
 
{
 
	assert(_sl.action == SLA_SAVE);
 

	
 
	if (obj == NULL) return 0;
 

	
 
	switch (rt) {
 
		case REF_VEHICLE_OLD: // Old vehicles we save as new onces
 
		case REF_VEHICLE:   return ((const  Vehicle*)obj)->index + 1;
 
		case REF_STATION:   return ((const  Station*)obj)->index + 1;
 
		case REF_TOWN:      return ((const     Town*)obj)->index + 1;
 
		case REF_ORDER:     return ((const    Order*)obj)->index + 1;
 
		case REF_ROADSTOPS: return ((const RoadStop*)obj)->index + 1;
 
		case REF_ENGINE_RENEWS: return ((const EngineRenew*)obj)->index + 1;
 
		case REF_CARGO_PACKET:  return ((const CargoPacket*)obj)->index + 1;
 
		case REF_ORDERLIST:     return ((const   OrderList*)obj)->index + 1;
 
		case REF_ENGINE_RENEWS: return ((const       EngineRenew*)obj)->index + 1;
 
		case REF_CARGO_PACKET:  return ((const       CargoPacket*)obj)->index + 1;
 
		case REF_ORDERLIST:     return ((const         OrderList*)obj)->index + 1;
 
		case REF_STORAGE:       return ((const PersistentStorage*)obj)->index + 1;
 
		default: NOT_REACHED();
 
	}
 
}
 

	
 
/**
 
 * Pointers cannot be loaded from a savegame, so this function
 
 * gets the index from the savegame and returns the appropiate
 
 * pointer from the already loaded base.
 
 * Remember that an index of 0 is a NULL pointer so all indices
 
 * are +1 so vehicle 0 is saved as 1.
 
 * @param index The index that is being converted to a pointer
 
 * @param rt SLRefType type of the object the pointer is sought of
 
 * @return Return the index converted to a pointer of any type
 
 */
 
static void *IntToReference(size_t index, SLRefType rt)
 
{
 
	assert_compile(sizeof(size_t) <= sizeof(void *));
 

	
 
	assert(_sl.action == SLA_PTRS);
 

	
 
	/* After version 4.3 REF_VEHICLE_OLD is saved as REF_VEHICLE,
 
	 * and should be loaded like that */
 
	if (rt == REF_VEHICLE_OLD && !IsSavegameVersionBefore(4, 4)) {
 
		rt = REF_VEHICLE;
 
@@ -1224,48 +1228,52 @@ static void *IntToReference(size_t index
 
		case REF_VEHICLE:
 
			if (Vehicle::IsValidID(index)) return Vehicle::Get(index);
 
			SlErrorCorrupt("Referencing invalid Vehicle");
 

	
 
		case REF_STATION:
 
			if (Station::IsValidID(index)) return Station::Get(index);
 
			SlErrorCorrupt("Referencing invalid Station");
 

	
 
		case REF_TOWN:
 
			if (Town::IsValidID(index)) return Town::Get(index);
 
			SlErrorCorrupt("Referencing invalid Town");
 

	
 
		case REF_ROADSTOPS:
 
			if (RoadStop::IsValidID(index)) return RoadStop::Get(index);
 
			SlErrorCorrupt("Referencing invalid RoadStop");
 

	
 
		case REF_ENGINE_RENEWS:
 
			if (EngineRenew::IsValidID(index)) return EngineRenew::Get(index);
 
			SlErrorCorrupt("Referencing invalid EngineRenew");
 

	
 
		case REF_CARGO_PACKET:
 
			if (CargoPacket::IsValidID(index)) return CargoPacket::Get(index);
 
			SlErrorCorrupt("Referencing invalid CargoPacket");
 

	
 
		case REF_STORAGE:
 
			if (PersistentStorage::IsValidID(index)) return PersistentStorage::Get(index);
 
			SlErrorCorrupt("Referencing invalid PersistentStorage");
 

	
 
		default: NOT_REACHED();
 
	}
 
}
 

	
 
/**
 
 * Return the size in bytes of a list
 
 * @param list The std::list to find the size of
 
 */
 
static inline size_t SlCalcListLen(const void *list)
 
{
 
	std::list<void *> *l = (std::list<void *> *) list;
 

	
 
	int type_size = IsSavegameVersionBefore(69) ? 2 : 4;
 
	/* Each entry is saved as type_size bytes, plus type_size bytes are used for the length
 
	 * of the list */
 
	return l->size() * type_size + type_size;
 
}
 

	
 

	
 
/**
 
 * Save/Load a list.
 
 * @param list The list being manipulated
 
 * @param conv SLRefType type of the list (Vehicle *, Station *, etc)
 
 */
src/saveload/saveload.h
Show inline comments
 
@@ -67,48 +67,49 @@ typedef void AutolengthProc(void *arg);
 
struct ChunkHandler {
 
	uint32 id;                          ///< Unique ID (4 letters).
 
	ChunkSaveLoadProc *save_proc;       ///< Save procedure of the chunk.
 
	ChunkSaveLoadProc *load_proc;       ///< Load procedure of the chunk.
 
	ChunkSaveLoadProc *ptrs_proc;       ///< Manipulate pointers in the chunk.
 
	ChunkSaveLoadProc *load_check_proc; ///< Load procedure for game preview.
 
	uint32 flags;                       ///< Flags of the chunk. @see ChunkType
 
};
 

	
 
struct NullStruct {
 
	byte null;
 
};
 

	
 
/** Type of reference (#SLE_REF, #SLE_CONDREF). */
 
enum SLRefType {
 
	REF_ORDER         = 0, ///< Load/save a reference to an order.
 
	REF_VEHICLE       = 1, ///< Load/save a reference to a vehicle.
 
	REF_STATION       = 2, ///< Load/save a reference to a station.
 
	REF_TOWN          = 3, ///< Load/save a reference to a town.
 
	REF_VEHICLE_OLD   = 4, ///< Load/save an old-style reference to a vehicle (for pre-4.4 savegames).
 
	REF_ROADSTOPS     = 5, ///< Load/save a reference to a bus/truck stop.
 
	REF_ENGINE_RENEWS = 6, ///< Load/save a reference to an engine renewal (autoreplace).
 
	REF_CARGO_PACKET  = 7, ///< Load/save a reference to a cargo packet.
 
	REF_ORDERLIST     = 8, ///< Load/save a reference to an orderlist.
 
	REF_STORAGE       = 9, ///< Load/save a reference to a persistent storage.
 
};
 

	
 
/** Highest possible savegame version. */
 
#define SL_MAX_VERSION 255
 

	
 
/** Flags of a chunk. */
 
enum ChunkType {
 
	CH_RIFF         =  0,
 
	CH_ARRAY        =  1,
 
	CH_SPARSE_ARRAY =  2,
 
	CH_TYPE_MASK    =  3,
 
	CH_LAST         =  8, ///< Last chunk in this array.
 
	CH_AUTO_LENGTH  = 16,
 
};
 

	
 
/**
 
 * VarTypes is the general bitmasked magic type that tells us
 
 * certain characteristics about the variable it refers to. For example
 
 * SLE_FILE_* gives the size(type) as it would be in the savegame and
 
 * SLE_VAR_* the size(type) as it is in memory during runtime. These are
 
 * the first 8 bits (0-3 SLE_FILE, 4-7 SLE_VAR).
 
 * Bits 8-15 are reserved for various flags as explained below
 
 */
 
enum VarTypes {
src/saveload/station_sl.cpp
Show inline comments
 
/* $Id$ */
 

	
 
/*
 
 * This file is part of OpenTTD.
 
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/** @file station_sl.cpp Code handling saving and loading of stations. */
 

	
 
#include "../stdafx.h"
 
#include "../station_base.h"
 
#include "../waypoint_base.h"
 
#include "../roadstop_base.h"
 
#include "../vehicle_base.h"
 
#include "../newgrf_station.h"
 
#include "../newgrf.h"
 

	
 
#include "saveload.h"
 
#include "table/strings.h"
 

	
 
/**
 
 * Update the buoy orders to be waypoint orders.
 
 * @param o the order 'list' to check.
 
 */
 
static void UpdateWaypointOrder(Order *o)
 
{
 
	if (!o->IsType(OT_GOTO_STATION)) return;
 

	
 
	const Station *st = Station::Get(o->GetDestination());
 
	if ((st->had_vehicle_of_type & HVOT_WAYPOINT) == 0) return;
 

	
 
	o->MakeGoToWaypoint(o->GetDestination());
 
}
 

	
 
/**
 
 * Perform all steps to upgrade from the old station buoys to the new version
 
 * that uses waypoints. This includes some old saveload mechanics.
 
 */
 
void MoveBuoysToWaypoints()
 
{
 
@@ -323,67 +324,70 @@ static void Ptrs_STNS()
 
		}
 
		SlObject(st, _old_station_desc);
 
	}
 
}
 

	
 

	
 
static const SaveLoad _base_station_desc[] = {
 
	      SLE_VAR(BaseStation, xy,                     SLE_UINT32),
 
	      SLE_REF(BaseStation, town,                   REF_TOWN),
 
	      SLE_VAR(BaseStation, string_id,              SLE_STRINGID),
 
	      SLE_STR(BaseStation, name,                   SLE_STR, 0),
 
	      SLE_VAR(BaseStation, delete_ctr,             SLE_UINT8),
 
	      SLE_VAR(BaseStation, owner,                  SLE_UINT8),
 
	      SLE_VAR(BaseStation, facilities,             SLE_UINT8),
 
	      SLE_VAR(BaseStation, build_date,             SLE_INT32),
 

	
 
	/* Used by newstations for graphic variations */
 
	      SLE_VAR(BaseStation, random_bits,            SLE_UINT16),
 
	      SLE_VAR(BaseStation, waiting_triggers,       SLE_UINT8),
 
	      SLE_VAR(BaseStation, num_specs,              SLE_UINT8),
 

	
 
	      SLE_END()
 
};
 

	
 
static OldPersistentStorage _old_st_persistent_storage;
 

	
 
static const SaveLoad _station_desc[] = {
 
	SLE_WRITEBYTE(Station, facilities,                 FACIL_NONE),
 
	SLE_ST_INCLUDE(),
 

	
 
	      SLE_VAR(Station, train_station.tile,         SLE_UINT32),
 
	      SLE_VAR(Station, train_station.w,            SLE_FILE_U8 | SLE_VAR_U16),
 
	      SLE_VAR(Station, train_station.h,            SLE_FILE_U8 | SLE_VAR_U16),
 

	
 
	      SLE_REF(Station, bus_stops,                  REF_ROADSTOPS),
 
	      SLE_REF(Station, truck_stops,                REF_ROADSTOPS),
 
	      SLE_VAR(Station, dock_tile,                  SLE_UINT32),
 
	      SLE_VAR(Station, airport.tile,               SLE_UINT32),
 
	  SLE_CONDVAR(Station, airport.w,                  SLE_FILE_U8 | SLE_VAR_U16, 140, SL_MAX_VERSION),
 
	  SLE_CONDVAR(Station, airport.h,                  SLE_FILE_U8 | SLE_VAR_U16, 140, SL_MAX_VERSION),
 
	      SLE_VAR(Station, airport.type,               SLE_UINT8),
 
	  SLE_CONDVAR(Station, airport.layout,             SLE_UINT8,                 145, SL_MAX_VERSION),
 
	      SLE_VAR(Station, airport.flags,              SLE_UINT64),
 
	  SLE_CONDVAR(Station, airport.rotation,           SLE_UINT8,                 145, SL_MAX_VERSION),
 
	  SLE_CONDARR(Station, airport.psa.storage,        SLE_UINT32, 16,            145, SL_MAX_VERSION),
 
	 SLEG_CONDARR(_old_st_persistent_storage.storage,  SLE_UINT32, 16,            145, 160),
 
	  SLE_CONDREF(Station, airport.psa,                REF_STORAGE,               161, SL_MAX_VERSION),
 

	
 
	      SLE_VAR(Station, indtype,                    SLE_UINT8),
 

	
 
	      SLE_VAR(Station, time_since_load,            SLE_UINT8),
 
	      SLE_VAR(Station, time_since_unload,          SLE_UINT8),
 
	      SLE_VAR(Station, last_vehicle_type,          SLE_UINT8),
 
	      SLE_VAR(Station, had_vehicle_of_type,        SLE_UINT8),
 
	      SLE_LST(Station, loading_vehicles,           REF_VEHICLE),
 
	  SLE_CONDVAR(Station, always_accepted,            SLE_UINT32, 127, SL_MAX_VERSION),
 

	
 
	      SLE_END()
 
};
 

	
 
static const SaveLoad _waypoint_desc[] = {
 
	SLE_WRITEBYTE(Waypoint, facilities,                FACIL_WAYPOINT),
 
	SLE_ST_INCLUDE(),
 

	
 
	      SLE_VAR(Waypoint, town_cn,                   SLE_UINT16),
 

	
 
	  SLE_CONDVAR(Waypoint, train_station.tile,        SLE_UINT32,                  124, SL_MAX_VERSION),
 
	  SLE_CONDVAR(Waypoint, train_station.w,           SLE_FILE_U8 | SLE_VAR_U16,   124, SL_MAX_VERSION),
 
	  SLE_CONDVAR(Waypoint, train_station.h,           SLE_FILE_U8 | SLE_VAR_U16,   124, SL_MAX_VERSION),
 

	
 
	      SLE_END()
 
@@ -416,48 +420,57 @@ static void RealSave_STNN(BaseStation *b
 
}
 

	
 
static void Save_STNN()
 
{
 
	BaseStation *st;
 
	/* Write the stations */
 
	FOR_ALL_BASE_STATIONS(st) {
 
		SlSetArrayIndex(st->index);
 
		SlAutolength((AutolengthProc*)RealSave_STNN, st);
 
	}
 
}
 

	
 
static void Load_STNN()
 
{
 
	int index;
 

	
 
	while ((index = SlIterateArray()) != -1) {
 
		bool waypoint = (SlReadByte() & FACIL_WAYPOINT) != 0;
 

	
 
		BaseStation *bst = waypoint ? (BaseStation *)new (index) Waypoint() : new (index) Station();
 
		SlObject(bst, waypoint ? _waypoint_desc : _station_desc);
 

	
 
		if (!waypoint) {
 
			Station *st = Station::From(bst);
 

	
 
			/* Before savegame version 161, persistent storages were not stored in a pool. */
 
			if (IsSavegameVersionBefore(161) && !IsSavegameVersionBefore(145) && st->facilities & FACIL_AIRPORT) {
 
				/* Store the old persistent storage. The GRFID will be added later. */
 
				assert(PersistentStorage::CanAllocateItem());
 
				st->airport.psa = new PersistentStorage(0);
 
				memcpy(st->airport.psa->storage, _old_st_persistent_storage.storage, sizeof(st->airport.psa->storage));
 
			}
 

	
 
			for (CargoID i = 0; i < NUM_CARGO; i++) {
 
				SlObject(&st->goods[i], GetGoodsDesc());
 
			}
 
		}
 

	
 
		if (bst->num_specs != 0) {
 
			/* Allocate speclist memory when loading a game */
 
			bst->speclist = CallocT<StationSpecList>(bst->num_specs);
 
			for (uint i = 0; i < bst->num_specs; i++) {
 
				SlObject(&bst->speclist[i], _station_speclist_desc);
 
			}
 
		}
 
	}
 
}
 

	
 
static void Ptrs_STNN()
 
{
 
	/* Don't run when savegame version lower than 123. */
 
	if (IsSavegameVersionBefore(123)) return;
 

	
 
	Station *st;
 
	FOR_ALL_STATIONS(st) {
 
		for (CargoID i = 0; i < NUM_CARGO; i++) {
 
			GoodsEntry *ge = &st->goods[i];
src/saveload/storage_sl.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/*
 
 * This file is part of OpenTTD.
 
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/** @file persistent_storage_sl.cpp Code handling saving and loading of persistent storages. */
 

	
 
#include "../stdafx.h"
 
#include "../newgrf_storage.h"
 
#include "saveload.h"
 

	
 
/** Description of the data to save and load in #PersistentStorage. */
 
static const SaveLoad _storage_desc[] = {
 
	 SLE_CONDVAR(PersistentStorage, grfid,    SLE_UINT32,                  6, SL_MAX_VERSION),
 
	 SLE_CONDARR(PersistentStorage, storage,  SLE_UINT32, 16,            161, SL_MAX_VERSION),
 
	 SLE_END()
 
};
 

	
 
/** Load persistent storage data. */
 
static void Load_PSAC()
 
{
 
	int index;
 

	
 
	while ((index = SlIterateArray()) != -1) {
 
		assert(PersistentStorage::CanAllocateItem());
 
		PersistentStorage *ps = new (index) PersistentStorage(0);
 
		SlObject(ps, _storage_desc);
 
	}
 
}
 

	
 
/** Save persistent storage data. */
 
static void Save_PSAC()
 
{
 
	PersistentStorage *ps;
 

	
 
	/* Write the industries */
 
	FOR_ALL_STORAGES(ps) {
 
		SlSetArrayIndex(ps->index);
 
		SlObject(ps, _storage_desc);
 
	}
 
}
 

	
 
/** Chunk handler for persistent storages. */
 
extern const ChunkHandler _persistent_storage_chunk_handlers[] = {
 
	{ 'PSAC', Save_PSAC, Load_PSAC, NULL, NULL, CH_ARRAY | CH_LAST},
 
};
src/station.cpp
Show inline comments
 
@@ -75,48 +75,52 @@ Station::~Station()
 
		for (CargoID c = 0; c < NUM_CARGO; c++) {
 
			this->goods[c].cargo.OnCleanPool();
 
		}
 
		return;
 
	}
 

	
 
	while (!this->loading_vehicles.empty()) {
 
		this->loading_vehicles.front()->LeaveStation();
 
	}
 

	
 
	Aircraft *a;
 
	FOR_ALL_AIRCRAFT(a) {
 
		if (!a->IsNormalAircraft()) continue;
 
		if (a->targetairport == this->index) a->targetairport = INVALID_STATION;
 
	}
 

	
 
	Vehicle *v;
 
	FOR_ALL_VEHICLES(v) {
 
		/* Forget about this station if this station is removed */
 
		if (v->last_station_visited == this->index) {
 
			v->last_station_visited = INVALID_STATION;
 
		}
 
	}
 

	
 
	/* Clear the persistent storage. */
 
	delete this->airport.psa;
 

	
 

	
 
	InvalidateWindowData(WC_STATION_LIST, this->owner, 0);
 

	
 
	DeleteWindowById(WC_STATION_VIEW, index);
 

	
 
	/* Now delete all orders that go to the station */
 
	RemoveOrderFromAllVehicles(OT_GOTO_STATION, this->index);
 

	
 
	/* Remove all news items */
 
	DeleteStationNews(this->index);
 

	
 
	for (CargoID c = 0; c < NUM_CARGO; c++) {
 
		this->goods[c].cargo.Truncate(0);
 
	}
 

	
 
	CargoPacket::InvalidateAllFrom(this->index);
 
}
 

	
 

	
 
/**
 
 * Invalidating of the JoinStation window has to be done
 
 * after removing item from the pool.
 
 * @param index index of deleted item
 
 */
 
void BaseStation::PostDestructor(size_t index)
src/station_base.h
Show inline comments
 
@@ -35,57 +35,56 @@ struct GoodsEntry {
 
		GES_LAST_MONTH,       ///< The cargo was accepted last month.
 
		GES_CURRENT_MONTH,    ///< The cargo was accepted this month.
 
		GES_ACCEPTED_BIGTICK, ///< The cargo has been accepted since the last periodic processing.
 
	};
 

	
 
	GoodsEntry() :
 
		acceptance_pickup(0),
 
		days_since_pickup(255),
 
		rating(INITIAL_STATION_RATING),
 
		last_speed(0),
 
		last_age(255)
 
	{}
 

	
 
	byte acceptance_pickup; ///< Status of this cargo, see #GoodsEntryStatus.
 
	byte days_since_pickup; ///< Number of days since the last pickup for this cargo (up to 255).
 
	byte rating;            ///< Station rating for this cargo.
 
	byte last_speed;        ///< Maximum speed of the last vehicle that picked up this cargo (up to 255).
 
	byte last_age;          ///< Age in years of the last vehicle that picked up this cargo.
 
	byte amount_fract;      ///< Fractional part of the amount in the cargo list
 
	StationCargoList cargo; ///< The cargo packets of cargo waiting in this station
 
};
 

	
 
/** All airport-related information. Only valid if tile != INVALID_TILE. */
 
struct Airport : public TileArea {
 
	typedef PersistentStorageArray<int32, 16> PersistentStorage;
 

	
 
	Airport() : TileArea(INVALID_TILE, 0, 0) {}
 

	
 
	uint64 flags;       ///< stores which blocks on the airport are taken. was 16 bit earlier on, then 32
 
	byte type;          ///< Type of this airport, @see AirportTypes.
 
	byte layout;        ///< Airport layout number.
 
	Direction rotation; ///< How this airport is rotated.
 
	PersistentStorage psa; ///< Persistent storage for NewGRF airports
 

	
 
	PersistentStorage *psa; ///< Persistent storage for NewGRF airports.
 

	
 
	/**
 
	 * Get the AirportSpec that from the airport type of this airport. If there
 
	 * is no airport (\c tile == INVALID_TILE) then return the dummy AirportSpec.
 
	 * @return The AirportSpec for this airport.
 
	 */
 
	const AirportSpec *GetSpec() const
 
	{
 
		if (this->tile == INVALID_TILE) return &AirportSpec::dummy;
 
		return AirportSpec::Get(this->type);
 
	}
 

	
 
	/**
 
	 * Get the finite-state machine for this airport or the finite-state machine
 
	 * for the dummy airport in case this isn't an airport.
 
	 * @pre this->type < NEW_AIRPORT_OFFSET.
 
	 * @return The state machine for this airport.
 
	 */
 
	const AirportFTAClass *GetFTA() const
 
	{
 
		return this->GetSpec()->fsm;
 
	}
 

	
 
	/** Check if this airport has at least one hangar. */
src/station_cmd.cpp
Show inline comments
 
@@ -2170,49 +2170,48 @@ CommandCost CmdBuildAirport(TileIndex ti
 

	
 
			st->town = t;
 
			st->string_id = GenerateStationName(st, tile, !(GetAirport(airport_type)->flags & AirportFTAClass::AIRPLANES) ? STATIONNAMING_HELIPORT : STATIONNAMING_AIRPORT);
 

	
 
			if (Company::IsValidID(_current_company)) {
 
				SetBit(st->town->have_ratings, _current_company);
 
			}
 
		}
 
	}
 

	
 
	const AirportTileTable *it = as->table[layout];
 
	do {
 
		cost.AddCost(_price[PR_BUILD_STATION_AIRPORT]);
 
	} while ((++it)->ti.x != -0x80);
 

	
 
	if (flags & DC_EXEC) {
 
		/* Always add the noise, so there will be no need to recalculate when option toggles */
 
		nearest->noise_reached += newnoise_level;
 

	
 
		st->AddFacility(FACIL_AIRPORT, tile);
 
		st->airport.type = airport_type;
 
		st->airport.layout = layout;
 
		st->airport.flags = 0;
 
		st->airport.rotation = rotation;
 
		st->airport.psa.ResetToZero();
 

	
 
		st->rect.BeforeAddRect(tile, w, h, StationRect::ADD_TRY);
 

	
 
		it = as->table[layout];
 
		do {
 
			TileIndex cur_tile = tile + ToTileIndexDiff(it->ti);
 
			MakeAirport(cur_tile, st->owner, st->index, it->gfx, WATER_CLASS_INVALID);
 
			SetStationTileRandomBits(cur_tile, GB(Random(), 0, 4));
 
			st->airport.Add(cur_tile);
 

	
 
			if (AirportTileSpec::Get(GetTranslatedAirportTileID(it->gfx))->animation.status != ANIM_STATUS_NO_ANIMATION) AddAnimatedTile(cur_tile);
 
		} while ((++it)->ti.x != -0x80);
 

	
 
		/* Only call the animation trigger after all tiles have been built */
 
		it = as->table[layout];
 
		do {
 
			TileIndex cur_tile = tile + ToTileIndexDiff(it->ti);
 
			AirportTileAnimationTrigger(st, cur_tile, AAT_BUILT);
 
		} while ((++it)->ti.x != -0x80);
 

	
 
		UpdateAirplanesOnNewStation(st);
 

	
 
		st->UpdateVirtCoord();
 
		UpdateStationAcceptance(st, false);
 
@@ -2250,66 +2249,68 @@ static CommandCost RemoveAirport(TileInd
 

	
 
	const Aircraft *a;
 
	FOR_ALL_AIRCRAFT(a) {
 
		if (!a->IsNormalAircraft()) continue;
 
		if (a->targetairport == st->index && a->state != FLYING) return CMD_ERROR;
 
	}
 

	
 
	TILE_AREA_LOOP(tile_cur, st->airport) {
 
		if (!st->TileBelongsToAirport(tile_cur)) continue;
 

	
 
		CommandCost ret = EnsureNoVehicleOnGround(tile_cur);
 
		if (ret.Failed()) return ret;
 

	
 
		cost.AddCost(_price[PR_CLEAR_STATION_AIRPORT]);
 

	
 
		if (flags & DC_EXEC) {
 
			if (IsHangarTile(tile_cur)) OrderBackup::Reset(tile_cur, false);
 
			DeleteAnimatedTile(tile_cur);
 
			DoClearSquare(tile_cur);
 
			DeleteNewGRFInspectWindow(GSF_AIRPORTTILES, tile_cur);
 
		}
 
	}
 

	
 
	if (flags & DC_EXEC) {
 
		/* Clear the persistent storage. */
 
		delete st->airport.psa;
 

	
 
		const AirportSpec *as = st->airport.GetSpec();
 
		for (uint i = 0; i < st->airport.GetNumHangars(); ++i) {
 
			DeleteWindowById(
 
				WC_VEHICLE_DEPOT, st->airport.GetHangarTile(i)
 
			);
 
		}
 

	
 
		/* 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
 
		 * need of recalculation */
 
		Town *nearest = AirportGetNearestTown(as, tile);
 
		nearest->noise_reached -= GetAirportNoiseLevelForTown(as, nearest->xy, tile);
 

	
 
		st->rect.AfterRemoveRect(st, st->airport);
 

	
 
		st->airport.Clear();
 
		st->facilities &= ~FACIL_AIRPORT;
 
		st->airport.psa.ResetToZero();
 

	
 
		SetWindowWidgetDirty(WC_STATION_VIEW, st->index, SVW_PLANES);
 

	
 
		if (_settings_game.economy.station_noise_level) {
 
			SetWindowDirty(WC_TOWN_VIEW, st->town->index);
 
		}
 

	
 
		st->UpdateVirtCoord();
 
		st->RecomputeIndustriesNear();
 
		DeleteStationIfEmpty(st);
 
		DeleteNewGRFInspectWindow(GSF_AIRPORTS, st->index);
 
	}
 

	
 
	return cost;
 
}
 

	
 
/**
 
 * Tests whether the company's vehicles have this station in orders
 
 * @param station station ID
 
 * @param include_company If true only check vehicles of \a company, if false only check vehicles of other companies
 
 * @param company company ID
 
 */
 
bool HasStationInUse(StationID station, bool include_company, CompanyID company)
 
{
src/table/newgrf_debug_data.h
Show inline comments
 
@@ -270,54 +270,55 @@ static const NIVariable _niv_industries[
 
	NIV(0x42, "waiting cargo 2"),
 
	NIV(0x43, "distance to closest dry/land tile"),
 
	NIV(0x44, "layout number"),
 
	NIV(0x45, "player info"),
 
	NIV(0x46, "industry construction date"),
 
	NIV(0x60, "get industry tile ID at offset"),
 
	NIV(0x61, "get random tile bits at offset"),
 
	NIV(0x62, "land info of nearby tiles"),
 
	NIV(0x63, "animation stage of nearby tiles"),
 
	NIV(0x64, "distance on nearest industry with given type"),
 
	NIV(0x65, "get town zone and Manhattan distance of closest town"),
 
	NIV(0x66, "get square of Euclidean distance of closes town"),
 
	NIV(0x67, "count of industry and distance of closest instance"),
 
	NIV(0x68, "count of industry and distance of closest instance with layout filter"),
 
	NIV_END()
 
};
 

	
 
class NIHIndustry : public NIHelper {
 
	bool IsInspectable(uint index) const                 { return GetIndustrySpec(Industry::Get(index)->type)->grf_prop.grffile != NULL; }
 
	uint GetParent(uint index) const                     { return GetInspectWindowNumber(GSF_FAKE_TOWNS, Industry::Get(index)->town->index); }
 
	const void *GetInstance(uint index)const             { return Industry::Get(index); }
 
	const void *GetSpec(uint index) const                { return GetIndustrySpec(Industry::Get(index)->type); }
 
	void SetStringParameters(uint index) const           { this->SetSimpleStringParameters(STR_INDUSTRY_NAME, index); }
 
	void Resolve(ResolverObject *ro, uint32 index) const { extern void GetIndustryResolver(ResolverObject *ro, uint index); GetIndustryResolver(ro, index); }
 
	uint GetPSASize(uint index, uint32 grfid) const      { return cpp_lengthof(Industry, psa.storage); }
 
	uint GetPSASize(uint index, uint32 grfid) const      { return cpp_lengthof(PersistentStorage, storage); }
 

	
 
	int32 *GetPSAFirstPosition(uint index, uint32 grfid) const
 
	{
 
		const void *base = this->GetInstance(index);
 
		return (int32*)((byte*)base + cpp_offsetof(Industry, psa.storage));
 
		Industry *i = (Industry *)this->GetInstance(index);
 
		if (i->psa == NULL) return NULL;
 
		return (int32 *)(&i->psa->storage);
 
	}
 
};
 

	
 
static const NIFeature _nif_industry = {
 
	_nip_industries,
 
	_nic_industries,
 
	_niv_industries,
 
	new NIHIndustry(),
 
};
 

	
 

	
 
/*** NewGRF objects ***/
 

	
 
#define NICO(cb_id, bit) NIC(cb_id, ObjectSpec, callback_mask, bit)
 
static const NICallback _nic_objects[] = {
 
	NICO(CBID_OBJECT_LAND_SLOPE_CHECK,     CBM_OBJ_SLOPE_CHECK),
 
	NICO(CBID_OBJECT_ANIMATION_NEXT_FRAME, CBM_OBJ_ANIMATION_NEXT_FRAME),
 
	NICO(CBID_OBJECT_ANIMATION_START_STOP, CBM_NO_BIT),
 
	NICO(CBID_OBJECT_ANIMATION_SPEED,      CBM_OBJ_ANIMATION_SPEED),
 
	NICO(CBID_OBJECT_COLOUR,               CBM_OBJ_COLOUR),
 
	NICO(CBID_OBJECT_FUND_MORE_TEXT,       CBM_OBJ_FUND_MORE_TEXT),
 
	NICO(CBID_OBJECT_AUTOSLOPE,            CBM_OBJ_AUTOSLOPE),
 
	NIC_END()
 
};
0 comments (0 inline, 0 general)