sscanf2.inc 56 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749
  1. /*
  2. * sscanf 2.13.8
  3. *
  4. * Version: MPL 1.1
  5. *
  6. * The contents of this file are subject to the Mozilla Public License Version
  7. * 1.1 (the "License"); you may not use this file except in compliance with
  8. * the License. You may obtain a copy of the License at
  9. * http://www.mozilla.org/MPL/
  10. *
  11. * Software distributed under the License is distributed on an "AS IS" basis,
  12. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  13. * for the specific language governing rights and limitations under the
  14. * License.
  15. *
  16. * The Original Code is the sscanf 2.0 SA:MP plugin.
  17. *
  18. * The Initial Developer of the Original Code is Alex "Y_Less" Cole.
  19. * Portions created by the Initial Developer are Copyright (c) 2022
  20. * the Initial Developer. All Rights Reserved.
  21. *
  22. * Contributor(s):
  23. *
  24. * Cheaterman
  25. * DEntisT
  26. * Emmet_
  27. * karimcambridge
  28. * kalacsparty
  29. * Kirima
  30. * leHeix
  31. * maddinat0r
  32. * Southclaws
  33. * Y_Less
  34. * ziggi
  35. *
  36. * Special Thanks to:
  37. *
  38. * SA:MP Team past, present, and future.
  39. * maddinat0r, for hosting the repo for a very long time.
  40. * Emmet_, for his efforts in maintaining it for almost a year.
  41. */
  42. #if defined _INC_SSCANF
  43. #endinput
  44. #endif
  45. #define _INC_SSCANF
  46. #if !defined _samp_included
  47. #error Please include <a_npc> or <a_samp> first.
  48. #endif
  49. /**
  50. * <library
  51. * name="sscanf"
  52. * summary="Extracts structured information from strings."
  53. * license="Copyright (c) 2022 Alex &quot;Y_Less&quot; Cole. Licensed under MPL 1.1"
  54. * >
  55. * <summary pawndoc="true">
  56. * This library uses the enhanced <em>pawndoc.xsl</em> from
  57. * <a href="https://github.com/pawn-lang/pawndoc">pawn-lang/pawndoc</a>.
  58. * This XSL has features such as library and markdown support, and will not
  59. * render this message when used.
  60. * </summary>
  61. * <remarks>
  62. * This is the <em>sscanf</em> plugin, which provides the <c>sscanf</c>
  63. * function to extract basic structured data from strings. This is slightly
  64. * different to regular expressions, but both have their place. A regular
  65. * expression gives you total control over the exact structure of data down
  66. * to the character level; however, extracting structured data like numbers
  67. * using it is tricky. Conversely this gives slightly higher-level
  68. * <em>specifiers</em> which can easily extract data types, at the expense
  69. * of fine-grained control. To convert a string in to two numbers would
  70. * look like:
  71. *
  72. * <code>
  73. * new num1, num2; <br />
  74. * sscanf("45 100", "ii", num1, num2);
  75. * </code>
  76. *
  77. * <c>ii</c> is the specifier string, which here means "integer integer";
  78. * stating that the input string should be two whole numbers in a row (which
  79. * is - <c>"45 100"</c>). <c>num1</c> and <c>num2</c> are the destination
  80. * variables to store the found numbers in (after conversion from strings).
  81. * You can check if the conversion failed by looking for a non-naught return
  82. * value:
  83. *
  84. * <code>
  85. * new num1, num2; <br />
  86. * if (sscanf("hello 100", "ii", num1, num2)) <br />
  87. * { <br /><indent />
  88. * printf("The input was not two numbers."); <br />
  89. * }
  90. * </code>
  91. *
  92. * This will fail because <c>"hello"</c> is not a whole number (or indeed
  93. * any type of number at all). For more information on using the function
  94. * refer to the tutorials or the reference documentation in
  95. * <a href="https://github.com/Y-Less/sscanf/blob/master/README.md">the
  96. * attached readme</a>.
  97. * </remarks>
  98. * </library>
  99. */
  100. /// <p/>
  101. #define SSCANF_STATIC__
  102. #if defined __PawnBuild
  103. #if __PawnBuild == 11
  104. // `const static` support.
  105. #undef SSCANF_STATIC__
  106. #define SSCANF_STATIC__ static
  107. #endif
  108. #else
  109. #if !defined SSCANF_NO_NICE_FEATURES
  110. #error sscanf utilises community compiler features. Use `#define SSCANF_NO_NICE_FEATURES` to live without (if you can call that living) or better yet download it here: github.com/pawn-lang/compiler/releases
  111. #endif
  112. #endif
  113. /**
  114. * <library>sscanf</library>
  115. * <remarks>
  116. * Was sscanf built for an NPC mode or a normal mode?
  117. * </remarks>
  118. */
  119. #if defined GetDistanceFromMeToPoint
  120. // NPC script.
  121. static stock SSCANF_NPC = 1;
  122. #define SSCANF_NPC (1)
  123. #pragma library sscanf
  124. #else
  125. static stock SSCANF_NPC = 0;
  126. #define SSCANF_NPC (0)
  127. #endif
  128. /**
  129. * <library>sscanf</library>
  130. * <remarks>
  131. * The sscanf major version number.
  132. * </remarks>
  133. */
  134. static stock SSCANF_VERSION_MAJOR = 2;
  135. #define SSCANF_VERSION_MAJOR 2
  136. /**
  137. * <library>sscanf</library>
  138. * <remarks>
  139. * The sscanf minor version number.
  140. * </remarks>
  141. */
  142. static stock SSCANF_VERSION_MINOR = 13;
  143. #define SSCANF_VERSION_MINOR 13
  144. /**
  145. * <library>sscanf</library>
  146. * <remarks>
  147. * The sscanf build number.
  148. * </remarks>
  149. */
  150. static stock SSCANF_VERSION_BUILD = 8;
  151. #define SSCANF_VERSION_BUILD 8
  152. /**
  153. * <library>sscanf</library>
  154. * <remarks>
  155. * The sscanf version as a string. E.g. <c>"2.8.1"</c>.
  156. * </remarks>
  157. */
  158. static stock SSCANF_VERSION_STRING[] = #SSCANF_VERSION_MAJOR "." #SSCANF_VERSION_MINOR "." #SSCANF_VERSION_BUILD;
  159. #define SSCANF_VERSION_STRING #SSCANF_VERSION_MAJOR "." #SSCANF_VERSION_MINOR "." #SSCANF_VERSION_BUILD
  160. /**
  161. * <library>sscanf</library>
  162. * <remarks>
  163. * Converts a version string to
  164. * <a href="https://en.wikipedia.org/wiki/Binary-coded_decimal">BCD</a>. For example:
  165. *
  166. * <code>
  167. * BCD(5.6.17);
  168. * </code>
  169. *
  170. * Returns:
  171. *
  172. * <code>
  173. * 0x050617
  174. * </code>
  175. *
  176. * Each section (between dots) is assigned a single byte and the last section is
  177. * always in the lowest byte. This implies a maximum of four sections and two
  178. * digits per section.
  179. *
  180. * </remarks>
  181. */
  182. forward BCD(number);
  183. #define BCD(%0) (_:MORE_BCD:NO_MORE_BCD:%0.$0)
  184. #define MORE_BCD:NO_MORE_BCD:%0.%1$%2) MORE_BCD:NO_MORE_BCD:%1$(%2) << 8 | DO_BCD(%0))
  185. #define NO_MORE_BCD:$
  186. #define DO_BCD(%0) _:(%0) / 10 << 4 | _:(%0) % 10
  187. /**
  188. * <library>sscanf</library>
  189. * <remarks>
  190. * The sscanf version in BCD as a proper constant. Example:
  191. *
  192. * <code>
  193. * 2.10.3 <br />
  194. * => 02 10 03 <br />
  195. * => 0x021003
  196. * </code>
  197. * </remarks>
  198. */
  199. const SSCANF_VERSION = BCD(SSCANF_VERSION_MAJOR.SSCANF_VERSION_MINOR.SSCANF_VERSION_BUILD);
  200. /**
  201. * <library>sscanf</library>
  202. * <remarks>
  203. * The sscanf version in BCD. Example:
  204. *
  205. * <code>
  206. * 2.10.3 <br />
  207. * => 02 10 03 <br />
  208. * => 0x021003
  209. * </code>
  210. * </remarks>
  211. */
  212. stock const SSCANF_VERSION_BCD = SSCANF_VERSION;
  213. #define sscanf_%0\32; sscanf_
  214. #define SSCANF:%0(%1) forward sscanf_%0(%1);public sscanf_%0(%1)
  215. #define @kustom()%0(%1) forward sscanf_%0(%1);public sscanf_%0(%1)
  216. // The check for `SSCANF_GetClosestString` ensures that this is the first
  217. // compiler pass and thus the check for `sscanf` only finds earlier definitions
  218. // not our later fake definition made purely for documentation purposes.
  219. #if defined sscanf && !defined SSCANF_GetClosestString
  220. #error sscanf already defined, or used before inclusion.
  221. #endif
  222. /**
  223. * <library>sscanf</library>
  224. * <param name="file">The file in which this call is found.</param>
  225. * <param name="line">The line at which this call is found.</param>
  226. * <param name="data">The input string containing the data to parse out.</param>
  227. * <param name="format">The format description of what the input data should contain.</param>
  228. * <remarks>
  229. * The current true implementation of <c>sscanf</c> in the plugin. This is
  230. * wrapped by macros to provide <c>sscanf</c> enhanced with filenames and line
  231. * numbers so that errors have more information. The plugin also contains a
  232. * native function called <c>sscanf</c> which is only for backwards-
  233. * compatibility with older versions of this include.
  234. * </remarks>
  235. */
  236. /* */ native SSCANF__(const file[], const line, const data[], const format[], {T_WEAPON, Float, _}:...);
  237. /**
  238. * <library>sscanf</library>
  239. * <param name="file">The file in which this call is found.</param>
  240. * <param name="line">The line at which this call is found.</param>
  241. * <param name="data">The input string containing the data to parse out.</param>
  242. * <param name="format">The format description of what the input data should contain.</param>
  243. * <remarks>
  244. * An alternative name for <c>SSCANF__</c>, used by <c>extract</c> so that the
  245. * name can be used as a macro.
  246. * </remarks>
  247. */
  248. /* */ native UNFORMAT__(const file[], const line, const data[], const format[], {T_WEAPON, Float, _}:...) = SSCANF__;
  249. /**
  250. * <library>sscanf</library>
  251. * <param name="players">The maximum players on the server.</param>
  252. * <param name="invalid">The invalid player ID.</param>
  253. * <param name="len"><c>MAX_PLAYER_NAME</c>.</param>
  254. * <remarks>
  255. * Initialise the plugin with real server information.
  256. * </remarks>
  257. */
  258. /* */ native SSCANF_Init(players, invalid, len);
  259. /**
  260. * <library>sscanf</library>
  261. * <param name="playerid">The ID of the player.</param>
  262. * <param name="name">The name of the player.</param>
  263. * <param name="npc">Is this player an NPC?</param>
  264. * <remarks>
  265. * Called when a player joins to inform the plugin of the connection.
  266. * </remarks>
  267. */
  268. /* */ native SSCANF_Join(playerid, const name[], bool:npc);
  269. /**
  270. * <library>sscanf</library>
  271. * <param name="playerid">The ID of the player.</param>
  272. * <remarks>
  273. * Called when a player leaves to inform the plugin of the disconnection.
  274. * </remarks>
  275. */
  276. /* */ native SSCANF_Leave(playerid);
  277. /**
  278. * <library>sscanf</library>
  279. * <param name="playerid">The ID of the player.</param>
  280. * <remarks>
  281. * Checks if the plugin knows about a given player ID. Used when modes restart
  282. * to re-add players.
  283. * </remarks>
  284. */
  285. /* */ native bool:SSCANF_IsConnected(playerid);
  286. /**
  287. * <library>sscanf</library>
  288. * <param name="string1">The first string to compare.</param>
  289. * <param name="string2">The second string to compare.</param>
  290. * <remarks>
  291. * Computes the <a href="https://en.wikipedia.org/wiki/Levenshtein_distance">
  292. * Levenshtein Distance</a> between two strings. This is simlar to
  293. * <c>strcmp</c> in usage, but is slightly more "fuzzy". Distances are used to
  294. * work out which string is the most similar to another one, though they may not
  295. * be identical. Useful in <c>k</c> callback functions to determine if the
  296. * entered string is close to a possible string.
  297. * </remarks>
  298. */
  299. native SSCANF_Levenshtein(const string1[], const string2[]);
  300. /**
  301. * <library>sscanf</library>
  302. * <param name="string1">The first string to compare.</param>
  303. * <param name="string2">The second string to compare.</param>
  304. * <remarks>
  305. * This works out the similarity between two strings. The Levenshtein distance
  306. * often produces results that seem weird to people, for example by that measure
  307. * <c>NRG</c> is closer to <c>TUG</c> than <c>NRG-500</c>. Instead this
  308. * function compares all pairs of letters between the two strings to work out
  309. * what percentage of each string is in the other string, then multiplies the
  310. * results to get the final similarity. This algorithm produces much more human
  311. * sane results, and can handle things like <c>ls police<c> matching
  312. * <c>Police Car (LSPD)</c>. It ignores all punctuation and case as well.
  313. * </remarks>
  314. */
  315. native Float:SSCANF_TextSimilarity(const string1[], const string2[]);
  316. /**
  317. * <library>sscanf</library>
  318. * <param name="name">The sscanf option to look up. For example <c>SSCANF_COLOUR_FORMS</c>.</param>
  319. * <remarks>
  320. * The old API used <c>SSCANF_Option</c> to both get and set parse options,
  321. * with an optional parameter for setting. This was problematic if you wanted
  322. * to actually set an option to the default value - there was no way to
  323. * differentiate between getting an option and setting an option to the default
  324. * value. Instead the new API has explicit <c>Get</c> and <c>Set</c> functions.
  325. * </remarks>
  326. */
  327. native SSCANF_GetOption(const name[]) = SSCANF_Option;
  328. /**
  329. * <library>sscanf</library>
  330. * <param name="name">The sscanf option to look up. For example <c>MATCH_NAME_PARTIAL</c>.</param>
  331. * <remarks>
  332. * The old API used <c>SSCANF_Option</c> to both get and set parse options,
  333. * with an optional parameter for setting. This was problematic if you wanted
  334. * to actually set an option to the default value - there was no way to
  335. * differentiate between getting an option and setting an option to the default
  336. * value. Instead the new API uses true parameter counts to differentiate in
  337. * the legacy <c>SSCANF_Option</c> function, which are resolved through macros
  338. * to <c>Get__</c> and <c>Set__</c> functions.
  339. * </remarks>
  340. */
  341. /* */ native SSCANF_GetOption__(const name[]) = SSCANF_Option;
  342. /**
  343. * <library>sscanf</library>
  344. * <param name="name">The sscanf option to set. For example <c>CELLMIN_ON_MATCHES</c>.</param>
  345. * <param name="value">The value to set the option to.</param>
  346. * <remarks>
  347. * The old API used <c>SSCANF_Option</c> to both get and set parse options,
  348. * with an optional parameter for setting. This was problematic if you wanted
  349. * to actually set an option to the default value - there was no way to
  350. * differentiate between getting an option and setting an option to the default
  351. * value. Instead the new API has explicit <c>Get</c> and <c>Set</c> functions.
  352. * </remarks>
  353. */
  354. native SSCANF_SetOption(const name[], {_, Float}:value) = SSCANF_Option;
  355. /**
  356. * <library>sscanf</library>
  357. * <param name="name">The sscanf option to set. For example <c>OLD_DEFAULT_CUSTOM</c>.</param>
  358. * <param name="value">The value to set the option to.</param>
  359. * <remarks>
  360. * The old API used <c>SSCANF_Option</c> to both get and set parse options,
  361. * with an optional parameter for setting. This was problematic if you wanted
  362. * to actually set an option to the default value - there was no way to
  363. * differentiate between getting an option and setting an option to the default
  364. * value. Instead the new API uses true parameter counts to differentiate in
  365. * the legacy <c>SSCANF_Option</c> function, which are resolved through macros
  366. * to <c>Get__</c> and <c>Set__</c> functions.
  367. * </remarks>
  368. */
  369. /* */ native SSCANF_SetOption__(const name[], {_, Float}:value) = SSCANF_Option;
  370. /**
  371. * <library>sscanf</library>
  372. * <param name="name">The sscanf option to get or set. For example <c>SSCANF_ARGB</c>.</param>
  373. * <param name="value">The optional value to use when setting the option.</param>
  374. * <remarks>
  375. * Backwards-compatibility with <c>SSCANF_Option</c>. Usage:
  376. *
  377. * <code>
  378. * SSCANF_Option(SSCANF_QUIET, 1); <br />
  379. * new quiet = SSCANF_Option(SSCANF_QUIET);
  380. * </code>
  381. *
  382. * This doesn't actually use a default parameter because a user may want to set
  383. * the option to whatever that parameter is. Instead this is a macro that calls
  384. * <c>SSCANF_GetOption__</c> when called with one parameter (just a name), or
  385. * instead calls <c>SSCANF_SetOption__</c> when called with two - a name and a
  386. * value.
  387. * </remarks>
  388. */
  389. forward SSCANF_Option(const name[], {_, Float}:value = -1);
  390. #define SSCANF_Option SSCANF_GetOption__
  391. #define SSCANF_GetOption__(%0,%1) SSCANF_SetOption__(%0,%1)
  392. #define _ALS_SSCANF_Option
  393. #define _ALS_SSCANF_GetOption__
  394. /**
  395. * <library>sscanf</library>
  396. * <param name="version">Pass-by-reference return value.</param>
  397. * <param name="size">The size of the destination array.</param>
  398. * <remarks>
  399. * Get the SSCANF plugin version as a string (e.g. <c>"2.11.2"</c>). Compare
  400. * this value to the constant <c>SSCANF_VERSION_STRING</c>.
  401. * </remarks>
  402. */
  403. native SSCANF_VersionString(version[], size = sizeof (version)) = SSCANF_Version;
  404. /**
  405. * <library>sscanf</library>
  406. * <param name="version">Pass-by-reference return value.</param>
  407. * <param name="size">The size of the destination array.</param>
  408. * <remarks>
  409. * Get the SSCANF plugin version as a string (e.g. <c>"2.11.2"</c>). Compare
  410. * this value to the constant <c>SSCANF_VERSION_STRING</c>. This internal
  411. * alternate spelling is used by the <c>SSCANF_Version</c> macro, which will
  412. * return a string when called with parameters, or a BCD value when not.
  413. * </remarks>
  414. */
  415. /* */ native SSCANF_VersionString__(version[], size = sizeof (version)) = SSCANF_Version;
  416. /**
  417. * <library>sscanf</library>
  418. * <remarks>
  419. * Get the SSCANF plugin version as a BCD-encoded value (e.g. <c>0x021102</c>).
  420. * Compare this value to the constant <c>SSCANF_VERSION_BCD</c>.
  421. * </remarks>
  422. */
  423. native SSCANF_VersionBCD() = SSCANF_Version;
  424. /**
  425. * <library>sscanf</library>
  426. * <remarks>
  427. * Get the SSCANF plugin version as a BCD-encoded value (e.g. <c>0x021102</c>).
  428. * Compare this value to the constant <c>SSCANF_VERSION_BCD</c>. This internal
  429. * alternate spelling is used by the <c>SSCANF_Version</c> macro, which will
  430. * return a string when called with parameters, or a BCD value when not.
  431. * </remarks>
  432. */
  433. /* */ native SSCANF_VersionBCD__() = SSCANF_Version;
  434. // The `SSCANF_Version` function is overloaded to take 0 or 2 parameters (or 1 plus a default).
  435. /**
  436. * <library>sscanf</library>
  437. * <param name="version">Pass-by-reference return value.</param>
  438. * <param name="size">The size of the destination array.</param>
  439. * <remarks>
  440. * Get the SSCANF plugin version as a string (e.g. <c>"2.11.2"</c>) <em>or</em>
  441. * a BCD-encoded value (e.g. <c>0x021102</c>). This function returns a string
  442. * (by reference) when called with parameters, or a number (directly) when not.
  443. * </remarks>
  444. */
  445. static stock SSCANF_Version(version[] = "", size = sizeof (version))
  446. {
  447. return SSCANF_VERSION_BCD;
  448. }
  449. #define SSCANF_Version SSCANF_VersionString__
  450. #define SSCANF_VersionString__() SSCANF_VersionBCD__()
  451. #define _ALS_SSCANF_Version
  452. #define _ALS_SSCANF_VersionString__
  453. /**
  454. * <library>sscanf</library>
  455. * <param name="data">The input string containing the data to parse out.</param>
  456. * <param name="format">The format description of what the input data should contain.</param>
  457. * <remarks>
  458. * The main entry point. See the readme for vast amounts of information on how
  459. * to call this function and all the details on what it does. This is a macro
  460. * that calls <c>SSCANF__</c> and passes the current file and line number as
  461. * well for improved error messages.
  462. * </remarks>
  463. */
  464. #if defined __PawnBuild
  465. // On old compilers, only issue the warning at the call site.
  466. #pragma warning push
  467. #pragma warning disable 234
  468. #endif
  469. #pragma deprecated - include <sscanf2> first.
  470. forward sscanf(const data[], const format[], {T_WEAPON, Float, _}:...);
  471. #if defined __PawnBuild
  472. #pragma warning pop
  473. #endif
  474. // For pawno native detection.
  475. /*
  476. native sscanf(const data[], const format[], {T_WEAPON, Float, _}:...);
  477. */
  478. #if defined __PawnBuild
  479. #define sscanf( SSCANF__(__file,__line,
  480. #else
  481. // `-1` because the old compiler doesn't have `__line` so we can't know
  482. // where this function was used. Tell the plugin this. Actually, we *can*
  483. // know, if we look at the CIP and try extract the file/line information
  484. // from any included debug information. `SSCANF_UNK_` tells the plugin that
  485. // this was called via `sscanf` not `unformat`, because they're actually the
  486. // same function once compiled.
  487. #define sscanf( SSCANF__(SSCANF_UNK_,-1,
  488. #endif
  489. /**
  490. * - include <sscanf2> first.
  491. * <library>sscanf</library>
  492. * <param name="data">The input string containing the data to parse out.</param>
  493. * <param name="format">The format description of what the input data should contain.</param>
  494. * <remarks>
  495. * An alternative spelling of <c>sscanf</c>, requested by Kalcor because the
  496. * original doesn't match the C specification for the format descriptor. This
  497. * is a macro that calls <c>UNFORMAT__</c> and passes the current file and line
  498. * number as well for improved error messages.
  499. * </remarks>
  500. */
  501. #if defined __PawnBuild
  502. // On old compilers, only issue the warning at the call site.
  503. #pragma warning push
  504. #pragma warning disable 234
  505. #endif
  506. #pragma deprecated - include <sscanf2> first.
  507. forward unformat(const data[], const format[], {T_WEAPON, Float, _}:...);
  508. #if defined __PawnBuild
  509. #pragma warning pop
  510. #endif
  511. // For pawno native detection.
  512. /*
  513. native unformat(const data[], const format[], {T_WEAPON, Float, _}:...);
  514. */
  515. #if defined __PawnBuild
  516. #define unformat( SSCANF__(__file,__line,
  517. #else
  518. // `-1` because the old compiler doesn't have `__line` so we can't know
  519. // where this function was used. Tell the plugin this. Actually, we *can*
  520. // know, if we look at the CIP and try extract the file/line information
  521. // from any included debug information. `SSCANF_FOM_` tells the plugin that
  522. // this was called via `unformat` not `sscanf`, because they're actually the
  523. // same function once compiled.
  524. #define unformat( SSCANF__(SSCANF_FOM_,-1,
  525. #endif
  526. /**
  527. * <library>sscanf</library>
  528. * <remarks>
  529. * The fallback for the filename in <c>sscanf</c> on the old compiler, which
  530. * doesn't have the inbuilt <c>__file</c> macro. This is the "feature" enabled
  531. * by <c>SSCANF_NO_NICE_FEATURES</c>. Appends <c>"unknown file"</c> in the
  532. * plugin when line number <c>&lt; 0</c>.
  533. * </remarks>
  534. */
  535. stock const SSCANF_UNK_[] = "sscanf";
  536. /**
  537. * <library>sscanf</library>
  538. * <remarks>
  539. * The fallback for the filename in <c>unformat</c> on the old compiler, which
  540. * doesn't have the inbuilt <c>__file</c> macro. This is the "feature" enabled
  541. * by <c>SSCANF_NO_NICE_FEATURES</c>. Appends <c>"unknown file"</c> in the
  542. * plugin when line number <c>&lt; 0</c>.
  543. * </remarks>
  544. */
  545. stock const SSCANF_FOM_[] = "unformat";
  546. /**
  547. * <library>sscanf</library>
  548. * <remarks>
  549. * The fallback for the filename in <c>extract</c> on the old compiler, which
  550. * doesn't have the inbuilt <c>__file</c> macro. This is the "feature" enabled
  551. * by <c>SSCANF_NO_NICE_FEATURES</c>. Appends <c>"unknown file"</c> in the
  552. * plugin when line number <c>&lt; 0</c>.
  553. * </remarks>
  554. */
  555. stock const SSCANF_EXT_[] = "extract";
  556. /**
  557. * <library>sscanf</library>
  558. * <remarks>
  559. * The <c>SSCANF_QUIET</c> option as a constant string so you can get compile-
  560. * time spell checking on the name. Don't print any errors to the console.
  561. * <em>Really</em> not recommended unless you <em>know</em> your code is stable
  562. * and in production.
  563. * </remarks>
  564. */
  565. stock const SSCANF_QUIET[] = "SSCANF_QUIET";
  566. /**
  567. * <library>sscanf</library>
  568. * <remarks>
  569. * The <c>OLD_DEFAULT_NAME</c> option as a constant string so you can get
  570. * compile-time spell checking on the name. The behaviour of <c>U</c>, <c>Q</c>
  571. * and <c>R</c> have been changed to take any number as a default, instead of a
  572. * connected player. Setting <c>OLD_DEFAULT_NAME</c> to <c>1</c> will revert to
  573. * the old version.
  574. * </remarks>
  575. */
  576. stock const OLD_DEFAULT_NAME[] = "OLD_DEFAULT_NAME";
  577. /**
  578. * <library>sscanf</library>
  579. * <remarks>
  580. * The <c>MATCH_NAME_PARTIAL</c> option as a constant string so you can get
  581. * compile-time spell checking on the name. Currently sscanf will search for
  582. * players by name, and will <em>always</em> search for player whose name
  583. * <em>starts</em> with the specified string. If someone types <c>Y_Less</c>,
  584. * sscanf will not find say <c>[CLAN]Y_Less</c> because there name doesn't start
  585. * with the specified text. This option, when set to <c>1</c>, will search
  586. * <em>anywhere</em> in the player's name for the given string.
  587. * </remarks>
  588. */
  589. stock const MATCH_NAME_PARTIAL[] = "MATCH_NAME_PARTIAL";
  590. /**
  591. * <library>sscanf</library>
  592. * <remarks>
  593. * The <c>CELLMIN_ON_MATCHES</c> option as a constant string so you can get
  594. * compile-time spell checking on the name. Whatever the value of
  595. * <c>MATCH_NAME_PARTIAL</c>, the first found player will always be returned,
  596. * so if you do a search for <c>_</c> on an RP server, you could get almost
  597. * anyone. To detect this case, if more than one player will match the
  598. * specified string then <em>sscanf</em> will return an ID of <c>cellmin</c>
  599. * instead. This can be combined with <c>U</c> for a lot more power:
  600. *
  601. * <code>
  602. * sscanf(params, "?&lt;CELLMIN_ON_MATCHES=1&gt;U(-1)", id); <br />
  603. * if (id == -1) <br />
  604. * { <br /><indent />
  605. * // No player was entered. <br />
  606. * } <br />
  607. * else if (id == cellmin) <br />
  608. * { <br /><indent />
  609. * // Multiple matches found <br />
  610. * } <br />
  611. * else if (id == INVALID_PLAYER_ID) <br />
  612. * { <br /><indent />
  613. * // Entered player is not connected. <br />
  614. * } <br />
  615. * else <br />
  616. * { <br /><indent />
  617. * // Found just one player. <br />
  618. * }
  619. * </code>
  620. * </remarks>
  621. */
  622. stock const CELLMIN_ON_MATCHES[] = "CELLMIN_ON_MATCHES";
  623. /**
  624. * <library>sscanf</library>
  625. * <remarks>
  626. * The <c>OLD_DEFAULT_KUSTOM</c> option as a constant string so you can get
  627. * compile-time spell checking on the name. As with <c>U</c>, <c>K</c> used to
  628. * require a valid identifier as the default and would parse it using the
  629. * specified callback, so this would <em>not</em> work:
  630. *
  631. * <code>
  632. * K&lt;vehicle&gt;(Veyron)
  633. * </code>
  634. *
  635. * Because that is not a valid vehicle name in GTA. The new version now just
  636. * takes a number and returns that regardless:
  637. *
  638. * <code>
  639. * K&lt;vehicle&gt;(999)
  640. * </code>
  641. *
  642. * This setting reverts to the old behaviour.
  643. * </remarks>
  644. */
  645. stock const OLD_DEFAULT_KUSTOM[] = "OLD_DEFAULT_KUSTOM";
  646. /**
  647. * <library>sscanf</library>
  648. * <remarks>
  649. * The <c>OLD_DEFAULT_CUSTOM</c> option as a constant string so you can get
  650. * compile-time spell checking on the name. This is the same as
  651. * <c>OLD_DEFAULT_KUSTOM</c>, but with an alternate spelling.
  652. * </remarks>
  653. */
  654. stock const OLD_DEFAULT_CUSTOM[] = "OLD_DEFAULT_CUSTOM";
  655. /**
  656. * <library>sscanf</library>
  657. * <remarks>
  658. * The <c>SSCANF_COLOUR_FORMS</c> option as a constant string so you can get
  659. * compile-time spell checking on the name. There are multiple valid colour
  660. * input formats, which you can enable or disable here. The parameter is a
  661. * bit map (flags) for all the following values:
  662. *
  663. * <ul>
  664. * <li><c>1</c> - <c>#RGB</c></li>
  665. * <li><c>2</c> - <c>#RRGGBB</c></li>
  666. * <li><c>4</c> - <c>0xRRGGBB</c></li>
  667. * <li><c>8</c> - <c>RRGGBB</c></li>
  668. * <li><c>16</c> - <c>{RRGGBB}</c></li>
  669. * <li><c>32</c> - <c>0xRRGGBBAA</c></li>
  670. * <li><c>64</c> - <c>RRGGBBAA</c></li>
  671. * </ul>
  672. *
  673. * So to ONLY accept SA:MP `SendClientMessage` colours use:
  674. *
  675. * <code>
  676. * SSCANF_Option(SSCANF_COLOUR_FORMS, 16);
  677. * </code>
  678. *
  679. * To only accept 8-digit values use:
  680. *
  681. * <code>
  682. * SSCANF_Option(SSCANF_COLOUR_FORMS, 96);
  683. * </code>
  684. *
  685. * Default values (those specified between <c>()</c>s for <c>M</c>) ignore this
  686. * setting - they can always use any form.
  687. * </remarks>
  688. */
  689. stock const SSCANF_COLOUR_FORMS[] = "SSCANF_COLOUR_FORMS";
  690. /**
  691. * <library>sscanf</library>
  692. * <remarks>
  693. * The <c>SSCANF_ALPHA</c> option as a constant string so you can get compile-
  694. * time spell checking on the name. Specify the default alpha value for colours
  695. * (<c>m</c>) which don't manually specify an alpha channel. The alpha values
  696. * are specified as a <em>decimal</em> number, <em>not</em> a <em>hex</em>
  697. * number, so setting an alpha of <c>0x80</c> would be:
  698. *
  699. * <code>
  700. * SSCANF_Option(SSCANF_ALPHA, 128);
  701. * </code>
  702. * </remarks>
  703. */
  704. stock const SSCANF_ALPHA[] = "SSCANF_ALPHA";
  705. /**
  706. * <library>sscanf</library>
  707. * <remarks>
  708. * The <c>SSCANF_ARGB</c> option as a constant string so you can get compile-
  709. * time spell checking on the name. Specify whether the returned colour is
  710. * <c>ARGB</c> or <c>RGBA</c>:
  711. *
  712. * <code>
  713. * SSCANF_Option(SSCANF_ARGB, 1); // Set 3- and 6-digit colour outputs to `AARRGGBB`. <br />
  714. * SSCANF_Option(SSCANF_ARGB, 0); // Set 3- and 6-digit colour outputs to `RRGGBBAA` (default).
  715. * </code>
  716. * </remarks>
  717. */
  718. stock const SSCANF_ARGB[] = "SSCANF_ARGB";
  719. /**
  720. * <library>sscanf</library>
  721. * <remarks>
  722. * The <c>MATCH_NAME_FIRST</c> option as a constant string so you can get compile-
  723. * time spell checking on the name. Specify whether <c>u</c> etc keep searching
  724. * for better matching player names after finding one:
  725. *
  726. * <code>
  727. * SSCANF_Option(MATCH_NAME_FIRST, 0); // Enable scanning for the best name match not the first (default). <br />
  728. * SSCANF_Option(MATCH_NAME_FIRST, 1); // Enable scanning for the first name match not the best (old behaviour).
  729. * </code>
  730. * </remarks>
  731. */
  732. stock const MATCH_NAME_FIRST[] = "MATCH_NAME_FIRST";
  733. /**
  734. * <library>sscanf</library>
  735. * <remarks>
  736. * The <c>MATCH_NAME_SIMILARITY</c> option as a constant string so you can get
  737. * compile-time spell checking on the name. Specify whether <c>u</c> etc should
  738. * use the ngrams-based similarity algorithm when searching for players matching
  739. * a given name. I.e. enable or disable fuzzy name matching. It will return
  740. * the best match found, but depending on the threshold that may still be very
  741. * different to what was typed.
  742. *
  743. * <code>
  744. * SSCANF_Option(MATCH_NAME_SIMILARITY, 0.0); // Will find all names, regardless of input. <br />
  745. * SSCANF_Option(MATCH_NAME_SIMILARITY, 1.0); // Will find exact matches only. <br />
  746. * SSCANF_Option(MATCH_NAME_SIMILARITY, 0.5); // Will find names somewhat similar to the input. <br />
  747. * SSCANF_Option(MATCH_NAME_SIMILARITY, -1.0); // Disable fuzzy name matching.
  748. * </code>
  749. * </remarks>
  750. */
  751. stock const MATCH_NAME_SIMILARITY[] = "MATCH_NAME_SIMILARITY";
  752. /**
  753. * <library>sscanf</library>
  754. * <remarks>
  755. * Has sscanf been initialised at least once already in this script? Avoids the
  756. * need to define <c>FILTERSCRIPT</c> by including <c>OnFilterScriptInit</c>
  757. * and <c>OnGameModeInit</c> (plus <c>OnNPCModeInit</c>) and seeing which one
  758. * gets called first.
  759. * </remarks>
  760. */
  761. static stock SSCANF_gInit = 0;
  762. // Pre-hook data.
  763. #if !defined CHAIN_ORDER
  764. #define CHAIN_ORDER() 0
  765. #endif
  766. #define CHAIN_HOOK(%0) forward @CO_%0();public @CO_%0(){return CHAIN_ORDER()+1;}
  767. #define CHAIN_NEXT(%0) @CO_%0
  768. #define CHAIN_FORWARD:%0_%2(%1)=%3; \
  769. forward %0_%2(%1); \
  770. public %0_%2(%1) <_ALS : _ALS_x0, _ALS : _ALS_x1> { return (%3); } \
  771. public %0_%2(%1) <> { return (%3); }
  772. #define CHAIN_PUBLIC:%0(%1) %0(%1) <_ALS : _ALS_go>
  773. CHAIN_HOOK(SSCANF)
  774. #undef CHAIN_ORDER
  775. #define CHAIN_ORDER CHAIN_NEXT(SSCANF)
  776. /**
  777. * <library>sscanf</library>
  778. * <remarks>
  779. * Common ALS boilerplate to ensure that all the <c>&lt;_ALS : &gt;</c> states
  780. * are known to the compiler.
  781. * </remarks>
  782. */
  783. static stock _SSCANF_IncludeStates() <_ALS : _ALS_x0, _ALS : _ALS_x1, _ALS : _ALS_x2, _ALS : _ALS_x3> {}
  784. static stock _SSCANF_IncludeStates() <_ALS : _ALS_go> {}
  785. #if SSCANF_NPC && !defined SSCANF_NO_PLAYERS
  786. forward SSCANF_PlayerCheck();
  787. #endif
  788. /**
  789. * <library>sscanf</library>
  790. * <remarks>
  791. * const-correct wrapper for <c>SetTimer</c>, mainly for NPC modes.
  792. * </remarks>
  793. */
  794. /* */ native SSCANF_SetTimer(const funcname[], interval, bool:repeating) = SetTimer;
  795. /// <library>sscanf</library>
  796. /// <remarks>
  797. /// Generic initialisation code called from a range of different init publics.
  798. /// </remarks>
  799. /// <!--
  800. #if !defined __PawnBuild /// <p/>
  801. forward SSCANF_RunInit(); /// <p/>
  802. /// There's a bug in the old compiler with the pawndoc generation for
  803. /// functions containing <c>state</c>. This little trick starts an XML
  804. /// comment at the end of the documentation <c>SSCANF_RunInit</c> and
  805. /// immediately closes it again in a dedicated function
  806. /// <c>SSCANF_RunInit0</c>, which is sorted next lexicographically.
  807. /// -->
  808. static stock SSCANF_RunInit0()
  809. {
  810. }
  811. #endif
  812. static stock SSCANF_RunInit()
  813. {
  814. #if SSCANF_NPC
  815. state _ALS : _ALS_go;
  816. SSCANF_Init(MAX_PLAYERS, INVALID_PLAYER_ID, MAX_PLAYER_NAME);
  817. #if !defined SSCANF_NO_PLAYERS
  818. // Initialise the system.
  819. SSCANF_PlayerCheck();
  820. // Will be run once per frame.
  821. SSCANF_SetTimer("SSCANF_PlayerCheck", 0, true);
  822. #endif
  823. #else
  824. state _ALS : _ALS_go;
  825. if ((SSCANF_gInit = SSCANF_Init(GetMaxPlayers(), INVALID_PLAYER_ID, MAX_PLAYER_NAME)) == 1)
  826. {
  827. // SA:MP plugin.
  828. new
  829. name[MAX_PLAYER_NAME + 1];
  830. // Check if there are any players that aren't initialized.
  831. for (new i = 0; i != MAX_PLAYERS; ++i)
  832. {
  833. if (IsPlayerConnected(i) && !SSCANF_IsConnected(i))
  834. {
  835. GetPlayerName(i, name, sizeof (name));
  836. SSCANF_Join(i, name, bool:IsPlayerNPC(i));
  837. }
  838. }
  839. }
  840. // If the return is `0` we can try again later. If it is `-1` the
  841. // native code is an open.mp component.
  842. #endif
  843. }
  844. /**
  845. * <library>sscanf</library>
  846. * <remarks>
  847. * Called when the script starts if it is a NPC mode, sets up the system, then
  848. * calls the "real" OnNPCModeInit (using the new ALS 2 hook method).
  849. * </remarks>
  850. */
  851. #if SSCANF_NPC
  852. public OnNPCModeInit()
  853. {
  854. SSCANF_RunInit();
  855. SSCANF_OnNPCModeInit();
  856. return 1;
  857. }
  858. #if defined _ALS_OnNPCModeInit
  859. #undef OnNPCModeInit
  860. #else
  861. #define _ALS_OnNPCModeInit
  862. #endif
  863. #define OnNPCModeInit(%0) CHAIN_PUBLIC:SSCANF_OnNPCModeInit(%0)
  864. CHAIN_FORWARD:SSCANF_OnNPCModeInit() = 1;
  865. #else
  866. const SSCANF_STATIC__ SSCANF_OnNPCModeInit = 0;
  867. #define SSCANF_OnNPCModeInit
  868. #endif
  869. /**
  870. * <library>sscanf</library>
  871. * <remarks>
  872. * NPC modes have no <c>OnPlayerConnect</c> callback, so we need to simulate one.
  873. * </remarks>
  874. */
  875. #if SSCANF_NPC && !defined SSCANF_NO_PLAYERS
  876. public SSCANF_PlayerCheck()
  877. {
  878. new
  879. name[MAX_PLAYER_NAME + 1];
  880. for (new i = 0; i != MAX_PLAYERS; ++i)
  881. {
  882. if (IsPlayerConnected(i))
  883. {
  884. if (!SSCANF_IsConnected(i))
  885. {
  886. GetPlayerName(i, name, sizeof (name));
  887. // We have no way to know if they are an NPC or not!
  888. SSCANF_Join(i, name, false);
  889. }
  890. }
  891. else
  892. {
  893. if (SSCANF_IsConnected(i))
  894. {
  895. SSCANF_Leave(i);
  896. }
  897. }
  898. }
  899. }
  900. #else
  901. const SSCANF_STATIC__ SSCANF_PlayerCheck = 0;
  902. #define SSCANF_PlayerCheck
  903. #endif
  904. // `SSCANF_BRACKETS` to avoid macro replacements.
  905. #define SSCANF_BRACKETS ()
  906. forward OnScriptInit SSCANF_BRACKETS;
  907. #undef SSCANF_BRACKETS
  908. /**
  909. * <library>sscanf</library>
  910. * <remarks>
  911. * Called for earlier initialisation by YSI.
  912. * </remarks>
  913. */
  914. #if SSCANF_NPC
  915. const SSCANF_STATIC__ SSCANF_OnScriptInit = 0;
  916. #define SSCANF_OnScriptInit
  917. #else
  918. public OnScriptInit()
  919. {
  920. if (!SSCANF_gInit)
  921. {
  922. SSCANF_RunInit();
  923. }
  924. SSCANF_OnScriptInit();
  925. return 1;
  926. }
  927. #if defined _ALS_OnScriptInit
  928. #undef OnScriptInit
  929. #else
  930. #define _ALS_OnScriptInit
  931. #endif
  932. #define OnScriptInit(%0) CHAIN_PUBLIC:SSCANF_OnScriptInit(%0)
  933. CHAIN_FORWARD:SSCANF_OnScriptInit() = 1;
  934. #endif
  935. /**
  936. * <library>sscanf</library>
  937. * <remarks>
  938. * Called when the script starts if it is a filterscript, sets up the system,
  939. * then calls the "real" OnFilterScriptInit (using the new ALS 2 hook method).
  940. * </remarks>
  941. */
  942. #if SSCANF_NPC
  943. const SSCANF_STATIC__ SSCANF_OnFilterScriptInit = 0;
  944. #define SSCANF_OnFilterScriptInit
  945. #else
  946. public OnFilterScriptInit()
  947. {
  948. if (!SSCANF_gInit)
  949. {
  950. SSCANF_RunInit();
  951. }
  952. SSCANF_OnFilterScriptInit();
  953. return 1;
  954. }
  955. #if defined _ALS_OnFilterScriptInit
  956. #undef OnFilterScriptInit
  957. #else
  958. #define _ALS_OnFilterScriptInit
  959. #endif
  960. #define OnFilterScriptInit(%0) CHAIN_PUBLIC:SSCANF_OnFilterScriptInit(%0)
  961. CHAIN_FORWARD:SSCANF_OnFilterScriptInit() = 1;
  962. #endif
  963. /**
  964. * <library>sscanf</library>
  965. * <remarks>
  966. * Called when the script starts if it is a gamemode. This callback is also
  967. * called in filterscripts so we don't want to reinitialise the system in that
  968. * case.
  969. * </remarks>
  970. */
  971. #if SSCANF_NPC
  972. const SSCANF_STATIC__ SSCANF_OnGameModeInit = 0;
  973. #define SSCANF_OnGameModeInit
  974. #else
  975. public OnGameModeInit()
  976. {
  977. if (!SSCANF_gInit)
  978. {
  979. SSCANF_RunInit();
  980. }
  981. SSCANF_OnGameModeInit();
  982. return 1;
  983. }
  984. #if defined _ALS_OnGameModeInit
  985. #undef OnGameModeInit
  986. #else
  987. #define _ALS_OnGameModeInit
  988. #endif
  989. #define OnGameModeInit(%0) CHAIN_PUBLIC:SSCANF_OnGameModeInit(%0)
  990. CHAIN_FORWARD:SSCANF_OnGameModeInit() = 1;
  991. #endif
  992. forward OnCachedInit();
  993. /**
  994. * <library>sscanf</library>
  995. * <remarks>
  996. * Called when the script starts if it is (legacy) YSI cached mode.
  997. * </remarks>
  998. */
  999. #if SSCANF_NPC
  1000. const SSCANF_STATIC__ SSCANF_OnCachedInit = 0;
  1001. #define SSCANF_OnCachedInit
  1002. #else
  1003. public OnCachedInit()
  1004. {
  1005. SSCANF_RunInit();
  1006. SSCANF_OnCachedInit();
  1007. return 1;
  1008. }
  1009. #if defined _ALS_OnCachedInit
  1010. #undef OnCachedInit
  1011. #else
  1012. #define _ALS_OnCachedInit
  1013. #endif
  1014. #define OnCachedInit(%0) CHAIN_PUBLIC:SSCANF_OnCachedInit(%0)
  1015. CHAIN_FORWARD:SSCANF_OnCachedInit() = 1;
  1016. #endif
  1017. /**
  1018. * <library>sscanf</library>
  1019. * <remarks>
  1020. * Called when a player connects. Actually increments an internal count so that
  1021. * if a script ends and <c>OnPlayerDisconnect</c> is called then <c>sscanf</c>
  1022. * still knows that the player is really connected. Also stores their name
  1023. * internally.
  1024. * </remarks>
  1025. */
  1026. #if SSCANF_NPC
  1027. const SSCANF_STATIC__ SSCANF_OnPlayerConnect = 0;
  1028. #define SSCANF_OnPlayerConnect
  1029. #else
  1030. public OnPlayerConnect(playerid)
  1031. {
  1032. if (SSCANF_gInit == 1)
  1033. {
  1034. new
  1035. name[MAX_PLAYER_NAME + 1];
  1036. GetPlayerName(playerid, name, sizeof(name));
  1037. SSCANF_Join(playerid, name, bool:IsPlayerNPC(playerid));
  1038. }
  1039. SSCANF_OnPlayerConnect(playerid);
  1040. return 1;
  1041. }
  1042. #if defined _ALS_OnPlayerConnect
  1043. #undef OnPlayerConnect
  1044. #else
  1045. #define _ALS_OnPlayerConnect
  1046. #endif
  1047. #define OnPlayerConnect(%0) CHAIN_PUBLIC:SSCANF_OnPlayerConnect(%0)
  1048. CHAIN_FORWARD:SSCANF_OnPlayerConnect(playerid) = 1;
  1049. #endif
  1050. /**
  1051. * <library>sscanf</library>
  1052. * <remarks>
  1053. * Called when a player disconnects, or when a script is ended.
  1054. * </remarks>
  1055. */
  1056. #if SSCANF_NPC
  1057. const SSCANF_STATIC__ SSCANF_OnPlayerDisconnect = 0;
  1058. #define SSCANF_OnPlayerDisconnect
  1059. #else
  1060. public OnPlayerDisconnect(playerid, reason)
  1061. {
  1062. SSCANF_OnPlayerDisconnect(playerid, reason);
  1063. if (SSCANF_gInit == 1)
  1064. {
  1065. SSCANF_Leave(playerid);
  1066. }
  1067. return 1;
  1068. }
  1069. #if defined _ALS_OnPlayerDisconnect
  1070. #undef OnPlayerDisconnect
  1071. #else
  1072. #define _ALS_OnPlayerDisconnect
  1073. #endif
  1074. #define OnPlayerDisconnect(%0) CHAIN_PUBLIC:SSCANF_OnPlayerDisconnect(%0)
  1075. CHAIN_FORWARD:SSCANF_OnPlayerDisconnect(playerid, reason) = 1;
  1076. #endif
  1077. // Ensure that these purely internal natives can't be called from outside this
  1078. // include.
  1079. #define SSCANF_Init
  1080. #define SSCANF_Join
  1081. #define SSCANF_Leave
  1082. #define SSCANF_IsConnected
  1083. #if defined __PawnBuild
  1084. #define extract%0->%1; EXTRN%1;UNFORMAT__(__file,__line,_:EXTRV:EXTRX:%0,""#,%1,,);
  1085. #else
  1086. #define extract%0->%1; EXTRN%1;UNFORMAT__(SSCANF_EXT_,-1,_:EXTRV:EXTRX:%0,""#,%1,,);
  1087. #endif
  1088. #define UNFORMAT__(%7,%8,_:EXTRV:EXTRX:%0,""#,%1);%2else if (UNFORMAT__(%7,%8,_:EXTRV:EXTRX:%0,""#,%1))
  1089. #define EXTRV:EXTRX:%0<%3>%4#,%9new%1,%2) EXTRZ:EXTRY:%0%4#P<%3>,|||%1|||%2)
  1090. #define EXTRZ:EXTRY:%0#P<,> EXTRY:%0"P<,>"#
  1091. #define EXTRX:%0#,%9new%1,%2) EXTRY:%0#,|||%1|||%2)
  1092. #define EXTRY: EXTR8:EXTR9:EXTR0:EXTR1:EXTR2:EXTR3:EXTR4:
  1093. #define EXTR8:EXTR9:EXTR0:EXTR1:EXTR2:EXTR3:EXTR4:%0#%1,%2|||%6:%3=%9|||%4) %6_EXTRO:%0#%1,%2|||%3=%9|||%4)
  1094. #define EXTR9:EXTR0:EXTR1:EXTR2:EXTR3:EXTR4:%0#%1,%2|||%3=%9|||%4) __EXTRO:%0#%1,%2|||%3=%9|||%4)
  1095. #define EXTR0:EXTR1:EXTR2:EXTR3:EXTR4:%0#%1,%2|||%6:%3[%7]|||%4) %6_EXTRW:%0#%1,%2|||%3[%7]|||%4)
  1096. #define EXTR1:EXTR2:EXTR3:EXTR4:%0#%1,%2|||%3[%7]|||%4) __EXTRW:%0#%1,%2|||%3[%7]|||%4)
  1097. #define EXTR2:EXTR3:EXTR4:%0#%1,%2|||%6:%3|||%4) %6_EXTRN:%0#%1,%2|||%3|||%4)
  1098. #define EXTR3:EXTR4:%0#%1,,%2||||||%4) %0#%1,%2)
  1099. #define EXTR4:%0#%1,%2|||%3|||%4) __EXTRN:%0#%1,%2|||%3|||%4)
  1100. // Optional specifiers.
  1101. #define __EXTRO:%0#%1,%2|||%3=%9|||%4,%5) EXTRY:%0#%1I"("#%9")"#,%2,%3|||%4|||%5)
  1102. #define Float_EXTRO:%0#%1,%2|||%3=%9|||%4,%5) EXTRY:%0#%1F"("#%9")"#,%2,%3|||%4|||%5)
  1103. #define player_EXTRO:%0#%1,%2|||%3=%9|||%4,%5) EXTRY:%0#%1U"("#%9")"#,%2,%3|||%4|||%5)
  1104. #define string_EXTRO:%0#%1,%2|||%3[%7]=%9|||%4,%5) EXTRY:%0#%1S"("#%9")[*]",%2,(%7),%3|||%4|||%5)
  1105. // Normal specifiers (the double underscore is to work for "_:".
  1106. #define __EXTRN:%0#%1,%2|||%3|||%4,%5) EXTRY:%0#%1i,%2,%3|||%4|||%5)
  1107. #define Float_EXTRN:%0#%1,%2|||%3|||%4,%5) EXTRY:%0#%1f,%2,%3|||%4|||%5)
  1108. #define player_EXTRN:%0#%1,%2|||%3|||%4,%5) EXTRY:%0#%1u,%2,%3|||%4|||%5)
  1109. //#define string_EXTRW:%0#%1,%2|||%3[%7]|||%4,%5) EXTRY:%0#%1s[%7],%2,%3|||%4|||%5)
  1110. // Array versions of normal specifiers.
  1111. #define __EXTRW:%0#%1,%2|||%3[%7]|||%4,%5) EXTRY:%0#%1a<i>[*],%2,(%7),%3|||%4|||%5)
  1112. #define Float_EXTRW:%0#%1,%2|||%3[%7]|||%4,%5) EXTRY:%0#%1a<f>[*],%2,(%7),%3|||%4|||%5)
  1113. #define player_EXTRW:%0#%1,%2|||%3[%7]|||%4,%5) EXTRY:%0#%1a<u>[*],%2,(%7),%3|||%4|||%5)
  1114. #define string_EXTRW:%0#%1,%2|||%3[%7]|||%4,%5) EXTRY:%0#%1s[*],%2,(%7),%3|||%4|||%5)
  1115. // Get rid of excess leading space which causes warnings.
  1116. #define EXTRN%0new%1; new%1;
  1117. #if !defined string
  1118. #define string:
  1119. #endif
  1120. #define player:%0;UNFORMAT__(%1) %0;UNFORMAT__(%1)
  1121. #define hex:%0;UNFORMAT__(%1) %0;UNFORMAT__(%1)
  1122. #define hex_EXTRO:%0#%1,%2|||%3=%9|||%4,%5) EXTRY:%0#%1H"("#%9")"#,%2,%3|||%4|||%5)
  1123. #define hex_EXTRN:%0#%1,%2|||%3|||%4,%5) EXTRY:%0#%1h,%2,%3|||%4|||%5)
  1124. #define hex_EXTRW:%0#%1,%2|||%3[%7]|||%4,%5) EXTRY:%0#%1a<h>[*],%2,(%7),%3|||%4|||%5)
  1125. #define bin:%0;UNFORMAT__(%1) %0;UNFORMAT__(%1)
  1126. #define bin_EXTRO:%0#%1,%2|||%3=%9|||%4,%5) EXTRY:%0#%1B"("#%9")"#,%2,%3|||%4|||%5)
  1127. #define bin_EXTRN:%0#%1,%2|||%3|||%4,%5) EXTRY:%0#%1b,%2,%3|||%4|||%5)
  1128. #define bin_EXTRW:%0#%1,%2|||%3[%7]|||%4,%5) EXTRY:%0#%1a<b>[*],%2,(%7),%3|||%4|||%5)
  1129. #define colour:%0;UNFORMAT__(%1) %0;UNFORMAT__(%1)
  1130. #define colour_EXTRO:%0#%1,%2|||%3=%9|||%4,%5) EXTRY:%0#%1M"("#%9")"#,%2,%3|||%4|||%5)
  1131. #define colour_EXTRN:%0#%1,%2|||%3|||%4,%5) EXTRY:%0#%1m,%2,%3|||%4|||%5)
  1132. #define colour_EXTRW:%0#%1,%2|||%3[%7]|||%4,%5) EXTRY:%0#%1a<m>[*],%2,(%7),%3|||%4|||%5)
  1133. #define kustom:%0<%1> %0
  1134. #define kustom_EXTRO:%0#%1,%2|||%3<%8>=%9|||%4,%5) EXTRY:%0#%1K<%8>"("#%9")"#,%2,%3|||%4|||%5)
  1135. #define kustom_EXTRN:%0#%1,%2|||%3<%8>|||%4,%5) EXTRY:%0#%1k<%8>,%2,%3|||%4|||%5)
  1136. //#define bin_EXTRW:%0#%1,%2|||%3[%7]|||%4,%5) EXTRY:%0#%1a<b>[*],%2,(%7),%3|||%4|||%5)
  1137. /**
  1138. * <library>sscanf</library>
  1139. * <param name="input">The first string to compare.</param>
  1140. * <param name="candidates">A list of other strings to compare against.</param>
  1141. * <param name="threshold">How similar the strings must be to be considered a match.</param>
  1142. * <param name="count">The number of candidates.</param>
  1143. * <remarks>
  1144. * Takes an input string and an array of string possibilities (candidates) and
  1145. * returns the index of the string closest to the input string. If no valid
  1146. * match is found, <c>-1</c> is returned. Note that this will always return the
  1147. * closest, even if the closest is not that close; which is why an optional
  1148. * <c>threshold</c> parameter is available. When this parameter is provided the
  1149. * closest match must be closer in Levenshtein distance than the threshold,
  1150. * otherwise again <c>-1</c> is returned.
  1151. * </remarks>
  1152. */
  1153. stock SSCANF_GetSimilarString(const input[], const candidates[][], Float:threshold = 0.111111, count = sizeof (candidates))
  1154. {
  1155. new
  1156. closest = cellmin,
  1157. Float:distance;
  1158. while (count--)
  1159. {
  1160. distance = SSCANF_TextSimilarity(input, candidates[count]);
  1161. if (distance >= threshold)
  1162. {
  1163. closest = count,
  1164. threshold = distance;
  1165. }
  1166. }
  1167. return closest;
  1168. }
  1169. /**
  1170. * <library>sscanf</library>
  1171. * <param name="input">The first string to compare.</param>
  1172. * <param name="candidates">A list of other strings to compare against.</param>
  1173. * <param name="results">The values to return when the corresponding candidate (by index) is the closest match.</param>
  1174. * <param name="fail">The value to return when there is no good match.</param>
  1175. * <param name="threshold">How similar the strings must be to be considered a match.</param>
  1176. * <param name="count">The number of candidates (must match <c>check</c>).</param>
  1177. * <param name="check">The number of results (must match <c>count</c>).</param>
  1178. * <remarks>
  1179. * Similar to <c>SSCANF_GetClosestString</c> in that it searches the
  1180. * <c>candidates</c> array for the string most closely matching the <c>input</c>
  1181. * and bounded by <c>threshold</c>. But instead of returning the index this
  1182. * function returns the value in the second <c>results</c> array at that index;
  1183. * and instead of returning <c>-1</c> on failure it returns the value of
  1184. * <c>fail</c>. The two arrays must match in size and an <c>assert</c> in the
  1185. * function checks for this.
  1186. * </remarks>
  1187. */
  1188. stock SSCANF_GetSimilarValue(const input[], const candidates[][], const results[], fail = cellmin, Float:threshold = 0.111111, count = sizeof (candidates), check = sizeof (results))
  1189. {
  1190. assert(count == check);
  1191. new closest = SSCANF_GetSimilarString(input, candidates, threshold, count);
  1192. if (closest == cellmin)
  1193. {
  1194. return fail;
  1195. }
  1196. return results[closest];
  1197. }
  1198. /**
  1199. * <library>sscanf</library>
  1200. * <param name="input">The first string to compare.</param>
  1201. * <param name="candidates">A list of other strings to compare against.</param>
  1202. * <param name="threshold">How similar the strings must be to be considered a match.</param>
  1203. * <param name="count">The number of candidates.</param>
  1204. * <remarks>
  1205. * Takes an input string and an array of string possibilities (candidates) and
  1206. * returns the index of the string closest to the input string. If no valid
  1207. * match is found, <c>-1</c> is returned. Note that this will always return the
  1208. * closest, even if the closest is not that close; which is why an optional
  1209. * <c>threshold</c> parameter is available. When this parameter is provided the
  1210. * closest match must be closer in Levenshtein distance than the threshold,
  1211. * otherwise again <c>-1</c> is returned.
  1212. * </remarks>
  1213. */
  1214. #if defined __PawnBuild
  1215. // On old compilers, only issue the warning at the call site.
  1216. #pragma warning push
  1217. #pragma warning disable 234
  1218. #endif
  1219. #pragma deprecated Use `SSCANF_GetSimilarString` for more human results.
  1220. stock SSCANF_GetClosestString(const input[], const candidates[][], threshold = cellmax, count = sizeof (candidates))
  1221. {
  1222. new
  1223. closest = cellmin,
  1224. distance;
  1225. while (count--)
  1226. {
  1227. distance = SSCANF_Levenshtein(input, candidates[count]);
  1228. if (distance < threshold)
  1229. {
  1230. closest = count,
  1231. threshold = distance;
  1232. }
  1233. }
  1234. return closest;
  1235. }
  1236. #if defined __PawnBuild
  1237. #pragma warning pop
  1238. #endif
  1239. /**
  1240. * <library>sscanf</library>
  1241. * <param name="input">The first string to compare.</param>
  1242. * <param name="candidates">A list of other strings to compare against.</param>
  1243. * <param name="results">The values to return when the corresponding candidate (by index) is the closest match.</param>
  1244. * <param name="fail">The value to return when there is no good match.</param>
  1245. * <param name="threshold">How similar the strings must be to be considered a match.</param>
  1246. * <param name="count">The number of candidates (must match <c>check</c>).</param>
  1247. * <param name="check">The number of results (must match <c>count</c>).</param>
  1248. * <remarks>
  1249. * Similar to <c>SSCANF_GetClosestString</c> in that it searches the
  1250. * <c>candidates</c> array for the string most closely matching the <c>input</c>
  1251. * and bounded by <c>threshold</c>. But instead of returning the index this
  1252. * function returns the value in the second <c>results</c> array at that index;
  1253. * and instead of returning <c>-1</c> on failure it returns the value of
  1254. * <c>fail</c>. The two arrays must match in size and an <c>assert</c> in the
  1255. * function checks for this.
  1256. * </remarks>
  1257. */
  1258. #if defined __PawnBuild
  1259. // On old compilers, only issue the warning at the call site.
  1260. #pragma warning push
  1261. #pragma warning disable 234
  1262. #endif
  1263. #pragma deprecated Use `SSCANF_GetSimilarValue` for more human results.
  1264. stock SSCANF_GetClosestValue(const input[], const candidates[][], const results[], fail = cellmin, threshold = cellmax, count = sizeof (candidates), check = sizeof (results))
  1265. {
  1266. assert(count == check);
  1267. new closest = SSCANF_GetClosestString(input, candidates, threshold, count);
  1268. if (closest == cellmin)
  1269. {
  1270. return fail;
  1271. }
  1272. return results[closest];
  1273. }
  1274. #if defined __PawnBuild
  1275. #pragma warning pop
  1276. #endif
  1277. /**
  1278. * <library>sscanf</library>
  1279. * <param name="string">The current word being parsed out of the <c>sscanf</c> input.</param>
  1280. * <remarks>
  1281. * The default implementation of <c>k&lt;weapon&gt;</c>. Finds the closest
  1282. * weapon by Levenshtein distance to the input.
  1283. * </remarks>
  1284. */
  1285. #if defined SSCANF_NO_K_WEAPON
  1286. /* */ native SSCANF_no_k_weapon();
  1287. #define SSCANF_no_k_weapon()
  1288. #else
  1289. SSCANF:weapon(const string[])
  1290. {
  1291. static const results[] = {
  1292. 0, 0, 1, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 22, 23, 24, 25,
  1293. 26, 27, 28, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46
  1294. };
  1295. static const candidates[][] = {
  1296. "Fists",
  1297. "Unarmed",
  1298. "Knuckles",
  1299. "Knuckledusters",
  1300. "Brass Knuckles",
  1301. "Golf Club",
  1302. "Night Stick",
  1303. "Knife",
  1304. "Baseball Bat",
  1305. "Shovel",
  1306. "Pool cue",
  1307. "Katana",
  1308. "Chainsaw",
  1309. "Purple Dildo",
  1310. "White Dildo",
  1311. "Long White Dildo",
  1312. "White Dildo 2",
  1313. "Flowers",
  1314. "Cane",
  1315. "Grenades",
  1316. "Tear Gas",
  1317. "Molotovs",
  1318. "Pistol",
  1319. "Silenced Pistol",
  1320. "Desert Eagle",
  1321. "Shotgun",
  1322. "Sawn Off Shotgun",
  1323. "Combat Shotgun",
  1324. "Micro Uzi",
  1325. "Mac 10",
  1326. "MP5",
  1327. "AK47",
  1328. "M4",
  1329. "Tec9",
  1330. "Rifle",
  1331. "Sniper Rifle",
  1332. "RPG",
  1333. "Missile Launcher",
  1334. "Flame Thrower",
  1335. "Minigun",
  1336. "Sachel Charges",
  1337. "Detonator",
  1338. "Spray Paint",
  1339. "Fire Extinguisher",
  1340. "Camera",
  1341. "Nightvision Goggles",
  1342. "Thermal Goggles",
  1343. "Parachute"
  1344. };
  1345. // This function is VERY basic, needs VASTLY improving to detect variations.
  1346. if ('0' <= string[0] <= '9')
  1347. {
  1348. new
  1349. ret = strval(string);
  1350. if (0 <= ret <= 18 || 22 <= ret <= 46)
  1351. {
  1352. return ret;
  1353. }
  1354. }
  1355. else
  1356. {
  1357. return SSCANF_GetSimilarValue(string, candidates, results, -1);
  1358. }
  1359. return -1;
  1360. }
  1361. #endif
  1362. /**
  1363. * <library>sscanf</library>
  1364. * <param name="string">The current word being parsed out of the <c>sscanf</c> input.</param>
  1365. * <remarks>
  1366. * The default implementation of <c>k&lt;vehicle&gt;</c>. Finds the closest
  1367. * vehicle by Levenshtein distance to the input.
  1368. * </remarks>
  1369. */
  1370. #if defined SSCANF_NO_K_VEHICLE
  1371. /* */ native SSCANF_no_k_vehicle();
  1372. #define SSCANF_no_k_vehicle()
  1373. #else
  1374. SSCANF:vehicle(const string[])
  1375. {
  1376. static const results[] = {
  1377. 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417,
  1378. 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435,
  1379. 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453,
  1380. 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471,
  1381. 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489,
  1382. 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507,
  1383. 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525,
  1384. 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543,
  1385. 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561,
  1386. 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579,
  1387. 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597,
  1388. 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611
  1389. };
  1390. static const candidates[][] = {
  1391. "Landstalker",
  1392. "Bravura",
  1393. "Buffalo",
  1394. "Linerunner",
  1395. "Perennial",
  1396. "Sentinel",
  1397. "Dumper",
  1398. "Firetruck",
  1399. "Trashmaster",
  1400. "Stretch",
  1401. "Manana",
  1402. "Infernus",
  1403. "Voodoo",
  1404. "Pony",
  1405. "Mule",
  1406. "Cheetah",
  1407. "Ambulance",
  1408. "Leviathan",
  1409. "Moonbeam",
  1410. "Esperanto",
  1411. "Taxi",
  1412. "Washington",
  1413. "Bobcat",
  1414. "Mr Whoopee",
  1415. "BF Injection",
  1416. "Hunter",
  1417. "Premier",
  1418. "Enforcer",
  1419. "Securicar",
  1420. "Banshee",
  1421. "Predator",
  1422. "Bus",
  1423. "Rhino",
  1424. "Barracks",
  1425. "Hotknife",
  1426. "Article Trailer",
  1427. "Previon",
  1428. "Coach",
  1429. "Cabbie",
  1430. "Stallion",
  1431. "Rumpo",
  1432. "RC Bandit",
  1433. "Romero",
  1434. "Packer",
  1435. "Monster",
  1436. "Admiral",
  1437. "Squalo",
  1438. "Seasparrow",
  1439. "Pizzaboy",
  1440. "Tram",
  1441. "Article Trailer 2",
  1442. "Turismo",
  1443. "Speeder",
  1444. "Reefer",
  1445. "Tropic",
  1446. "Flatbed",
  1447. "Yankee",
  1448. "Caddy",
  1449. "Solair",
  1450. "Topfun Van (Berkley's RC)",
  1451. "Skimmer",
  1452. "PCJ-600",
  1453. "Faggio",
  1454. "Freeway",
  1455. "RC Baron",
  1456. "RC Raider",
  1457. "Glendale",
  1458. "Oceanic",
  1459. "Sanchez",
  1460. "Sparrow",
  1461. "Patriot",
  1462. "Quad",
  1463. "Coastguard",
  1464. "Dinghy",
  1465. "Hermes",
  1466. "Sabre",
  1467. "Rustler",
  1468. "ZR-350",
  1469. "Walton",
  1470. "Regina",
  1471. "Comet",
  1472. "BMX",
  1473. "Burrito",
  1474. "Camper",
  1475. "Marquis",
  1476. "Baggage",
  1477. "Dozer",
  1478. "Maverick",
  1479. "SAN News Maverick",
  1480. "Rancher",
  1481. "FBI Rancher",
  1482. "Virgo",
  1483. "Greenwood",
  1484. "Jetmax",
  1485. "Hotring Racer",
  1486. "Sandking",
  1487. "Blista Compact",
  1488. "Police Maverick",
  1489. "Boxville",
  1490. "Benson",
  1491. "Mesa",
  1492. "RC Goblin",
  1493. "Hotring Racer \"A\"",
  1494. "Hotring Racer \"B\"",
  1495. "Bloodring Banger",
  1496. "Rancher Lure",
  1497. "Super GT",
  1498. "Elegant",
  1499. "Journey",
  1500. "Bike",
  1501. "Mountain Bike",
  1502. "Beagle",
  1503. "Cropduster",
  1504. "Stuntplane",
  1505. "Tanker",
  1506. "Roadtrain",
  1507. "Nebula",
  1508. "Majestic",
  1509. "Buccaneer",
  1510. "Shamal",
  1511. "Hydra",
  1512. "FCR-900",
  1513. "NRG-500",
  1514. "HPV1000",
  1515. "Cement Truck",
  1516. "Towtruck",
  1517. "Fortune",
  1518. "Cadrona",
  1519. "FBI Truck",
  1520. "Willard",
  1521. "Forklift",
  1522. "Tractor",
  1523. "Combine Harvester",
  1524. "Feltzer",
  1525. "Remington",
  1526. "Slamvan",
  1527. "Blade",
  1528. "Freight (Train)",
  1529. "Brownstreak (Train)",
  1530. "Vortex",
  1531. "Vincent",
  1532. "Bullet",
  1533. "Clover",
  1534. "Sadler",
  1535. "Firetruck LA",
  1536. "Hustler",
  1537. "Intruder",
  1538. "Primo",
  1539. "Cargobob",
  1540. "Tampa",
  1541. "Sunrise",
  1542. "Merit",
  1543. "Utility Van",
  1544. "Nevada",
  1545. "Yosemite",
  1546. "Windsor",
  1547. "Monster \"A\"",
  1548. "Monster \"B\"",
  1549. "Uranus",
  1550. "Jester",
  1551. "Sultan",
  1552. "Stratum",
  1553. "Elegy",
  1554. "Raindance",
  1555. "RC Tiger",
  1556. "Flash",
  1557. "Tahoma",
  1558. "Savanna",
  1559. "Bandito",
  1560. "Freight Flat Trailer (Train)",
  1561. "Streak Trailer (Train)",
  1562. "Kart",
  1563. "Mower",
  1564. "Dune",
  1565. "Sweeper",
  1566. "Broadway",
  1567. "Tornado",
  1568. "AT400",
  1569. "DFT-30",
  1570. "Huntley",
  1571. "Stafford",
  1572. "BF-400",
  1573. "Newsvan",
  1574. "Tug",
  1575. "Petrol Trailer",
  1576. "Emperor",
  1577. "Wayfarer",
  1578. "Euros",
  1579. "Hotdog",
  1580. "Club",
  1581. "Freight Box Trailer (Train)",
  1582. "Article Trailer 3",
  1583. "Andromada",
  1584. "Dodo",
  1585. "RC Cam",
  1586. "Launch",
  1587. "Police Car (LSPD)",
  1588. "Police Car (SFPD)",
  1589. "Police Car (LVPD)",
  1590. "Police Ranger",
  1591. "Picador",
  1592. "S.W.A.T.",
  1593. "Alpha",
  1594. "Phoenix",
  1595. "Glendale Shit",
  1596. "Sadler Shit",
  1597. "Baggage Trailer \"A\"",
  1598. "Baggage Trailer \"B\"",
  1599. "Tug Stairs Trailer",
  1600. "Boxville",
  1601. "Farm Trailer",
  1602. "Utility Trailer"
  1603. };
  1604. // This function is VERY basic, needs VASTLY improving to detect variations.
  1605. if ('0' <= string[0] <= '9')
  1606. {
  1607. new
  1608. ret = strval(string);
  1609. if (400 <= ret <= 611)
  1610. {
  1611. return ret;
  1612. }
  1613. }
  1614. else
  1615. {
  1616. return SSCANF_GetSimilarValue(string, candidates, results, -1);
  1617. }
  1618. return -1;
  1619. }
  1620. #endif
  1621. // Fix the compiler crash when both the PAWN and Plugin versions of sscanf are
  1622. // found by renaming the old version at declaration. (fixes.inc compatible
  1623. // naming scheme: "BAD_Function()").
  1624. #define SSCANF__(%0:...) BAD_sscanf(%0:...)