Advertisement
Guest User

foreach.inc

a guest
Jan 17th, 2023
42
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 46.87 KB | Gaming | 0 0
  1. /*----------------------------------------------------------------------------
  2.                     ===========================
  3.                      foreach efficient looping
  4.                     ===========================
  5. Description:
  6.     Provides efficient looping through sparse data sets, such as connected
  7.     players. Significantly improved from the original version to be a generic
  8.     loop system, rather then purely a player loop system. When used for
  9.     players this has constant time O(n) for number of connected players (n),
  10.     unlike standard player loops which are O(MAX_PLAYERS), regardless of the
  11.     actual number of connected players. Even when n is MAX_PLAYERS this is
  12.     still faster.
  13. Legal:
  14.     Version: MPL 1.1
  15.  
  16.     The contents of this file are subject to the Mozilla Public License Version
  17.     1.1 (the "License"); you may not use this file except in compliance with
  18.     the License. You may obtain a copy of the License at
  19.     http://www.mozilla.org/MPL/
  20.  
  21.     Software distributed under the License is distributed on an "AS IS" basis,
  22.     WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  23.     for the specific language governing rights and limitations under the
  24.     License.
  25.  
  26.     The Original Code is the YSI foreach include.
  27.  
  28.     The Initial Developer of the Original Code is Alex "Y_Less" Cole.
  29.     Portions created by the Initial Developer are Copyright (C) 2011
  30.     the Initial Developer. All Rights Reserved.
  31.  
  32.     Contributors:
  33.         ZeeX, koolk, JoeBullet/Google63, g_aSlice/Slice, Kar
  34.  
  35.     Thanks:
  36.         JoeBullet/Google63 - Handy arbitrary ASM jump code using SCTRL.
  37.         ZeeX - Very productive conversations.
  38.         koolk - IsPlayerinAreaEx code.
  39.         TheAlpha - Danish translation.
  40.         breadfish - German translation.
  41.         Fireburn - Dutch translation.
  42.         yom - French translation.
  43.         50p - Polish translation.
  44.         Zamaroht - Spanish translation.
  45.         Dracoblue, sintax, mabako, Xtreme, other coders - Producing other modes
  46.             for me to strive to better.
  47.         Pixels^ - Running XScripters where the idea was born.
  48.         Matite - Pestering me to release it and using it.
  49.  
  50.     Very special thanks to:
  51.         Thiadmer - PAWN, whose limits continue to amaze me!
  52.         Kye/Kalcor - SA:MP.
  53.         SA:MP Team past, present and future - SA:MP.
  54.  
  55. Version:
  56.     19 (0.4.2)
  57. Changelog:
  58.     14/05/15:
  59.         Cleaned up the entire include.
  60.     16/07/12:
  61.         Fixed a bug with "loadfs" blocking callbacks.
  62.         Slightly reduced the memory consumption of constant strings.
  63.     25/05/12:
  64.         Added a delay timer to remove players for "Kick" crashes.
  65.     05/01/12:
  66.         Fixed multi-dimensional iterators.
  67.         Fixed "FOREACH_NO_BOTS".
  68.         Made "Iterator:" support multi-dimensional arrays.
  69.     07/12/11:
  70.         Underlying implementation tweak for more consistent code.
  71.         Added Iter_Contains.
  72.     06/12/11:
  73.         Minor fixes.
  74.     31/10/11:
  75.         Changed the underlying loop code to be slightly faster.
  76.         Added support for Iter_SafeRemove, prompting refactoring.
  77.     17/09/11:
  78.         Fixed arrays under the new syntax.
  79.     28/04/11:
  80.         Moved iterator identifiers to end of variables.
  81.         Rewrote "foreach" to accept two syntaxes for "foreach (new i : Iter)".
  82.     16/08/10:
  83.         Removed all the "2" versions of the functions.
  84.     14/08/10:
  85.         Added Iter_Clear to reset an array.
  86.     06/08/10:
  87.         Added special array declaration format.
  88.     18/12/09:
  89.         Added Iter_Func2 functions for multi-dimensional iterators.
  90.         Renamed foreact et al as keywords in the documentation.
  91.         Changed licensing from GPL to MPL.
  92.     02/09/09:
  93.         Fixed (again) for 0.3.
  94.         Added free slot finding.
  95.     21/08/09:
  96.         Updated to include random functions.
  97.         Made entirely stand alone.
  98.         Ported to 0.3 (separate version).
  99.         Added automatic callback hook code.
  100.         Removed debug information from stand alone version.
  101.     06/01/08:
  102.         Added debug information.
  103.     09/10/07:
  104.         Moved to system.
  105.     16/09/07:
  106.         Added list sorting.
  107.         Made this part of Y SeRver Includes, not Y Sever Includes.
  108.         Made list sorting optional.
  109.         Fixed version number.
  110.     08/09/07:
  111.         First version.
  112. Functions:
  113.     Public:
  114.         OnPlayerDisconnect - Called when a player leaves to remove them.
  115.         OnPlayerConnect - Called when a player connects to add them.
  116.     Core:
  117.         -
  118.     Stock:
  119.         Iter_AddInternal - Add a value to an iterator.
  120.         Iter_RemoveInternal - Remove a value from an iterator.
  121.         Iter_RandomInternal - Get a random item from an iterator.
  122.         Iter_FreeInternal - Gets the first free slot in the iterator.
  123.         Iter_InitInternal - Initialises a multi-dimensional iterator.
  124.         Iter_ContainsInternal - Checks if a value is in an iterator.
  125.     Static:
  126.         -
  127.     Inline:
  128.         Iter_Create - Create a new iterator value set.
  129.         Iter_Add - Wraps Iter_AddInternal.
  130.         Iter_SafeRemove - Wraps Iter_SafeRemoveInternal.
  131.         Iter_Remove - Wraps Iter_RemoveInternal.
  132.         Iter_Random - Wraps Iter_RandomInternal.
  133.         Iter_Count - Gets the number of items in an iterator.
  134.         Iter_Free - Wraps around Iter_FreeInternal.
  135.         Iter_Contains - Wraps around Iter_ContainsInternal.
  136.     API:
  137.         -
  138. Callbacks:
  139.     -
  140. Hooks:
  141.     Iter_OnPlayerConnect - Hook for the OnPlayerConnect callback.
  142.     Iter_OnPlayerDisconnect - Hook for the OnPlayerDisconnect callback.
  143.     Iter_OnGameModeInit - Only exists to make the code compile correctly...
  144. Definitions:
  145.     -
  146. Enums:
  147.     -
  148. Macros:
  149.     -
  150. Keywords:
  151.     foreach - Function to loop an iterator.
  152. Tags:
  153.     Iterator - Declare an iterator.
  154. Variables:
  155.     Global:
  156.         -
  157.     Static:
  158.         -
  159. Commands:
  160.     -
  161. Operators:
  162.     -
  163. Iterators:
  164.     Player - List of all players connected.
  165.     Bot - List of all bots (npcs) connected.
  166.     NPC - Alias of Bot.
  167.     Character - All players and bots.
  168. --------------------------------------------------------------------------------
  169. */
  170.  
  171. #define _FOREACH_LOCAL_VERSION 19
  172.  
  173. // Foreach is testing us.
  174. #if defined _FOREACH_INC_TEST
  175.     #endinput
  176. #endif
  177. #define _FOREACH_INC_TEST
  178.  
  179. #if !defined _samp_included
  180.     #error "Please include a_samp or a_npc before foreach"
  181. #endif
  182.  
  183. #if defined FOREACH_PLAYERSSTREAM_ITERATOR
  184.     #error FOREACH_PLAYERSSTREAM_ITERATOR is deprecated, use FOREACH_I_PlayerPlayersStream
  185. #endif
  186.  
  187. #if defined FOREACH_VEHICLESSTREAM_ITERATOR
  188.     #error FOREACH_VEHICLESSTREAM_ITERATOR is deprecated, use FOREACH_I_PlayerVehiclesStream
  189. #endif
  190.  
  191. #if defined FOREACH_ACTORSSTREAM_ITERATOR
  192.     #error FOREACH_ACTORSSTREAM_ITERATOR is deprecated, use FOREACH_I_PlayerActorsStream
  193. #endif
  194.  
  195. #if defined PlayersStream@YSII_Cg
  196.     #error PlayersStream is deprecated, use PlayerPlayersStream
  197. #endif
  198.  
  199. #if defined VehiclesStream@YSII_Cg
  200.     #error VehiclesStream is deprecated, use PlayerVehiclesStream
  201. #endif
  202.  
  203. #if defined ActorsStream@YSII_Cg
  204.     #error ActorsStream is deprecated, use PlayerActorsStream
  205. #endif
  206.  
  207. /*
  208. --------------------------------------------------------------------------------
  209.     Base defines
  210. --------------------------------------------------------------------------------
  211. */
  212.  
  213. #define ITER_NONE -1
  214.  
  215. #define _Y_ITER_ARRAY: _:_Y_ITER_C0:
  216. #define _Y_ITER_ARRAY_SIZE(%1) _:_Y_ITER_C1:_Y_ITER_C2:sizeof %1@YSII_Ag-1
  217.  
  218. #define _Y_ITER_C0:%0[%1]@YSII_%4g%3) %0@YSII_%4g[%1]%3)
  219. #define _Y_ITER_C1:_Y_ITER_C2:%0[%1]@YSII_Ag%3) %0@YSII_Ag[]%3)
  220. #define _Y_ITER_C2:sizeof%0(%1)@YSII_Ag-1;_:(%2=_Y_ITER_ARRAY:%3(%4)@YSII_Ag[%5])!=_Y_ITER_ARRAY_SIZE(%6);) -1;_:(%2=%3@YSII_Ag(%4,%5))!=-1;)
  221. #define _Y_ITER_C3:%0[%1]@YSII_Cg,%2[%3]@YSII_Ag[%4]={%5} _Y_ITER_C3:%0@YSII_Cg[%1],%0@YSII_Ag[%1][%4]
  222.  
  223. forward Iter_AddInternal(&count, array[], value, size);
  224. forward Iter_RemoveInternal(&count, array[], value, size);
  225. forward Iter_ClearInternal(&count, array[], size);
  226. forward Iter_OPDCInternal(playerid);
  227.  
  228. static
  229.     bool:Iter_gIsFilterscript = false;
  230.  
  231. #if !defined FOREACH_I_Player
  232.     #define FOREACH_I_Player 1
  233. #endif
  234.  
  235. #if !defined FOREACH_I_Bot
  236.     #define FOREACH_I_Bot 1
  237. #endif
  238.  
  239. #if !defined FOREACH_I_Character
  240.     #define FOREACH_I_Character 1
  241. #endif
  242.  
  243. #if !defined FOREACH_I_Vehicle
  244.     #define FOREACH_I_Vehicle 1
  245. #endif
  246.  
  247. #if !defined FOREACH_I_Actor
  248.     #define FOREACH_I_Actor 1
  249. #endif
  250.  
  251. #if !defined FOREACH_I_PlayerPlayersStream
  252.     #define FOREACH_I_PlayerPlayersStream 0
  253. #else
  254.     #undef FOREACH_I_PlayerPlayersStream
  255.     #define FOREACH_I_PlayerPlayersStream 1
  256. #endif
  257.  
  258. #if !defined FOREACH_I_PlayerVehiclesStream
  259.     #define FOREACH_I_PlayerVehiclesStream 0
  260. #else
  261.     #undef FOREACH_I_PlayerVehiclesStream
  262.     #define FOREACH_I_PlayerVehiclesStream 1
  263. #endif
  264.  
  265. #if !defined FOREACH_I_VehiclePlayersStream
  266.     #define FOREACH_I_VehiclePlayersStream 0
  267. #else
  268.     #undef FOREACH_I_VehiclePlayersStream
  269.     #define FOREACH_I_VehiclePlayersStream 1
  270. #endif
  271.  
  272. #if !defined FOREACH_I_PlayerActorsStream
  273.     #define FOREACH_I_PlayerActorsStream 0
  274. #else
  275.     #undef FOREACH_I_PlayerActorsStream
  276.     #define FOREACH_I_PlayerActorsStream 1
  277. #endif
  278.  
  279. #if !defined FOREACH_I_ActorPlayersStream
  280.     #define FOREACH_I_ActorPlayersStream 0
  281. #else
  282.     #undef FOREACH_I_ActorPlayersStream
  283.     #define FOREACH_I_ActorPlayersStream 1
  284. #endif
  285.  
  286. #if !defined FOREACH_I_PlayerInVehicle
  287.     #define FOREACH_I_PlayerInVehicle 0
  288. #else
  289.     #undef FOREACH_I_PlayerInVehicle
  290.     #define FOREACH_I_PlayerInVehicle 1
  291. #endif
  292.  
  293. #if defined FOREACH_MULTISCRIPT
  294.     #if FOREACH_I_Vehicle
  295.         forward Iter_AddVehicle(vehicleid);
  296.         forward Iter_RemoveVehicle(vehicleid);
  297.     #endif
  298.  
  299.     #if FOREACH_I_Actor
  300.         forward Iter_AddActor(actorid);
  301.         forward Iter_RemoveActor(actorid);
  302.     #endif
  303. #endif
  304.  
  305. /*
  306. --------------------------------------------------------------------------------
  307. Array:
  308.     IteratorArray
  309. Notes:
  310.     Creates a new iterator array start/array pair.
  311. --------------------------------------------------------------------------------
  312. */
  313.  
  314. #define IteratorArray:%1[%2]<%3> %1@YSII_Cg[%2],%1@YSII_Ag[%2][%3+1]
  315.  
  316. /*
  317. --------------------------------------------------------------------------------
  318. Array:
  319.     Iterator
  320. Notes:
  321.     Creates a new iterator start/array pair.
  322. --------------------------------------------------------------------------------
  323. */
  324.  
  325. #define Iterator:%1<%2> _Y_ITER_C3:%1@YSII_Cg,%1@YSII_Ag[(%2)+1]={(%2)*2,(%2)*2-1,...}
  326. #define iterator%0<%1> new Iterator:%0<%1>
  327.  
  328. /*
  329. --------------------------------------------------------------------------------
  330. Function:
  331.     Iter_Init
  332. Params:
  333.     iter - Name of the iterator array to initialise.
  334. Return:
  335.     -
  336. Notes:
  337.     Wrapper for Iter_InitInternal.
  338.  
  339. native Iter_Init(IteratorArray:Name[]<>);
  340. --------------------------------------------------------------------------------
  341. */
  342.  
  343. #define Iter_Init(%1) \
  344.     Iter_InitInternal(%1@YSII_Ag,sizeof %1@YSII_Ag,sizeof %1@YSII_Ag[]-1)
  345.  
  346. /*
  347. --------------------------------------------------------------------------------
  348. Function:
  349.     Iter_Add
  350. Params:
  351.     iter - Name of the iterator to add the data to.
  352.     value - Value to add to the iterator.
  353. Return:
  354.     -
  355. Notes:
  356.     Wrapper for Iter_AddInternal.
  357.  
  358. native Iter_Add(Iterator:Name<>, value);
  359. --------------------------------------------------------------------------------
  360. */
  361.  
  362. #define Iter_Add(%1,%2) Iter_AddInternal(_Y_ITER_ARRAY:%1@YSII_Cg,_Y_ITER_ARRAY:%1@YSII_Ag,%2,_Y_ITER_ARRAY_SIZE(%1))
  363.  
  364. /*
  365. --------------------------------------------------------------------------------
  366. Function:
  367.     Iter_Free
  368. Params:
  369.     iter - Name of the iterator to get the first free slot in.
  370. Return:
  371.     -
  372. Notes:
  373.     Wrapper for Iter_FreeInternal.
  374.  
  375. native Iter_Free(Iterator:Name<>);
  376. --------------------------------------------------------------------------------
  377. */
  378.  
  379. #define Iter_Free(%1) Iter_FreeInternal(_Y_ITER_ARRAY:%1@YSII_Ag,_Y_ITER_ARRAY_SIZE(%1))
  380.  
  381. /*
  382. --------------------------------------------------------------------------------
  383. Function:
  384.     Iter_Remove
  385. Params:
  386.     iter - Name of the iterator to remove data from.
  387.     value - Data to remove.
  388. Return:
  389.     -
  390. Notes:
  391.     Wrapper for Iter_RemoveInternal.
  392.  
  393. native Iter_Remove(Iterator:Name<>, value);
  394. --------------------------------------------------------------------------------
  395. */
  396.  
  397. #define Iter_Remove(%1,%2) Iter_RemoveInternal(_Y_ITER_ARRAY:%1@YSII_Cg,_Y_ITER_ARRAY:%1@YSII_Ag,%2,_Y_ITER_ARRAY_SIZE(%1))
  398.  
  399. /*
  400. --------------------------------------------------------------------------------
  401. Function:
  402.     Iter_Contains
  403. Params:
  404.     iter - Name of the iterator to check membership of.
  405.     value - Value to check.
  406. Return:
  407.     -
  408. Notes:
  409.     Checks if the given value is in the given iterator.
  410.  
  411. native Iter_Remove(Iterator:Name<>, value);
  412. --------------------------------------------------------------------------------
  413. */
  414.  
  415. #define Iter_Contains(%1,%2) Iter_ContainsInternal(_Y_ITER_ARRAY:%1@YSII_Ag,%2,_Y_ITER_ARRAY_SIZE(%1))
  416.  
  417. /*
  418. --------------------------------------------------------------------------------
  419. Function:
  420.     Iter_SafeRemove
  421. Params:
  422.     iter - Name of the iterator to remove data from.
  423.     value - Data to remove.
  424.     next - Container for the pointer to the next element.
  425. Return:
  426.     -
  427. Notes:
  428.     Wrapper for Iter_SafeRemoveInternal. Common use:
  429.  
  430.     Iter_SafeRemove(iter, i, i);
  431.  
  432. native Iter_SafeRemove(Iterator:Name<>, value, &next);
  433. --------------------------------------------------------------------------------
  434. */
  435.  
  436. #define Iter_SafeRemove(%1,%2,%3) Iter_SafeRemoveInternal(_Y_ITER_ARRAY:%1@YSII_Cg,_Y_ITER_ARRAY:%1@YSII_Ag,%2,%3,_Y_ITER_ARRAY_SIZE(%1))
  437.  
  438. /*
  439. --------------------------------------------------------------------------------
  440. Function:
  441.     Iter_Random
  442. Params:
  443.     iter - Name of the iterator to get a random slot from.
  444. Return:
  445.     -
  446. Notes:
  447.     Wrapper for Iter_RandomInternal.
  448.  
  449. native Iter_Random(Iterator:Name<>);
  450. --------------------------------------------------------------------------------
  451. */
  452.  
  453. #define Iter_Random(%1) Iter_RandomInternal(_Y_ITER_ARRAY:%1@YSII_Cg,_Y_ITER_ARRAY:%1@YSII_Ag,_Y_ITER_ARRAY_SIZE(%1))
  454.  
  455. /*
  456. --------------------------------------------------------------------------------
  457. Function:
  458.     Iter_Count
  459. Params:
  460.     iter - Name of the iterator to get the number of items from.
  461. Return:
  462.     -
  463. Notes:
  464.     Returns the number of items in this iterator.
  465.  
  466. native Iter_Count(Iterator:Name<>);
  467. --------------------------------------------------------------------------------
  468. */
  469.  
  470. #define Iter_Count(%1) (_Y_ITER_ARRAY:%1@YSII_Cg)
  471.  
  472. /*
  473. --------------------------------------------------------------------------------
  474. Function:
  475.     Iter_Clear
  476. Params:
  477.     iter - Name of the iterator empty.
  478. Return:
  479.     -
  480. Notes:
  481.     Wrapper for Iter_ClearInternal.
  482.  
  483. native Iter_Clear(IteratorArray:Name[]<>);
  484. --------------------------------------------------------------------------------
  485. */
  486.  
  487. #define Iter_Clear(%1) Iter_ClearInternal(_Y_ITER_ARRAY:%1@YSII_Cg,_Y_ITER_ARRAY:%1@YSII_Ag,_Y_ITER_ARRAY_SIZE(%1))
  488.  
  489. /*
  490. --------------------------------------------------------------------------------
  491. Function:
  492.     Iter_Index
  493. Params:
  494.     iter - Name of the iterator empty.
  495.     value - Value of the iterator element.
  496. Return:
  497.     -
  498. Notes:
  499.     Wrapper for Iter_IndexInternal.
  500.  
  501. native Iter_Index(IteratorArray:Name[]<>, index);
  502. --------------------------------------------------------------------------------
  503. */
  504.  
  505. #define Iter_Index(%1,%2) Iter_IndexInternal(_Y_ITER_ARRAY:%1@YSII_Cg,_Y_ITER_ARRAY:%1@YSII_Ag,_Y_ITER_ARRAY_SIZE(%1),_Y_ITER_ARRAY_SIZE(%1),%2)
  506.  
  507. /*
  508. --------------------------------------------------------------------------------
  509.     Create the internal iterators.
  510. --------------------------------------------------------------------------------
  511. */
  512.  
  513. #if FOREACH_I_Player
  514.     new Iterator:Player<MAX_PLAYERS>;
  515. #endif
  516.  
  517. #if FOREACH_I_Bot
  518.     new Iterator:Bot<MAX_PLAYERS>;
  519.  
  520.     #define NPC@YSII_Cg Bot@YSII_Cg
  521.     #define NPC@YSII_Ag Bot@YSII_Ag
  522. #endif
  523.  
  524. #if FOREACH_I_Character
  525.     new Iterator:Character<MAX_PLAYERS>;
  526. #endif
  527.  
  528. #if FOREACH_I_Vehicle
  529.     new Iterator:Vehicle<MAX_VEHICLES>;
  530. #endif
  531.  
  532. #if FOREACH_I_Actor
  533.     new Iterator:Actor<MAX_ACTORS>;
  534. #endif
  535.  
  536. #if FOREACH_I_PlayerPlayersStream
  537.     new Iterator:PlayerPlayersStream[MAX_PLAYERS]<MAX_PLAYERS>;
  538. #endif
  539.  
  540. #if FOREACH_I_PlayerVehiclesStream
  541.     new Iterator:PlayerVehiclesStream[MAX_PLAYERS]<MAX_VEHICLES>;
  542. #endif
  543.  
  544. #if FOREACH_I_VehiclePlayersStream
  545.     new Iterator:VehiclePlayersStream[MAX_VEHICLES]<MAX_PLAYERS>;
  546. #endif
  547.  
  548. #if FOREACH_I_PlayerActorsStream
  549.     new Iterator:PlayerActorsStream[MAX_PLAYERS]<MAX_ACTORS>;
  550. #endif
  551.  
  552. #if FOREACH_I_ActorPlayersStream
  553.     new Iterator:ActorPlayersStream[MAX_ACTORS]<MAX_PLAYERS>;
  554. #endif
  555.  
  556. #if FOREACH_I_PlayerInVehicle
  557.     new Iterator:PlayerInVehicle[MAX_VEHICLES]<MAX_PLAYERS>;
  558.     static Iter_gPlayerVehicleId[MAX_PLAYERS] = {INVALID_VEHICLE_ID, ...};
  559. #endif
  560.  
  561. /*
  562. --------------------------------------------------------------------------------
  563. Function:
  564.     foreach
  565. Params:
  566.     data - Data to iterate through.
  567.     as - Variable to set value to.
  568. Return:
  569.     -
  570. Notes:
  571.     Not exactly the same as PHP foreach, just iterates through a list and
  572.     returns the value of the current slot but uses that slot as the next index
  573.     too. Variables must be in the form @YSII_<gname>S for the start index and
  574.     @YSII_<gname>A for the data array where <name> is what's entered in data.
  575. --------------------------------------------------------------------------------
  576. */
  577.  
  578. #define foreach%1(%0) for(new Y_FOREACH_SECOND|||Y_FOREACH_THIRD|||%0|||)
  579. // This allows us to use "new" multiple times - stripping off ONLY whole words.
  580. #define new%0|||%9|||%1:%2||| %9|||%0|||%1|||%2|||
  581.  
  582. // This one is called if the new syntax is required, but the state of "new" is
  583. // as-yet unknown. This attempts to call "%1" as a macro, if it starts with
  584. // "new" as a whole word then it will (and will also helpfully strip off the
  585. // "new" keyword for us).
  586. #define Y_FOREACH_THIRD|||%0|||%1|||%2||| %1=Y_FOREACH_FIFTH|||Y_FOREACH_FOURTH|||%1:%2|||
  587.  
  588. // This is called if the "new" macro is called for a second time.
  589. #define Y_FOREACH_FOURTH|||%0=Y_FOREACH_FIFTH|||%1|||%2||| new Y_FOREACH_SIXTH;%0|||Y_FOREACH_SEVENTH|||%2|||
  590.  
  591. // This is called when there are tags on the "new" declaration.
  592. #define Y_FOREACH_SEVENTH|||%9Y_FOREACH_SIXTH;%0|||%1|||%2||| new %0:%1=%0:(_Y_ITER_ARRAY_SIZE(%2));_:(%1=%0:_Y_ITER_ARRAY:%2@YSII_Ag[_:%1])!=_Y_ITER_ARRAY_SIZE(%2);
  593.  
  594. // This is called when there aren't.
  595. #define Y_FOREACH_SIXTH;%0|||Y_FOREACH_SEVENTH|||%2||| %0=_Y_ITER_ARRAY_SIZE(%2);_:(%0=_Y_ITER_ARRAY:%2@YSII_Ag[%0])!=_Y_ITER_ARRAY_SIZE(%2);
  596.  
  597. // This is called if "%1" didn't have "new" at the start.
  598. #define Y_FOREACH_FIFTH|||Y_FOREACH_FOURTH|||%1:%2||| _Y_ITER_ARRAY_SIZE(%2);_:(%1=_Y_ITER_ARRAY:%2@YSII_Ag[%1])!=_Y_ITER_ARRAY_SIZE(%2);
  599.  
  600. // This is the old version, but DON'T add "new" because that already exists from
  601. // the failed "new" macro call above.
  602. #define Y_FOREACH_SECOND|||Y_FOREACH_THIRD|||%1,%2||| %2=_Y_ITER_ARRAY_SIZE(%1);_:(%2=_Y_ITER_ARRAY:%1@YSII_Ag[%2])!=_Y_ITER_ARRAY_SIZE(%1);
  603.  
  604. /*
  605. --------------------------------------------------------------------------------
  606. Function:
  607.     Iter_OnFilterScriptInit
  608. Params:
  609.     -
  610. Return:
  611.     -
  612. Notes:
  613.     Fixes a bug where callbacks are not detected when "loadfs" is used after the
  614.     GM has already started. If this is a GM this is just never used called.
  615. --------------------------------------------------------------------------------
  616. */
  617.  
  618. public OnFilterScriptInit()
  619. {
  620.     Iter_gIsFilterscript = true;
  621.     Iter_ScriptInit();
  622.  
  623.     #if defined Iter_OnFilterScriptInit
  624.         return Iter_OnFilterScriptInit();
  625.     #else
  626.         return 1;
  627.     #endif
  628. }
  629. #if defined _ALS_OnFilterScriptInit
  630.     #undef OnFilterScriptInit
  631. #else
  632.     #define _ALS_OnFilterScriptInit
  633. #endif
  634.  
  635. #define OnFilterScriptInit Iter_OnFilterScriptInit
  636. #if defined Iter_OnFilterScriptInit
  637.     forward Iter_OnFilterScriptInit();
  638. #endif
  639.  
  640. /*
  641. --------------------------------------------------------------------------------
  642. Function:
  643.     Iter_OnGameModeInit
  644. Params:
  645.     -
  646. Return:
  647.     -
  648. Notes:
  649.     -
  650. --------------------------------------------------------------------------------
  651. */
  652.  
  653. public OnGameModeInit()
  654. {
  655.     if (!Iter_gIsFilterscript) {
  656.         Iter_ScriptInit();
  657.     }
  658.  
  659.     #if defined Iter_OnGameModeInit
  660.         return Iter_OnGameModeInit();
  661.     #else
  662.         return 1;
  663.     #endif
  664. }
  665. #if defined _ALS_OnGameModeInit
  666.     #undef OnGameModeInit
  667. #else
  668.     #define _ALS_OnGameModeInit
  669. #endif
  670.  
  671. #define OnGameModeInit Iter_OnGameModeInit
  672. #if defined Iter_OnGameModeInit
  673.     forward Iter_OnGameModeInit();
  674. #endif
  675.  
  676. /*
  677. --------------------------------------------------------------------------------
  678. Function:
  679.     Iter_ScriptInit
  680. Params:
  681.     -
  682. Return:
  683.     -
  684. Notes:
  685.     -
  686. --------------------------------------------------------------------------------
  687. */
  688.  
  689. stock Iter_ScriptInit()
  690. {
  691.     #if defined GetPlayerPoolSize
  692.         new
  693.             LAST_PLAYER_ID,
  694.             LAST_VEHICLE_ID,
  695.             LAST_ACTOR_ID;
  696.     #else
  697.         #define LAST_PLAYER_ID  MAX_PLAYERS
  698.         #define LAST_VEHICLE_ID MAX_VEHICLES
  699.         #define LAST_ACTOR_ID   MAX_ACTORS
  700.     #endif
  701.  
  702.     #if FOREACH_I_Player || FOREACH_I_Bot || FOREACH_I_Character
  703.         #if FOREACH_I_Player
  704.             Iter_Clear(Player);
  705.         #endif
  706.  
  707.         #if FOREACH_I_Bot
  708.             Iter_Clear(Bot);
  709.         #endif
  710.  
  711.         #if FOREACH_I_Character
  712.             Iter_Clear(Character);
  713.         #endif
  714.  
  715.         for (new playerid = 0; playerid != LAST_PLAYER_ID; ++playerid) {
  716.             if (!IsPlayerConnected(playerid)) {
  717.                 continue;
  718.             }
  719.  
  720.             if (!IsPlayerNPC(playerid)) {
  721.                 #if FOREACH_I_Player
  722.                     Iter_Add(Player, playerid);
  723.                 #endif
  724.             } else {
  725.                 #if FOREACH_I_Bot
  726.                     Iter_Add(Bot, playerid);
  727.                 #endif
  728.             }
  729.  
  730.             #if FOREACH_I_Character
  731.                 Iter_Add(Character, playerid);
  732.             #endif
  733.         }
  734.     #endif
  735.  
  736.     #if FOREACH_I_Vehicle
  737.         Iter_Clear(Vehicle);
  738.  
  739.         for (new vehicleid = 1; vehicleid != LAST_VEHICLE_ID; ++vehicleid) {
  740.             if (!GetVehicleModel(vehicleid)) {
  741.                 continue;
  742.             }
  743.  
  744.             Iter_Add(Vehicle, vehicleid);
  745.         }
  746.     #endif
  747.  
  748.     #if FOREACH_I_Actor
  749.         Iter_Clear(Actor);
  750.  
  751.         for (new actorid = 0; actorid != LAST_ACTOR_ID; ++actorid) {
  752.             if (!IsValidActor(actorid)) {
  753.                 continue;
  754.             }
  755.  
  756.             Iter_Add(Actor, actorid);
  757.         }
  758.     #endif
  759.  
  760.     #if FOREACH_I_PlayerPlayersStream
  761.         Iter_Init(PlayerPlayersStream);
  762.  
  763.         for (new playerid = 0; playerid != LAST_PLAYER_ID; ++playerid) {
  764.             if (!IsPlayerConnected(playerid)) {
  765.                 continue;
  766.             }
  767.  
  768.             for (new targetid = 0; targetid != LAST_PLAYER_ID; ++targetid) {
  769.                 if (!IsPlayerStreamedIn(playerid, targetid)) {
  770.                     continue;
  771.                 }
  772.  
  773.                 Iter_Add(PlayerPlayersStream[playerid], targetid);
  774.             }
  775.         }
  776.     #endif
  777.  
  778.     #if FOREACH_I_PlayerVehiclesStream || FOREACH_I_VehiclePlayersStream
  779.         #if FOREACH_I_PlayerVehiclesStream
  780.             Iter_Init(PlayerVehiclesStream);
  781.         #endif
  782.  
  783.         #if FOREACH_I_VehiclePlayersStream
  784.             Iter_Init(VehiclePlayersStream);
  785.         #endif
  786.  
  787.         for (new playerid = 0; playerid != LAST_PLAYER_ID; ++playerid) {
  788.             if (!IsPlayerConnected(playerid)) {
  789.                 continue;
  790.             }
  791.  
  792.             for (new vehicleid = 1; vehicleid != LAST_VEHICLE_ID; ++vehicleid) {
  793.                 if (!IsVehicleStreamedIn(vehicleid, playerid)) {
  794.                     continue;
  795.                 }
  796.  
  797.                 #if FOREACH_I_PlayerVehiclesStream
  798.                     Iter_Add(PlayerVehiclesStream[playerid], vehicleid);
  799.                 #endif
  800.  
  801.                 #if FOREACH_I_VehiclePlayersStream
  802.                     Iter_Add(VehiclePlayersStream[vehicleid], playerid);
  803.                 #endif
  804.             }
  805.         }
  806.     #endif
  807.  
  808.     #if FOREACH_I_PlayerActorsStream || FOREACH_I_ActorPlayersStream
  809.         #if FOREACH_I_PlayerActorsStream
  810.             Iter_Init(PlayerActorsStream);
  811.         #endif
  812.  
  813.         #if FOREACH_I_ActorPlayersStream
  814.             Iter_Init(ActorPlayersStream);
  815.         #endif
  816.  
  817.         for (new playerid = 0; playerid != LAST_PLAYER_ID; ++playerid) {
  818.             if (!IsPlayerConnected(playerid)) {
  819.                 continue;
  820.             }
  821.  
  822.             for (new actorid = 0; actorid != LAST_ACTOR_ID; ++actorid) {
  823.                 if (!IsActorStreamedIn(actorid, playerid)) {
  824.                     continue;
  825.                 }
  826.  
  827.                 #if FOREACH_I_PlayerActorsStream
  828.                     Iter_Add(PlayerActorsStream[playerid], actorid);
  829.                 #endif
  830.  
  831.                 #if FOREACH_I_ActorPlayersStream
  832.                     Iter_Add(ActorPlayersStream[actorid], playerid);
  833.                 #endif
  834.             }
  835.         }
  836.     #endif
  837.    
  838.     #if FOREACH_I_PlayerInVehicle
  839.         Iter_Init(PlayerInVehicle);
  840.  
  841.         for (new playerid = 0; playerid != LAST_PLAYER_ID; ++playerid) {
  842.             if (!IsPlayerConnected(playerid)) {
  843.                 continue;
  844.             }
  845.  
  846.             for (new vehicleid = 1; vehicleid != LAST_VEHICLE_ID; ++vehicleid) {
  847.                 if (!IsPlayerInVehicle(playerid, vehicleid)) {
  848.                     continue;
  849.                 }
  850.  
  851.                 Iter_Add(PlayerInVehicle[vehicleid], playerid);
  852.             }
  853.         }
  854.     #endif
  855.  
  856.     #pragma unused LAST_PLAYER_ID, LAST_VEHICLE_ID, LAST_ACTOR_ID
  857. }
  858.  
  859. /*
  860.     CHARACTERS
  861. */
  862.  
  863. #if FOREACH_I_Player || FOREACH_I_Bot || FOREACH_I_Character
  864.  
  865.     /*
  866.     --------------------------------------------------------------------------------
  867.     Function:
  868.         Iter_OnPlayerConnect
  869.     Params:
  870.         playerid - Player who joined.
  871.     Return:
  872.         -
  873.     Notes:
  874.         Adds a player to the loop data. Now sorts the list too. Note that I found
  875.         the most bizzare bug ever (I *think* it may be a compiler but, but it
  876.         requires further investigation), basically it seems that multiple variables
  877.         were being treated as the same variable (namely @YSII_EgotS and
  878.         @YSII_CgharacterS were the same and @YSII_EgotC and @YSII_CgharacterC were the
  879.         same). Adding print statements which reference these variables seem to fix
  880.         the problem, and I have tried to make sure that the values will never actually
  881.         get printed.
  882.     --------------------------------------------------------------------------------
  883.     */
  884.  
  885.     public OnPlayerConnect(playerid)
  886.     {
  887.         if (!IsPlayerNPC(playerid)) {
  888.             #if FOREACH_I_Player
  889.                 Iter_Add(Player, playerid);
  890.             #endif
  891.         } else {
  892.             #if FOREACH_I_Bot
  893.                 Iter_Add(Bot, playerid);
  894.             #endif
  895.         }
  896.  
  897.         #if FOREACH_I_Character
  898.             Iter_Add(Character, playerid);
  899.         #endif
  900.  
  901.         #if defined Iter_OnPlayerConnect
  902.             return Iter_OnPlayerConnect(playerid);
  903.         #else
  904.             return 1;
  905.         #endif
  906.     }
  907.     #if defined _ALS_OnPlayerConnect
  908.         #undef OnPlayerConnect
  909.     #else
  910.         #define _ALS_OnPlayerConnect
  911.     #endif
  912.  
  913.     #define OnPlayerConnect Iter_OnPlayerConnect
  914.     #if defined Iter_OnPlayerConnect
  915.         forward Iter_OnPlayerConnect(playerid);
  916.     #endif
  917.  
  918.     /*
  919.     --------------------------------------------------------------------------------
  920.     Function:
  921.         Iter_OnPlayerDisconnect
  922.     Params:
  923.         playerid - Player who left.
  924.     Return:
  925.         -
  926.     Notes:
  927.         Removes a player from the loop data. No longer uses "hook" to ENSURE that
  928.         this is always last. Previously I think that the order of evaluation in
  929.         y_hooks meant that this got called before the user "OnPlayerDisconnect".
  930.     --------------------------------------------------------------------------------
  931.     */
  932.  
  933.     public OnPlayerDisconnect(playerid, reason)
  934.     {
  935.     #if defined Iter_OnPlayerDisconnect
  936.         Iter_OnPlayerDisconnect(playerid, reason);
  937.     #endif
  938.  
  939.         SetTimerEx("Iter_OPDCInternal", 0, false, "i", playerid);
  940.         return 1;
  941.     }
  942.     #if defined _ALS_OnPlayerDisconnect
  943.         #undef OnPlayerDisconnect
  944.     #else
  945.         #define _ALS_OnPlayerDisconnect
  946.     #endif
  947.  
  948.     #define OnPlayerDisconnect Iter_OnPlayerDisconnect
  949.     #if defined Iter_OnPlayerDisconnect
  950.         forward Iter_OnPlayerDisconnect(playerid, reason);
  951.     #endif
  952.  
  953.     /*
  954.     --------------------------------------------------------------------------------
  955.     Function:
  956.         Iter_OPDCInternal
  957.     Params:
  958.         playerid - Player who left.
  959.     Return:
  960.         -
  961.     Notes:
  962.         Called AFTER "OnPlayerDisconnect" so that using "Kick" inside a "foreach"
  963.         loop does not crash the server due to an OOB error.
  964.     --------------------------------------------------------------------------------
  965.     */
  966.  
  967.     public Iter_OPDCInternal(playerid)
  968.     {
  969.         if (IsPlayerConnected(playerid)) {
  970.             return;
  971.         }
  972.  
  973.         if (!IsPlayerNPC(playerid)) {
  974.             #if FOREACH_I_Player
  975.                 Iter_Remove(Player, playerid);
  976.             #endif
  977.         } else {
  978.             #if FOREACH_I_Bot
  979.                 Iter_Remove(Bot, playerid);
  980.             #endif
  981.         }
  982.  
  983.         #if FOREACH_I_Character
  984.             Iter_Remove(Character, playerid);
  985.         #endif
  986.        
  987.         #if FOREACH_I_PlayerInVehicle
  988.             if (Iter_gPlayerVehicleId[playerid] != INVALID_VEHICLE_ID) {
  989.                 Iter_Remove(PlayerInVehicle[Iter_gPlayerVehicleId[playerid]], playerid);
  990.                 Iter_gPlayerVehicleId[playerid] = INVALID_VEHICLE_ID;
  991.             }
  992.         #endif
  993.  
  994.         #if FOREACH_I_PlayerPlayersStream
  995.             Iter_Clear(PlayerPlayersStream[playerid]);
  996.         #endif
  997.  
  998.         #if FOREACH_I_PlayerVehiclesStream
  999.             Iter_Clear(PlayerVehiclesStream[playerid]);
  1000.         #endif
  1001.  
  1002.         #if FOREACH_I_PlayerActorsStream
  1003.             Iter_Clear(PlayerActorsStream[playerid]);
  1004.         #endif
  1005.     }
  1006.  
  1007. #endif
  1008.  
  1009. /*
  1010.     CHARACTERS ENDS
  1011. */
  1012.  
  1013. /*
  1014.     VEHICLES
  1015. */
  1016.  
  1017. #if FOREACH_I_Vehicle
  1018.  
  1019.     /*
  1020.         Iter_CreateVehicle
  1021.     */
  1022.  
  1023.     stock Iter_CreateVehicle(modelid, Float:x, Float:y, Float:z, Float:angle, color1, color2, respawn_delay, addsiren = 0)
  1024.     {
  1025.         new
  1026.             ret = CreateVehicle(modelid, x, y, z, angle, color1, color2, respawn_delay, addsiren);
  1027.  
  1028.         if (ret != INVALID_VEHICLE_ID && ret != 0) {
  1029.             #if defined FOREACH_MULTISCRIPT
  1030.                 CallRemoteFunction("Iter_AddVehicle", "i", ret);
  1031.             #else
  1032.                 Iter_Add(Vehicle, ret);
  1033.             #endif
  1034.         }
  1035.  
  1036.         return ret;
  1037.     }
  1038.     #if defined _ALS_CreateVehicle
  1039.         #undef CreateVehicle
  1040.     #else
  1041.         #define _ALS_CreateVehicle
  1042.     #endif
  1043.  
  1044.     #define CreateVehicle Iter_CreateVehicle
  1045.  
  1046.     /*
  1047.         Iter_AddStaticVehicle
  1048.     */
  1049.  
  1050.     stock Iter_AddStaticVehicle(modelid, Float:spawn_x, Float:spawn_y, Float:spawn_z, Float:angle, color1, color2)
  1051.     {
  1052.         new
  1053.             ret = AddStaticVehicle(modelid, spawn_x, spawn_y, spawn_z, angle, color1, color2);
  1054.  
  1055.         if (ret != INVALID_VEHICLE_ID) {
  1056.             #if defined FOREACH_MULTISCRIPT
  1057.                 CallRemoteFunction("Iter_AddVehicle", "i", ret);
  1058.             #else
  1059.                 Iter_Add(Vehicle, ret);
  1060.             #endif
  1061.         }
  1062.  
  1063.         return ret;
  1064.     }
  1065.     #if defined _ALS_AddStaticVehicle
  1066.         #undef AddStaticVehicle
  1067.     #else
  1068.         #define _ALS_AddStaticVehicle
  1069.     #endif
  1070.  
  1071.     #define AddStaticVehicle Iter_AddStaticVehicle
  1072.  
  1073.     /*
  1074.         Iter_AddStaticVehicleEx
  1075.     */
  1076.  
  1077.     stock Iter_AddStaticVehicleEx(modelid, Float:spawn_x, Float:spawn_y, Float:spawn_z, Float:angle, color1, color2, respawn_delay, bool:addsiren = false)
  1078.     {
  1079.         new
  1080.             ret = AddStaticVehicleEx(modelid, spawn_x, spawn_y, spawn_z, angle, color1, color2, respawn_delay, addsiren);
  1081.  
  1082.         if (ret != INVALID_VEHICLE_ID) {
  1083.             #if defined FOREACH_MULTISCRIPT
  1084.                 CallRemoteFunction("Iter_AddVehicle", "i", ret);
  1085.             #else
  1086.                 Iter_Add(Vehicle, ret);
  1087.             #endif
  1088.         }
  1089.  
  1090.         return ret;
  1091.     }
  1092.     #if defined _ALS_AddStaticVehicleEx
  1093.         #undef AddStaticVehicleEx
  1094.     #else
  1095.         #define _ALS_AddStaticVehicleEx
  1096.     #endif
  1097.  
  1098.     #define AddStaticVehicleEx Iter_AddStaticVehicleEx
  1099.  
  1100.     /*
  1101.         DestroyVehicleSafe
  1102.     */
  1103.  
  1104.     stock DestroyVehicleSafe(&vehicleid)
  1105.     {
  1106.         new success = DestroyVehicle(vehicleid);
  1107.         #if defined FOREACH_MULTISCRIPT
  1108.             vehicleid = CallRemoteFunction("Iter_RemoveVehicle", "i", vehicleid);
  1109.         #else
  1110.             Iter_SafeRemove(Vehicle, vehicleid, vehicleid);
  1111.         #endif
  1112.         return success;
  1113.     }
  1114.  
  1115.     /*
  1116.         Iter_DestroyVehicle
  1117.     */
  1118.  
  1119.     stock Iter_DestroyVehicle(vehicleid)
  1120.     {
  1121.         #if defined FOREACH_MULTISCRIPT
  1122.             CallRemoteFunction("Iter_RemoveVehicle", "i", vehicleid);
  1123.         #else
  1124.             Iter_Remove(Vehicle, vehicleid);
  1125.         #endif
  1126.         return DestroyVehicle(vehicleid);
  1127.     }
  1128.     #if defined _ALS_DestroyVehicle
  1129.         #undef DestroyVehicle
  1130.     #else
  1131.         #define _ALS_DestroyVehicle
  1132.     #endif
  1133.  
  1134.     #define DestroyVehicle Iter_DestroyVehicle
  1135.  
  1136.     /*
  1137.         Iter_AddVehicle
  1138.     */
  1139.  
  1140.     #if defined FOREACH_MULTISCRIPT
  1141.  
  1142.         public Iter_AddVehicle(vehicleid)
  1143.         {
  1144.             return Iter_Add(Vehicle, vehicleid);
  1145.         }
  1146.  
  1147.     #endif
  1148.  
  1149.     /*
  1150.         Iter_RemoveVehicle
  1151.     */
  1152.  
  1153.     #if defined FOREACH_MULTISCRIPT
  1154.  
  1155.         public Iter_RemoveVehicle(vehicleid)
  1156.         {
  1157.             Iter_SafeRemove(Vehicle, vehicleid, vehicleid);
  1158.             return vehicleid;
  1159.         }
  1160.  
  1161.     #endif
  1162.  
  1163. #endif
  1164.  
  1165. /*
  1166.     VEHICLES ENDS
  1167. */
  1168.  
  1169. /*
  1170.     ACTORS
  1171. */
  1172.  
  1173. #if FOREACH_I_Actor
  1174.  
  1175.     /*
  1176.         Iter_CreateActor
  1177.     */
  1178.  
  1179.     stock Iter_CreateActor(modelid, Float:X, Float:Y, Float:Z, Float:Rotation)
  1180.     {
  1181.         new
  1182.             ret = CreateActor(modelid, X, Y, Z, Rotation);
  1183.         if (ret != INVALID_ACTOR_ID) {
  1184.             #if defined FOREACH_MULTISCRIPT
  1185.                 CallRemoteFunction("Iter_AddActor", "i", ret);
  1186.             #else
  1187.                 Iter_Add(Actor, ret);
  1188.             #endif
  1189.         }
  1190.         return ret;
  1191.     }
  1192.     #if defined _ALS_CreateActor
  1193.         #undef CreateActor
  1194.     #else
  1195.         #define _ALS_CreateActor
  1196.     #endif
  1197.  
  1198.     #define CreateActor Iter_CreateActor
  1199.  
  1200.     /*
  1201.         DestroyActorSafe
  1202.     */
  1203.  
  1204.     stock DestroyActorSafe(&actorid)
  1205.     {
  1206.         new success = DestroyActor(actorid);
  1207.         #if defined FOREACH_MULTISCRIPT
  1208.             actorid = CallRemoteFunction("Iter_RemoveActor", "i", actorid);
  1209.         #else
  1210.             Iter_SafeRemove(Actor, actorid, actorid);
  1211.         #endif
  1212.         return success;
  1213.     }
  1214.  
  1215.     /*
  1216.         Iter_DestroyActor
  1217.     */
  1218.  
  1219.     stock Iter_DestroyActor(actorid)
  1220.     {
  1221.         #if defined FOREACH_MULTISCRIPT
  1222.             CallRemoteFunction("Iter_RemoveActor", "i", actorid);
  1223.         #else
  1224.             Iter_Remove(Actor, actorid);
  1225.         #endif
  1226.         return DestroyActor(actorid);
  1227.     }
  1228.     #if defined _ALS_DestroyActor
  1229.         #undef DestroyActor
  1230.     #else
  1231.         #define _ALS_DestroyActor
  1232.     #endif
  1233.  
  1234.     #define DestroyActor Iter_DestroyActor
  1235.  
  1236.     /*
  1237.         Iter_AddActor
  1238.     */
  1239.  
  1240.     #if defined FOREACH_MULTISCRIPT
  1241.  
  1242.         public Iter_AddActor(actorid)
  1243.         {
  1244.             return Iter_Add(Actor, actorid);
  1245.         }
  1246.  
  1247.     #endif
  1248.  
  1249.     /*
  1250.         Iter_RemoveActor
  1251.     */
  1252.  
  1253.     #if defined FOREACH_MULTISCRIPT
  1254.  
  1255.         public Iter_RemoveActor(actorid)
  1256.         {
  1257.             Iter_SafeRemove(Actor, actorid, actorid);
  1258.             return actorid;
  1259.         }
  1260.  
  1261.     #endif
  1262.  
  1263. #endif
  1264.  
  1265. /*
  1266.     ACTORS ENDS
  1267. */
  1268.  
  1269. /*
  1270.     PLAYERS STREAM
  1271. */
  1272.  
  1273. #if FOREACH_I_PlayerPlayersStream
  1274.  
  1275.     /*
  1276.         Iter_OnPlayerStreamIn
  1277.     */
  1278.  
  1279.     public OnPlayerStreamIn(playerid, forplayerid)
  1280.     {
  1281.         Iter_Add(PlayerPlayersStream[playerid], forplayerid);
  1282.  
  1283.         #if defined Iter_OnPlayerStreamIn
  1284.             return Iter_OnPlayerStreamIn(playerid, forplayerid);
  1285.         #else
  1286.             return 1;
  1287.         #endif
  1288.     }
  1289.     #if defined _ALS_OnPlayerStreamIn
  1290.         #undef OnPlayerStreamIn
  1291.     #else
  1292.         #define _ALS_OnPlayerStreamIn
  1293.     #endif
  1294.  
  1295.     #define OnPlayerStreamIn Iter_OnPlayerStreamIn
  1296.     #if defined Iter_OnPlayerStreamIn
  1297.         forward Iter_OnPlayerStreamIn(playerid, forplayerid);
  1298.     #endif
  1299.  
  1300.     /*
  1301.         Iter_OnPlayerStreamOut
  1302.     */
  1303.  
  1304.     public OnPlayerStreamOut(playerid, forplayerid)
  1305.     {
  1306.         Iter_Remove(PlayerPlayersStream[playerid], forplayerid);
  1307.  
  1308.         #if defined Iter_OnPlayerStreamOut
  1309.             return Iter_OnPlayerStreamOut(playerid, forplayerid);
  1310.         #else
  1311.             return 1;
  1312.         #endif
  1313.     }
  1314.     #if defined _ALS_OnPlayerStreamOut
  1315.         #undef OnPlayerStreamOut
  1316.     #else
  1317.         #define _ALS_OnPlayerStreamOut
  1318.     #endif
  1319.  
  1320.     #define OnPlayerStreamOut Iter_OnPlayerStreamOut
  1321.     #if defined Iter_OnPlayerStreamOut
  1322.         forward Iter_OnPlayerStreamOut(playerid, forplayerid);
  1323.     #endif
  1324.  
  1325. #endif
  1326.  
  1327. /*
  1328.     PLAYERS STREAM ENDS
  1329. */
  1330.  
  1331. /*
  1332.     VEHICLES STREAM
  1333. */
  1334.  
  1335. #if FOREACH_I_PlayerVehiclesStream || FOREACH_I_VehiclePlayersStream
  1336.  
  1337.     /*
  1338.         Iter_OnVehicleStreamIn
  1339.     */
  1340.  
  1341.     public OnVehicleStreamIn(vehicleid, forplayerid)
  1342.     {
  1343.         #if FOREACH_I_PlayerVehiclesStream
  1344.             Iter_Add(PlayerVehiclesStream[forplayerid], vehicleid);
  1345.         #endif
  1346.  
  1347.         #if FOREACH_I_VehiclePlayersStream
  1348.             Iter_Add(VehiclePlayersStream[vehicleid], forplayerid);
  1349.         #endif
  1350.  
  1351.         #if defined Iter_OnVehicleStreamIn
  1352.             return Iter_OnVehicleStreamIn(vehicleid, forplayerid);
  1353.         #else
  1354.             return 1;
  1355.         #endif
  1356.     }
  1357.     #if defined _ALS_OnVehicleStreamIn
  1358.         #undef OnVehicleStreamIn
  1359.     #else
  1360.         #define _ALS_OnVehicleStreamIn
  1361.     #endif
  1362.  
  1363.     #define OnVehicleStreamIn Iter_OnVehicleStreamIn
  1364.     #if defined Iter_OnVehicleStreamIn
  1365.         forward Iter_OnVehicleStreamIn(vehicleid, forplayerid);
  1366.     #endif
  1367.  
  1368.     /*
  1369.         Iter_OnVehicleStreamOut
  1370.     */
  1371.  
  1372.     public OnVehicleStreamOut(vehicleid, forplayerid)
  1373.     {
  1374.         #if FOREACH_I_PlayerVehiclesStream
  1375.             Iter_Remove(PlayerVehiclesStream[forplayerid], vehicleid);
  1376.         #endif
  1377.  
  1378.         #if FOREACH_I_VehiclePlayersStream
  1379.             Iter_Remove(VehiclePlayersStream[vehicleid], forplayerid);
  1380.         #endif
  1381.  
  1382.         #if defined Iter_OnVehicleStreamOut
  1383.             return Iter_OnVehicleStreamOut(vehicleid, forplayerid);
  1384.         #else
  1385.             return 1;
  1386.         #endif
  1387.     }
  1388.     #if defined _ALS_OnVehicleStreamOut
  1389.         #undef OnVehicleStreamOut
  1390.     #else
  1391.         #define _ALS_OnVehicleStreamOut
  1392.     #endif
  1393.  
  1394.     #define OnVehicleStreamOut Iter_OnVehicleStreamOut
  1395.     #if defined Iter_OnVehicleStreamOut
  1396.         forward Iter_OnVehicleStreamOut(vehicleid, forplayerid);
  1397.     #endif
  1398.  
  1399. #endif
  1400.  
  1401. /*
  1402.     VEHICLES STREAM ENDS
  1403. */
  1404.  
  1405. /*
  1406.     ACTORS STREAM
  1407. */
  1408.  
  1409. #if FOREACH_I_PlayerActorsStream || FOREACH_I_ActorPlayersStream
  1410.  
  1411.     /*
  1412.         Iter_OnActorStreamIn
  1413.     */
  1414.  
  1415.     public OnActorStreamIn(actorid, forplayerid)
  1416.     {
  1417.         #if FOREACH_I_PlayerActorsStream
  1418.             Iter_Add(PlayerActorsStream[forplayerid], actorid);
  1419.         #endif
  1420.  
  1421.         #if FOREACH_I_ActorPlayersStream
  1422.             Iter_Add(ActorPlayersStream[actorid], forplayerid);
  1423.         #endif
  1424.  
  1425.         #if defined Iter_OnActorStreamIn
  1426.             return Iter_OnActorStreamIn(actorid, forplayerid);
  1427.         #else
  1428.             return 1;
  1429.         #endif
  1430.     }
  1431.     #if defined _ALS_OnActorStreamIn
  1432.         #undef OnActorStreamIn
  1433.     #else
  1434.         #define _ALS_OnActorStreamIn
  1435.     #endif
  1436.  
  1437.     #define OnActorStreamIn Iter_OnActorStreamIn
  1438.     #if defined Iter_OnActorStreamIn
  1439.         forward Iter_OnActorStreamIn(actorid, forplayerid);
  1440.     #endif
  1441.  
  1442.     /*
  1443.         Iter_OnActorStreamOut
  1444.     */
  1445.  
  1446.     public OnActorStreamOut(actorid, forplayerid)
  1447.     {
  1448.         #if FOREACH_I_PlayerActorsStream
  1449.             Iter_Remove(PlayerActorsStream[forplayerid], actorid);
  1450.         #endif
  1451.  
  1452.         #if FOREACH_I_ActorPlayersStream
  1453.             Iter_Remove(ActorPlayersStream[actorid], forplayerid);
  1454.         #endif
  1455.  
  1456.         #if defined Iter_OnActorStreamOut
  1457.             return Iter_OnActorStreamOut(actorid, forplayerid);
  1458.         #else
  1459.             return 1;
  1460.         #endif
  1461.     }
  1462.     #if defined _ALS_OnActorStreamOut
  1463.         #undef OnActorStreamOut
  1464.     #else
  1465.         #define _ALS_OnActorStreamOut
  1466.     #endif
  1467.  
  1468.     #define OnActorStreamOut Iter_OnActorStreamOut
  1469.     #if defined Iter_OnActorStreamOut
  1470.         forward Iter_OnActorStreamOut(actorid, forplayerid);
  1471.     #endif
  1472.  
  1473. #endif
  1474.  
  1475. /*
  1476.     ACTORS STREAM ENDS
  1477. */
  1478.  
  1479. /*
  1480.     PLAYERS IN VEHICLE
  1481. */
  1482.  
  1483. #if FOREACH_I_PlayerInVehicle
  1484.  
  1485.     /*
  1486.         Iter_OnPlayerStateChange
  1487.     */
  1488.  
  1489.     public OnPlayerStateChange(playerid, newstate, oldstate)
  1490.     {
  1491.         if (newstate == PLAYER_STATE_DRIVER || newstate == PLAYER_STATE_PASSENGER) {
  1492.             Iter_gPlayerVehicleId[playerid] = GetPlayerVehicleID(playerid);
  1493.             Iter_Add(PlayerInVehicle[Iter_gPlayerVehicleId[playerid]], playerid);
  1494.         } else if (oldstate == PLAYER_STATE_DRIVER || oldstate == PLAYER_STATE_PASSENGER) {
  1495.             if (Iter_gPlayerVehicleId[playerid] != INVALID_VEHICLE_ID) {
  1496.                 Iter_Remove(PlayerInVehicle[Iter_gPlayerVehicleId[playerid]], playerid);
  1497.                 Iter_gPlayerVehicleId[playerid] = INVALID_VEHICLE_ID;
  1498.             }
  1499.         }
  1500.  
  1501.         #if defined Iter_OnPlayerStateChange
  1502.             return Iter_OnPlayerStateChange(playerid, newstate, oldstate);
  1503.         #else
  1504.             return 1;
  1505.         #endif
  1506.     }
  1507.     #if defined _ALS_OnPlayerStateChange
  1508.         #undef OnPlayerStateChange
  1509.     #else
  1510.         #define _ALS_OnPlayerStateChange
  1511.     #endif
  1512.  
  1513.     #define OnPlayerStateChange Iter_OnPlayerStateChange
  1514.     #if defined Iter_OnPlayerStateChange
  1515.         forward Iter_OnPlayerStateChange(playerid, newstate, oldstate);
  1516.     #endif
  1517.  
  1518. #endif
  1519.  
  1520. /*
  1521.     PLAYERS IN VEHECLE ENDS
  1522. */
  1523.  
  1524. /*
  1525. --------------------------------------------------------------------------------
  1526. Function:
  1527.     Iter_RandomInternal
  1528. Params:
  1529.     count - Number of items in the iterator.
  1530.     array[] - Iterator data.
  1531.     size - Size of the iterator.
  1532. Return:
  1533.     -
  1534. Notes:
  1535.     Returns a random value from an iterator.
  1536. --------------------------------------------------------------------------------
  1537. */
  1538.  
  1539. stock Iter_RandomInternal(count, const array[], size)
  1540. {
  1541.     if (count == 0) {
  1542.         return ITER_NONE;
  1543.     }
  1544.     new
  1545.         rnd = random(count),
  1546.         cur = array[size];
  1547.     while (cur != size) {
  1548.         if (rnd-- == 0) {
  1549.             return cur;
  1550.         }
  1551.         cur = array[cur];
  1552.     }
  1553.     return ITER_NONE;
  1554. }
  1555.  
  1556. /*
  1557. --------------------------------------------------------------------------------
  1558. Function:
  1559.     Iter_FreeInternal
  1560. Params:
  1561.     array[] - Iterator data.
  1562.     size - Size of the iterator.
  1563. Return:
  1564.     -
  1565. Notes:
  1566.     Finds the first free slot in the iterator. Iterators now HAVE to be
  1567.     sorted for this function to work correctly as it uses that fact to decide
  1568.     whether a slot is unused or the last one. If you want to use the slot
  1569.     straight after finding it the iterator will need to re-find it to add in
  1570.     the data.
  1571. --------------------------------------------------------------------------------
  1572. */
  1573.  
  1574. stock Iter_FreeInternal(const array[], size)
  1575. {
  1576.     for (new i = 0; i != size; ++i) {
  1577.         if (array[i] > size) {
  1578.             return i;
  1579.         }
  1580.     }
  1581.     return ITER_NONE;
  1582. }
  1583.  
  1584. /*
  1585. --------------------------------------------------------------------------------
  1586. Function:
  1587.     Iter_AddInternal
  1588. Params:
  1589.     &count - Number of items in the iterator.
  1590.     array[] - Iterator data.
  1591.     value - Item to add.
  1592.     size - Size of the iterator.
  1593. Return:
  1594.     -
  1595. Notes:
  1596.     Adds a value to a given iterator set. Now detects when you try and add the
  1597.     last item multiple times, as well as all the other items. Now simplified even
  1598.     further with the new internal representation.
  1599. --------------------------------------------------------------------------------
  1600. */
  1601.  
  1602. stock Iter_AddInternal(&count, array[], value, size)
  1603. {
  1604.     if (0 <= value < size && array[value] > size) {
  1605.         new
  1606.             last = size,
  1607.             next = array[last];
  1608.         while (next < value) {
  1609.             last = next;
  1610.             next = array[last];
  1611.         }
  1612.         array[last] = value;
  1613.         array[value] = next;
  1614.         ++count;
  1615.         return 1;
  1616.     }
  1617.     return 0;
  1618. }
  1619.  
  1620. /*
  1621. --------------------------------------------------------------------------------
  1622. Function:
  1623.     Iter_RemoveInternal
  1624. Params:
  1625.     &count - Number of items in the iterator.
  1626.     array[] - Iterator data.
  1627.     value - Item to remove.
  1628.     size - Size of the iterator.
  1629. Return:
  1630.     -
  1631. Notes:
  1632.     Removes a value from an iterator.
  1633. --------------------------------------------------------------------------------
  1634. */
  1635.  
  1636. stock Iter_RemoveInternal(&count, array[], value, size)
  1637. {
  1638.     new
  1639.         last;
  1640.     return Iter_SafeRemoveInternal(count, array, value, last, size);
  1641. }
  1642.  
  1643. /*
  1644. --------------------------------------------------------------------------------
  1645. Function:
  1646.     Iter_SafeRemoveInternal
  1647. Params:
  1648.     &count - Number of items in the iterator.
  1649.     array[] - Iterator data.
  1650.     value - Item to remove.
  1651.     &last - Pointer in which to store the last pointer.
  1652.     size - Size of the iterator.
  1653. Return:
  1654.     -
  1655. Notes:
  1656.     Removes a value from an iterator safely.
  1657. --------------------------------------------------------------------------------
  1658. */
  1659.  
  1660. stock Iter_SafeRemoveInternal(&count, array[], value, &last, size)
  1661. {
  1662.     if (0 <= value < size && array[value] <= size) {
  1663.         last = size;
  1664.         new
  1665.             next = array[last];
  1666.         while (next < size) {
  1667.             if (next == value) {
  1668.                 array[last] = array[value];
  1669.                 array[value] = size + 1;
  1670.                 --count;
  1671.                 return 1;
  1672.             }
  1673.             last = next;
  1674.             next = array[last];
  1675.         }
  1676.     }
  1677.     return 0;
  1678. }
  1679.  
  1680. /*
  1681. --------------------------------------------------------------------------------
  1682. Function:
  1683.     Iter_ContainsInternal
  1684. Params:
  1685.     array[] - Iterator data.
  1686.     value - Item to check.
  1687.     size - Size of the iterator.
  1688. Return:
  1689.     -
  1690. Notes:
  1691.     Checks if this item is in the iterator.
  1692. --------------------------------------------------------------------------------
  1693. */
  1694.  
  1695. stock Iter_ContainsInternal(const array[], value, size)
  1696. {
  1697.     return 0 <= value < size && array[value] <= size;
  1698. }
  1699.  
  1700. /*
  1701. --------------------------------------------------------------------------------
  1702. Function:
  1703.     Iter_ClearInternal
  1704. Params:
  1705.     &count - Number of items in the iterator.
  1706.     array[] - Iterator data.
  1707.     size - Size of the iterator.
  1708. Return:
  1709.     -
  1710. Notes:
  1711.     Resets an iterator.
  1712. --------------------------------------------------------------------------------
  1713. */
  1714.  
  1715. stock Iter_ClearInternal(&count, array[], size)
  1716. {
  1717.     for (new i = 0, t = size + 1; i < size; ++i) {
  1718.         array[i] = t;
  1719.     }
  1720.     array[size] = size;
  1721.     count = 0;
  1722. }
  1723.  
  1724. /*-------------------------------------------------------------------------*//**
  1725.  * <param name="count">Number of items in the iterator.</param>
  1726.  * <param name="array">iterator data.</param>
  1727.  * <param name="start">Array start index.</param>
  1728.  * <param name="size">Array size.</param>
  1729.  * <param name="index">Index to find Nth value.</param>
  1730.  * <param name="wrap">Keep going around until a value is found?</param>
  1731.  * <remarks>
  1732.  *  Allows you to find the Nth value in the iterator.  DO NOT call this in a
  1733.  *  loop to get all values - that totally defeats the purpose of "foreach", just
  1734.  *  use a normal "foreach" loop with an index counter for that case.
  1735.  * </remarks>
  1736.  *//*------------------------------------------------------------------------**/
  1737.  
  1738. stock Iter_IndexInternal(count, const array[], start, size, index)
  1739. {
  1740.     // If there are no elements in the iterator, we can't ever return the Nth
  1741.     // item.  Also if the parameters are invalid.
  1742.     if (index < 0 || start < size || array[start] >= size) {
  1743.         return ITER_NONE;
  1744.     }
  1745.     // We could wrap around in the loop (it would work), but it is better to set
  1746.     // the limit first.
  1747.     if (index >= count) {
  1748.         return ITER_NONE;
  1749.     }
  1750.     start = array[start];
  1751.     while (index--) {
  1752.         start = array[start];
  1753.     }
  1754.     return start;
  1755. }
  1756.  
  1757. /*
  1758. --------------------------------------------------------------------------------
  1759. Function:
  1760.     Iter_InitInternal
  1761. Params:
  1762.     array[][] - Iterator array to initialise.
  1763.     s0 - Size of first dimension.
  1764.     s1 - Size of second dimension.
  1765. Return:
  1766.     -
  1767. Notes:
  1768.     Multi-dimensional arrays can not be initialised at compile time, so need to be
  1769.     done at run time, which is slightly annoying.
  1770. --------------------------------------------------------------------------------
  1771. */
  1772.  
  1773. stock Iter_InitInternal(arr[][], s0, s1)
  1774. {
  1775.     for (new i = 0, t = s1 + 1; i < s0; ++i) {
  1776.         for (new j = 0; j < s1; ++j) {
  1777.             arr[i][j] = t;
  1778.         }
  1779.         arr[i][s1] = s1;
  1780.     }
  1781. }
  1782.  
  1783. /*
  1784. --------------------------------------------------------------------------------
  1785. Function:
  1786.     Iter_PrevInternal
  1787. Params:
  1788.     array[] - Iterator data.
  1789.     size - Size of the iterator.
  1790.     slot - The current slot.
  1791. Return:
  1792.     -
  1793. Notes:
  1794.     Gets the element in an iterator that points to the current element.
  1795. --------------------------------------------------------------------------------
  1796. */
  1797.  
  1798. stock Iter_PrevInternal(const array[], size, slot)
  1799. {
  1800.     if (0 <= slot <= size && array[slot] <= size) {
  1801.         for (new last = slot; last--; ) {
  1802.             if (array[last] == slot) {
  1803.                 return last;
  1804.             }
  1805.         }
  1806.     }
  1807.     return size;
  1808. }
  1809.  
  1810. /*
  1811. --------------------------------------------------------------------------------
  1812. Function:
  1813.     Iter_Begin
  1814. Params:
  1815.     iter - Name of the iterator to get the start of.
  1816. Return:
  1817.     -
  1818. Notes:
  1819.     Gets a point BEFORE the start of the iterator (the theoretical beginning).
  1820. --------------------------------------------------------------------------------
  1821. */
  1822.  
  1823. #define Iter_Begin(%1) (_Y_ITER_ARRAY_SIZE(%1))
  1824. #define Iter_Start Iter_Begin
  1825.  
  1826. /*
  1827. --------------------------------------------------------------------------------
  1828. Function:
  1829.     Iter_End
  1830. Params:
  1831.     iter - Name of the iterator to
  1832. Return:
  1833.     -
  1834. Notes:
  1835.     Gets a point AFTER the end of the iterator (think "MAX_PLAYERS").
  1836. --------------------------------------------------------------------------------
  1837. */
  1838.  
  1839. #define Iter_End(%1) (_Y_ITER_ARRAY_SIZE(%1))
  1840. #define Iter_Finish Iter_End
  1841.  
  1842. /*
  1843. --------------------------------------------------------------------------------
  1844. Function:
  1845.     Iter_First
  1846. Params:
  1847.     iter - Name of the iterator to
  1848. Return:
  1849.     -
  1850. Notes:
  1851.     Gets the first element in an iterator.
  1852. --------------------------------------------------------------------------------
  1853. */
  1854.  
  1855. #define Iter_First(%1) (_Y_ITER_ARRAY:%1@YSII_Ag[_Y_ITER_ARRAY_SIZE(%1)])
  1856.  
  1857. /*
  1858. --------------------------------------------------------------------------------
  1859. Function:
  1860.     Iter_Last
  1861. Params:
  1862.     iter - Name of the iterator to
  1863. Return:
  1864.     -
  1865. Notes:
  1866.     Gets the last element in an iterator.
  1867. --------------------------------------------------------------------------------
  1868. */
  1869.  
  1870. #define Iter_Last(%1) Iter_PrevInternal(_Y_ITER_ARRAY:%1@YSII_Ag,_Y_ITER_ARRAY_SIZE(%1),_Y_ITER_ARRAY_SIZE(%1))
  1871.  
  1872. /*
  1873. --------------------------------------------------------------------------------
  1874. Function:
  1875.     Iter_Next
  1876. Params:
  1877.     iter - Name of the iterator to
  1878. Return:
  1879.     -
  1880. Notes:
  1881.     Gets the element in an interator after the current one.
  1882. --------------------------------------------------------------------------------
  1883. */
  1884.  
  1885. #define Iter_Next(%1,%2) (_Y_ITER_ARRAY:%1@YSII_Ag[(%2)])
  1886.  
  1887. /*
  1888. --------------------------------------------------------------------------------
  1889. Function:
  1890.     Iter_Prev
  1891. Params:
  1892.     iter - Name of the iterator to
  1893. Return:
  1894.     -
  1895. Notes:
  1896.     Gets the element in an iterator before the current one. Slow.
  1897. --------------------------------------------------------------------------------
  1898. */
  1899.  
  1900. #define Iter_Prev(%1,%2) Iter_PrevInternal(_Y_ITER_ARRAY:%1@YSII_Ag,_Y_ITER_ARRAY_SIZE(%1),(%2))
  1901. #define Iter_Previous Iter_Prev
  1902.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement