Changeset - r18294:67a72ead8996
[Not reviewed]
master
0 4 0
frosch - 13 years ago 2011-11-08 17:24:15
frosch@openttd.org
(svn r23140) -Add: ErrorUnknownCallbackResult()
4 files changed with 40 insertions and 0 deletions:
0 comments (0 inline, 0 general)
src/lang/english.txt
Show inline comments
 
@@ -2331,384 +2331,385 @@ STR_MAPGEN_TERRAIN_TYPE                 
 
STR_MAPGEN_QUANTITY_OF_SEA_LAKES                                :{BLACK}Sea level:
 
STR_MAPGEN_QUANTITY_OF_RIVERS                                   :{BLACK}Rivers:
 
STR_MAPGEN_SMOOTHNESS                                           :{BLACK}Smoothness:
 
STR_MAPGEN_VARIETY                                              :{BLACK}Variety distribution:
 
STR_MAPGEN_GENERATE                                             :{WHITE}Generate
 

	
 
# Strings for map borders at game generation
 
STR_MAPGEN_BORDER_TYPE                                          :{BLACK}Map edges:
 
STR_MAPGEN_NORTHWEST                                            :{BLACK}Northwest
 
STR_MAPGEN_NORTHEAST                                            :{BLACK}Northeast
 
STR_MAPGEN_SOUTHEAST                                            :{BLACK}Southeast
 
STR_MAPGEN_SOUTHWEST                                            :{BLACK}Southwest
 
STR_MAPGEN_BORDER_FREEFORM                                      :{BLACK}Freeform
 
STR_MAPGEN_BORDER_WATER                                         :{BLACK}Water
 
STR_MAPGEN_BORDER_RANDOM                                        :{BLACK}Random
 
STR_MAPGEN_BORDER_RANDOMIZE                                     :{BLACK}Random
 
STR_MAPGEN_BORDER_MANUAL                                        :{BLACK}Manual
 

	
 
STR_MAPGEN_HEIGHTMAP_ROTATION                                   :{BLACK}Heightmap rotation:
 
STR_MAPGEN_HEIGHTMAP_NAME                                       :{BLACK}Heightmap name:
 
STR_MAPGEN_HEIGHTMAP_SIZE_LABEL                                 :{BLACK}Size:
 
STR_MAPGEN_HEIGHTMAP_SIZE                                       :{ORANGE}{NUM} x {NUM}
 

	
 
STR_MAPGEN_RANDOM_SEED_OSKTITLE                                 :{BLACK}Enter a random seed
 
STR_MAPGEN_SNOW_LINE_QUERY_CAPT                                 :{WHITE}Change snow line height
 
STR_MAPGEN_START_DATE_QUERY_CAPT                                :{WHITE}Change starting year
 

	
 
# SE Map generation
 
STR_SE_MAPGEN_CAPTION                                           :{WHITE}Scenario Type
 
STR_SE_MAPGEN_FLAT_WORLD                                        :{WHITE}Flat land
 
STR_SE_MAPGEN_FLAT_WORLD_TOOLTIP                                :{BLACK}Generate a flat land
 
STR_SE_MAPGEN_RANDOM_LAND                                       :{WHITE}Random land
 
STR_SE_MAPGEN_FLAT_WORLD_HEIGHT                                 :{BLACK}Height of flat land:
 
STR_SE_MAPGEN_FLAT_WORLD_HEIGHT_DOWN                            :{BLACK}Move the height of flat land one down
 
STR_SE_MAPGEN_FLAT_WORLD_HEIGHT_UP                              :{BLACK}Move the height of flat land one up
 

	
 
STR_SE_MAPGEN_FLAT_WORLD_HEIGHT_QUERY_CAPT                      :{WHITE}Change height of flat land
 

	
 
# Map generation progress
 
STR_GENERATION_WORLD                                            :{WHITE}Generating World...
 
STR_GENERATION_ABORT                                            :{BLACK}Abort
 
STR_GENERATION_ABORT_CAPTION                                    :{WHITE}Abort World Generation
 
STR_GENERATION_ABORT_MESSAGE                                    :{YELLOW}Do you really want to abort the generation?
 
STR_GENERATION_PROGRESS                                         :{WHITE}{NUM}% complete
 
STR_GENERATION_PROGRESS_NUM                                     :{BLACK}{NUM} / {NUM}
 
STR_GENERATION_WORLD_GENERATION                                 :{BLACK}World generation
 
STR_GENERATION_RIVER_GENERATION                                 :{BLACK}River generation
 
STR_GENERATION_TREE_GENERATION                                  :{BLACK}Tree generation
 
STR_GENERATION_OBJECT_GENERATION                                :{BLACK}Object generation
 
STR_GENERATION_CLEARING_TILES                                   :{BLACK}Rough and rocky area generation
 
STR_GENERATION_SETTINGUP_GAME                                   :{BLACK}Setting up game
 
STR_GENERATION_PREPARING_TILELOOP                               :{BLACK}Running tile-loop
 
STR_GENERATION_PREPARING_GAME                                   :{BLACK}Preparing game
 

	
 
# NewGRF settings
 
STR_NEWGRF_SETTINGS_CAPTION                                     :{WHITE}NewGRF Settings
 
STR_NEWGRF_SETTINGS_INFO_TITLE                                  :{WHITE}Detailed NewGRF information
 
STR_NEWGRF_SETTINGS_ACTIVE_LIST                                 :{WHITE}Active NewGRF files
 
STR_NEWGRF_SETTINGS_INACTIVE_LIST                               :{WHITE}Inactive NewGRF files
 
STR_NEWGRF_SETTINGS_SELECT_PRESET                               :{ORANGE}Select preset:
 
STR_NEWGRF_FILTER_TITLE                                         :{ORANGE}Filter string:
 
STR_NEWGRF_SETTINGS_PRESET_LIST_TOOLTIP                         :{BLACK}Load the selected preset
 
STR_NEWGRF_SETTINGS_PRESET_SAVE                                 :{BLACK}Save preset
 
STR_NEWGRF_SETTINGS_PRESET_SAVE_TOOLTIP                         :{BLACK}Save the current list as a preset
 
STR_NEWGRF_SETTINGS_PRESET_SAVE_QUERY                           :{BLACK}Enter name for preset
 
STR_NEWGRF_SETTINGS_PRESET_DELETE                               :{BLACK}Delete preset
 
STR_NEWGRF_SETTINGS_PRESET_DELETE_TOOLTIP                       :{BLACK}Delete the currently selected preset
 
STR_NEWGRF_SETTINGS_ADD                                         :{BLACK}Add
 
STR_NEWGRF_SETTINGS_ADD_FILE_TOOLTIP                            :{BLACK}Add the selected NewGRF file to your configuration
 
STR_NEWGRF_SETTINGS_RESCAN_FILES                                :{BLACK}Rescan files
 
STR_NEWGRF_SETTINGS_RESCAN_FILES_TOOLTIP                        :{BLACK}Update the list of available NewGRF files
 
STR_NEWGRF_SETTINGS_REMOVE                                      :{BLACK}Remove
 
STR_NEWGRF_SETTINGS_REMOVE_TOOLTIP                              :{BLACK}Remove the selected NewGRF file from the list
 
STR_NEWGRF_SETTINGS_MOVEUP                                      :{BLACK}Move Up
 
STR_NEWGRF_SETTINGS_MOVEUP_TOOLTIP                              :{BLACK}Move the selected NewGRF file up the list
 
STR_NEWGRF_SETTINGS_MOVEDOWN                                    :{BLACK}Move Down
 
STR_NEWGRF_SETTINGS_MOVEDOWN_TOOLTIP                            :{BLACK}Move the selected NewGRF file down the list
 
STR_NEWGRF_SETTINGS_FILE_TOOLTIP                                :{BLACK}A list of the NewGRF files that are installed. Click a file to change its parameters
 

	
 
STR_NEWGRF_SETTINGS_SET_PARAMETERS                              :{BLACK}Set parameters
 
STR_NEWGRF_SETTINGS_TOGGLE_PALETTE                              :{BLACK}Toggle palette
 
STR_NEWGRF_SETTINGS_TOGGLE_PALETTE_TOOLTIP                      :{BLACK}Toggle the palette of the selected NewGRF.{}Do this when the graphics from this NewGRF look pink in-game
 
STR_NEWGRF_SETTINGS_APPLY_CHANGES                               :{BLACK}Apply changes
 

	
 
STR_NEWGRF_SETTINGS_FIND_MISSING_CONTENT_BUTTON                 :{BLACK}Find missing content online
 
STR_NEWGRF_SETTINGS_FIND_MISSING_CONTENT_TOOLTIP                :{BLACK}Check whether the missing content can be found online
 

	
 
STR_NEWGRF_SETTINGS_FILENAME                                    :{BLACK}Filename: {SILVER}{RAW_STRING}
 
STR_NEWGRF_SETTINGS_GRF_ID                                      :{BLACK}GRF ID: {SILVER}{RAW_STRING}
 
STR_NEWGRF_SETTINGS_VERSION                                     :{BLACK}Version: {SILVER}{NUM}
 
STR_NEWGRF_SETTINGS_MIN_VERSION                                 :{BLACK}Min. compatible version: {SILVER}{NUM}
 
STR_NEWGRF_SETTINGS_MD5SUM                                      :{BLACK}MD5sum: {SILVER}{RAW_STRING}
 
STR_NEWGRF_SETTINGS_PALETTE                                     :{BLACK}Palette: {SILVER}{RAW_STRING}
 
STR_NEWGRF_SETTINGS_PARAMETER                                   :{BLACK}Parameters: {SILVER}{STRING1}
 

	
 
STR_NEWGRF_SETTINGS_NO_INFO                                     :{BLACK}No information available
 
STR_NEWGRF_SETTINGS_NOT_FOUND                                   :{RED}Matching file not found
 
STR_NEWGRF_SETTINGS_DISABLED                                    :{RED}Disabled
 
STR_NEWGRF_SETTINGS_INCOMPATIBLE                                :{RED}Incompatible with this version of OpenTTD
 

	
 
STR_NEWGRF_SETTINGS_PARAMETER_QUERY                             :{BLACK}Enter NewGRF parameters
 

	
 
# NewGRF parameters window
 
STR_NEWGRF_PARAMETERS_CAPTION                                   :{WHITE}Change NewGRF parameters
 
STR_NEWGRF_PARAMETERS_CLOSE                                     :{BLACK}Close
 
STR_NEWGRF_PARAMETERS_RESET                                     :{BLACK}Reset
 
STR_NEWGRF_PARAMETERS_RESET_TOOLTIP                             :{BLACK}Set all parameters to their default value
 
STR_NEWGRF_PARAMETERS_DEFAULT_NAME                              :Parameter {NUM}
 
STR_NEWGRF_PARAMETERS_SETTING                                   :{STRING1}: {ORANGE}{STRING1}
 
STR_NEWGRF_PARAMETERS_NUM_PARAM                                 :{LTBLUE}Number of parameters: {ORANGE}{NUM}
 

	
 
# NewGRF inspect window
 
STR_NEWGRF_INSPECT_CAPTION                                      :{WHITE}Inspect - {STRING5}
 
STR_NEWGRF_INSPECT_PARENT_BUTTON                                :{BLACK}Parent
 
STR_NEWGRF_INSPECT_PARENT_TOOLTIP                               :{BLACK}Inspect the object of the parent scope
 

	
 
STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT                            :{STRING1} at {HEX}
 
STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT_OBJECT                     :Object
 
STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT_RAIL_TYPE                  :Rail type
 

	
 
STR_NEWGRF_INSPECT_QUERY_CAPTION                                :{WHITE}NewGRF variable 60+x parameter (hexadecimal)
 

	
 
# Sprite aligner window
 
STR_SPRITE_ALIGNER_CAPTION                                      :{WHITE}Aligning sprite {COMMA} ({RAW_STRING})
 
STR_SPRITE_ALIGNER_NEXT_BUTTON                                  :{BLACK}Next sprite
 
STR_SPRITE_ALIGNER_NEXT_TOOLTIP                                 :{BLACK}Proceed to the next normal sprite, skipping any pseudo/recolour/font sprites and wrapping around at the end
 
STR_SPRITE_ALIGNER_GOTO_BUTTON                                  :{BLACK}Go to sprite
 
STR_SPRITE_ALIGNER_GOTO_TOOLTIP                                 :{BLACK}Go to the given sprite. If the sprite is not a normal sprite, proceed to the next normal sprite
 
STR_SPRITE_ALIGNER_PREVIOUS_BUTTON                              :{BLACK}Previous sprite
 
STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP                             :{BLACK}Proceed to the previous normal sprite, skipping any pseudo/recolour/font sprites and wrapping around at the begin
 
STR_SPRITE_ALIGNER_SPRITE_TOOLTIP                               :{BLACK}Representation of the currently selected sprite. The alignment is ignored when drawing this sprite
 
STR_SPRITE_ALIGNER_MOVE_TOOLTIP                                 :{BLACK}Move the sprite around, changing the X and Y offsets
 
STR_SPRITE_ALIGNER_OFFSETS                                      :{BLACK}X offset: {NUM}, Y offset: {NUM}
 
STR_SPRITE_ALIGNER_PICKER_BUTTON                                :{BLACK}Pick sprite
 
STR_SPRITE_ALIGNER_PICKER_TOOLTIP                               :{BLACK}Pick a sprite from anywhere on the screen
 

	
 
STR_SPRITE_ALIGNER_GOTO_CAPTION                                 :{WHITE}Go to sprite
 

	
 
# NewGRF (self) generated warnings/errors
 
STR_NEWGRF_ERROR_MSG_INFO                                       :{SILVER}{RAW_STRING}
 
STR_NEWGRF_ERROR_MSG_WARNING                                    :{RED}Warning: {SILVER}{RAW_STRING}
 
STR_NEWGRF_ERROR_MSG_ERROR                                      :{RED}Error: {SILVER}{RAW_STRING}
 
STR_NEWGRF_ERROR_MSG_FATAL                                      :{RED}Fatal: {SILVER}{RAW_STRING}
 
STR_NEWGRF_ERROR_FATAL_POPUP                                    :{WHITE}A fatal NewGRF error has occurred: {}{STRING5}
 
STR_NEWGRF_ERROR_VERSION_NUMBER                                 :{1:STRING1} will not work with the TTDPatch version reported by OpenTTD
 
STR_NEWGRF_ERROR_DOS_OR_WINDOWS                                 :{1:STRING1} is for the {STRING1} version of TTD
 
STR_NEWGRF_ERROR_UNSET_SWITCH                                   :{1:STRING1} is designed to be used with {STRING1}
 
STR_NEWGRF_ERROR_INVALID_PARAMETER                              :Invalid parameter for {1:STRING1}: parameter {STRING1} ({NUM})
 
STR_NEWGRF_ERROR_LOAD_BEFORE                                    :{1:STRING1} must be loaded before {STRING1}
 
STR_NEWGRF_ERROR_LOAD_AFTER                                     :{1:STRING1} must be loaded after {STRING1}
 
STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER                            :{1:STRING1} requires OpenTTD version {STRING1} or better
 
STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE                          :the GRF file it was designed to translate
 
STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED                        :Too many NewGRFs are loaded
 
STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC                       :Loading {2:RAW_STRING} as static NewGRF with {4:RAW_STRING} could cause desyncs
 
STR_NEWGRF_ERROR_UNEXPECTED_SPRITE                              :Unexpected sprite
 
STR_NEWGRF_ERROR_UNKNOWN_PROPERTY                               :Unknown Action 0 property
 
STR_NEWGRF_ERROR_INVALID_ID                                     :Attempt to use invalid ID
 
STR_NEWGRF_ERROR_CORRUPT_SPRITE                                 :{YELLOW}{RAW_STRING} contains a corrupt sprite. All corrupt sprites will be shown as a red question mark (?)
 
STR_NEWGRF_ERROR_MULTIPLE_ACTION_8                              :Contains multiple Action 8 entries
 
STR_NEWGRF_ERROR_READ_BOUNDS                                    :Read past end of pseudo-sprite
 
STR_NEWGRF_ERROR_MISSING_SPRITES                                :{WHITE}The currently used base graphics set is missing a number of sprites.{}Please update the base graphics set
 
STR_NEWGRF_ERROR_GRM_FAILED                                     :Requested GRF resources not available
 
STR_NEWGRF_ERROR_FORCEFULLY_DISABLED                            :{2:RAW_STRING} was disabled by {4:RAW_STRING}
 
STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT                          :Invalid/unknown sprite layout format
 

	
 
# NewGRF related 'general' warnings
 
STR_NEWGRF_POPUP_CAUTION_CAPTION                                :{WHITE}Caution!
 
STR_NEWGRF_CONFIRMATION_TEXT                                    :{YELLOW}You are about to make changes to a running game. This can crash OpenTTD or break the game state. Do not file bug reports about these issues.{}Are you absolutely sure about this?
 

	
 
STR_NEWGRF_DUPLICATE_GRFID                                      :{WHITE}Can't add file: duplicate GRF ID
 
STR_NEWGRF_COMPATIBLE_LOADED                                    :{ORANGE}Matching file not found (compatible GRF loaded)
 

	
 
STR_NEWGRF_COMPATIBLE_LOAD_WARNING                              :{WHITE}Compatible GRF(s) loaded for missing files
 
STR_NEWGRF_DISABLED_WARNING                                     :{WHITE}Missing GRF file(s) have been disabled
 
STR_NEWGRF_UNPAUSE_WARNING_TITLE                                :{YELLOW}Missing GRF file(s)
 
STR_NEWGRF_UNPAUSE_WARNING                                      :{WHITE}Unpausing can crash OpenTTD. Do not file bug reports for subsequent crashes.{}Do you really want to unpause?
 

	
 
# NewGRF status
 
STR_NEWGRF_LIST_NONE                                            :None
 
STR_NEWGRF_LIST_ALL_FOUND                                       :All files present
 
STR_NEWGRF_LIST_COMPATIBLE                                      :{YELLOW}Found compatible files
 
STR_NEWGRF_LIST_MISSING                                         :{RED}Missing files
 

	
 
# NewGRF 'it's broken' warnings
 
STR_NEWGRF_BROKEN                                               :{WHITE}Behaviour of NewGRF '{0:RAW_STRING}' is likely to cause desyncs and/or crashes
 
STR_NEWGRF_BROKEN_POWERED_WAGON                                 :{WHITE}It changed powered-wagon state for '{1:ENGINE}' when not inside a depot
 
STR_NEWGRF_BROKEN_VEHICLE_LENGTH                                :{WHITE}It changed vehicle length for '{1:ENGINE}' when not inside a depot
 
STR_BROKEN_VEHICLE_LENGTH                                       :{WHITE}Train '{VEHICLE}' belonging to '{COMPANY}' has invalid length. It is probably caused by problems with NewGRFs. Game may desync or crash
 

	
 
STR_NEWGRF_BUGGY                                                :{WHITE}NewGRF '{0:RAW_STRING}' provides incorrect information
 
STR_NEWGRF_BUGGY_ARTICULATED_CARGO                              :{WHITE}Cargo/refit information for '{1:ENGINE}' differs from purchase list after construction. This might cause autorenew/-replace to fail refitting correctly
 
STR_NEWGRF_BUGGY_ENDLESS_PRODUCTION_CALLBACK                    :{WHITE}'{1:STRING}' caused an endless loop in the production callback
 
STR_NEWGRF_BUGGY_UNKNOWN_CALLBACK_RESULT                        :{WHITE}Callback 0x{HEX} returned unknown/invalid result 0x{HEX}
 

	
 
# 'User removed essential NewGRFs'-placeholders for stuff without specs
 
STR_NEWGRF_INVALID_CARGO                                        :<invalid cargo>
 
STR_NEWGRF_INVALID_CARGO_ABBREV                                 :??
 
STR_NEWGRF_INVALID_CARGO_QUANTITY                               :{COMMA} of <invalid cargo>
 
STR_NEWGRF_INVALID_ENGINE                                       :<invalid vehicle model>
 
STR_NEWGRF_INVALID_INDUSTRYTYPE                                 :<invalid industry>
 

	
 
# NewGRF scanning window
 
STR_NEWGRF_SCAN_CAPTION                                         :{WHITE}Scanning NewGRFs
 
STR_NEWGRF_SCAN_MESSAGE                                         :{BLACK}Scanning NewGRFs. Depending on the amount this can take a while...
 
STR_NEWGRF_SCAN_STATUS                                          :{BLACK}{NUM} NewGRF{P "" s} scanned out of an estimated {NUM} NewGRF{P "" s}
 
STR_NEWGRF_SCAN_ARCHIVES                                        :Scanning for archives
 

	
 
# Sign list window
 
STR_SIGN_LIST_CAPTION                                           :{WHITE}Sign List - {COMMA} Sign{P "" s}
 
STR_SIGN_LIST_MATCH_CASE                                        :{BLACK}Match case
 
STR_SIGN_LIST_CLEAR                                             :{BLACK}Clear filter
 
STR_SIGN_LIST_MATCH_CASE_TOOLTIP                                :{BLACK}Toggle matching case when comparing sign names against the filter string
 
STR_SIGN_LIST_CLEAR_TOOLTIP                                     :{BLACK}Clear filter string
 

	
 
# Sign window
 
STR_EDIT_SIGN_CAPTION                                           :{WHITE}Edit sign text
 
STR_EDIT_SIGN_NEXT_SIGN_TOOLTIP                                 :{BLACK}Go to next sign
 
STR_EDIT_SIGN_PREVIOUS_SIGN_TOOLTIP                             :{BLACK}Go to previous sign
 

	
 
STR_EDIT_SIGN_SIGN_OSKTITLE                                     :{BLACK}Enter a name for the sign
 

	
 
# Town directory window
 
STR_TOWN_DIRECTORY_CAPTION                                      :{WHITE}Towns
 
STR_TOWN_DIRECTORY_NONE                                         :{ORANGE}- None -
 
STR_TOWN_DIRECTORY_TOWN                                         :{ORANGE}{TOWN}{BLACK} ({COMMA})
 
STR_TOWN_DIRECTORY_LIST_TOOLTIP                                 :{BLACK}Town names - click on name to centre main view on town. Ctrl+Click opens a new viewport on town location
 
STR_TOWN_POPULATION                                             :{BLACK}World population: {COMMA}
 

	
 
# Town view window
 
STR_TOWN_VIEW_TOWN_CAPTION                                      :{WHITE}{TOWN}
 
STR_TOWN_VIEW_CITY_CAPTION                                      :{WHITE}{TOWN} (City)
 
STR_TOWN_VIEW_POPULATION_HOUSES                                 :{BLACK}Population: {ORANGE}{COMMA}{BLACK}  Houses: {ORANGE}{COMMA}
 
STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX                         :{BLACK}Passengers last month: {ORANGE}{COMMA}{BLACK}  max: {ORANGE}{COMMA}
 
STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX                               :{BLACK}Mail last month: {ORANGE}{COMMA}{BLACK}  max: {ORANGE}{COMMA}
 
STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH                              :{BLACK}Cargo needed for town growth:
 
STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED                     :{ORANGE}{STRING}{BLACK} required
 
STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER              :{ORANGE}{STRING}{BLACK} required in winter
 
STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_LAST_MONTH                   :{ORANGE}{CARGO}{BLACK} delivered last month
 
STR_TOWN_VIEW_NOISE_IN_TOWN                                     :{BLACK}Noise limit in town: {ORANGE}{COMMA}{BLACK}  max: {ORANGE}{COMMA}
 
STR_TOWN_VIEW_CENTER_TOOLTIP                                    :{BLACK}Centre the main view on town location. Ctrl+Click opens a new viewport on town location
 
STR_TOWN_VIEW_LOCAL_AUTHORITY_BUTTON                            :{BLACK}Local authority
 
STR_TOWN_VIEW_LOCAL_AUTHORITY_TOOLTIP                           :{BLACK}Show information on local authority
 
STR_TOWN_VIEW_RENAME_TOOLTIP                                    :{BLACK}Change town name
 

	
 
STR_TOWN_VIEW_EXPAND_BUTTON                                     :{BLACK}Expand
 
STR_TOWN_VIEW_EXPAND_TOOLTIP                                    :{BLACK}Increase size of town
 
STR_TOWN_VIEW_DELETE_BUTTON                                     :{BLACK}Delete
 
STR_TOWN_VIEW_DELETE_TOOLTIP                                    :{BLACK}Delete this town completely
 

	
 
STR_TOWN_VIEW_RENAME_TOWN_BUTTON                                :Rename Town
 

	
 
# Town local authority window
 
STR_LOCAL_AUTHORITY_CAPTION                                     :{WHITE}{TOWN} local authority
 
STR_LOCAL_AUTHORITY_COMPANY_RATINGS                             :{BLACK}Transport company ratings:
 
STR_LOCAL_AUTHORITY_COMPANY_RATING                              :{YELLOW}{COMPANY} {COMPANYNUM}: {ORANGE}{STRING}
 
STR_LOCAL_AUTHORITY_ACTIONS_TITLE                               :{BLACK}Actions available:
 
STR_LOCAL_AUTHORITY_ACTIONS_TOOLTIP                             :{BLACK}List of things to do at this town - click on item for more details
 
STR_LOCAL_AUTHORITY_DO_IT_BUTTON                                :{BLACK}Do it
 
STR_LOCAL_AUTHORITY_DO_IT_TOOLTIP                               :{BLACK}Carry out the highlighted action in the list above
 

	
 
STR_LOCAL_AUTHORITY_ACTION_SMALL_ADVERTISING_CAMPAIGN           :Small advertising campaign
 
STR_LOCAL_AUTHORITY_ACTION_MEDIUM_ADVERTISING_CAMPAIGN          :Medium advertising campaign
 
STR_LOCAL_AUTHORITY_ACTION_LARGE_ADVERTISING_CAMPAIGN           :Large advertising campaign
 
STR_LOCAL_AUTHORITY_ACTION_ROAD_RECONSTRUCTION                  :Fund local road reconstruction
 
STR_LOCAL_AUTHORITY_ACTION_STATUE_OF_COMPANY                    :Build statue of company owner
 
STR_LOCAL_AUTHORITY_ACTION_NEW_BUILDINGS                        :Fund new buildings
 
STR_LOCAL_AUTHORITY_ACTION_EXCLUSIVE_TRANSPORT                  :Buy exclusive transport rights
 
STR_LOCAL_AUTHORITY_ACTION_BRIBE                                :Bribe the local authority
 

	
 
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING            :{YELLOW}Initiate a small local advertising campaign, to attract more passengers and cargo to your transport services.{}Cost: {CURRENCY}
 
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING           :{YELLOW}Initiate a medium local advertising campaign, to attract more passengers and cargo to your transport services.{}Cost: {CURRENCY}
 
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING            :{YELLOW}Initiate a large local advertising campaign, to attract more passengers and cargo to your transport services.{}Cost: {CURRENCY}
 
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION          :{YELLOW}Fund the reconstruction of the urban road network. Causes considerable disruption to road traffic for up to 6 months.{}Cost: {CURRENCY}
 
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY            :{YELLOW}Build a statue in honour of your company.{}Cost: {CURRENCY}
 
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS                :{YELLOW}Fund the construction of new commercial buildings in the town.{}Cost: {CURRENCY}
 
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT          :{YELLOW}Buy 1 year's exclusive transport rights in town. Town authority will only allow passengers and cargo to use your company's stations.{}Cost: {CURRENCY}
 
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE                        :{YELLOW}Bribe the local authority to increase your rating, at the risk of a severe penalty if caught.{}Cost: {CURRENCY}
 

	
 
# Subsidies window
 
STR_SUBSIDIES_CAPTION                                           :{WHITE}Subsidies
 
STR_SUBSIDIES_OFFERED_TITLE                                     :{BLACK}Subsidies on offer for services taking:
 
STR_SUBSIDIES_OFFERED_FROM_TO                                   :{ORANGE}{STRING} from {STRING2} to {STRING2}{YELLOW} (by {DATE_SHORT})
 
STR_SUBSIDIES_NONE                                              :{ORANGE}- None -
 
STR_SUBSIDIES_SUBSIDISED_TITLE                                  :{BLACK}Services already subsidised:
 
STR_SUBSIDIES_SUBSIDISED_FROM_TO                                :{ORANGE}{STRING} from {STRING2} to {STRING2}{YELLOW} ({COMPANY}{YELLOW}, until {DATE_SHORT})
 
STR_SUBSIDIES_TOOLTIP_CLICK_ON_SERVICE_TO_CENTER                :{BLACK}Click on service to centre main view on industry/town. Ctrl+Click opens a new viewport on industry/town location
 

	
 
# Station list window
 
STR_STATION_LIST_TOOLTIP                                        :{BLACK}Station names - click on name to centre main view on station. Ctrl+Click opens a new viewport on station location
 
STR_STATION_LIST_USE_CTRL_TO_SELECT_MORE                        :{BLACK}Hold Ctrl to select more than one item
 
STR_STATION_LIST_CAPTION                                        :{WHITE}{COMPANY} - {COMMA} Station{P "" s}
 
STR_STATION_LIST_STATION                                        :{YELLOW}{STATION} {STATIONFEATURES}
 
STR_STATION_LIST_WAYPOINT                                       :{YELLOW}{WAYPOINT}
 
STR_STATION_LIST_NONE                                           :{YELLOW}- None -
 
STR_STATION_LIST_SELECT_ALL_FACILITIES                          :{BLACK}Select all facilities
 
STR_STATION_LIST_SELECT_ALL_TYPES                               :{BLACK}Select all cargo types (including no waiting cargo)
 
STR_STATION_LIST_NO_WAITING_CARGO                               :{BLACK}No cargo of any type is waiting
 

	
 
# Station view window
 
STR_STATION_VIEW_CAPTION                                        :{WHITE}{STATION} {STATIONFEATURES}
 
STR_STATION_VIEW_WAITING_TITLE                                  :{BLACK}Waiting: {WHITE}{STRING}
 
STR_STATION_VIEW_WAITING_CARGO                                  :{WHITE}{CARGO}
 
STR_STATION_VIEW_EN_ROUTE_FROM                                  :{YELLOW}({SHORTCARGO} en-route from {STATION})
 

	
 
STR_STATION_VIEW_ACCEPTS_BUTTON                                 :{BLACK}Accepts
 
STR_STATION_VIEW_ACCEPTS_TOOLTIP                                :{BLACK}Show list of accepted cargo
 
STR_STATION_VIEW_ACCEPTS_CARGO                                  :{BLACK}Accepts: {WHITE}{RAW_STRING}
 

	
 
STR_STATION_VIEW_RATINGS_BUTTON                                 :{BLACK}Ratings
 
STR_STATION_VIEW_RATINGS_TOOLTIP                                :{BLACK}Show station ratings
 
STR_STATION_VIEW_CARGO_RATINGS_TITLE                            :{BLACK}Local rating of transport service:
 
STR_STATION_VIEW_CARGO_RATING                                   :{WHITE}{STRING}: {YELLOW}{STRING} ({COMMA}%)
 

	
 
############ range for rating starts
 
STR_CARGO_RATING_APPALLING                                      :Appalling
 
STR_CARGO_RATING_VERY_POOR                                      :Very Poor
 
STR_CARGO_RATING_POOR                                           :Poor
 
STR_CARGO_RATING_MEDIOCRE                                       :Mediocre
 
STR_CARGO_RATING_GOOD                                           :Good
 
STR_CARGO_RATING_VERY_GOOD                                      :Very Good
 
STR_CARGO_RATING_EXCELLENT                                      :Excellent
 
STR_CARGO_RATING_OUTSTANDING                                    :Outstanding
 
############ range for rating ends
 

	
 
STR_STATION_VIEW_CENTER_TOOLTIP                                 :{BLACK}Centre main view on station location. Ctrl+Click opens a new viewport on station location
 
STR_STATION_VIEW_RENAME_TOOLTIP                                 :{BLACK}Change name of station
 

	
 
STR_STATION_VIEW_SCHEDULED_TRAINS_TOOLTIP                       :{BLACK}Show all trains which have this station on their schedule
 
STR_STATION_VIEW_SCHEDULED_ROAD_VEHICLES_TOOLTIP                :{BLACK}Show all road vehicles which have this station on their schedule
 
STR_STATION_VIEW_SCHEDULED_AIRCRAFT_TOOLTIP                     :{BLACK}Show all aircraft which have this station on their schedule
 
STR_STATION_VIEW_SCHEDULED_SHIPS_TOOLTIP                        :{BLACK}Show all ships which have this station on their schedule
 

	
 
STR_STATION_VIEW_RENAME_STATION_CAPTION                         :Rename station/loading area
 

	
 
# Waypoint/buoy view window
 
STR_WAYPOINT_VIEW_CAPTION                                       :{WHITE}{WAYPOINT}
 
STR_WAYPOINT_VIEW_CENTER_TOOLTIP                                :{BLACK}Centre main view on waypoint location. Ctrl+Click opens a new viewport on waypoint location
 
STR_WAYPOINT_VIEW_CHANGE_WAYPOINT_NAME                          :{BLACK}Change waypoint name
 
STR_BUOY_VIEW_CENTER_TOOLTIP                                    :{BLACK}Centre main view on buoy location. Ctrl+Click opens a new viewport on buoy location
 
STR_BUOY_VIEW_CHANGE_BUOY_NAME                                  :{BLACK}Change buoy name
 

	
 
STR_EDIT_WAYPOINT_NAME                                          :{WHITE}Edit waypoint name
 

	
 
# Finances window
 
STR_FINANCES_CAPTION                                            :{WHITE}{COMPANY} Finances {BLACK}{COMPANYNUM}
 
STR_FINANCES_EXPENDITURE_INCOME_TITLE                           :{WHITE}Expenditure/Income
 
STR_FINANCES_YEAR                                               :{WHITE}{NUM}
 
STR_FINANCES_SECTION_CONSTRUCTION                               :{GOLD}Construction
 
STR_FINANCES_SECTION_NEW_VEHICLES                               :{GOLD}New Vehicles
 
STR_FINANCES_SECTION_TRAIN_RUNNING_COSTS                        :{GOLD}Train Running Costs
 
STR_FINANCES_SECTION_ROAD_VEHICLE_RUNNING_COSTS                 :{GOLD}Road Vehicle Running Costs
 
STR_FINANCES_SECTION_AIRCRAFT_RUNNING_COSTS                     :{GOLD}Aircraft Running Costs
 
STR_FINANCES_SECTION_SHIP_RUNNING_COSTS                         :{GOLD}Ship Running Costs
 
STR_FINANCES_SECTION_PROPERTY_MAINTENANCE                       :{GOLD}Property Maintenance
 
STR_FINANCES_SECTION_TRAIN_INCOME                               :{GOLD}Train Income
 
STR_FINANCES_SECTION_ROAD_VEHICLE_INCOME                        :{GOLD}Road Vehicle Income
 
STR_FINANCES_SECTION_AIRCRAFT_INCOME                            :{GOLD}Aircraft Income
 
STR_FINANCES_SECTION_SHIP_INCOME                                :{GOLD}Ship Income
 
STR_FINANCES_SECTION_LOAN_INTEREST                              :{GOLD}Loan Interest
 
STR_FINANCES_SECTION_OTHER                                      :{GOLD}Other
 
STR_FINANCES_NEGATIVE_INCOME                                    :{BLACK}-{CURRENCY}
 
STR_FINANCES_POSITIVE_INCOME                                    :{BLACK}+{CURRENCY}
 
STR_FINANCES_TOTAL_CAPTION                                      :{WHITE}Total:
 
STR_FINANCES_BANK_BALANCE_TITLE                                 :{WHITE}Bank Balance
 
STR_FINANCES_LOAN_TITLE                                         :{WHITE}Loan
 
STR_FINANCES_MAX_LOAN                                           :{WHITE}Max Loan: {BLACK}{CURRENCY}
 
STR_FINANCES_TOTAL_CURRENCY                                     :{BLACK}{CURRENCY}
 
STR_FINANCES_BORROW_BUTTON                                      :{BLACK}Borrow {CURRENCY}
 
STR_FINANCES_BORROW_TOOLTIP                                     :{BLACK}Increase size of loan. Ctrl+Click borrows as much as possible
 
STR_FINANCES_REPAY_BUTTON                                       :{BLACK}Repay {CURRENCY}
 
STR_FINANCES_REPAY_TOOLTIP                                      :{BLACK}Repay part of loan. Ctrl+Click repays as much loan as possible
 

	
 
# Company view
 
STR_COMPANY_VIEW_CAPTION                                        :{WHITE}{COMPANY} {BLACK}{COMPANYNUM}
 
STR_COMPANY_VIEW_PRESIDENT_MANAGER_TITLE                        :{WHITE}{PRESIDENTNAME}{}{GOLD}(Manager)
 

	
 
STR_COMPANY_VIEW_INAUGURATED_TITLE                              :{GOLD}Inaugurated: {WHITE}{NUM}
 
STR_COMPANY_VIEW_COLOUR_SCHEME_TITLE                            :{GOLD}Colour Scheme:
 
STR_COMPANY_VIEW_VEHICLES_TITLE                                 :{GOLD}Vehicles:
 
STR_COMPANY_VIEW_TRAINS                                         :{WHITE}{COMMA} train{P "" s}
 
STR_COMPANY_VIEW_ROAD_VEHICLES                                  :{WHITE}{COMMA} road vehicle{P "" s}
 
STR_COMPANY_VIEW_AIRCRAFT                                       :{WHITE}{COMMA} aircraft
 
STR_COMPANY_VIEW_SHIPS                                          :{WHITE}{COMMA} ship{P "" s}
 
STR_COMPANY_VIEW_VEHICLES_NONE                                  :{WHITE}None
 
STR_COMPANY_VIEW_COMPANY_VALUE                                  :{GOLD}Company value: {WHITE}{CURRENCY}
src/newgrf_commons.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_commons.cpp Implementation of the class OverrideManagerBase
 
 * and its descendance, present and futur
 
 */
 

	
 
#include "stdafx.h"
 
#include "debug.h"
 
#include "landscape.h"
 
#include "house.h"
 
#include "industrytype.h"
 
#include "newgrf.h"
 
#include "newgrf_config.h"
 
#include "clear_map.h"
 
#include "station_map.h"
 
#include "tree_map.h"
 
#include "tunnelbridge_map.h"
 
#include "newgrf_object.h"
 
#include "genworld.h"
 
#include "newgrf_spritegroup.h"
 
#include "newgrf_text.h"
 
#include "livery.h"
 
#include "company_base.h"
 
#include "gui.h"
 
#include "strings_func.h"
 

	
 
#include "table/strings.h"
 

	
 
/**
 
 * Constructor of generic class
 
 * @param offset end of original data for this entity. i.e: houses = 110
 
 * @param maximum of entities this manager can deal with. i.e: houses = 512
 
 * @param invalid is the ID used to identify an invalid entity id
 
 */
 
OverrideManagerBase::OverrideManagerBase(uint16 offset, uint16 maximum, uint16 invalid)
 
{
 
	max_offset = offset;
 
	max_new_entities = maximum;
 
	invalid_ID = invalid;
 

	
 
	mapping_ID = CallocT<EntityIDMapping>(max_new_entities);
 
	entity_overrides = MallocT<uint16>(max_offset);
 
	for (size_t i = 0; i < max_offset; i++) entity_overrides[i] = invalid;
 
	grfid_overrides = CallocT<uint32>(max_offset);
 
}
 

	
 
/**
 
 * Destructor of the generic class.
 
 * Frees allocated memory of constructor
 
 */
 
OverrideManagerBase::~OverrideManagerBase()
 
{
 
	free(mapping_ID);
 
	free(entity_overrides);
 
	free(grfid_overrides);
 
}
 

	
 
/**
 
 * Since the entity IDs defined by the GRF file does not necessarily correlate
 
 * to those used by the game, the IDs used for overriding old entities must be
 
 * translated when the entity spec is set.
 
 * @param local_id ID in grf file
 
 * @param grfid  ID of the grf file
 
 * @param entity_type original entity type
 
 */
 
void OverrideManagerBase::Add(uint8 local_id, uint32 grfid, uint entity_type)
 
{
 
	assert(entity_type < max_offset);
 
	/* An override can be set only once */
 
	if (entity_overrides[entity_type] != invalid_ID) return;
 
	entity_overrides[entity_type] = local_id;
 
	grfid_overrides[entity_type] = grfid;
 
}
 

	
 
/** Resets the mapping, which is used while initializing game */
 
void OverrideManagerBase::ResetMapping()
 
{
 
	memset(mapping_ID, 0, (max_new_entities - 1) * sizeof(EntityIDMapping));
 
}
 

	
 
/** Resets the override, which is used while initializing game */
 
void OverrideManagerBase::ResetOverride()
 
{
 
	for (uint16 i = 0; i < max_offset; i++) {
 
		entity_overrides[i] = invalid_ID;
 
		grfid_overrides[i] = 0;
 
	}
 
}
 

	
 
/**
 
 * Return the ID (if ever available) of a previously inserted entity.
 
 * @param grf_local_id ID of this enity withing the grfID
 
 * @param grfid ID of the grf file
 
 * @return the ID of the candidate, of the Invalid flag item ID
 
 */
 
uint16 OverrideManagerBase::GetID(uint8 grf_local_id, uint32 grfid) const
 
{
 
	const EntityIDMapping *map;
 

	
 
	for (uint16 id = 0; id < max_new_entities; id++) {
 
		map = &mapping_ID[id];
 
		if (map->entity_id == grf_local_id && map->grfid == grfid) {
 
			return id;
 
		}
 
	}
 

	
 
	return invalid_ID;
 
}
 

	
 
/**
 
 * Reserves a place in the mapping array for an entity to be installed
 
 * @param grf_local_id is an arbitrary id given by the grf's author.  Also known as setid
 
 * @param grfid is the id of the grf file itself
 
 * @param substitute_id is the original entity from which data is copied for the new one
 
 * @return the proper usable slot id, or invalid marker if none is found
 
 */
 
uint16 OverrideManagerBase::AddEntityID(byte grf_local_id, uint32 grfid, byte substitute_id)
 
{
 
	uint16 id = this->GetID(grf_local_id, grfid);
 
	EntityIDMapping *map;
 

	
 
	/* Look to see if this entity has already been added. This is done
 
	 * separately from the loop below in case a GRF has been deleted, and there
 
	 * are any gaps in the array.
 
	 */
 
	if (id != invalid_ID) {
 
		return id;
 
	}
 

	
 
	/* This entity hasn't been defined before, so give it an ID now. */
 
	for (id = max_offset; id < max_new_entities; id++) {
 
		map = &mapping_ID[id];
 

	
 
		if (CheckValidNewID(id) && map->entity_id == 0 && map->grfid == 0) {
 
			map->entity_id     = grf_local_id;
 
			map->grfid         = grfid;
 
			map->substitute_id = substitute_id;
 
			return id;
 
		}
 
	}
 

	
 
	return invalid_ID;
 
}
 

	
 
/**
 
 * Gives the GRFID of the file the entity belongs to.
 
 * @param entity_id ID of the entity being queried.
 
 * @return GRFID.
 
 */
 
uint32 OverrideManagerBase::GetGRFID(uint16 entity_id) const
 
{
 
	return mapping_ID[entity_id].grfid;
 
}
 

	
 
/**
 
 * Gives the substitute of the entity, as specified by the grf file
 
 * @param entity_id of the entity being queried
 
 * @return mapped id
 
 */
 
uint16 OverrideManagerBase::GetSubstituteID(uint16 entity_id) const
 
{
 
	return mapping_ID[entity_id].substitute_id;
 
}
 

	
 
/**
 
 * Install the specs into the HouseSpecs array
 
 * It will find itself the proper slot onwhich it will go
 
 * @param hs HouseSpec read from the grf file, ready for inclusion
 
 */
 
void HouseOverrideManager::SetEntitySpec(const HouseSpec *hs)
 
{
 
	HouseID house_id = this->AddEntityID(hs->grf_prop.local_id, hs->grf_prop.grffile->grfid, hs->grf_prop.subst_id);
 

	
 
	if (house_id == invalid_ID) {
 
		grfmsg(1, "House.SetEntitySpec: Too many houses allocated. Ignoring.");
 
		return;
 
	}
 

	
 
	MemCpyT(HouseSpec::Get(house_id), hs);
 

	
 
	/* Now add the overrides. */
 
	for (int i = 0; i != max_offset; i++) {
 
		HouseSpec *overridden_hs = HouseSpec::Get(i);
 

	
 
		if (entity_overrides[i] != hs->grf_prop.local_id || grfid_overrides[i] != hs->grf_prop.grffile->grfid) continue;
 

	
 
		overridden_hs->grf_prop.override = house_id;
 
		entity_overrides[i] = invalid_ID;
 
		grfid_overrides[i] = 0;
 
	}
 
}
 

	
 
/**
 
 * Return the ID (if ever available) of a previously inserted entity.
 
 * @param grf_local_id ID of this enity withing the grfID
 
 * @param grfid ID of the grf file
 
 * @return the ID of the candidate, of the Invalid flag item ID
 
 */
 
uint16 IndustryOverrideManager::GetID(uint8 grf_local_id, uint32 grfid) const
 
{
 
	uint16 id = OverrideManagerBase::GetID(grf_local_id, grfid);
 
	if (id != invalid_ID) return id;
 

	
 
	/* No mapping found, try the overrides */
 
	for (id = 0; id < max_offset; id++) {
 
		if (entity_overrides[id] == grf_local_id && grfid_overrides[id] == grfid) return id;
 
	}
 

	
 
	return invalid_ID;
 
}
 

	
 
/**
 
 * Method to find an entity ID and to mark it as reserved for the Industry to be included.
 
 * @param grf_local_id ID used by the grf file for pre-installation work (equivalent of TTDPatch's setid
 
 * @param grfid ID of the current grf file
 
 * @param substitute_id industry from which data has been copied
 
 * @return a free entity id (slotid) if ever one has been found, or Invalid_ID marker otherwise
 
@@ -306,384 +310,416 @@ void IndustryTileOverrideManager::SetEnt
 

	
 
/**
 
 * Method to install the new object data in its proper slot
 
 * The slot assigment is internal of this method, since it requires
 
 * checking what is available
 
 * @param spec ObjectSpec that comes from the grf decoding process
 
 */
 
void ObjectOverrideManager::SetEntitySpec(ObjectSpec *spec)
 
{
 
	/* First step : We need to find if this object is already specified in the savegame data. */
 
	ObjectType type = this->GetID(spec->grf_prop.local_id, spec->grf_prop.grffile->grfid);
 

	
 
	if (type == invalid_ID) {
 
		/* Not found.
 
		 * Or it has already been overriden, so you've lost your place old boy.
 
		 * Or it is a simple substitute.
 
		 * We need to find a free available slot */
 
		type = this->AddEntityID(spec->grf_prop.local_id, spec->grf_prop.grffile->grfid, OBJECT_TRANSMITTER);
 
	}
 

	
 
	if (type == invalid_ID) {
 
		grfmsg(1, "Object.SetEntitySpec: Too many objects allocated. Ignoring.");
 
		return;
 
	}
 

	
 
	extern ObjectSpec _object_specs[NUM_OBJECTS];
 

	
 
	/* Now that we know we can use the given id, copy the spec to its final destination. */
 
	memcpy(&_object_specs[type], spec, sizeof(*spec));
 
	ObjectClass::Assign(&_object_specs[type]);
 
}
 

	
 
/**
 
 * Function used by houses (and soon industries) to get information
 
 * on type of "terrain" the tile it is queries sits on.
 
 * @param tile TileIndex of the tile been queried
 
 * @param context The context of the tile.
 
 * @return value corresponding to the grf expected format:
 
 *         Terrain type: 0 normal, 1 desert, 2 rainforest, 4 on or above snowline
 
 */
 
uint32 GetTerrainType(TileIndex tile, TileContext context)
 
{
 
	switch (_settings_game.game_creation.landscape) {
 
		case LT_TROPIC: return GetTropicZone(tile);
 
		case LT_ARCTIC: {
 
			bool has_snow;
 
			switch (GetTileType(tile)) {
 
				case MP_CLEAR:
 
					/* During map generation the snowstate may not be valid yet, as the tileloop may not have run yet. */
 
					if (_generating_world) goto genworld;
 
					has_snow = IsSnowTile(tile) && GetClearDensity(tile) >= 2;
 
					break;
 

	
 
				case MP_RAILWAY: {
 
					/* During map generation the snowstate may not be valid yet, as the tileloop may not have run yet. */
 
					if (_generating_world) goto genworld; // we do not care about foundations here
 
					RailGroundType ground = GetRailGroundType(tile);
 
					has_snow = (ground == RAIL_GROUND_ICE_DESERT || (context == TCX_UPPER_HALFTILE && ground == RAIL_GROUND_HALF_SNOW));
 
					break;
 
				}
 

	
 
				case MP_ROAD:
 
					/* During map generation the snowstate may not be valid yet, as the tileloop may not have run yet. */
 
					if (_generating_world) goto genworld; // we do not care about foundations here
 
					has_snow = IsOnSnow(tile);
 
					break;
 

	
 
				case MP_TREES: {
 
					/* During map generation the snowstate may not be valid yet, as the tileloop may not have run yet. */
 
					if (_generating_world) goto genworld;
 
					TreeGround ground = GetTreeGround(tile);
 
					has_snow = (ground == TREE_GROUND_SNOW_DESERT || ground == TREE_GROUND_ROUGH_SNOW) && GetTreeDensity(tile) >= 2;
 
					break;
 
				}
 

	
 
				case MP_TUNNELBRIDGE:
 
					if (context == TCX_ON_BRIDGE) {
 
						has_snow = (GetBridgeHeight(tile) > GetSnowLine());
 
					} else {
 
						/* During map generation the snowstate may not be valid yet, as the tileloop may not have run yet. */
 
						if (_generating_world) goto genworld; // we do not care about foundations here
 
						has_snow = HasTunnelBridgeSnowOrDesert(tile);
 
					}
 
					break;
 

	
 
				case MP_STATION:
 
				case MP_HOUSE:
 
				case MP_INDUSTRY:
 
				case MP_OBJECT:
 
					/* These tiles usually have a levelling foundation. So use max Z */
 
					has_snow = (GetTileMaxZ(tile) > GetSnowLine());
 
					break;
 

	
 
				case MP_VOID:
 
				case MP_WATER:
 
				genworld:
 
					has_snow = (GetTileZ(tile) > GetSnowLine());
 
					break;
 

	
 
				default: NOT_REACHED();
 
			}
 
			return has_snow ? 4 : 0;
 
		}
 
		default:        return 0;
 
	}
 
}
 

	
 
/**
 
 * Get the tile at the given offset.
 
 * @param parameter The NewGRF "encoded" offset.
 
 * @param tile The tile to base the offset from.
 
 * @param signed_offsets Whether the offsets are to be interpreted as signed or not.
 
 * @param axis Axis of a railways station.
 
 * @return The tile at the offset.
 
 */
 
TileIndex GetNearbyTile(byte parameter, TileIndex tile, bool signed_offsets, Axis axis)
 
{
 
	int8 x = GB(parameter, 0, 4);
 
	int8 y = GB(parameter, 4, 4);
 

	
 
	if (signed_offsets && x >= 8) x -= 16;
 
	if (signed_offsets && y >= 8) y -= 16;
 

	
 
	/* Swap width and height depending on axis for railway stations */
 
	if (axis == INVALID_AXIS && HasStationTileRail(tile)) axis = GetRailStationAxis(tile);
 
	if (axis == AXIS_Y) Swap(x, y);
 

	
 
	/* Make sure we never roam outside of the map, better wrap in that case */
 
	return TILE_MASK(tile + TileDiffXY(x, y));
 
}
 

	
 
/**
 
 * Common part of station var 0x67, house var 0x62, indtile var 0x60, industry var 0x62.
 
 *
 
 * @param tile the tile of interest.
 
 * @return 0czzbbss: c = TileType; zz = TileZ; bb: 7-3 zero, 4-2 TerrainType, 1 water/shore, 0 zero; ss = TileSlope
 
 */
 
uint32 GetNearbyTileInformation(TileIndex tile)
 
{
 
	TileType tile_type = GetTileType(tile);
 

	
 
	/* Fake tile type for trees on shore */
 
	if (IsTileType(tile, MP_TREES) && GetTreeGround(tile) == TREE_GROUND_SHORE) tile_type = MP_WATER;
 

	
 
	int z;
 
	Slope tileh = GetTilePixelSlope(tile, &z);
 
	/* Return 0 if the tile is a land tile */
 
	byte terrain_type = (HasTileWaterClass(tile) ? (GetWaterClass(tile) + 1) & 3 : 0) << 5 | GetTerrainType(tile) << 2 | (tile_type == MP_WATER ? 1 : 0) << 1;
 
	return tile_type << 24 | z << 16 | terrain_type << 8 | tileh;
 
}
 

	
 
/**
 
 * Returns company information like in vehicle var 43 or station var 43.
 
 * @param owner Owner of the object.
 
 * @param l Livery of the object; NULL to use default.
 
 * @return NewGRF company information.
 
 */
 
uint32 GetCompanyInfo(CompanyID owner, const Livery *l)
 
{
 
	if (l == NULL && Company::IsValidID(owner)) l = &Company::Get(owner)->livery[LS_DEFAULT];
 
	return owner | (Company::IsValidAiID(owner) ? 0x10000 : 0) | (l != NULL ? (l->colour1 << 24) | (l->colour2 << 28) : 0);
 
}
 

	
 
/**
 
 * Get the error message from a shape/location/slope check callback result.
 
 * @param cb_res Callback result to translate. If bit 10 is set this is a standard error message, otherwise a NewGRF provided string.
 
 * @param grfid grfID to use to resolve a custom error message.
 
 * @param default_error Error message to use for the generic error.
 
 * @return CommandCost indicating success or the error message.
 
 */
 
CommandCost GetErrorMessageFromLocationCallbackResult(uint16 cb_res, uint32 grfid, StringID default_error)
 
{
 
	CommandCost res;
 
	switch (cb_res) {
 
		case 0x400: return res; // No error.
 
		case 0x401: res = CommandCost(default_error); break;
 
		case 0x402: res = CommandCost(STR_ERROR_CAN_ONLY_BE_BUILT_IN_RAINFOREST); break;
 
		case 0x403: res = CommandCost(STR_ERROR_CAN_ONLY_BE_BUILT_IN_DESERT); break;
 
		case 0x404: res = CommandCost(STR_ERROR_CAN_ONLY_BE_BUILT_ABOVE_SNOW_LINE); break;
 
		case 0x405: res = CommandCost(STR_ERROR_CAN_ONLY_BE_BUILT_BELOW_SNOW_LINE); break;
 
		case 0x406: res = CommandCost(STR_ERROR_CAN_T_BUILD_ON_SEA); break;
 
		case 0x407: res = CommandCost(STR_ERROR_CAN_T_BUILD_ON_CANAL); break;
 
		case 0x408: res = CommandCost(STR_ERROR_CAN_T_BUILD_ON_RIVER); break;
 
		default:    res = CommandCost(GetGRFStringID(grfid, 0xD000 + cb_res)); break;
 
	}
 

	
 
	/* Copy some parameters from the registers to the error message text ref. stack */
 
	res.UseTextRefStack(4);
 

	
 
	return res;
 
}
 

	
 
/**
 
 * Record that a NewGRF returned an unknown/invalid callback result.
 
 * Also show an error to the user.
 
 * @param grfid ID of the NewGRF causing the problem.
 
 * @param cbid Callback causing the problem.
 
 * @param cb_res Invalid result returned by the callback.
 
 */
 
void ErrorUnknownCallbackResult(uint32 grfid, uint16 cbid, uint16 cb_res)
 
{
 
	GRFConfig *grfconfig = GetGRFConfig(grfid);
 

	
 
	if (!HasBit(grfconfig->grf_bugs, GBUG_UNKNOWN_CB_RESULT)) {
 
		SetBit(grfconfig->grf_bugs, GBUG_UNKNOWN_CB_RESULT);
 
		SetDParamStr(0, grfconfig->GetName());
 
		SetDParam(1, cbid);
 
		SetDParam(2, cb_res);
 
		ShowErrorMessage(STR_NEWGRF_BUGGY, STR_NEWGRF_BUGGY_UNKNOWN_CALLBACK_RESULT, WL_CRITICAL);
 
	}
 

	
 
	/* debug output */
 
	char buffer[512];
 

	
 
	SetDParamStr(0, grfconfig->GetName());
 
	GetString(buffer, STR_NEWGRF_BUGGY, lastof(buffer));
 
	DEBUG(grf, 0, "%s", buffer + 3);
 

	
 
	SetDParam(1, cbid);
 
	SetDParam(2, cb_res);
 
	GetString(buffer, STR_NEWGRF_BUGGY_UNKNOWN_CALLBACK_RESULT, lastof(buffer));
 
	DEBUG(grf, 0, "%s", buffer + 3);
 
}
 

	
 
/* static */ SmallVector<DrawTileSeqStruct, 8> NewGRFSpriteLayout::result_seq;
 

	
 
/**
 
 * Clone the building sprites of a spritelayout.
 
 * @param source The building sprites to copy.
 
 */
 
void NewGRFSpriteLayout::Clone(const DrawTileSeqStruct *source)
 
{
 
	assert(this->seq == NULL);
 
	assert(source != NULL);
 

	
 
	size_t count = 1; // 1 for the terminator
 
	const DrawTileSeqStruct *element;
 
	foreach_draw_tile_seq(element, source) count++;
 

	
 
	DrawTileSeqStruct *sprites = MallocT<DrawTileSeqStruct>(count);
 
	MemCpyT(sprites, source, count);
 
	this->seq = sprites;
 
}
 

	
 
/**
 
 * Clone a spritelayout.
 
 * @param source The spritelayout to copy.
 
 */
 
void NewGRFSpriteLayout::Clone(const NewGRFSpriteLayout *source)
 
{
 
	this->Clone((const DrawTileSprites*)source);
 

	
 
	if (source->registers != NULL) {
 
		size_t count = 1; // 1 for the ground sprite
 
		const DrawTileSeqStruct *element;
 
		foreach_draw_tile_seq(element, source->seq) count++;
 

	
 
		TileLayoutRegisters *regs = MallocT<TileLayoutRegisters>(count);
 
		MemCpyT(regs, source->registers, count);
 
		this->registers = regs;
 
	}
 
}
 

	
 

	
 
/**
 
 * Allocate a spritelayout for \a num_sprites building sprites.
 
 * @param num_sprites Number of building sprites to allocate memory for. (not counting the terminator)
 
 */
 
void NewGRFSpriteLayout::Allocate(uint num_sprites)
 
{
 
	assert(this->seq == NULL);
 

	
 
	DrawTileSeqStruct *sprites = CallocT<DrawTileSeqStruct>(num_sprites + 1);
 
	sprites[num_sprites].MakeTerminator();
 
	this->seq = sprites;
 
}
 

	
 
/**
 
 * Allocate memory for register modifiers.
 
 */
 
void NewGRFSpriteLayout::AllocateRegisters()
 
{
 
	assert(this->seq != NULL);
 
	assert(this->registers == NULL);
 

	
 
	size_t count = 1; // 1 for the ground sprite
 
	const DrawTileSeqStruct *element;
 
	foreach_draw_tile_seq(element, this->seq) count++;
 

	
 
	this->registers = CallocT<TileLayoutRegisters>(count);
 
}
 

	
 
/**
 
 * Prepares a sprite layout before resolving action-1-2-3 chains.
 
 * Integrates offsets into the layout and determines which chains to resolve.
 
 * @note The function uses statically allocated temporary storage, which is reused everytime when calling the function.
 
 *       That means, you have to use the sprite layout before calling #PrepareLayout() the next time.
 
 * @param orig_offset          Offset to apply to non-action-1 sprites.
 
 * @param newgrf_ground_offset Offset to apply to action-1 ground sprites.
 
 * @param newgrf_offset        Offset to apply to action-1 non-ground sprites.
 
 * @param constr_stage         Construction stage (0-3) to apply to all action-1 sprites.
 
 * @param separate_ground      Whether the ground sprite shall be resolved by a separate action-1-2-3 chain by default.
 
 * @return Bitmask of values for variable 10 to resolve action-1-2-3 chains for.
 
 */
 
uint32 NewGRFSpriteLayout::PrepareLayout(uint32 orig_offset, uint32 newgrf_ground_offset, uint32 newgrf_offset, uint constr_stage, bool separate_ground) const
 
{
 
	result_seq.Clear();
 
	uint32 var10_values = 0;
 

	
 
	/* Create a copy of the spritelayout, so we can modify some values.
 
	 * Also include the groundsprite into the sequence for easier processing. */
 
	DrawTileSeqStruct *result = result_seq.Append();
 
	result->image = ground;
 
	result->delta_x = 0;
 
	result->delta_y = 0;
 
	result->delta_z = (int8)0x80;
 

	
 
	const DrawTileSeqStruct *dtss;
 
	foreach_draw_tile_seq(dtss, this->seq) {
 
		*result_seq.Append() = *dtss;
 
	}
 
	result_seq.Append()->MakeTerminator();
 

	
 
	/* Determine the var10 values the action-1-2-3 chains needs to be resolved for,
 
	 * and apply the default sprite offsets (unless disabled). */
 
	const TileLayoutRegisters *regs = this->registers;
 
	bool ground = true;
 
	foreach_draw_tile_seq(result, result_seq.Begin()) {
 
		TileLayoutFlags flags = TLF_NOTHING;
 
		if (regs != NULL) flags = regs->flags;
 

	
 
		/* Record var10 value for the sprite */
 
		if (HasBit(result->image.sprite, SPRITE_MODIFIER_CUSTOM_SPRITE) || (flags & TLF_SPRITE_REG_FLAGS)) {
 
			uint8 var10 = (flags & TLF_SPRITE_VAR10) ? regs->sprite_var10 : (ground && separate_ground ? 1 : 0);
 
			SetBit(var10_values, var10);
 
		}
 

	
 
		/* Add default sprite offset, unless there is a custom one */
 
		if (!(flags & TLF_SPRITE)) {
 
			if (HasBit(result->image.sprite, SPRITE_MODIFIER_CUSTOM_SPRITE)) {
 
				result->image.sprite += ground ? newgrf_ground_offset : newgrf_offset;
 
				if (constr_stage > 0 && regs != NULL) result->image.sprite += GetConstructionStageOffset(constr_stage, regs->max_sprite_offset);
 
			} else {
 
				result->image.sprite += orig_offset;
 
			}
 
		}
 

	
 
		/* Record var10 value for the palette */
 
		if (HasBit(result->image.pal, SPRITE_MODIFIER_CUSTOM_SPRITE) || (flags & TLF_PALETTE_REG_FLAGS)) {
 
			uint8 var10 = (flags & TLF_PALETTE_VAR10) ? regs->palette_var10 : (ground && separate_ground ? 1 : 0);
 
			SetBit(var10_values, var10);
 
		}
 

	
 
		/* Add default palette offset, unless there is a custom one */
 
		if (!(flags & TLF_PALETTE)) {
 
			if (HasBit(result->image.pal, SPRITE_MODIFIER_CUSTOM_SPRITE)) {
 
				result->image.sprite += ground ? newgrf_ground_offset : newgrf_offset;
 
				if (constr_stage > 0 && regs != NULL) result->image.sprite += GetConstructionStageOffset(constr_stage, regs->max_palette_offset);
 
			}
 
		}
 

	
 
		ground = false;
 
		if (regs != NULL) regs++;
 
	}
 

	
 
	return var10_values;
 
}
 

	
 
/**
 
 * Evaluates the register modifiers and integrates them into the preprocessed sprite layout.
 
 * @pre #PrepareLayout() needs calling first.
 
 * @param resolved_var10  The value of var10 the action-1-2-3 chain was evaluated for.
 
 * @param resolved_sprite Result sprite of the action-1-2-3 chain.
 
 * @param separate_ground Whether the ground sprite is resolved by a separate action-1-2-3 chain.
 
 * @return Resulting spritelayout after processing the registers.
 
 */
 
void NewGRFSpriteLayout::ProcessRegisters(uint8 resolved_var10, uint32 resolved_sprite, bool separate_ground) const
 
{
 
	DrawTileSeqStruct *result;
 
	const TileLayoutRegisters *regs = this->registers;
 
	bool ground = true;
 
	foreach_draw_tile_seq(result, result_seq.Begin()) {
 
		TileLayoutFlags flags = TLF_NOTHING;
 
		if (regs != NULL) flags = regs->flags;
 

	
 
		/* Is the sprite or bounding box affected by an action-1-2-3 chain? */
 
		if (HasBit(result->image.sprite, SPRITE_MODIFIER_CUSTOM_SPRITE) || (flags & TLF_SPRITE_REG_FLAGS)) {
 
			/* Does the var10 value apply to this sprite? */
 
			uint8 var10 = (flags & TLF_SPRITE_VAR10) ? regs->sprite_var10 : (ground && separate_ground ? 1 : 0);
 
			if (var10 == resolved_var10) {
 
				/* Apply registers */
 
				if ((flags & TLF_DODRAW) && GetRegister(regs->dodraw) == 0) {
 
					result->image.sprite = 0;
 
				} else {
 
					if (HasBit(result->image.sprite, SPRITE_MODIFIER_CUSTOM_SPRITE)) result->image.sprite += resolved_sprite;
 
					if (flags & TLF_SPRITE) {
 
						int16 offset = (int16)GetRegister(regs->sprite); // mask to 16 bits to avoid trouble
 
						if (!HasBit(result->image.sprite, SPRITE_MODIFIER_CUSTOM_SPRITE) || (offset >= 0 && offset < regs->max_sprite_offset)) {
 
							result->image.sprite += offset;
 
						} else {
 
							result->image.sprite = SPR_IMG_QUERY;
 
						}
 
					}
 

	
 
					if (result->IsParentSprite()) {
 
						if (flags & TLF_BB_XY_OFFSET) {
 
							result->delta_x += (int32)GetRegister(regs->delta.parent[0]);
 
							result->delta_y += (int32)GetRegister(regs->delta.parent[1]);
 
						}
 
						if (flags & TLF_BB_Z_OFFSET)    result->delta_z += (int32)GetRegister(regs->delta.parent[2]);
 
					} else {
 
						if (flags & TLF_CHILD_X_OFFSET) result->delta_x += (int32)GetRegister(regs->delta.child[0]);
 
						if (flags & TLF_CHILD_Y_OFFSET) result->delta_y += (int32)GetRegister(regs->delta.child[1]);
 
					}
 
				}
 
			}
src/newgrf_commons.h
Show inline comments
 
@@ -111,225 +111,227 @@ static const uint TLR_MAX_VAR10 = 7; ///
 
/**
 
 * NewGRF supplied spritelayout.
 
 * In contrast to #DrawTileSprites this struct is for allocated
 
 * layouts on the heap. It allocates data and frees them on destruction.
 
 */
 
struct NewGRFSpriteLayout : ZeroedMemoryAllocator, DrawTileSprites {
 
	const TileLayoutRegisters *registers;
 

	
 
	/**
 
	 * Number of sprites in all referenced spritesets.
 
	 * If these numbers are inconsistent, then this is 0 and the real values are in \c registers.
 
	 */
 
	uint consistent_max_offset;
 

	
 
	void Allocate(uint num_sprites);
 
	void AllocateRegisters();
 
	void Clone(const DrawTileSeqStruct *source);
 
	void Clone(const NewGRFSpriteLayout *source);
 

	
 
	/**
 
	 * Clone a spritelayout.
 
	 * @param source The spritelayout to copy.
 
	 */
 
	void Clone(const DrawTileSprites *source)
 
	{
 
		assert(source != NULL && this != source);
 
		this->ground = source->ground;
 
		this->Clone(source->seq);
 
	}
 

	
 
	virtual ~NewGRFSpriteLayout()
 
	{
 
		free(const_cast<DrawTileSeqStruct*>(this->seq));
 
		free(const_cast<TileLayoutRegisters*>(this->registers));
 
	}
 

	
 
	/**
 
	 * Tests whether this spritelayout needs preprocessing by
 
	 * #PrepareLayout() and #ProcessRegisters(), or whether it can be
 
	 * used directly.
 
	 * @return true if preprocessing is needed
 
	 */
 
	bool NeedsPreprocessing() const
 
	{
 
		return this->registers != NULL;
 
	}
 

	
 
	uint32 PrepareLayout(uint32 orig_offset, uint32 newgrf_ground_offset, uint32 newgrf_offset, uint constr_stage, bool separate_ground) const;
 
	void ProcessRegisters(uint8 resolved_var10, uint32 resolved_sprite, bool separate_ground) const;
 

	
 
	/**
 
	 * Returns the result spritelayout after preprocessing.
 
	 * @pre #PrepareLayout() and #ProcessRegisters() need calling first.
 
	 * @return result spritelayout
 
	 */
 
	const DrawTileSeqStruct *GetLayout(PalSpriteID *ground) const
 
	{
 
		DrawTileSeqStruct *front = result_seq.Begin();
 
		*ground = front->image;
 
		return front + 1;
 
	}
 

	
 
private:
 
	static SmallVector<DrawTileSeqStruct, 8> result_seq; ///< Temporary storage when preprocessing spritelayouts.
 
};
 

	
 
/**
 
 * Maps an entity id stored on the map to a GRF file.
 
 * Entities are objects used ingame (houses, industries, industry tiles) for
 
 * which we need to correlate the ids from the grf files with the ones in the
 
 * the savegames themselves.
 
 * An array of EntityIDMapping structs is saved with the savegame so
 
 * that those GRFs can be loaded in a different order, or removed safely. The
 
 * index in the array is the entity's ID stored on the map.
 
 *
 
 * The substitute ID is the ID of an original entity that should be used instead
 
 * if the GRF containing the new entity is not available.
 
 */
 
struct EntityIDMapping {
 
	uint32 grfid;          ///< The GRF ID of the file the entity belongs to
 
	uint8  entity_id;      ///< The entity ID within the GRF file
 
	uint8  substitute_id;  ///< The (original) entity ID to use if this GRF is not available
 
};
 

	
 
class OverrideManagerBase {
 
protected:
 
	uint16 *entity_overrides;
 
	uint32 *grfid_overrides;
 

	
 
	uint16 max_offset;       ///< what is the length of the original entity's array of specs
 
	uint16 max_new_entities; ///< what is the amount of entities, old and new summed
 

	
 
	uint16 invalid_ID;       ///< ID used to dected invalid entities;
 
	virtual bool CheckValidNewID(uint16 testid) { return true; }
 

	
 
public:
 
	EntityIDMapping *mapping_ID; ///< mapping of ids from grf files.  Public out of convenience
 

	
 
	OverrideManagerBase(uint16 offset, uint16 maximum, uint16 invalid);
 
	virtual ~OverrideManagerBase();
 

	
 
	void ResetOverride();
 
	void ResetMapping();
 

	
 
	void Add(uint8 local_id, uint32 grfid, uint entity_type);
 
	virtual uint16 AddEntityID(byte grf_local_id, uint32 grfid, byte substitute_id);
 

	
 
	uint32 GetGRFID(uint16 entity_id) const;
 
	uint16 GetSubstituteID(uint16 entity_id) const;
 
	virtual uint16 GetID(uint8 grf_local_id, uint32 grfid) const;
 

	
 
	inline uint16 GetMaxMapping() const { return max_new_entities; }
 
	inline uint16 GetMaxOffset() const { return max_offset; }
 
};
 

	
 

	
 
struct HouseSpec;
 
class HouseOverrideManager : public OverrideManagerBase {
 
public:
 
	HouseOverrideManager(uint16 offset, uint16 maximum, uint16 invalid) :
 
			OverrideManagerBase(offset, maximum, invalid) {}
 
	void SetEntitySpec(const HouseSpec *hs);
 
};
 

	
 

	
 
struct IndustrySpec;
 
class IndustryOverrideManager : public OverrideManagerBase {
 
public:
 
	IndustryOverrideManager(uint16 offset, uint16 maximum, uint16 invalid) :
 
			OverrideManagerBase(offset, maximum, invalid) {}
 

	
 
	virtual uint16 AddEntityID(byte grf_local_id, uint32 grfid, byte substitute_id);
 
	virtual uint16 GetID(uint8 grf_local_id, uint32 grfid) const;
 
	void SetEntitySpec(IndustrySpec *inds);
 
};
 

	
 

	
 
struct IndustryTileSpec;
 
class IndustryTileOverrideManager : public OverrideManagerBase {
 
protected:
 
	virtual bool CheckValidNewID(uint16 testid) { return testid != 0xFF; }
 
public:
 
	IndustryTileOverrideManager(uint16 offset, uint16 maximum, uint16 invalid) :
 
			OverrideManagerBase(offset, maximum, invalid) {}
 

	
 
	void SetEntitySpec(const IndustryTileSpec *indts);
 
};
 

	
 
struct AirportSpec;
 
class AirportOverrideManager : public OverrideManagerBase {
 
public:
 
	AirportOverrideManager(uint16 offset, uint16 maximum, uint16 invalid) :
 
			OverrideManagerBase(offset, maximum, invalid) {}
 

	
 
	void SetEntitySpec(AirportSpec *inds);
 
};
 

	
 
struct AirportTileSpec;
 
class AirportTileOverrideManager : public OverrideManagerBase {
 
protected:
 
	virtual bool CheckValidNewID(uint16 testid) { return testid != 0xFF; }
 
public:
 
	AirportTileOverrideManager(uint16 offset, uint16 maximum, uint16 invalid) :
 
			OverrideManagerBase(offset, maximum, invalid) {}
 

	
 
	void SetEntitySpec(const AirportTileSpec *ats);
 
};
 

	
 
struct ObjectSpec;
 
class ObjectOverrideManager : public OverrideManagerBase {
 
protected:
 
	virtual bool CheckValidNewID(uint16 testid) { return testid != 0xFF; }
 
public:
 
	ObjectOverrideManager(uint16 offset, uint16 maximum, uint16 invalid) :
 
			OverrideManagerBase(offset, maximum, invalid) {}
 

	
 
	void SetEntitySpec(ObjectSpec *spec);
 
};
 

	
 
extern HouseOverrideManager _house_mngr;
 
extern IndustryOverrideManager _industry_mngr;
 
extern IndustryTileOverrideManager _industile_mngr;
 
extern AirportOverrideManager _airport_mngr;
 
extern AirportTileOverrideManager _airporttile_mngr;
 
extern ObjectOverrideManager _object_mngr;
 

	
 
uint32 GetTerrainType(TileIndex tile, TileContext context = TCX_NORMAL);
 
TileIndex GetNearbyTile(byte parameter, TileIndex tile, bool signed_offsets = true, Axis axis = INVALID_AXIS);
 
uint32 GetNearbyTileInformation(TileIndex tile);
 
uint32 GetCompanyInfo(CompanyID owner, const struct Livery *l = NULL);
 
CommandCost GetErrorMessageFromLocationCallbackResult(uint16 cb_res, uint32 grfid, StringID default_error);
 

	
 
void ErrorUnknownCallbackResult(uint32 grfid, uint16 cbid, uint16 cb_res);
 

	
 
/**
 
 * Data related to the handling of grf files.
 
 * @tparam Tcnt Number of spritegroups
 
 */
 
template <size_t Tcnt>
 
struct GRFFilePropsBase {
 
	GRFFilePropsBase() : local_id(0), grffile(0)
 
	{
 
		/* The lack of some compilers to provide default constructors complying to the specs
 
		 * requires us to zero the stuff ourself. */
 
		memset(spritegroup, 0, sizeof(spritegroup));
 
	}
 

	
 
	uint16 local_id;                             ///< id defined by the grf file for this entity
 
	const struct GRFFile *grffile;               ///< grf file that introduced this entity
 
	const struct SpriteGroup *spritegroup[Tcnt]; ///< pointer to the different sprites of the entity
 
};
 

	
 
/** Data related to the handling of grf files. */
 
struct GRFFileProps : GRFFilePropsBase<1> {
 
	/** Set all default data constructor for the props. */
 
	GRFFileProps(uint16 subst_id) :
 
			GRFFilePropsBase<1>(), subst_id(subst_id), override(subst_id)
 
	{
 
	}
 

	
 
	/** Simple constructor for the props. */
 
	GRFFileProps() : GRFFilePropsBase<1>() {}
 
	uint16 subst_id;
 
	uint16 override;                      ///< id of the entity been replaced by
 
};
 

	
 
#endif /* NEWGRF_COMMONS_H */
src/newgrf_config.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_config.h Functions to find and configure NewGRFs. */
 

	
 
#ifndef NEWGRF_CONFIG_H
 
#define NEWGRF_CONFIG_H
 

	
 
#include "strings_type.h"
 
#include "core/alloc_type.hpp"
 
#include "core/smallmap_type.hpp"
 
#include "misc/countedptr.hpp"
 
#include "fileio_type.h"
 

	
 
/** GRF config bit flags */
 
enum GCF_Flags {
 
	GCF_SYSTEM,     ///< GRF file is an openttd-internal system grf
 
	GCF_UNSAFE,     ///< GRF file is unsafe for static usage
 
	GCF_STATIC,     ///< GRF file is used statically (can be used in any MP game)
 
	GCF_COMPATIBLE, ///< GRF file does not exactly match the requested GRF (different MD5SUM), but grfid matches)
 
	GCF_COPY,       ///< The data is copied from a grf in _all_grfs
 
	GCF_INIT_ONLY,  ///< GRF file is processed up to GLS_INIT
 
	GCF_RESERVED,   ///< GRF file passed GLS_RESERVE stage
 
	GCF_INVALID,    ///< GRF is unusable with this version of OpenTTD
 
};
 

	
 
/** Status of GRF */
 
enum GRFStatus {
 
	GCS_UNKNOWN,      ///< The status of this grf file is unknown
 
	GCS_DISABLED,     ///< GRF file is disabled
 
	GCS_NOT_FOUND,    ///< GRF file was not found in the local cache
 
	GCS_INITIALISED,  ///< GRF file has been initialised
 
	GCS_ACTIVATED     ///< GRF file has been activated
 
};
 

	
 
/** Encountered GRF bugs */
 
enum GRFBugs {
 
	GBUG_VEH_LENGTH,        ///< Length of rail vehicle changes when not inside a depot
 
	GBUG_VEH_REFIT,         ///< Articulated vehicles carry different cargos resp. are differently refittable than specified in purchase list
 
	GBUG_VEH_POWERED_WAGON, ///< Powered wagon changed poweredness state when not inside a depot
 
	GBUG_UNKNOWN_CB_RESULT, ///< A callback returned an unknown/invalid result
 
};
 

	
 
/** Status of post-gameload GRF compatibility check */
 
enum GRFListCompatibility {
 
	GLC_ALL_GOOD,   ///< All GRF needed by game are present
 
	GLC_COMPATIBLE, ///< Compatible (eg. the same ID, but different chacksum) GRF found in at least one case
 
	GLC_NOT_FOUND   ///< At least one GRF couldn't be found (higher priority than GLC_COMPATIBLE)
 
};
 

	
 
/** Information that can/has to be stored about a GRF's palette. */
 
enum GRFPalette {
 
	GRFP_USE_BIT     = 0,   ///< The bit used for storing the palette to use.
 
	GRFP_GRF_OFFSET  = 2,   ///< The offset of the GRFP_GRF data.
 
	GRFP_GRF_SIZE    = 2,   ///< The size of the GRFP_GRF data.
 
	GRFP_BLT_OFFSET  = 4,   ///< The offset of the GRFP_BLT data.
 
	GRFP_BLT_SIZE    = 1,   ///< The size of the GRFP_BLT data.
 

	
 
	GRFP_USE_DOS     = 0x0, ///< The palette state is set to use the DOS palette.
 
	GRFP_USE_WINDOWS = 0x1, ///< The palette state is set to use the Windows palette.
 
	GRFP_USE_MASK    = 0x1, ///< Bitmask to get only the use palette use states.
 

	
 
	GRFP_GRF_UNSET   = 0x0 << GRFP_GRF_OFFSET,          ///< The NewGRF provided no information.
 
	GRFP_GRF_DOS     = 0x1 << GRFP_GRF_OFFSET,          ///< The NewGRF says the DOS palette can be used.
 
	GRFP_GRF_WINDOWS = 0x2 << GRFP_GRF_OFFSET,          ///< The NewGRF says the Windows palette can be used.
 
	GRFP_GRF_ANY     = GRFP_GRF_DOS | GRFP_GRF_WINDOWS, ///< The NewGRF says any palette can be used.
 
	GRFP_GRF_MASK    = GRFP_GRF_ANY,                    ///< Bitmask to get only the NewGRF supplied information.
 

	
 
	GRFP_BLT_UNSET   = 0x0 << GRFP_BLT_OFFSET,          ///< The NewGRF provided no information or doesn't care about a 32 bpp blitter.
 
	GRFP_BLT_32BPP   = 0x1 << GRFP_BLT_OFFSET,          ///< The NewGRF prefers a 32 bpp blitter.
 
	GRFP_BLT_MASK    = GRFP_BLT_32BPP,                  ///< Bitmask to only get the blitter information.
 
};
 

	
 

	
 
/** Basic data to distinguish a GRF. Used in the server list window */
 
struct GRFIdentifier {
 
	uint32 grfid;     ///< GRF ID (defined by Action 0x08)
 
	uint8 md5sum[16]; ///< MD5 checksum of file to distinguish files with the same GRF ID (eg. newer version of GRF)
 

	
 
	/**
 
	 * Does the identification match the provided values?
 
	 * @param grfid  Expected grfid.
 
	 * @param md5sum Expected md5sum, may be \c NULL (in which case, do not check it).
 
	 * @return the object has the provided grfid and md5sum.
 
	 */
 
	FORCEINLINE bool HasGrfIdentifier(uint32 grfid, const uint8 *md5sum) const
 
	{
 
		if (this->grfid != grfid) return false;
 
		if (md5sum == NULL) return true;
 
		return memcmp(md5sum, this->md5sum, sizeof(this->md5sum)) == 0;
 
	}
 
};
 

	
 
/** Information about why GRF had problems during initialisation */
 
struct GRFError : ZeroedMemoryAllocator {
 
	GRFError(StringID severity, StringID message = 0);
 
	GRFError(const GRFError &error);
 
	~GRFError();
 

	
 
	char *custom_message;  ///< Custom message (if present)
 
	char *data;            ///< Additional data for message and custom_message
 
	StringID message;      ///< Default message
 
	StringID severity;     ///< Info / Warning / Error / Fatal
 
	uint8 num_params;      ///< Number of additinal parameters for message and custom_message (0, 1 or 2)
 
	uint32 param_value[2]; ///< Values of GRF parameters to show for message and custom_message
 
};
 

	
 
/** The possible types of a newgrf parameter. */
 
enum GRFParameterType {
 
	PTYPE_UINT_ENUM, ///< The parameter allows a range of numbers, each of which can have a special name
 
	PTYPE_BOOL,      ///< The parameter is either 0 or 1
 
	PTYPE_END,       ///< Invalid parameter type
 
};
 

	
 
/** Information about one grf parameter. */
 
struct GRFParameterInfo {
 
	GRFParameterInfo(uint nr);
 
	GRFParameterInfo(GRFParameterInfo &info);
 
	~GRFParameterInfo();
 
	struct GRFText *name;  ///< The name of this parameter
 
	struct GRFText *desc;  ///< The description of this parameter
 
	GRFParameterType type; ///< The type of this parameter
 
	uint32 min_value;      ///< The minimal value this parameter can have
 
	uint32 max_value;      ///< The maximal value of this parameter
 
	uint32 def_value;      ///< Default value of this parameter
 
	byte param_nr;         ///< GRF parameter to store content in
 
	byte first_bit;        ///< First bit to use in the GRF parameter
 
	byte num_bit;          ///< Number of bits to use for this parameter
 
	SmallMap<uint32, struct GRFText *, 8> value_names; ///< Names for each value.
 

	
 
	uint32 GetValue(struct GRFConfig *config) const;
 
	void SetValue(struct GRFConfig *config, uint32 value);
 
};
 

	
 
/** Reference counted wrapper around a GRFText pointer. */
 
struct GRFTextWrapper : public SimpleCountedObject {
 
	struct GRFText *text; ///< The actual text
 

	
 
	GRFTextWrapper();
 
	~GRFTextWrapper();
 
};
 

	
 
/** Information about GRF, used in the game and (part of it) in savegames */
 
struct GRFConfig : ZeroedMemoryAllocator {
 
	GRFConfig(const char *filename = NULL);
 
	GRFConfig(const GRFConfig &config);
 
	~GRFConfig();
 

	
 
	GRFIdentifier ident;                           ///< grfid and md5sum to uniquely identify newgrfs
 
	uint8 original_md5sum[16];                     ///< MD5 checksum of original file if only a 'compatible' file was loaded
 
	char *filename;                                ///< Filename - either with or without full path
 
	GRFTextWrapper *name;                          ///< NOSAVE: GRF name (Action 0x08)
 
	GRFTextWrapper *info;                          ///< NOSAVE: GRF info (author, copyright, ...) (Action 0x08)
 
	GRFError *error;                               ///< NOSAVE: Error/Warning during GRF loading (Action 0x0B)
 

	
 
	uint32 version;                                ///< NOSAVE: Version a NewGRF can set so only the newest NewGRF is shown
 
	uint32 min_loadable_version;                   ///< NOSAVE: Minimum compatible version a NewGRF can define
 
	uint8 flags;                                   ///< NOSAVE: GCF_Flags, bitset
 
	GRFStatus status;                              ///< NOSAVE: GRFStatus, enum
 
	uint32 grf_bugs;                               ///< NOSAVE: bugs in this GRF in this run, @see enum GRFBugs
 
	uint32 param[0x80];                            ///< GRF parameters
 
	uint8 num_params;                              ///< Number of used parameters
 
	uint8 num_valid_params;                        ///< NOSAVE: Number of valid parameters (action 0x14)
 
	uint8 palette;                                 ///< GRFPalette, bitset
 
	SmallVector<GRFParameterInfo *, 4> param_info; ///< NOSAVE: extra information about the parameters
 
	bool has_param_defaults;                       ///< NOSAVE: did this newgrf specify any defaults for it's parameters
 

	
 
	struct GRFConfig *next;                        ///< NOSAVE: Next item in the linked list
 

	
 
	bool IsOpenTTDBaseGRF() const;
 

	
 
	const char *GetName() const;
 
	const char *GetDescription() const;
 

	
 
	void SetParameterDefaults();
 
	void SetSuitablePalette();
 
};
 

	
 
/** Method to find GRFs using FindGRFConfig */
 
enum FindGRFConfigMode {
 
	FGCM_EXACT,       ///< Only find Grfs matching md5sum
 
	FGCM_COMPATIBLE,  ///< Find best compatible Grf wrt. desired_version
 
	FGCM_NEWEST,      ///< Find newest Grf
 
	FGCM_NEWEST_VALID,///< Find newest Grf, ignoring Grfs with GCF_INVALID set
 
	FGCM_ANY,         ///< Use first found
 
};
 

	
 
extern GRFConfig *_all_grfs;          ///< First item in list of all scanned NewGRFs
 
extern GRFConfig *_grfconfig;         ///< First item in list of current GRF set up
 
extern GRFConfig *_grfconfig_newgame; ///< First item in list of default GRF set up
 
extern GRFConfig *_grfconfig_static;  ///< First item in list of static GRF set up
 

	
 
/** Callback for NewGRF scanning. */
 
struct NewGRFScanCallback {
 
	/** Make sure the right destructor gets called. */
 
	virtual ~NewGRFScanCallback() {}
 
	/** Called whenever the NewGRF scan completed. */
 
	virtual void OnNewGRFsScanned() = 0;
 
};
 

	
 
void ScanNewGRFFiles(NewGRFScanCallback *callback);
 
void CheckForMissingSprites();
 
const GRFConfig *FindGRFConfig(uint32 grfid, FindGRFConfigMode mode, const uint8 *md5sum = NULL, uint32 desired_version = 0);
 
GRFConfig *GetGRFConfig(uint32 grfid, uint32 mask = 0xFFFFFFFF);
 
GRFConfig **CopyGRFConfigList(GRFConfig **dst, const GRFConfig *src, bool init_only);
 
void AppendStaticGRFConfigs(GRFConfig **dst);
 
void AppendToGRFConfigList(GRFConfig **dst, GRFConfig *el);
 
void ClearGRFConfigList(GRFConfig **config);
 
void ResetGRFConfig(bool defaults);
 
GRFListCompatibility IsGoodGRFConfigList(GRFConfig *grfconfig);
 
bool FillGRFDetails(GRFConfig *config, bool is_static, Subdirectory subdir = NEWGRF_DIR);
 
char *GRFBuildParamList(char *dst, const GRFConfig *c, const char *last);
 

	
 
/* In newgrf_gui.cpp */
 
void ShowNewGRFSettings(bool editable, bool show_params, bool exec_changes, GRFConfig **config);
 

	
 
#ifdef ENABLE_NETWORK
 
/** For communication about GRFs over the network */
 
#define UNKNOWN_GRF_NAME_PLACEHOLDER "<Unknown>"
 
GRFTextWrapper *FindUnknownGRFName(uint32 grfid, uint8 *md5sum, bool create);
 
#endif /* ENABLE_NETWORK */
 

	
 
void UpdateNewGRFScanStatus(uint num, const char *name);
 

	
 
#endif /* NEWGRF_CONFIG_H */
0 comments (0 inline, 0 general)