1 /* 2 * This file is part of OpenTTD. 3 * 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. 4 * 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. 5 * 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/>. 6 */ 7 8 /** @file script_error.hpp Everything to query errors. */ 9 10 #ifndef SCRIPT_ERROR_HPP 11 #define SCRIPT_ERROR_HPP 12 13 #include "script_object.hpp" 14 #include <map> 15 16 /** 17 * Helper to write precondition enforcers for the script API in an abbreviated manner. 18 * @param returnval The value to return on failure. 19 * @param condition The condition that must be obeyed. 20 */ 21 #define EnforcePrecondition(returnval, condition) \ 22 if (!(condition)) { \ 23 ScriptObject::SetLastError(ScriptError::ERR_PRECONDITION_FAILED); \ 24 return returnval; \ 25 } 26 27 /** 28 * Helper to write precondition enforcers for the script API in an abbreviated manner. 29 * @param returnval The value to return on failure. 30 * @param condition The condition that must be obeyed. 31 * @param error_code The error code passed to ScriptObject::SetLastError. 32 */ 33 #define EnforcePreconditionCustomError(returnval, condition, error_code) \ 34 if (!(condition)) { \ 35 ScriptObject::SetLastError(error_code); \ 36 return returnval; \ 37 } 38 39 /** 40 * Helper to write precondition enforcers for the script API in an abbreviated manner for encoded texts. 41 * @param returnval The value to return on failure. 42 * @param string The string that is checked. 43 */ 44 #define EnforcePreconditionEncodedText(returnval, string) \ 45 if ((string) == nullptr) { \ 46 ScriptObject::SetLastError(ScriptError::ERR_PRECONDITION_TOO_MANY_PARAMETERS); \ 47 return returnval; \ 48 } \ 49 if (StrEmpty(string)) { \ 50 ScriptObject::SetLastError(ScriptError::ERR_PRECONDITION_FAILED); \ 51 return returnval; \ 52 } 53 54 /** 55 * Class that handles all error related functions. 56 * @api ai game 57 */ 58 class ScriptError : public ScriptObject { 59 public: 60 /** 61 * All categories errors can be divided in. 62 */ 63 enum ErrorCategories { 64 ERR_CAT_NONE = 0, ///< Error messages not related to any category. 65 ERR_CAT_GENERAL, ///< Error messages related to general things. 66 ERR_CAT_VEHICLE, ///< Error messages related to building / maintaining vehicles. 67 ERR_CAT_STATION, ///< Error messages related to building / maintaining stations. 68 ERR_CAT_BRIDGE, ///< Error messages related to building / removing bridges. 69 ERR_CAT_TUNNEL, ///< Error messages related to building / removing tunnels. 70 ERR_CAT_TILE, ///< Error messages related to raising / lowering and demolishing tiles. 71 ERR_CAT_SIGN, ///< Error messages related to building / removing signs. 72 ERR_CAT_RAIL, ///< Error messages related to building / maintaining rails. 73 ERR_CAT_ROAD, ///< Error messages related to building / maintaining roads. 74 ERR_CAT_ORDER, ///< Error messages related to managing orders. 75 ERR_CAT_MARINE, ///< Error messages related to building / removing ships, docks and channels. 76 ERR_CAT_WAYPOINT, ///< Error messages related to building / maintaining waypoints. 77 78 /** 79 * DO NOT USE! The error bitsize determines how many errors can be stored in 80 * a category and what the offsets are of all categories. 81 */ 82 ERR_CAT_BIT_SIZE = 8, 83 }; 84 85 /** 86 * All general related error messages. 87 */ 88 enum ErrorMessages { 89 /** Initial error value */ 90 ERR_NONE = ERR_CAT_NONE << ERR_CAT_BIT_SIZE, // [] 91 /** If an error occurred and the error wasn't mapped */ 92 ERR_UNKNOWN, // [] 93 /** If a precondition is not met */ 94 ERR_PRECONDITION_FAILED, // [] 95 /** A string supplied was too long */ 96 ERR_PRECONDITION_STRING_TOO_LONG, // [] 97 /** A string had too many parameters */ 98 ERR_PRECONDITION_TOO_MANY_PARAMETERS, // [] 99 /** The company you use is invalid */ 100 ERR_PRECONDITION_INVALID_COMPANY, // [] 101 /** An error returned by a NewGRF. No possibility to get the exact error in an script readable format */ 102 ERR_NEWGRF_SUPPLIED_ERROR, // [] 103 104 /** Base for general errors */ 105 ERR_GENERAL_BASE = ERR_CAT_GENERAL << ERR_CAT_BIT_SIZE, 106 107 /** Not enough cash to perform the previous action */ 108 ERR_NOT_ENOUGH_CASH, // [STR_ERROR_NOT_ENOUGH_CASH_REQUIRES_CURRENCY] 109 110 /** Local authority won't allow the previous action */ 111 ERR_LOCAL_AUTHORITY_REFUSES, // [STR_ERROR_LOCAL_AUTHORITY_REFUSES_TO_ALLOW_THIS, STR_ERROR_LOCAL_AUTHORITY_REFUSES_NOISE] 112 113 /** The piece of infrastructure you tried to build is already in place */ 114 ERR_ALREADY_BUILT, // [STR_ERROR_ALREADY_BUILT, STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST, STR_ERROR_TREE_ALREADY_HERE] 115 116 /** Area isn't clear, try to demolish the building on it */ 117 ERR_AREA_NOT_CLEAR, // [STR_ERROR_BUILDING_MUST_BE_DEMOLISHED, STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST, STR_ERROR_MUST_DEMOLISH_RAILROAD, STR_ERROR_MUST_DEMOLISH_AIRPORT_FIRST, STR_ERROR_MUST_DEMOLISH_CARGO_TRAM_STATION_FIRST, STR_ERROR_MUST_DEMOLISH_TRUCK_STATION_FIRST, STR_ERROR_MUST_DEMOLISH_PASSENGER_TRAM_STATION_FIRST, STR_ERROR_MUST_DEMOLISH_BUS_STATION_FIRST, STR_ERROR_BUOY_IN_THE_WAY, STR_ERROR_MUST_DEMOLISH_DOCK_FIRST, STR_ERROR_GENERIC_OBJECT_IN_THE_WAY, STR_ERROR_COMPANY_HEADQUARTERS_IN, STR_ERROR_OBJECT_IN_THE_WAY, STR_ERROR_MUST_REMOVE_ROAD_FIRST, STR_ERROR_MUST_REMOVE_RAILROAD_TRACK, STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST, STR_ERROR_MUST_DEMOLISH_TUNNEL_FIRST, STR_ERROR_EXCAVATION_WOULD_DAMAGE] 118 119 /** Area / property is owned by another company */ 120 ERR_OWNED_BY_ANOTHER_COMPANY, // [STR_ERROR_AREA_IS_OWNED_BY_ANOTHER, STR_ERROR_OWNED_BY] 121 122 /** The name given is not unique for the object type */ 123 ERR_NAME_IS_NOT_UNIQUE, // [STR_ERROR_NAME_MUST_BE_UNIQUE] 124 125 /** The building you want to build requires flat land */ 126 ERR_FLAT_LAND_REQUIRED, // [STR_ERROR_FLAT_LAND_REQUIRED] 127 128 /** Land is sloped in the wrong direction for this build action */ 129 ERR_LAND_SLOPED_WRONG, // [STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION] 130 131 /** A vehicle is in the way */ 132 ERR_VEHICLE_IN_THE_WAY, // [STR_ERROR_TRAIN_IN_THE_WAY, STR_ERROR_ROAD_VEHICLE_IN_THE_WAY, STR_ERROR_SHIP_IN_THE_WAY, STR_ERROR_AIRCRAFT_IN_THE_WAY] 133 134 /** Site is unsuitable */ 135 ERR_SITE_UNSUITABLE, // [STR_ERROR_SITE_UNSUITABLE, STR_ERROR_TREE_WRONG_TERRAIN_FOR_TREE_TYPE] 136 137 /** Too close to the edge of the map */ 138 ERR_TOO_CLOSE_TO_EDGE, // [STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP] 139 140 /** Station is too spread out */ 141 ERR_STATION_TOO_SPREAD_OUT, // [STR_ERROR_STATION_TOO_SPREAD_OUT] 142 }; 143 144 /** 145 * Check the membership of the last thrown error. 146 * @return The category the error belongs to. 147 * @note The last throw error can be acquired by calling GetLastError(). 148 */ 149 static ErrorCategories GetErrorCategory(); 150 151 /** 152 * Get the last error. 153 * @return An ErrorMessages enum value. 154 */ 155 static ScriptErrorType GetLastError(); 156 157 /** 158 * Get the last error in string format (for human readability). 159 * @return An ErrorMessage enum item, as string. 160 */ 161 static char *GetLastErrorString(); 162 163 /** 164 * Get the error based on the OpenTTD StringID. 165 * @api -all 166 * @param internal_string_id The string to convert. 167 * @return The script equivalent error message. 168 */ 169 static ScriptErrorType StringToError(StringID internal_string_id); 170 171 /** 172 * Map an internal OpenTTD error message to its script equivalent. 173 * @api -all 174 * @param internal_string_id The OpenTTD StringID used for an error. 175 * @param ai_error_msg The script equivalent error message. 176 */ 177 static void RegisterErrorMap(StringID internal_string_id, ScriptErrorType ai_error_msg); 178 179 /** 180 * Map an internal OpenTTD error message to its script equivalent. 181 * @api -all 182 * @param ai_error_msg The script error message representation. 183 * @param message The string representation of this error message, used for debug purposes. 184 */ 185 static void RegisterErrorMapString(ScriptErrorType ai_error_msg, const char *message); 186 187 private: 188 typedef std::map<StringID, ScriptErrorType> ScriptErrorMap; ///< The type for mapping between error (internal OpenTTD) StringID to the script error type. 189 typedef std::map<ScriptErrorType, const char *> ScriptErrorMapString; ///< The type for mapping between error type and textual representation. 190 191 static ScriptErrorMap error_map; ///< The mapping between error (internal OpenTTD) StringID to the script error type. 192 static ScriptErrorMapString error_map_string; ///< The mapping between error type and textual representation. 193 }; 194 195 #endif /* SCRIPT_ERROR_HPP */ 196