Files
openttd/src/sl/extended_ver_sl.h
Patric Stout 4280c413a6 Fix: only count distance traveled in vehicles for cargo payment (#11283)
No longer you can utilize the free (and instant) labour of station
workers, transporting your cargo from one part of the station to
the other. No more!

Based on patch by dP.

(cherry picked from commit df400ef84a)
2023-10-02 19:26:08 +01:00

283 lines
18 KiB
C++

/*
* 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 extended_ver_sl.h Functions/types related to handling save/load extended version info. */
#ifndef SL_EXTENDED_VER_SL_H
#define SL_EXTENDED_VER_SL_H
#include "../core/bitmath_func.hpp"
#include "../core/enum_type.hpp"
#include <array>
#include <vector>
enum SaveLoadVersion : uint16;
/**
* List of extended features, each feature has its own (16 bit) version
*/
enum SlXvFeatureIndex {
XSLFI_NULL = 0, ///< Unused value, to indicate that no extended feature test is in use
XSLFI_VERSION_LABEL, ///< Version label
XSLFI_UPSTREAM_VERSION, ///< Corresponding upstream savegame version
XSLFI_TRACE_RESTRICT, ///< Trace restrict
XSLFI_TRACE_RESTRICT_OWNER, ///< Trace restrict: train owner test
XSLFI_TRACE_RESTRICT_ORDRCND, ///< Trace restrict: slot conditional order
XSLFI_TRACE_RESTRICT_STATUSCND, ///< Trace restrict: train status condition
XSLFI_TRACE_RESTRICT_REVERSE, ///< Trace restrict: reverse
XSLFI_TRACE_RESTRICT_NEWSCTRL, ///< Trace restrict: news control
XSLFI_TRACE_RESTRICT_COUNTER, ///< Trace restrict: counters
XSLFI_TRACE_RESTRICT_TIMEDATE, ///< Trace restrict: time/date
XSLFI_TRACE_RESTRICT_BRKCND, ///< Trace restrict: realistic braking related conditionals
XSLFI_TRACE_RESTRICT_CTGRYCND, ///< Trace restrict: category conditionals
XSLFI_TRACE_RESTRICT_PENCTRL, ///< Trace restrict: PF penalty control
XSLFI_TRACE_RESTRICT_TUNBRIDGE, ///< Trace restrict: restricted signalled tunnel/bridge support
XSLFI_TRACE_RESTRICT_SPDADAPTCTRL, ///< Trace restrict: speed adaptation control
XSLFI_PROG_SIGS, ///< programmable pre-signals patch
XSLFI_ADJACENT_CROSSINGS, ///< Adjacent level crossings closure patch
XSLFI_SAFER_CROSSINGS, ///< Safer level crossings
XSLFI_DEPARTURE_BOARDS, ///< Departure boards patch, in ticks mode
XSLFI_TIMETABLES_START_TICKS, ///< Timetable start time is in ticks, instead of days (from departure boards patch)
XSLFI_TOWN_CARGO_ADJ, ///< Town cargo adjustment patch
XSLFI_SIG_TUNNEL_BRIDGE, ///< Signals on tunnels and bridges
XSLFI_IMPROVED_BREAKDOWNS, ///< Improved breakdowns patch
XSLFI_CONSIST_BREAKDOWN_FLAG, ///< Consist breakdown flag
XSLFI_TT_WAIT_IN_DEPOT, ///< Timetabling waiting time in depot patch
XSLFI_AUTO_TIMETABLE, ///< Auto timetables and separation patch
XSLFI_VEHICLE_REPAIR_COST, ///< Vehicle repair costs patch
XSLFI_ENH_VIEWPORT_PLANS, ///< Enhanced viewport patch: plans
XSLFI_INFRA_SHARING, ///< Infrastructure sharing patch
XSLFI_VARIABLE_DAY_LENGTH, ///< Variable day length patch
XSLFI_ORDER_OCCUPANCY, ///< Running average of order occupancy
XSLFI_MORE_COND_ORDERS, ///< More conditional orders patch
XSLFI_EXTRA_LARGE_MAP, ///< Extra large map
XSLFI_REVERSE_AT_WAYPOINT, ///< Reverse at waypoint orders
XSLFI_VEH_LIFETIME_PROFIT, ///< Vehicle lifetime profit patch
XSLFI_LINKGRAPH_DAY_SCALE, ///< Linkgraph job duration & interval may be in non-scaled days
XSLFI_TEMPLATE_REPLACEMENT, ///< Template-based train replacement
XSLFI_MORE_RAIL_TYPES, ///< Increased number of rail types
XSLFI_CARGO_TYPE_ORDERS, ///< Cargo-specific load/unload order flags
XSLFI_EXTENDED_GAMELOG, ///< Extended gamelog
XSLFI_STATION_CATCHMENT_INC, ///< Station catchment radius increase
XSLFI_CUSTOM_BRIDGE_HEADS, ///< Custom bridge heads
XSLFI_CHUNNEL, ///< Tunnels under water (channel tunnel)
XSLFI_SCHEDULED_DISPATCH, ///< Scheduled vehicle dispatching
XSLFI_MORE_TOWN_GROWTH_RATES, ///< More town growth rates
XSLFI_MULTIPLE_DOCKS, ///< Multiple docks
XSLFI_TIMETABLE_EXTRA, ///< Vehicle timetable extra fields
XSLFI_TRAIN_FLAGS_EXTRA, ///< Train flags field extra size
XSLFI_VEHICLE_FLAGS_EXTRA, ///< Vehicle flags field extra size
XSLFI_TRAIN_THROUGH_LOAD, ///< Train through load/unload
XSLFI_ORDER_EXTRA_DATA, ///< Order extra data field(s)
XSLFI_WHOLE_MAP_CHUNK, ///< Whole map chunk
XSLFI_ST_LAST_VEH_TYPE, ///< Per-cargo station last vehicle type
XSLFI_SELL_AT_DEPOT_ORDER, ///< Sell vehicle on arrival at depot orders
XSLFI_BUY_LAND_RATE_LIMIT, ///< Buy land rate limit
XSLFI_DUAL_RAIL_TYPES, ///< Two rail-types per tile
XSLFI_CONSIST_SPEED_RD_FLAG, ///< Consist speed reduction flag
XSLFI_SAVEGAME_UNIQUE_ID, ///< Savegame unique ID
XSLFI_RV_OVERTAKING, ///< Roadvehicle overtaking
XSLFI_LINKGRAPH_MODES, ///< Linkgraph additional distribution modes
XSLFI_GAME_EVENTS, ///< Game event flags
XSLFI_ROAD_LAYOUT_CHANGE_CTR, ///< Road layout change counter
XSLFI_TOWN_CARGO_MATRIX, ///< Town cargo matrix savegame format changes (now obsolete)
XSLFI_STATE_CHECKSUM, ///< State checksum
XSLFI_DEBUG, ///< Debugging info
XSLFI_FLOW_STAT_FLAGS, ///< FlowStat flags
XSLFI_SPEED_RESTRICTION, ///< Train speed restrictions
XSLFI_STATION_GOODS_EXTRA, ///< Extra station goods entry statuses
XSLFI_DOCKING_CACHE_VER, ///< Multiple docks - docking tile cache version
XSLFI_EXTRA_CHEATS, ///< Extra cheats
XSLFI_TOWN_MULTI_BUILDING, ///< Allow multiple stadium/church buildings in a single town
XSLFI_SHIP_LOST_COUNTER, ///< Ship lost counter
XSLFI_BUILD_OBJECT_RATE_LIMIT, ///< Build object rate limit
XSLFI_LOCAL_COMPANY, ///< Local company ID
XSLFI_THROUGH_TRAIN_DEPOT, ///< Drive-through train depots
XSLFI_MORE_VEHICLE_ORDERS, ///< More vehicle orders - VehicleOrderID is 16 bits instead of 8
XSLFI_ORDER_FLAGS_EXTRA, ///< Order flags field extra size
XSLFI_ONE_WAY_DT_ROAD_STOP, ///< One-way drive-through road stops
XSLFI_ONE_WAY_ROAD_STATE, ///< One-way road state cache
XSLFI_VENC_CHUNK, ///< VENC chunk
XSLFI_ANIMATED_TILE_EXTRA, ///< Animated tile extra info
XSLFI_NEWGRF_INFO_EXTRA, ///< Extra NewGRF info in savegame
XSLFI_INDUSTRY_CARGO_ADJ, ///< Industry cargo adjustment patch
XSLFI_REALISTIC_TRAIN_BRAKING, ///< Realistic train braking
XSLFI_INFLATION_FIXED_DATES, ///< Inflation is applied between fixed dates
XSLFI_WATER_FLOODING, ///< Water flooding map bit
XSLFI_MORE_HOUSES, ///< More house types
XSLFI_CUSTOM_TOWN_ZONE, ///< Custom town zones
XSLFI_STATION_CARGO_HISTORY, ///< Station waiting cargo history
XSLFI_TRAIN_SPEED_ADAPTATION, ///< Train speed adaptation
XSLFI_EXTRA_STATION_NAMES, ///< Extra station names
XSLFI_DEPOT_ORDER_EXTRA_FLAGS, ///< Depot order extra flags
XSLFI_EXTRA_SIGNAL_TYPES, ///< Extra signal types
XSLFI_BANKRUPTCY_EXTRA, ///< Extra company bankruptcy fields
XSLFI_OBJECT_GROUND_TYPES, ///< Object ground types
XSLFI_LINKGRAPH_AIRCRAFT, ///< Link graph last aircraft update field and aircraft link scaling setting
XSLFI_COMPANY_PW, ///< Company passwords
XSLFI_ST_INDUSTRY_CARGO_MODE, ///< Station industry cargo mode setting
XSLFI_TL_SPEED_LIMIT, ///< Through load maximum speed setting
XSLFI_RAIL_DEPOT_SPEED_LIMIT, ///< Rail depot maximum speed setting
XSLFI_WAYPOINT_FLAGS, ///< Waypoint flags
XSLFI_ROAD_WAYPOINTS, ///< Road waypoints
XSLFI_MORE_STATION_TYPES, ///< More station types (field widening)
XSLFI_RV_ORDER_EXTRA_FLAGS, ///< Road vehicle order extra flags
XSLFI_GRF_ROADSTOPS, ///< NewGRF road stops
XSLFI_INDUSTRY_ANIM_MASK, ///< Industry tile animation masking
XSLFI_NEW_SIGNAL_STYLES, ///< New signal styles
XSLFI_NO_TREE_COUNTER, ///< No tree counter
XSLFI_TOWN_SETTING_OVERRIDE, ///< Town setting overrides
XSLFI_LINKGRAPH_SPARSE_EDGES, ///< Link graph edge matrix is stored in sparse format, and saved in order
XSLFI_AUX_TILE_LOOP, ///< Auxiliary tile loop
XSLFI_NEWGRF_ENTITY_EXTRA, ///< NewGRF entity mappings are 16 bit
XSLFI_TNNC_CHUNK, ///< TNNC chunk
XSLFI_MULTI_CARGO_SHIPS, ///< Multi-cargo ships
XSLFI_REMAIN_NEXT_ORDER_STATION, ///< Remain in station if next order is for same station
XSLFI_LABEL_ORDERS, ///< Label orders
XSLFI_VARIABLE_TICK_RATE, ///< Variable tick rate
XSLFI_ROAD_VEH_FLAGS, ///< Road vehicle flags
XSLFI_STATION_TILE_CACHE_FLAGS, ///< Station tile cache flags
XSLFI_SCRIPT_INT64, ///< See: SLV_SCRIPT_INT64
XSLFI_U64_TICK_COUNTER, ///< See: SLV_U64_TICK_COUNTER
XSLFI_LINKGRAPH_TRAVEL_TIME, ///< See: SLV_LINKGRAPH_TRAVEL_TIME
XSLFI_LAST_LOADING_TICK, ///< See: SLV_LAST_LOADING_TICK
XSLFI_SCRIPT_LEAGUE_TABLES, ///< See: Scriptable league tables (PR #10001)
XSLFI_VELOCITY_NAUTICAL, ///< See: SLV_VELOCITY_NAUTICAL (PR #10594)
XSLFI_CONSISTENT_PARTIAL_Z, ///< See: SLV_CONSISTENT_PARTIAL_Z (PR #10570)
XSLFI_MORE_CARGO_AGE, ///< See: SLV_MORE_CARGO_AGE (PR #10596)
XSLFI_AI_START_DATE, ///< See: SLV_AI_START_DATE (PR #10653)
XSLFI_EXTEND_VEHICLE_RANDOM, ///< See: SLV_EXTEND_VEHICLE_RANDOM (PR #10701)
XSLFI_DISASTER_VEH_STATE, ///< See: SLV_DISASTER_VEH_STATE (PR #10798)
XSLFI_SAVEGAME_ID, ///< See: SLV_SAVEGAME_ID (PR #10719)
XSLFI_NEWGRF_LAST_SERVICE, ///< See: SLV_NEWGRF_LAST_SERVICE (PR #11124)
XSLFI_CARGO_TRAVELLED, ///< See: SLV_CARGO_TRAVELLED (PR #11283)
XSLFI_RIFF_HEADER_60_BIT, ///< Size field in RIFF chunk header is 60 bit
XSLFI_HEIGHT_8_BIT, ///< Map tile height is 8 bit instead of 4 bit, but savegame version may be before this became true in trunk
XSLFI_ZPOS_32_BIT, ///< Vehicle/sign z_pos is 32 bit instead of 8 bit, but savegame version may be before this became true in trunk
XSLFI_MIGHT_USE_PAX_SIGNALS, ///< This save game might use the pax-signals feature
XSLFI_TRAFFIC_LIGHTS, ///< This save game uses road traffic lights
XSLFI_RAIL_AGEING, ///< This save game uses the rail aging patch
XSLFI_SPRINGPP, ///< This is a SpringPP game, use this for loading some settings
XSLFI_JOKERPP, ///< This is a JokerPP game, use this for loading some settings
XSLFI_CHILLPP, ///< This is a ChillPP game, use this for loading some settings
XSLFI_SIZE, ///< Total count of features, including null feature
};
extern std::array<uint16, XSLFI_SIZE> _sl_xv_feature_versions;
extern std::array<uint16, XSLFI_SIZE> _sl_xv_feature_static_versions;
/**
* Operator to use when combining traditional savegame number test with an extended feature version test
*/
enum SlXvFeatureTestOperator {
XSLFTO_OR = 0, ///< Test if traditional savegame version is in bounds OR extended feature is in version bounds
XSLFTO_AND ///< Test if traditional savegame version is in bounds AND extended feature is in version bounds
};
/**
* Structure to describe an extended feature version test, and how it combines with a traditional savegame version test
*/
struct SlXvFeatureTest {
using TestFunctorPtr = bool (*)(uint16, bool, const std::array<uint16, XSLFI_SIZE> &); ///< Return true if feature present, first parameter is standard savegame version, second is whether standard savegame version is within bounds
private:
uint16 min_version;
uint16 max_version;
SlXvFeatureIndex feature;
SlXvFeatureTestOperator op;
TestFunctorPtr functor = nullptr;
public:
SlXvFeatureTest()
: min_version(0), max_version(0), feature(XSLFI_NULL), op(XSLFTO_OR) { }
SlXvFeatureTest(SlXvFeatureTestOperator op_, SlXvFeatureIndex feature_, uint16 min_version_ = 1, uint16 max_version_ = 0xFFFF)
: min_version(min_version_), max_version(max_version_), feature(feature_), op(op_) { }
SlXvFeatureTest(TestFunctorPtr functor_)
: min_version(0), max_version(0), feature(XSLFI_NULL), op(XSLFTO_OR), functor(functor_) { }
bool IsFeaturePresent(const std::array<uint16, XSLFI_SIZE> &feature_versions, SaveLoadVersion savegame_version, SaveLoadVersion savegame_version_from, SaveLoadVersion savegame_version_to) const;
inline bool IsFeaturePresent(SaveLoadVersion savegame_version, SaveLoadVersion savegame_version_from, SaveLoadVersion savegame_version_to) const
{
return this->IsFeaturePresent(_sl_xv_feature_versions, savegame_version, savegame_version_from, savegame_version_to);
}
};
bool SlXvIsFeaturePresent(const std::array<uint16, XSLFI_SIZE> &feature_versions, SlXvFeatureIndex feature, uint16 min_version = 1, uint16 max_version = 0xFFFF);
inline bool SlXvIsFeaturePresent(SlXvFeatureIndex feature, uint16 min_version = 1, uint16 max_version = 0xFFFF)
{
return SlXvIsFeaturePresent(_sl_xv_feature_versions, feature, min_version, max_version);
}
/**
* Returns true if @p feature is missing (i.e. has a version of 0, or less than the specified minimum version)
*/
inline bool SlXvIsFeatureMissing(SlXvFeatureIndex feature, uint16 min_version = 1)
{
return !SlXvIsFeaturePresent(feature, min_version);
}
/**
* Returns true if @p feature is missing (i.e. has a version of 0, or less than the specified minimum version)
*/
inline bool SlXvIsFeatureMissing(const std::array<uint16, XSLFI_SIZE> &feature_versions, SlXvFeatureIndex feature, uint16 min_version = 1)
{
return !SlXvIsFeaturePresent(feature_versions, feature, min_version);
}
const char *SlXvGetFeatureName(SlXvFeatureIndex feature);
/**
* sub chunk flags, this is saved as-is
* (XSCF_EXTRA_DATA_PRESENT and XSCF_CHUNK_ID_LIST_PRESENT must only be set by the save code, and read by the load code)
*/
enum SlxiSubChunkFlags {
XSCF_NULL = 0, ///< zero value
XSCF_IGNORABLE_UNKNOWN = 1 << 0, ///< the loader is free to ignore this without aborting the load if it doesn't know what it is at all
XSCF_IGNORABLE_VERSION = 1 << 1, ///< the loader is free to ignore this without aborting the load if the version is greater than the maximum that can be loaded
XSCF_EXTRA_DATA_PRESENT = 1 << 2, ///< extra data field is present, extra data in some sub-chunk/feature specific format
XSCF_CHUNK_ID_LIST_PRESENT = 1 << 3, ///< chunk ID list field is present, list of chunks which this sub-chunk/feature adds to the save game, this can be used to discard the chunks if the feature is unknown
XSCF_IGNORABLE_ALL = XSCF_IGNORABLE_UNKNOWN | XSCF_IGNORABLE_VERSION, ///< all "ignorable" flags
};
DECLARE_ENUM_AS_BIT_SET(SlxiSubChunkFlags)
struct SlxiSubChunkInfo;
typedef uint32 SlxiSubChunkSaveProc(const SlxiSubChunkInfo *info, bool dry_run); ///< sub chunk save procedure type, must return length and write no data when dry_run is true
typedef void SlxiSubChunkLoadProc(const SlxiSubChunkInfo *info, uint32 length); ///< sub chunk load procedure, must consume length bytes
/** Handlers and description of chunk. */
struct SlxiSubChunkInfo {
SlXvFeatureIndex index; ///< feature index, this is saved
SlxiSubChunkFlags flags; ///< flags, this is saved
uint16 save_version; ///< version to save
uint16 max_version; ///< maximum version to accept on load
const char *name; ///< feature name, this *IS* saved, so must be globally unique
SlxiSubChunkSaveProc *save_proc; ///< save procedure of the sub chunk, this may be nullptr in which case no extra chunk data is saved
SlxiSubChunkLoadProc *load_proc; ///< load procedure of the sub chunk, this may be nullptr in which case the extra chunk data must be missing or of 0 length
const char *chunk_list; ///< this is a list of chunks that this feature uses, which should be written to the savegame, this must be a comma-seperated list of 4-character IDs, with no spaces, or nullptr
};
void SlXvResetState();
void SlXvSetCurrentState();
void SlXvSetStaticCurrentVersions();
bool SlXvCheckSpecialSavegameVersions();
bool SlXvIsChunkDiscardable(uint32 id);
#endif /* SL_EXTENDED_VER_SL_H */