audio.pwn 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787
  1. #define COLOR_RED (0xFF0000FF)
  2. #define COLOR_YELLOW (0xFFFF00FF)
  3. #define dcmd(%1,%2,%3) if ((strcmp((%3)[1], #%1, true, (%2)) == 0) && ((((%3)[(%2) + 1] == 0) && (dcmd_%1(playerid, "")))||(((%3)[(%2) + 1] == 32) && (dcmd_%1(playerid, (%3)[(%2) + 2]))))) return 1 // Courtesy of DracoBlue
  4. #include <a_samp>
  5. #include <audio>
  6. public
  7. OnFilterScriptInit()
  8. {
  9. // Set the audio pack when the filterscript loads
  10. Audio_SetPack("default_pack", true);
  11. return 1;
  12. }
  13. /*
  14. Here are some testing commands.
  15. */
  16. public
  17. OnPlayerCommandText(playerid, cmdtext[])
  18. {
  19. dcmd(createsequence, 14, cmdtext);
  20. dcmd(destroysequence, 15, cmdtext);
  21. dcmd(addtosequence, 13, cmdtext);
  22. dcmd(removefromsequence, 18, cmdtext);
  23. dcmd(play, 4, cmdtext);
  24. dcmd(playsequence, 12, cmdtext);
  25. dcmd(playstreamed, 12, cmdtext);
  26. dcmd(pause, 5, cmdtext);
  27. dcmd(resume, 6, cmdtext);
  28. dcmd(stop, 4, cmdtext);
  29. dcmd(restart, 7, cmdtext);
  30. dcmd(seek, 4, cmdtext);
  31. dcmd(setvolume, 9, cmdtext);
  32. dcmd(set3dposition, 13, cmdtext);
  33. dcmd(set3doffsets, 12, cmdtext);
  34. dcmd(seteax, 6, cmdtext);
  35. dcmd(removeeax, 9, cmdtext);
  36. dcmd(setfx, 5, cmdtext);
  37. dcmd(removefx, 8, cmdtext);
  38. dcmd(connected, 9, cmdtext);
  39. dcmd(setpack, 7, cmdtext);
  40. return 0;
  41. }
  42. dcmd_createsequence(playerid, params[])
  43. {
  44. #pragma unused playerid, params
  45. new
  46. sequenceid,
  47. string[64];
  48. sequenceid = Audio_CreateSequence();
  49. if (sequenceid)
  50. {
  51. format(string, sizeof(string), "Sequence ID %d created", sequenceid);
  52. }
  53. else
  54. {
  55. format(string, sizeof(string), "Error creating sequence ID %d", sequenceid);
  56. }
  57. SendClientMessageToAll(COLOR_YELLOW, string);
  58. return 1;
  59. }
  60. dcmd_destroysequence(playerid, params[])
  61. {
  62. #pragma unused playerid
  63. new
  64. sequenceid = strval(params);
  65. if (!sequenceid)
  66. {
  67. SendClientMessage(playerid, COLOR_YELLOW, "USAGE: /destroysequence <sequenceid>");
  68. return 1;
  69. }
  70. new
  71. string[64];
  72. if (Audio_DestroySequence(sequenceid))
  73. {
  74. format(string, sizeof(string), "Sequence ID %d destroyed", sequenceid);
  75. }
  76. else
  77. {
  78. format(string, sizeof(string), "Error destroying sequence ID %d", sequenceid);
  79. }
  80. SendClientMessageToAll(COLOR_YELLOW, string);
  81. return 1;
  82. }
  83. dcmd_addtosequence(playerid, params[])
  84. {
  85. #pragma unused playerid
  86. new
  87. audioid,
  88. sequenceid;
  89. if (sscanf(params, "dd", sequenceid, audioid))
  90. {
  91. SendClientMessage(playerid, COLOR_YELLOW, "USAGE: /addtosequence <sequenceid> <audioid>");
  92. return 1;
  93. }
  94. new
  95. string[64];
  96. if (Audio_AddToSequence(sequenceid, audioid))
  97. {
  98. format(string, sizeof(string), "Audio ID %d added to sequence ID %d", audioid, sequenceid);
  99. }
  100. else
  101. {
  102. format(string, sizeof(string), "Error adding audio ID %d to sequence ID %d", audioid, sequenceid);
  103. }
  104. SendClientMessageToAll(COLOR_YELLOW, string);
  105. return 1;
  106. }
  107. dcmd_removefromsequence(playerid, params[])
  108. {
  109. #pragma unused playerid
  110. new
  111. audioid,
  112. sequenceid;
  113. if (sscanf(params, "dd", sequenceid, audioid))
  114. {
  115. SendClientMessage(playerid, COLOR_YELLOW, "USAGE: /removefromsequence <sequenceid> <audioid>");
  116. return 1;
  117. }
  118. new
  119. string[64];
  120. if (Audio_RemoveFromSequence(sequenceid, audioid))
  121. {
  122. format(string, sizeof(string), "Audio ID %d removed from sequence ID %d", audioid, sequenceid);
  123. }
  124. else
  125. {
  126. format(string, sizeof(string), "Error removing audio ID %d from sequence ID %d", audioid, sequenceid);
  127. }
  128. SendClientMessageToAll(COLOR_YELLOW, string);
  129. return 1;
  130. }
  131. dcmd_play(playerid, params[])
  132. {
  133. #pragma unused playerid
  134. new
  135. audioid,
  136. bool:downmix,
  137. bool:loop,
  138. bool:pause;
  139. if (sscanf(params, "dddd", audioid, pause, loop, downmix))
  140. {
  141. SendClientMessage(playerid, COLOR_YELLOW, "USAGE: /play <audioid> <pause (0/1)> <loop (0/1)> <downmix (0/1)>");
  142. return 1;
  143. }
  144. Audio_Play(playerid, audioid, pause, loop, downmix);
  145. return 1;
  146. }
  147. dcmd_playsequence(playerid, params[])
  148. {
  149. #pragma unused playerid
  150. new
  151. audioid,
  152. bool:downmix,
  153. bool:loop,
  154. bool:pause;
  155. if (sscanf(params, "dddd", audioid, pause, loop, downmix))
  156. {
  157. SendClientMessage(playerid, COLOR_YELLOW, "USAGE: /playsequence <sequenceid> <pause (0/1)> <loop (0/1)> <downmix (0/1)>");
  158. return 1;
  159. }
  160. Audio_PlaySequence(playerid, audioid, pause, loop, downmix);
  161. return 1;
  162. }
  163. dcmd_playstreamed(playerid, params[])
  164. {
  165. #pragma unused playerid
  166. new
  167. bool:downmix,
  168. bool:loop,
  169. bool:pause,
  170. url[256];
  171. if (sscanf(params, "sddd", url, pause, loop, downmix))
  172. {
  173. SendClientMessage(playerid, COLOR_YELLOW, "USAGE: /playstreamed <url> <pause (0/1)> <loop (0/1)> <downmix (0/1)>");
  174. return 1;
  175. }
  176. Audio_PlayStreamed(playerid, url, pause, loop, downmix);
  177. return 1;
  178. }
  179. dcmd_pause(playerid, params[])
  180. {
  181. #pragma unused playerid
  182. new
  183. handleid = strval(params);
  184. if (!handleid)
  185. {
  186. SendClientMessage(playerid, COLOR_YELLOW, "USAGE: /pause <handleid>");
  187. return 1;
  188. }
  189. new
  190. string[64];
  191. format(string, sizeof(string), "Audio playback paused for handle ID %d", handleid);
  192. SendClientMessage(playerid, COLOR_YELLOW, string);
  193. Audio_Pause(playerid, handleid);
  194. return 1;
  195. }
  196. dcmd_resume(playerid, params[])
  197. {
  198. #pragma unused playerid
  199. new
  200. handleid = strval(params);
  201. if (!handleid)
  202. {
  203. SendClientMessage(playerid, COLOR_YELLOW, "USAGE: /resume <handleid>");
  204. return 1;
  205. }
  206. new
  207. string[64];
  208. format(string, sizeof(string), "Audio playback resumed for handle ID %d", handleid);
  209. SendClientMessage(playerid, COLOR_YELLOW, string);
  210. Audio_Resume(playerid, handleid);
  211. return 1;
  212. }
  213. dcmd_stop(playerid, params[])
  214. {
  215. #pragma unused playerid
  216. new
  217. handleid = strval(params);
  218. if (!handleid)
  219. {
  220. SendClientMessage(playerid, COLOR_YELLOW, "USAGE: /stop <handleid>");
  221. return 1;
  222. }
  223. Audio_Stop(playerid, handleid);
  224. return 1;
  225. }
  226. dcmd_restart(playerid, params[])
  227. {
  228. #pragma unused playerid
  229. new
  230. handleid = strval(params);
  231. if (!handleid)
  232. {
  233. SendClientMessage(playerid, COLOR_YELLOW, "USAGE: /restart <handleid>");
  234. return 1;
  235. }
  236. new
  237. string[64];
  238. format(string, sizeof(string), "Audio playback restarted for handle ID %d", handleid);
  239. SendClientMessage(playerid, COLOR_YELLOW, string);
  240. Audio_Restart(playerid, handleid);
  241. return 1;
  242. }
  243. dcmd_seek(playerid, params[])
  244. {
  245. #pragma unused playerid
  246. new
  247. handleid,
  248. seconds;
  249. if (sscanf(params, "dd", handleid, seconds))
  250. {
  251. SendClientMessage(playerid, COLOR_YELLOW, "USAGE: /seek <handleid> <seconds>");
  252. return 1;
  253. }
  254. new
  255. string[64];
  256. format(string, sizeof(string), "Audio seeked to %d seconds for handle ID %d", seconds, handleid);
  257. SendClientMessage(playerid, COLOR_YELLOW, string);
  258. Audio_Seek(playerid, handleid, seconds);
  259. return 1;
  260. }
  261. dcmd_setvolume(playerid, params[])
  262. {
  263. #pragma unused playerid
  264. new
  265. handleid,
  266. volume;
  267. if (sscanf(params, "dd", handleid, volume))
  268. {
  269. SendClientMessage(playerid, COLOR_YELLOW, "USAGE: /setvolume <handleid> <volume (0-100)>");
  270. return 1;
  271. }
  272. new
  273. string[64];
  274. format(string, sizeof(string), "Audio volume set to %d for handle ID %d", volume, handleid);
  275. SendClientMessage(playerid, COLOR_YELLOW, string);
  276. Audio_SetVolume(playerid, handleid, volume);
  277. return 1;
  278. }
  279. dcmd_set3dposition(playerid, params[])
  280. {
  281. #pragma unused playerid
  282. new
  283. handleid,
  284. Float:distance,
  285. Float:x,
  286. Float:y,
  287. Float:z;
  288. if (sscanf(params, "dffff", handleid, x, y, z, distance))
  289. {
  290. SendClientMessage(playerid, COLOR_YELLOW, "USAGE: /set3dposition <handleid> <x> <y> <z> <distance>");
  291. return 1;
  292. }
  293. new
  294. string[128];
  295. format(string, sizeof(string), "Audio 3D position set to %.01f, %.01f, %.01f (distance: %.01f) for handle ID %d", x, y, z, distance, handleid);
  296. SendClientMessage(playerid, COLOR_YELLOW, string);
  297. Audio_Set3DPosition(playerid, handleid, x, y, z, distance);
  298. return 1;
  299. }
  300. dcmd_set3doffsets(playerid, params[])
  301. {
  302. #pragma unused playerid
  303. new
  304. handleid,
  305. Float:x,
  306. Float:y,
  307. Float:z;
  308. if (sscanf(params, "dfff", handleid, x, y, z))
  309. {
  310. SendClientMessage(playerid, COLOR_YELLOW, "USAGE: /set3doffsets <handleid> <x> <y> <z>");
  311. return 1;
  312. }
  313. new
  314. string[128];
  315. format(string, sizeof(string), "Audio 3D offsets set to %.01f, %.01f, %.01f for handle ID %d", x, y, z, handleid);
  316. SendClientMessage(playerid, COLOR_YELLOW, string);
  317. Audio_Set3DOffsets(playerid, handleid, x, y, z);
  318. return 1;
  319. }
  320. dcmd_seteax(playerid, params[])
  321. {
  322. #pragma unused playerid
  323. new
  324. environment;
  325. if (sscanf(params, "d", environment))
  326. {
  327. SendClientMessage(playerid, COLOR_YELLOW, "USAGE: /seteax <environment (0-25)>");
  328. return 1;
  329. }
  330. new
  331. string[64];
  332. format(string, sizeof(string), "Audio EAX environment set to %d", environment);
  333. SendClientMessage(playerid, COLOR_YELLOW, string);
  334. Audio_SetEAX(playerid, environment);
  335. return 1;
  336. }
  337. dcmd_removeeax(playerid, params[])
  338. {
  339. #pragma unused params, playerid
  340. new
  341. string[32];
  342. format(string, sizeof(string), "Audio EAX environment removed");
  343. SendClientMessage(playerid, COLOR_YELLOW, string);
  344. Audio_RemoveEAX(playerid);
  345. return 1;
  346. }
  347. dcmd_setfx(playerid, params[])
  348. {
  349. #pragma unused playerid
  350. new
  351. handleid,
  352. type;
  353. if (sscanf(params, "dd", handleid, type))
  354. {
  355. SendClientMessage(playerid, COLOR_YELLOW, "USAGE: /setfx <handleid> <type (0-8)>");
  356. return 1;
  357. }
  358. new
  359. string[64];
  360. format(string, sizeof(string), "Audio FX type %d applied to handle ID %d", type, handleid);
  361. SendClientMessage(playerid, COLOR_YELLOW, string);
  362. Audio_SetFX(playerid, handleid, type);
  363. return 1;
  364. }
  365. dcmd_removefx(playerid, params[])
  366. {
  367. #pragma unused playerid
  368. new
  369. handleid,
  370. type;
  371. if (sscanf(params, "dd", handleid, type))
  372. {
  373. SendClientMessage(playerid, COLOR_YELLOW, "USAGE: /removefx <handleid> <type (0-8)>");
  374. return 1;
  375. }
  376. new
  377. string[64];
  378. format(string, sizeof(string), "Audio FX type %d removed from handle ID %d", type, handleid);
  379. SendClientMessage(playerid, COLOR_YELLOW, string);
  380. Audio_RemoveFX(playerid, handleid, type);
  381. return 1;
  382. }
  383. dcmd_connected(playerid, params[])
  384. {
  385. new
  386. clientMsg[32];
  387. if (Audio_IsClientConnected(strval(params)))
  388. {
  389. format(clientMsg, sizeof(clientMsg), "Client ID %d is connected", strval(params));
  390. SendClientMessage(playerid, COLOR_YELLOW, clientMsg);
  391. }
  392. else
  393. {
  394. format(clientMsg, sizeof(clientMsg), "Client ID %d is not connected", strval(params));
  395. SendClientMessage(playerid, COLOR_YELLOW, clientMsg);
  396. }
  397. return 1;
  398. }
  399. dcmd_setpack(playerid, params[])
  400. {
  401. if (!IsPlayerAdmin(playerid))
  402. {
  403. SendClientMessage(playerid, COLOR_RED, "ERROR: You do not have permission to use this command.");
  404. return 1;
  405. }
  406. new
  407. audiopack[32],
  408. bool:transferable;
  409. if (sscanf(params, "sd", audiopack, transferable))
  410. {
  411. SendClientMessage(playerid, COLOR_YELLOW, "USAGE: /setpack <audiopack> <transferable (0/1)>");
  412. return 1;
  413. }
  414. Audio_SetPack(audiopack, transferable);
  415. return 1;
  416. }
  417. public
  418. Audio_OnClientConnect(playerid)
  419. {
  420. new
  421. string[128];
  422. format(string, sizeof(string), "Audio client ID %d connected", playerid);
  423. SendClientMessageToAll(COLOR_YELLOW, string);
  424. // Transfer the audio pack when the player connects
  425. Audio_TransferPack(playerid);
  426. return 1;
  427. }
  428. public
  429. Audio_OnClientDisconnect(playerid)
  430. {
  431. new
  432. string[128];
  433. format(string, sizeof(string), "Audio client ID %d disconnected", playerid);
  434. SendClientMessageToAll(COLOR_YELLOW, string);
  435. return 1;
  436. }
  437. public
  438. Audio_OnPlay(playerid, handleid)
  439. {
  440. new
  441. string[64];
  442. format(string, sizeof(string), "Audio playback started for handle ID %d", handleid);
  443. SendClientMessage(playerid, COLOR_YELLOW, string);
  444. return 1;
  445. }
  446. public
  447. Audio_OnStop(playerid, handleid)
  448. {
  449. new
  450. string[64];
  451. format(string, sizeof(string), "Audio playback stopped for handle ID %d", handleid);
  452. SendClientMessage(playerid, COLOR_YELLOW, string);
  453. return 1;
  454. }
  455. public
  456. Audio_OnSetPack(audiopack[])
  457. {
  458. new
  459. string[64];
  460. format(string, sizeof(string), "Audio pack \"%s\" set", audiopack);
  461. for (new i = 0; i < MAX_PLAYERS; i++)
  462. {
  463. // Transfer the audio pack to all players when it is set
  464. Audio_TransferPack(i);
  465. }
  466. return 1;
  467. }
  468. public
  469. Audio_OnTransferFile(playerid, file[], current, total, result)
  470. {
  471. new
  472. string[128];
  473. switch (result)
  474. {
  475. case 0:
  476. {
  477. format(string, sizeof(string), "Audio file \"%s\" (%d of %d) finished local download", file, current, total);
  478. }
  479. case 1:
  480. {
  481. format(string, sizeof(string), "Audio file \"%s\" (%d of %d) finished remote download", file, current, total);
  482. }
  483. case 2:
  484. {
  485. format(string, sizeof(string), "Audio archive \"%s\" (%d of %d) finished extraction", file, current, total);
  486. }
  487. case 3:
  488. {
  489. format(string, sizeof(string), "Audio file/archive \"%s\" (%d of %d) passed check", file, current, total);
  490. }
  491. case 4:
  492. {
  493. format(string, sizeof(string), "Audio file/archive \"%s\" (%d of %d) could not be downloaded or extracted", file, current, total);
  494. }
  495. }
  496. SendClientMessage(playerid, COLOR_YELLOW, string);
  497. if (current == total)
  498. {
  499. SendClientMessage(playerid, COLOR_YELLOW, "All files have been processed");
  500. }
  501. return 1;
  502. }
  503. public
  504. Audio_OnTrackChange(playerid, handleid, track[])
  505. {
  506. new
  507. string[128];
  508. format(string, sizeof(string), "Now playing \"%s\" for handle ID %d", track, handleid);
  509. SendClientMessage(playerid, COLOR_YELLOW, string);
  510. }
  511. stock
  512. sscanf(string[], format[], {Float,_}:...)
  513. {
  514. #if defined isnull
  515. if (isnull(string))
  516. #else
  517. if (string[0] == 0 || (string[0] == 1 && string[1] == 0))
  518. #endif
  519. {
  520. return format[0];
  521. }
  522. #pragma tabsize 4
  523. new
  524. formatPos = 0,
  525. stringPos = 0,
  526. paramPos = 2,
  527. paramCount = numargs(),
  528. delim = ' ';
  529. while (string[stringPos] && string[stringPos] <= ' ')
  530. {
  531. stringPos++;
  532. }
  533. while (paramPos < paramCount && string[stringPos])
  534. {
  535. switch (format[formatPos++])
  536. {
  537. case '\0':
  538. {
  539. return 0;
  540. }
  541. case 'i', 'd':
  542. {
  543. new
  544. neg = 1,
  545. num = 0,
  546. ch = string[stringPos];
  547. if (ch == '-')
  548. {
  549. neg = -1;
  550. ch = string[++stringPos];
  551. }
  552. do
  553. {
  554. stringPos++;
  555. if ('0' <= ch <= '9')
  556. {
  557. num = (num * 10) + (ch - '0');
  558. }
  559. else
  560. {
  561. return -1;
  562. }
  563. }
  564. while ((ch = string[stringPos]) > ' ' && ch != delim);
  565. setarg(paramPos, 0, num * neg);
  566. }
  567. case 'h', 'x':
  568. {
  569. new
  570. num = 0,
  571. ch = string[stringPos];
  572. do
  573. {
  574. stringPos++;
  575. switch (ch)
  576. {
  577. case 'x', 'X':
  578. {
  579. num = 0;
  580. continue;
  581. }
  582. case '0' .. '9':
  583. {
  584. num = (num << 4) | (ch - '0');
  585. }
  586. case 'a' .. 'f':
  587. {
  588. num = (num << 4) | (ch - ('a' - 10));
  589. }
  590. case 'A' .. 'F':
  591. {
  592. num = (num << 4) | (ch - ('A' - 10));
  593. }
  594. default:
  595. {
  596. return -1;
  597. }
  598. }
  599. }
  600. while ((ch = string[stringPos]) > ' ' && ch != delim);
  601. setarg(paramPos, 0, num);
  602. }
  603. case 'c':
  604. {
  605. setarg(paramPos, 0, string[stringPos++]);
  606. }
  607. case 'f':
  608. {
  609. setarg(paramPos, 0, _:floatstr(string[stringPos]));
  610. }
  611. case 'p':
  612. {
  613. delim = format[formatPos++];
  614. continue;
  615. }
  616. case '\'':
  617. {
  618. new
  619. end = formatPos - 1,
  620. ch;
  621. while ((ch = format[++end]) && ch != '\'') {}
  622. if (!ch)
  623. {
  624. return -1;
  625. }
  626. format[end] = '\0';
  627. if ((ch = strfind(string, format[formatPos], false, stringPos)) == -1)
  628. {
  629. if (format[end + 1])
  630. {
  631. return -1;
  632. }
  633. return 0;
  634. }
  635. format[end] = '\'';
  636. stringPos = ch + (end - formatPos);
  637. formatPos = end + 1;
  638. }
  639. case 'u':
  640. {
  641. new
  642. end = stringPos - 1,
  643. id = 0,
  644. bool:num = true,
  645. ch;
  646. while ((ch = string[++end]) && ch != delim)
  647. {
  648. if (num)
  649. {
  650. if ('0' <= ch <= '9')
  651. {
  652. id = (id * 10) + (ch - '0');
  653. }
  654. else
  655. {
  656. num = false;
  657. }
  658. }
  659. }
  660. if (num && IsPlayerConnected(id))
  661. {
  662. setarg(paramPos, 0, id);
  663. }
  664. else
  665. {
  666. #if !defined foreach
  667. #define foreach(%1,%2) for (new %2 = 0; %2 < MAX_PLAYERS; %2++) if (IsPlayerConnected(%2))
  668. #define __SSCANF_FOREACH__
  669. #endif
  670. string[end] = '\0';
  671. num = false;
  672. new
  673. name[MAX_PLAYER_NAME];
  674. id = end - stringPos;
  675. foreach (Player, playerid)
  676. {
  677. GetPlayerName(playerid, name, sizeof (name));
  678. if (!strcmp(name, string[stringPos], true, id))
  679. {
  680. setarg(paramPos, 0, playerid);
  681. num = true;
  682. break;
  683. }
  684. }
  685. if (!num)
  686. {
  687. setarg(paramPos, 0, INVALID_PLAYER_ID);
  688. }
  689. string[end] = ch;
  690. #if defined __SSCANF_FOREACH__
  691. #undef foreach
  692. #undef __SSCANF_FOREACH__
  693. #endif
  694. }
  695. stringPos = end;
  696. }
  697. case 's', 'z':
  698. {
  699. new
  700. i = 0,
  701. ch;
  702. if (format[formatPos])
  703. {
  704. while ((ch = string[stringPos++]) && ch != delim)
  705. {
  706. setarg(paramPos, i++, ch);
  707. }
  708. if (!i)
  709. {
  710. return -1;
  711. }
  712. }
  713. else
  714. {
  715. while ((ch = string[stringPos++]))
  716. {
  717. setarg(paramPos, i++, ch);
  718. }
  719. }
  720. stringPos--;
  721. setarg(paramPos, i, '\0');
  722. }
  723. default:
  724. {
  725. continue;
  726. }
  727. }
  728. while (string[stringPos] && string[stringPos] != delim && string[stringPos] > ' ')
  729. {
  730. stringPos++;
  731. }
  732. while (string[stringPos] && (string[stringPos] == delim || string[stringPos] <= ' '))
  733. {
  734. stringPos++;
  735. }
  736. paramPos++;
  737. }
  738. do
  739. {
  740. if ((delim = format[formatPos++]) > ' ')
  741. {
  742. if (delim == '\'')
  743. {
  744. while ((delim = format[formatPos++]) && delim != '\'') {}
  745. }
  746. else if (delim != 'z')
  747. {
  748. return delim;
  749. }
  750. }
  751. }
  752. while (delim > ' ');
  753. return 0;
  754. }