/* * 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 . */ /** @file newgrf_extension.cpp NewGRF extension support. */ #include "stdafx.h" #include "newgrf.h" #include "newgrf_extension.h" #include "table/sprites.h" #include "safeguards.h" /** Action14 feature list */ extern const GRFFeatureInfo _grf_feature_list[] = { GRFFeatureInfo("feature_test", 2), GRFFeatureInfo("property_mapping", 3), GRFFeatureInfo("variable_mapping", 3), GRFFeatureInfo("feature_id_mapping", 2), GRFFeatureInfo("action5_type_id_mapping", 2), GRFFeatureInfo("action0_station_prop1B", 1), GRFFeatureInfo("action0_station_disallowed_bridge_pillars", 1), GRFFeatureInfo("varaction2_station_var42", 1), GRFFeatureInfo("varaction2_station_station_nearby_info_v2", 1), GRFFeatureInfo("more_bridge_types", 1), GRFFeatureInfo("action0_bridge_prop14", 1), GRFFeatureInfo("action0_bridge_pillar_flags", 1), GRFFeatureInfo("action0_bridge_availability_flags", 1), GRFFeatureInfo("action5_programmable_signals", 1), GRFFeatureInfo("action5_no_entry_signals", 1), GRFFeatureInfo("action5_misc_gui", 1), GRFFeatureInfo("action5_road_waypoints", 1), GRFFeatureInfo("action0_railtype_programmable_signals", 1), GRFFeatureInfo("action0_railtype_no_entry_signals", 1), GRFFeatureInfo("action0_railtype_restricted_signals", 2), GRFFeatureInfo("action0_railtype_disable_realistic_braking", 1), GRFFeatureInfo("action0_railtype_recolour", 1), GRFFeatureInfo("action0_railtype_extra_aspects", 1), GRFFeatureInfo("action0_roadtype_extra_flags", 2), GRFFeatureInfo("action0_roadtype_collision_mode", 1), GRFFeatureInfo("varaction2_railtype_signal_context", 1), GRFFeatureInfo("varaction2_railtype_signal_side", 1), GRFFeatureInfo("varaction2_railtype_signal_vertical_clearance", 1), GRFFeatureInfo("varaction2_railtype_adjacent_crossing", 1), GRFFeatureInfo("action0_global_extra_station_names", 2), GRFFeatureInfo("action0_global_default_object_generate_amount", 1), GRFFeatureInfo("action0_global_allow_rocks_in_desert", 1), GRFFeatureInfo("action0_signals_programmable_signals", 1), GRFFeatureInfo("action0_signals_no_entry_signals", 1), GRFFeatureInfo("action0_signals_restricted_signals", 2), GRFFeatureInfo("action0_signals_recolour", 1), GRFFeatureInfo("action0_signals_extra_aspects", 1), GRFFeatureInfo("action0_signals_style", 3), GRFFeatureInfo("varaction2_signals_signal_context", 1), GRFFeatureInfo("varaction2_signals_signal_side", 1), GRFFeatureInfo("varaction2_signals_signal_vertical_clearance", 1), GRFFeatureInfo("action3_signals_custom_signal_sprites", 1), GRFFeatureInfo("action0_object_use_land_ground", 1), GRFFeatureInfo("action0_object_edge_foundation_mode", 2), GRFFeatureInfo("action0_object_flood_resistant", 1), GRFFeatureInfo("action0_object_viewport_map_tile_type", 1), GRFFeatureInfo("varaction2_airporttiles_airport_info", 1), GRFFeatureInfo("road_stops", 10, GFTOF_ROAD_STOPS), GRFFeatureInfo("new_landscape", 2), GRFFeatureInfo("more_objects_per_grf", 1), GRFFeatureInfo("more_action2_ids", 1, GFTOF_MORE_ACTION2_IDS), GRFFeatureInfo("town_feature", 1), GRFFeatureInfo("town_uncapped_variables", 1), GRFFeatureInfo("town_zone_callback", 1, GFTOF_TOWN_ZONE_CALLBACK), GRFFeatureInfo("varaction2_towns_town_xy", 1), GRFFeatureInfo("more_varaction2_types", 1, GFTOF_MORE_VARACTION2_TYPES), GRFFeatureInfo("multi_part_ships", 3, GFTOF_MULTI_PART_SHIPS), GRFFeatureInfo("more_stations_per_grf", 1), GRFFeatureInfo(), }; /** Action14 remappable feature list */ extern const GRFFeatureMapDefinition _grf_remappable_features[] = { GRFFeatureMapDefinition(GSF_ROADSTOPS, "road_stops"), GRFFeatureMapDefinition(GSF_NEWLANDSCAPE, "new_landscape"), GRFFeatureMapDefinition(GSF_FAKE_TOWNS, "town"), GRFFeatureMapDefinition(), }; /** Action14 Action0 remappable property list */ extern const GRFPropertyMapDefinition _grf_action0_remappable_properties[] = { GRFPropertyMapDefinition(GSF_INVALID, A0RPI_ID_EXTENSION, "id_extension"), GRFPropertyMapDefinition(GSF_STATIONS, A0RPI_STATION_MIN_BRIDGE_HEIGHT, "station_min_bridge_height"), GRFPropertyMapDefinition(GSF_STATIONS, A0RPI_STATION_DISALLOWED_BRIDGE_PILLARS, "station_disallowed_bridge_pillars"), GRFPropertyMapDefinition(GSF_BRIDGES, A0RPI_BRIDGE_MENU_ICON, "bridge_menu_icon"), GRFPropertyMapDefinition(GSF_BRIDGES, A0RPI_BRIDGE_PILLAR_FLAGS, "bridge_pillar_flags"), GRFPropertyMapDefinition(GSF_BRIDGES, A0RPI_BRIDGE_AVAILABILITY_FLAGS, "bridge_availability_flags"), GRFPropertyMapDefinition(GSF_RAILTYPES, A0RPI_RAILTYPE_ENABLE_PROGRAMMABLE_SIGNALS, "railtype_enable_programmable_signals"), GRFPropertyMapDefinition(GSF_RAILTYPES, A0RPI_RAILTYPE_ENABLE_NO_ENTRY_SIGNALS, "railtype_enable_no_entry_signals"), GRFPropertyMapDefinition(GSF_RAILTYPES, A0RPI_RAILTYPE_ENABLE_RESTRICTED_SIGNALS, "railtype_enable_restricted_signals"), GRFPropertyMapDefinition(GSF_RAILTYPES, A0RPI_RAILTYPE_DISABLE_REALISTIC_BRAKING, "railtype_disable_realistic_braking"), GRFPropertyMapDefinition(GSF_RAILTYPES, A0RPI_RAILTYPE_ENABLE_SIGNAL_RECOLOUR, "railtype_enable_signal_recolour"), GRFPropertyMapDefinition(GSF_RAILTYPES, A0RPI_RAILTYPE_EXTRA_ASPECTS, "railtype_extra_aspects"), GRFPropertyMapDefinition(GSF_ROADTYPES, A0RPI_ROADTYPE_EXTRA_FLAGS, "roadtype_extra_flags"), GRFPropertyMapDefinition(GSF_ROADTYPES, A0RPI_ROADTYPE_COLLISION_MODE, "roadtype_collision_mode"), GRFPropertyMapDefinition(GSF_TRAMTYPES, A0RPI_ROADTYPE_EXTRA_FLAGS, "roadtype_extra_flags"), GRFPropertyMapDefinition(GSF_TRAMTYPES, A0RPI_ROADTYPE_COLLISION_MODE, "roadtype_collision_mode"), GRFPropertyMapDefinition(GSF_GLOBALVAR, A0RPI_GLOBALVAR_EXTRA_STATION_NAMES, "global_extra_station_names"), GRFPropertyMapDefinition(GSF_GLOBALVAR, A0RPI_GLOBALVAR_EXTRA_STATION_NAMES_PROBABILITY, "global_extra_station_names_probability"), GRFPropertyMapDefinition(GSF_GLOBALVAR, A0RPI_GLOBALVAR_LIGHTHOUSE_GENERATE_AMOUNT, "global_lighthouse_generate_amount"), GRFPropertyMapDefinition(GSF_GLOBALVAR, A0RPI_GLOBALVAR_TRANSMITTER_GENERATE_AMOUNT, "global_transmitter_generate_amount"), GRFPropertyMapDefinition(GSF_GLOBALVAR, A0RPI_GLOBALVAR_ALLOW_ROCKS_DESERT, "global_allow_rocks_in_desert"), GRFPropertyMapDefinition(GSF_SIGNALS, A0RPI_SIGNALS_ENABLE_PROGRAMMABLE_SIGNALS, "signals_enable_programmable_signals"), GRFPropertyMapDefinition(GSF_SIGNALS, A0RPI_SIGNALS_ENABLE_NO_ENTRY_SIGNALS, "signals_enable_no_entry_signals"), GRFPropertyMapDefinition(GSF_SIGNALS, A0RPI_SIGNALS_ENABLE_RESTRICTED_SIGNALS, "signals_enable_restricted_signals"), GRFPropertyMapDefinition(GSF_SIGNALS, A0RPI_SIGNALS_ENABLE_SIGNAL_RECOLOUR, "signals_enable_signal_recolour"), GRFPropertyMapDefinition(GSF_SIGNALS, A0RPI_SIGNALS_EXTRA_ASPECTS, "signals_extra_aspects"), GRFPropertyMapDefinition(GSF_SIGNALS, A0RPI_SIGNALS_NO_DEFAULT_STYLE, "signals_no_default_style"), GRFPropertyMapDefinition(GSF_SIGNALS, A0RPI_SIGNALS_DEFINE_STYLE, "signals_define_style"), GRFPropertyMapDefinition(GSF_SIGNALS, A0RPI_SIGNALS_STYLE_NAME, "signals_style_name"), GRFPropertyMapDefinition(GSF_SIGNALS, A0RPI_SIGNALS_STYLE_NO_ASPECT_INCREASE, "signals_style_no_aspect_increase"), GRFPropertyMapDefinition(GSF_SIGNALS, A0RPI_SIGNALS_STYLE_ALWAYS_RESERVE_THROUGH, "signals_style_always_reserve_through"), GRFPropertyMapDefinition(GSF_SIGNALS, A0RPI_SIGNALS_STYLE_LOOKAHEAD_EXTRA_ASPECTS, "signals_style_lookahead_extra_aspects"), GRFPropertyMapDefinition(GSF_SIGNALS, A0RPI_SIGNALS_STYLE_LOOKAHEAD_SINGLE_SIGNAL_ONLY, "signals_style_lookahead_single_signal_only"), GRFPropertyMapDefinition(GSF_SIGNALS, A0RPI_SIGNALS_STYLE_SEMAPHORE_ENABLED, "signals_style_semaphore_enabled"), GRFPropertyMapDefinition(GSF_SIGNALS, A0RPI_SIGNALS_STYLE_ELECTRIC_ENABLED, "signals_style_electric_enabled"), GRFPropertyMapDefinition(GSF_SIGNALS, A0RPI_SIGNALS_STYLE_OPPOSITE_SIDE, "signals_style_opposite_side"), GRFPropertyMapDefinition(GSF_SIGNALS, A0RPI_SIGNALS_STYLE_COMBINED_NORMAL_SHUNT, "signals_style_combined_normal_shunt"), GRFPropertyMapDefinition(GSF_SIGNALS, A0RPI_SIGNALS_STYLE_REALISTIC_BRAKING_ONLY, "signals_style_realistic_braking_only"), GRFPropertyMapDefinition(GSF_SIGNALS, A0RPI_SIGNALS_STYLE_BOTH_SIDES, "signals_style_both_sides"), GRFPropertyMapDefinition(GSF_OBJECTS, A0RPI_OBJECT_USE_LAND_GROUND, "object_use_land_ground"), GRFPropertyMapDefinition(GSF_OBJECTS, A0RPI_OBJECT_EDGE_FOUNDATION_MODE, "object_edge_foundation_mode"), GRFPropertyMapDefinition(GSF_OBJECTS, A0RPI_OBJECT_FLOOD_RESISTANT, "object_flood_resistant"), GRFPropertyMapDefinition(GSF_OBJECTS, A0RPI_OBJECT_VIEWPORT_MAP_TYPE, "object_viewport_map_tile_type"), GRFPropertyMapDefinition(GSF_OBJECTS, A0RPI_OBJECT_VIEWPORT_MAP_SUBTYPE, "object_viewport_map_tile_subtype"), GRFPropertyMapDefinition(GSF_ROADSTOPS, A0RPI_ROADSTOP_CLASS_ID, "roadstop_class_id"), GRFPropertyMapDefinition(GSF_ROADSTOPS, A0RPI_ROADSTOP_STOP_TYPE, "roadstop_stop_type"), GRFPropertyMapDefinition(GSF_ROADSTOPS, A0RPI_ROADSTOP_STOP_NAME, "roadstop_stop_name"), GRFPropertyMapDefinition(GSF_ROADSTOPS, A0RPI_ROADSTOP_CLASS_NAME, "roadstop_class_name"), GRFPropertyMapDefinition(GSF_ROADSTOPS, A0RPI_ROADSTOP_DRAW_MODE, "roadstop_draw_mode"), GRFPropertyMapDefinition(GSF_ROADSTOPS, A0RPI_ROADSTOP_TRIGGER_CARGOES, "roadstop_random_trigger_cargoes"), GRFPropertyMapDefinition(GSF_ROADSTOPS, A0RPI_ROADSTOP_ANIMATION_INFO, "roadstop_animation_info"), GRFPropertyMapDefinition(GSF_ROADSTOPS, A0RPI_ROADSTOP_ANIMATION_SPEED, "roadstop_animation_speed"), GRFPropertyMapDefinition(GSF_ROADSTOPS, A0RPI_ROADSTOP_ANIMATION_TRIGGERS, "roadstop_animation_triggers"), GRFPropertyMapDefinition(GSF_ROADSTOPS, A0RPI_ROADSTOP_CALLBACK_MASK, "roadstop_callback_mask"), GRFPropertyMapDefinition(GSF_ROADSTOPS, A0RPI_ROADSTOP_GENERAL_FLAGS, "roadstop_general_flags"), GRFPropertyMapDefinition(GSF_ROADSTOPS, A0RPI_ROADSTOP_MIN_BRIDGE_HEIGHT, "roadstop_min_bridge_height"), GRFPropertyMapDefinition(GSF_ROADSTOPS, A0RPI_ROADSTOP_DISALLOWED_BRIDGE_PILLARS, "roadstop_disallowed_bridge_pillars"), GRFPropertyMapDefinition(GSF_ROADSTOPS, A0RPI_ROADSTOP_COST_MULTIPLIERS, "roadstop_cost_multipliers"), GRFPropertyMapDefinition(GSF_ROADSTOPS, A0RPI_ROADSTOP_HEIGHT, "roadstop_height"), GRFPropertyMapDefinition(GSF_NEWLANDSCAPE, A0RPI_NEWLANDSCAPE_ENABLE_RECOLOUR, "newlandscape_enable_recolour"), GRFPropertyMapDefinition(GSF_NEWLANDSCAPE, A0RPI_NEWLANDSCAPE_ENABLE_DRAW_SNOWY_ROCKS, "newlandscape_enable_draw_snowy_rocks"), GRFPropertyMapDefinition(), }; /** Action14 Action2 remappable variable list */ extern const GRFVariableMapDefinition _grf_action2_remappable_variables[] = { GRFVariableMapDefinition(GSF_STATIONS, A2VRI_STATION_INFO_NEARBY_TILES_V2, "station_station_info_nearby_tiles_v2"), GRFVariableMapDefinition(GSF_OBJECTS, A2VRI_OBJECT_FOUNDATION_SLOPE, "object_foundation_tile_slope"), GRFVariableMapDefinition(GSF_OBJECTS, A2VRI_OBJECT_FOUNDATION_SLOPE_CHANGE, "object_foundation_change_tile_slope"), GRFVariableMapDefinition(GSF_ROADSTOPS, 0x40, "roadstop_view"), GRFVariableMapDefinition(GSF_ROADSTOPS, 0x41, "roadstop_type"), GRFVariableMapDefinition(GSF_ROADSTOPS, 0x42, "roadstop_terrain_type"), GRFVariableMapDefinition(GSF_ROADSTOPS, 0x43, "roadstop_road_type"), GRFVariableMapDefinition(GSF_ROADSTOPS, 0x44, "roadstop_tram_type"), GRFVariableMapDefinition(GSF_ROADSTOPS, 0x45, "roadstop_town_zone"), GRFVariableMapDefinition(GSF_ROADSTOPS, 0x46, "roadstop_town_distance_squared"), GRFVariableMapDefinition(GSF_ROADSTOPS, 0x47, "roadstop_company_info"), GRFVariableMapDefinition(GSF_ROADSTOPS, 0x49, "roadstop_animation_frame"), GRFVariableMapDefinition(GSF_ROADSTOPS, 0x50, "roadstop_misc_info"), GRFVariableMapDefinition(GSF_ROADSTOPS, 0x66, "roadstop_animation_frame_nearby_tiles"), GRFVariableMapDefinition(GSF_ROADSTOPS, 0x67, "roadstop_land_info_nearby_tiles"), GRFVariableMapDefinition(GSF_ROADSTOPS, 0x68, "roadstop_road_stop_info_nearby_tiles"), GRFVariableMapDefinition(GSF_ROADSTOPS, 0x6A, "roadstop_road_stop_grfid_nearby_tiles"), GRFVariableMapDefinition(GSF_ROADSTOPS, A2VRI_ROADSTOP_ROAD_INFO_NEARBY_TILES, "roadstop_road_info_nearby_tiles"), GRFVariableMapDefinition(GSF_ROADSTOPS, A2VRI_ROADSTOP_INFO_NEARBY_TILES_V2, "roadstop_road_stop_info_nearby_tiles_v2"), GRFVariableMapDefinition(GSF_RAILTYPES, A2VRI_RAILTYPE_SIGNAL_RESTRICTION_INFO, "railtype_signal_restriction_info"), GRFVariableMapDefinition(GSF_RAILTYPES, A2VRI_RAILTYPE_SIGNAL_CONTEXT, "railtype_signal_context"), GRFVariableMapDefinition(GSF_RAILTYPES, A2VRI_RAILTYPE_SIGNAL_SIDE, "railtype_signal_side"), GRFVariableMapDefinition(GSF_RAILTYPES, A2VRI_RAILTYPE_SIGNAL_VERTICAL_CLEARANCE, "railtype_signal_vertical_clearance"), GRFVariableMapDefinition(GSF_RAILTYPES, A2VRI_RAILTYPE_ADJACENT_CROSSING, "railtype_adjacent_crossing"), GRFVariableMapDefinition(GSF_SIGNALS, A2VRI_SIGNALS_SIGNAL_RESTRICTION_INFO, "signals_signal_restriction_info"), GRFVariableMapDefinition(GSF_SIGNALS, A2VRI_SIGNALS_SIGNAL_CONTEXT, "signals_signal_context"), GRFVariableMapDefinition(GSF_SIGNALS, A2VRI_SIGNALS_SIGNAL_STYLE, "signals_signal_style"), GRFVariableMapDefinition(GSF_SIGNALS, A2VRI_SIGNALS_SIGNAL_SIDE, "signals_signal_side"), GRFVariableMapDefinition(GSF_SIGNALS, A2VRI_SIGNALS_SIGNAL_VERTICAL_CLEARANCE, "signals_signal_vertical_clearance"), GRFVariableMapDefinition(GSF_AIRPORTTILES, A2VRI_AIRPORTTILES_AIRPORT_LAYOUT, "airporttiles_airport_layout"), GRFVariableMapDefinition(GSF_AIRPORTTILES, A2VRI_AIRPORTTILES_AIRPORT_ID, "airporttiles_airport_id"), GRFVariableMapDefinition(GSF_FAKE_TOWNS, A2VRI_TOWNS_HOUSE_COUNT, "town_house_count"), GRFVariableMapDefinition(GSF_FAKE_TOWNS, A2VRI_TOWNS_POPULATION, "town_population"), GRFVariableMapDefinition(GSF_FAKE_TOWNS, A2VRI_TOWNS_ZONE_0, "town_zone_0_radius_square"), GRFVariableMapDefinition(GSF_FAKE_TOWNS, A2VRI_TOWNS_ZONE_1, "town_zone_1_radius_square"), GRFVariableMapDefinition(GSF_FAKE_TOWNS, A2VRI_TOWNS_ZONE_2, "town_zone_2_radius_square"), GRFVariableMapDefinition(GSF_FAKE_TOWNS, A2VRI_TOWNS_ZONE_3, "town_zone_3_radius_square"), GRFVariableMapDefinition(GSF_FAKE_TOWNS, A2VRI_TOWNS_ZONE_4, "town_zone_4_radius_square"), GRFVariableMapDefinition(GSF_FAKE_TOWNS, A2VRI_TOWNS_XY, "town_xy"), GRFVariableMapDefinition(GSF_NEWLANDSCAPE, 0x40, "newlandscape_terrain_type"), GRFVariableMapDefinition(GSF_NEWLANDSCAPE, 0x41, "newlandscape_tile_slope"), GRFVariableMapDefinition(GSF_NEWLANDSCAPE, 0x42, "newlandscape_tile_height"), GRFVariableMapDefinition(GSF_NEWLANDSCAPE, 0x43, "newlandscape_tile_hash"), GRFVariableMapDefinition(GSF_NEWLANDSCAPE, 0x44, "newlandscape_landscape_type"), GRFVariableMapDefinition(GSF_NEWLANDSCAPE, 0x45, "newlandscape_ground_info"), GRFVariableMapDefinition(GSF_NEWLANDSCAPE, 0x60, "newlandscape_land_info_nearby_tiles"), GRFVariableMapDefinition(), }; extern const GRFNameOnlyVariableMapDefinition _grf_action2_internal_variable_names[] = { GRFNameOnlyVariableMapDefinition(A2VRI_VEHICLE_CURRENT_SPEED_SCALED, "current speed scaled"), GRFNameOnlyVariableMapDefinition(A2VRI_ROADSTOP_INFO_NEARBY_TILES_EXT, "68 (extended)"), GRFNameOnlyVariableMapDefinition(), }; /** Action14 Action5 remappable type list */ extern const Action5TypeRemapDefinition _grf_action5_remappable_types[] = { Action5TypeRemapDefinition("programmable_signals", A5BLOCK_ALLOW_OFFSET, SPR_PROGSIGNAL_BASE, 1, 32, "Programmable pre-signal graphics"), Action5TypeRemapDefinition("no_entry_signals", A5BLOCK_ALLOW_OFFSET, SPR_EXTRASIGNAL_BASE, 1, 16, "No-entry signal graphics"), Action5TypeRemapDefinition("misc_gui", A5BLOCK_ALLOW_OFFSET, SPR_MISC_GUI_BASE, 1, 1, "Miscellaneous GUI graphics"), Action5TypeRemapDefinition("road_waypoints", A5BLOCK_ALLOW_OFFSET, SPR_ROAD_WAYPOINTS_BASE, 1, 4, "Road waypoints"), Action5TypeRemapDefinition(), };